下面列出了com.google.common.collect.ImmutableMap#containsKey ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/** Returns the merged jar derived from an AAR, in the unpacked AAR directory. */
@Nullable
public File getClassJar(ArtifactLocationDecoder decoder, AarLibrary library) {
if (library.libraryArtifact == null) {
return null;
}
ImmutableMap<String, File> cacheState = this.cacheState;
BlazeArtifact artifact = decoder.resolveOutput(library.libraryArtifact.jarForIntellijLibrary());
if (cacheState.isEmpty()) {
return getFallbackFile(artifact);
}
String cacheKey = cacheKeyForAar(decoder.resolveOutput(library.aarArtifact));
// check if it was actually cached
if (!cacheState.containsKey(cacheKey)) {
return getFallbackFile(artifact);
}
return jarFileForKey(cacheKey);
}
private void addEntitlementsPlistIntoTarget(
TargetNode<? extends HasAppleBundleFields> targetNode,
ImmutableXCodeNativeTargetAttributes.Builder nativeTargetBuilder) {
ImmutableMap<String, String> infoPlistSubstitutions =
targetNode.getConstructorArg().getInfoPlistSubstitutions();
if (infoPlistSubstitutions.containsKey(AppleBundle.CODE_SIGN_ENTITLEMENTS)) {
// Expand SOURCE_ROOT to the target base path so we can get the full proper path to the
// entitlements file instead of a path relative to the project.
String targetPath =
targetNode.getBuildTarget().getCellRelativeBasePath().getPath().toString();
String entitlementsPlistPath =
InfoPlistSubstitution.replaceVariablesInString(
"$(" + AppleBundle.CODE_SIGN_ENTITLEMENTS + ")",
AppleBundle.withDefaults(
infoPlistSubstitutions,
ImmutableMap.of(
"SOURCE_ROOT", targetPath,
"SRCROOT", targetPath)));
nativeTargetBuilder.setEntitlementsPlistPath(Optional.of(Paths.get(entitlementsPlistPath)));
}
}
/**
* Populates provided {@code builder} with values from {@code kwargs} assuming {@code ruleClass}
* as the target {@link BaseDescription} class.
*
* @param kwargs The keyword arguments and their values passed to rule function in build file.
* @param builder The map builder used for storing extracted attributes and their values.
* @param allParamInfo The parameter information for every build rule attribute.
*/
private void populateAttributes(
Map<String, Object> kwargs,
ImmutableMap.Builder<String, Object> builder,
ImmutableMap<String, ParamInfo<?>> allParamInfo) {
for (Map.Entry<String, Object> kwargEntry : kwargs.entrySet()) {
String paramName =
CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, kwargEntry.getKey());
if (!allParamInfo.containsKey(paramName)
&& !(IMPLICIT_ATTRIBUTES.contains(kwargEntry.getKey()))) {
throw new IllegalArgumentException(kwargEntry.getKey() + " is not a recognized attribute");
}
if (Runtime.NONE.equals(kwargEntry.getValue())) {
continue;
}
builder.put(paramName, kwargEntry.getValue());
}
}
/**
* Perform the merging and return the result.
*
* @return an instance of {@link com.android.manifmerger.MergingReport} that will give
* access to all the logging and merging records.
*
* This method can be invoked several time and will re-do the file merges.
*
* @throws MergeFailureException if the merging
* cannot be completed successfully.
*/
public MergingReport merge() throws MergeFailureException {
// provide some free placeholders values.
ImmutableMap<SystemProperty, Object> systemProperties = mSystemProperties.build();
if (systemProperties.containsKey(SystemProperty.PACKAGE)) {
mPlaceholders.put(PACKAGE_NAME, systemProperties.get(SystemProperty.PACKAGE));
mPlaceholders.put(APPLICATION_ID, systemProperties.get(SystemProperty.PACKAGE));
}
ManifestMerger2 manifestMerger =
new ManifestMerger2(
mLogger,
mMainManifestFile,
mLibraryFilesBuilder.build(),
mFlavorsAndBuildTypeFiles.build(),
mFeaturesBuilder.build(),
mPlaceholders.build(),
new MapBasedKeyBasedValueResolver<SystemProperty>(systemProperties),
mMergeType,
Optional.fromNullable(mReportFile));
return manifestMerger.merge();
}
/**
* Recursively constructs file descriptors for all dependencies of the supplied proto and returns
* a {@link FileDescriptor} for the supplied proto itself. For maximal efficiency, reuse the
* descriptorCache argument across calls.
*/
private static FileDescriptor descriptorFromProto(
FileDescriptorProto descriptorProto,
ImmutableMap<String, FileDescriptorProto> descriptorProtoIndex,
Map<String, FileDescriptor> descriptorCache) throws DescriptorValidationException {
// First, check the cache.
String descriptorName = descriptorProto.getName();
if (descriptorCache.containsKey(descriptorName)) {
return descriptorCache.get(descriptorName);
}
// Then, fetch all the required dependencies recursively.
ImmutableList.Builder<FileDescriptor> dependencies = ImmutableList.builder();
for (String dependencyName : descriptorProto.getDependencyList()) {
if (!descriptorProtoIndex.containsKey(dependencyName)) {
throw new IllegalArgumentException("Could not find dependency: " + dependencyName);
}
FileDescriptorProto dependencyProto = descriptorProtoIndex.get(dependencyName);
dependencies.add(descriptorFromProto(dependencyProto, descriptorProtoIndex, descriptorCache));
}
// Finally, construct the actual descriptor.
FileDescriptor[] empty = new FileDescriptor[0];
return FileDescriptor.buildFrom(descriptorProto, dependencies.build().toArray(empty));
}
CommandWithArgs parseCommand(ImmutableMap<String, ? extends CopybaraCmd> commands,
CopybaraCmd defaultCmd) throws CommandLineException {
if (unnamed.isEmpty()) {
return new CommandWithArgs(defaultCmd, ImmutableList.of());
}
String firstArg = unnamed.get(0);
// Default command might take a config file as param.
if (firstArg.endsWith(COPYBARA_SKYLARK_CONFIG_FILENAME)) {
return new CommandWithArgs(defaultCmd, ImmutableList.copyOf(unnamed));
}
if (!commands.containsKey(firstArg.toLowerCase())) {
throw new CommandLineException(
String.format("Invalid subcommand '%s'. Available commands: %s", firstArg,
new TreeSet<>(commands.keySet())));
}
return new CommandWithArgs(commands.get(firstArg.toLowerCase()),
ImmutableList.copyOf(unnamed.subList(1, unnamed.size())));
}
public static ImmutableMap<Path, SourcePath> addMissingInitModules(
ImmutableMap<Path, SourcePath> modules, SourcePath emptyInit) {
Map<Path, SourcePath> initModules = new LinkedHashMap<>();
// Insert missing `__init__.py` modules.
Set<Path> packages = new HashSet<>();
for (Path module : modules.keySet()) {
Path pkg = module;
while ((pkg = pkg.getParent()) != null && !packages.contains(pkg)) {
Path init = pkg.resolve("__init__.py");
if (!modules.containsKey(init)) {
initModules.put(init, emptyInit);
}
packages.add(pkg);
}
}
return ImmutableMap.<Path, SourcePath>builder().putAll(modules).putAll(initModules).build();
}
public boolean confirm(String question) throws IOException {
ImmutableMap<String, Boolean> supportedResponses =
ImmutableMap.of(
"", true,
"y", true,
"yes", true,
"no", false,
"n", false);
for (; ; ) {
output.println();
output.println(question + " (Y/n)?");
output.flush();
String line = reader.readLine();
// Stdin was closed.
if (line == null) {
return false;
}
String response = line.trim().toLowerCase();
if (supportedResponses.containsKey(response)) {
return supportedResponses.get(response);
} else {
output.println("Please answer 'y' or 'n'.");
}
}
}
private Optional<String> getMessageForCheck(
InternetDomainName domainName,
ImmutableMap<String, ForeignKeyIndex<DomainBase>> existingDomains,
ImmutableMap<InternetDomainName, String> tokenCheckResults,
ImmutableMap<String, TldState> tldStates,
Optional<AllocationToken> allocationToken) {
if (existingDomains.containsKey(domainName.toString())) {
return Optional.of("In use");
}
TldState tldState = tldStates.get(domainName.parent().toString());
if (isReserved(domainName, START_DATE_SUNRISE.equals(tldState))) {
if (!isValidReservedCreate(domainName, allocationToken)
&& !isAnchorTenant(domainName, allocationToken, Optional.empty())) {
ImmutableSet<ReservationType> reservationTypes = getReservationTypes(domainName);
if (!reservationTypes.isEmpty()) {
ReservationType highestSeverityType = getTypeOfHighestSeverity(reservationTypes);
return Optional.of(highestSeverityType.getMessageForCheck());
}
}
}
return Optional.ofNullable(emptyToNull(tokenCheckResults.get(domainName)));
}
public static ImmutableMap<String, String> withDefaults(
ImmutableMap<String, String> map, ImmutableMap<String, String> defaults) {
ImmutableMap.Builder<String, String> builder =
ImmutableMap.<String, String>builder().putAll(map);
for (ImmutableMap.Entry<String, String> entry : defaults.entrySet()) {
if (!map.containsKey(entry.getKey())) {
builder = builder.put(entry.getKey(), entry.getValue());
}
}
return builder.build();
}
private void addFileReferenceToSourcesBuildPhase(
ProjectFileWriter.Result result,
SourceWithFlags sourceWithFlags,
PBXSourcesBuildPhase sourcesBuildPhase,
ImmutableMap<CxxSource.Type, ImmutableList<String>> langPreprocessorFlags) {
PBXFileReference fileReference = result.getFileReference();
SourceTreePath sourceTreePath = result.getSourceTreePath();
PBXBuildFile buildFile = objectFactory.createBuildFile(fileReference);
sourcesBuildPhase.getFiles().add(buildFile);
ImmutableList<String> customLangPreprocessorFlags = ImmutableList.of();
Optional<CxxSource.Type> sourceType =
CxxSource.Type.fromExtension(Files.getFileExtension(sourceTreePath.toString()));
if (sourceType.isPresent() && langPreprocessorFlags.containsKey(sourceType.get())) {
customLangPreprocessorFlags = langPreprocessorFlags.get(sourceType.get());
}
ImmutableList<String> customFlags =
ImmutableList.copyOf(
Iterables.concat(customLangPreprocessorFlags, sourceWithFlags.getFlags()));
if (!customFlags.isEmpty()) {
NSDictionary settings = new NSDictionary();
settings.put("COMPILER_FLAGS", Joiner.on(' ').join(customFlags));
buildFile.setSettings(Optional.of(settings));
}
LOG.verbose(
"Added source path %s to sources build phase, flags %s, PBXFileReference %s",
sourceWithFlags, customFlags, fileReference);
}
/**
* Determines whether a dequeue request should be allowed.
*
* @param queueName name of the queue.
* @param numJobs number of jobs intended to be dequeued.
* @return whether to allow the request.
*/
public boolean allowDequeue(String queueName, int numJobs) {
MorePreconditions.checkNotBlank(queueName);
Preconditions.checkArgument(numJobs > 0);
ImmutableMap<String, QueueRateLimiter.IFace> queueRateLimitMap = queueRateLimitMapRef.get();
if (queueRateLimitMap != null && queueRateLimitMap.containsKey(queueName)) {
return queueRateLimitMap.get(queueName).allowDequeue(numJobs);
} else {
// No rate limit specified for this queue, so always allow.
return true;
}
}
@Override
public void run() {
ImmutableMap.Builder<String, AllocationToken> builder = new ImmutableMap.Builder<>();
for (List<String> tokens : Lists.partition(mainParameters, BATCH_SIZE)) {
ImmutableList<Key<AllocationToken>> tokenKeys =
tokens.stream().map(t -> Key.create(AllocationToken.class, t)).collect(toImmutableList());
ofy().load().keys(tokenKeys).forEach((k, v) -> builder.put(k.getName(), v));
}
ImmutableMap<String, AllocationToken> loadedTokens = builder.build();
ImmutableMap<Key<DomainBase>, DomainBase> domains = loadRedeemedDomains(loadedTokens.values());
for (String token : mainParameters) {
if (loadedTokens.containsKey(token)) {
AllocationToken loadedToken = loadedTokens.get(token);
System.out.println(loadedToken.toString());
if (loadedToken.getRedemptionHistoryEntry() == null) {
System.out.printf("Token %s was not redeemed.\n", token);
} else {
DomainBase domain =
domains.get(loadedToken.getRedemptionHistoryEntry().<DomainBase>getParent());
if (domain == null) {
System.out.printf("ERROR: Token %s was redeemed but domain can't be loaded.\n", token);
} else {
System.out.printf(
"Token %s was redeemed to create domain %s at %s.\n",
token, domain.getDomainName(), domain.getCreationTime());
}
}
} else {
System.out.printf("ERROR: Token %s does not exist.\n", token);
}
System.out.println();
}
}
private GitRepo getGitRepo(String repoName, ImmutableMap<String, GitRepo> repoNameToGitRepos) {
if (!repoNameToGitRepos.containsKey(repoName)) {
throw new IllegalArgumentException("Cant find the git repo: " + repoName);
}
return repoNameToGitRepos.get(repoName);
}
protected void ensureOptionExists(final ImmutableMap<OutOfBandManagement.Option, String> options, final OutOfBandManagement.Option option) {
if (options != null && option != null && options.containsKey(option) && !Strings.isNullOrEmpty(options.get(option))) {
return;
}
throw new CloudRuntimeException("Invalid out-of-band management configuration detected for the nested-cloudstack driver");
}
@Override
public ExitCode runWithoutHelp(CommandRunnerParams params) throws Exception {
String projectIde =
ide == null
? getIdeFromBuckConfig(params.getBuckConfig()).map(String::toLowerCase).orElse(null)
: ide.toLowerCase();
if (projectIde == null) {
throw new CommandLineException("project IDE is not specified in Buck config or --ide");
}
int rc = runPreprocessScriptIfNeeded(params, projectIde);
if (rc != 0) {
return ExitCode.map(rc);
}
try (CommandThreadManager pool =
new CommandThreadManager("Project", getConcurrencyLimit(params.getBuckConfig()))) {
ImmutableMap<String, ProjectSubCommand> subcommands =
ides.stream()
.collect(
ImmutableMap.toImmutableMap(
ProjectSubCommand::getOptionValue, Function.identity()));
if (!subcommands.containsKey(projectIde)) {
throw new CommandLineException(
"Unknown IDE: %s. Known IDEs: %s",
projectIde, Joiner.on(", ").join(subcommands.keySet()));
}
ProjectSubCommand subCommand = subcommands.get(projectIde);
ProjectGeneratorParameters projectGeneratorParameters =
ImmutableProjectGeneratorParameters.of(
params,
dryRun,
withTests,
withoutTests,
withoutDependenciesTests,
getEnableParserProfiling(),
arguments ->
parseArgumentsAsTargetNodeSpecs(
params.getCells().getRootCell(),
params.getClientWorkingDir(),
arguments,
params.getBuckConfig()));
params.getBuckEventBus().post(ProjectGenerationEvent.started());
ExitCode result;
try {
result = subCommand.run(params, pool, projectGeneratorParameters, arguments);
rc = runPostprocessScriptIfNeeded(params, projectIde);
if (rc != 0) {
return ExitCode.map(rc);
}
} finally {
params.getBuckEventBus().post(ProjectGenerationEvent.finished());
}
return result;
}
}
private void parseConfigFileOption(
ImmutableMap<CellName, AbsPath> cellMapping, CellConfig.Builder builder, String filename) {
// See if the filename argument specifies the cell.
String[] matches = filename.split("=", 2);
// By default, this config file applies to all cells.
CellName configCellName = CellName.ALL_CELLS_SPECIAL_NAME;
if (matches.length == 2) {
// Filename argument specified the cell to which this config applies.
filename = matches[1];
if (matches[0].equals("//")) {
// Config applies only to the current cell .
configCellName = CellName.ROOT_CELL_NAME;
} else if (!matches[0].equals("*")) { // '*' is the default.
CellName cellName = CellName.of(matches[0]);
if (!cellMapping.containsKey(cellName)) {
throw new HumanReadableException("Unknown cell: %s", matches[0]);
}
configCellName = cellName;
}
}
// Filename may also contain the cell name, so resolve the path to the file.
BuckCellArg filenameArg = BuckCellArg.of(filename);
filename = BuckCellArg.of(filename).getArg();
AbsPath projectRoot =
cellMapping.get(
filenameArg.getCellName().isPresent()
? CellName.of(filenameArg.getCellName().get())
: CellName.ROOT_CELL_NAME);
AbsPath path = projectRoot.resolve(filename);
ImmutableMap<String, ImmutableMap<String, String>> sectionsToEntries;
try {
sectionsToEntries = Configs.parseConfigFile(path.getPath());
} catch (IOException e) {
throw new HumanReadableException(e, "File could not be read: %s", filename);
}
for (Map.Entry<String, ImmutableMap<String, String>> entry : sectionsToEntries.entrySet()) {
String section = entry.getKey();
for (Map.Entry<String, String> sectionEntry : entry.getValue().entrySet()) {
String field = sectionEntry.getKey();
String value = sectionEntry.getValue();
builder.put(configCellName, section, field, value);
}
}
LOG.debug("Loaded a configuration file %s, %s", filename, sectionsToEntries.toString());
}
private void processModule(
APKModule module,
ImmutableSet.Builder<Path> nativeLibraryDirectoriesBuilder,
ImmutableSet.Builder<Path> nativeLibraryAsAssetDirectories,
ImmutableSet.Builder<Path> moduleResourcesDirectories,
ImmutableList.Builder<Step> steps,
SourcePathResolverAdapter pathResolver,
BuildContext context,
ImmutableMap<String, SourcePath> mapOfModuleToSecondaryDexSourcePaths,
ImmutableModuleInfo.Builder baseModuleInfo,
ImmutableSet.Builder<ModuleInfo> modulesInfo) {
boolean addThisModule = false;
ImmutableMap.Builder<Path, String> assetDirectoriesBuilderForThisModule =
ImmutableMap.builder();
ImmutableSet.Builder<Path> nativeLibraryDirectoriesBuilderForThisModule =
ImmutableSet.builder();
Path resourcesDirectoryForThisModule = null;
ImmutableSet.Builder<Path> dexFileDirectoriesBuilderForThisModule = ImmutableSet.builder();
if (mapOfModuleToSecondaryDexSourcePaths.containsKey(module.getName())) {
addDexFileDirectories(
pathResolver,
module,
mapOfModuleToSecondaryDexSourcePaths,
dexFileDirectoriesBuilderForThisModule,
assetDirectoriesBuilderForThisModule);
}
boolean shouldPackageAssetLibraries = packageAssetLibraries || !module.isRootModule();
if (!ExopackageMode.enabledForNativeLibraries(exopackageModes)
&& nativeFilesInfo.nativeLibsDirs.isPresent()
&& nativeFilesInfo.nativeLibsDirs.get().containsKey(module)) {
addThisModule = true;
addNativeDirectory(
shouldPackageAssetLibraries,
module,
pathResolver,
nativeLibraryDirectoriesBuilder,
nativeLibraryDirectoriesBuilderForThisModule);
}
// Package prebuilt libs which need to be loaded by `System.loadLibrary` in the standard dir,
// even in exopackage builds.
if (nativeFilesInfo.nativeLibsDirForSystemLoader.isPresent() && module.isRootModule()) {
addThisModule = true;
Path relativePath =
pathResolver.getRelativePath(nativeFilesInfo.nativeLibsDirForSystemLoader.get());
nativeLibraryDirectoriesBuilder.add(relativePath);
nativeLibraryDirectoriesBuilderForThisModule.add(relativePath);
}
if (shouldPackageAssetLibraries) {
addThisModule = true;
addNativeLibraryAsAssetDirectory(
module,
context,
nativeLibraryAsAssetDirectories,
assetDirectoriesBuilderForThisModule,
steps);
}
if (moduleResourceApkPaths.get(module) != null) {
addThisModule = true;
resourcesDirectoryForThisModule =
addModuleResourceDirectory(module, context, moduleResourcesDirectories, steps);
}
if (!addThisModule || isApk) {
return;
}
if (module.isRootModule()) {
baseModuleInfo
.putAllAssetDirectories(assetDirectoriesBuilderForThisModule.build())
.addAllNativeLibraryDirectories(nativeLibraryDirectoriesBuilderForThisModule.build())
.addAllDexFile(dexFileDirectoriesBuilderForThisModule.build());
} else {
String moduleName = module.getName();
modulesInfo.add(
ImmutableModuleInfo.of(
moduleName,
resourcesDirectoryForThisModule,
dexFileDirectoriesBuilderForThisModule.build(),
assetDirectoriesBuilderForThisModule.build(),
nativeLibraryDirectoriesBuilderForThisModule.build(),
ImmutableSet.<Path>builder().build(),
ImmutableSet.<Path>builder().build()));
}
}
private MethodSpec generateConstructorFromParcel(
ProcessingEnvironment env,
ImmutableList<Property> properties,
ImmutableMap<TypeMirror, FieldSpec> typeAdapters) {
// Create the PRIVATE constructor from Parcel
MethodSpec.Builder builder = MethodSpec.constructorBuilder()
.addModifiers(PRIVATE) // private
.addParameter(ClassName.bestGuess("android.os.Parcel"), "in"); // input param
// get a code block builder
CodeBlock.Builder block = CodeBlock.builder();
// First thing is reading the Parcelable object version
block.add("this.version = in.readInt();\n");
// FIXME: 31/07/16 remove if not used
boolean requiresSuppressWarnings = false;
// Now, iterate all properties, check the version initialize them
for (Property p : properties) {
// get the property version
int pVersion = p.version();
if (pVersion > 0) {
block.beginControlFlow("if (this.version >= $L)", pVersion);
}
block.add("this.$N = ", p.fieldName);
if (p.typeAdapter != null && typeAdapters.containsKey(p.typeAdapter)) {
Parcelables.readValueWithTypeAdapter(block, p, typeAdapters.get(p.typeAdapter));
} else {
requiresSuppressWarnings |= Parcelables.isTypeRequiresSuppressWarnings(p.typeName);
TypeName parcelableType = Parcelables.getTypeNameFromProperty(p, env.getTypeUtils());
Parcelables.readValue(block, p, parcelableType);
}
block.add(";\n");
if (pVersion > 0) {
block.endControlFlow();
}
}
builder.addCode(block.build());
return builder.build();
}
/**
* Validates that non-zero fees are acked (i.e. they are specified and the amount matches).
*
* <p>This is used directly by update operations, i.e. those that otherwise don't have implicit
* costs, and is also used as a helper method to validate if fees are required for operations that
* do have implicit costs, e.g. creates and renews.
*/
public static void validateFeesAckedIfPresent(
final Optional<? extends FeeTransformCommandExtension> feeCommand,
FeesAndCredits feesAndCredits)
throws EppException {
// Check for the case where a fee command extension was required but not provided.
// This only happens when the total fees are non-zero and include custom fees requiring the
// extension.
if (!feeCommand.isPresent()) {
if (!feesAndCredits.getEapCost().isZero()) {
throw new FeesRequiredDuringEarlyAccessProgramException(feesAndCredits.getEapCost());
}
if (feesAndCredits.getTotalCost().isZero() || !feesAndCredits.isFeeExtensionRequired()) {
return;
}
throw new FeesRequiredForNonFreeOperationException(feesAndCredits.getTotalCost());
}
List<Fee> fees = feeCommand.get().getFees();
// The schema guarantees that at least one fee will be present.
checkState(!fees.isEmpty());
BigDecimal total = zeroInCurrency(feeCommand.get().getCurrency());
for (Fee fee : fees) {
if (!fee.hasDefaultAttributes()) {
throw new UnsupportedFeeAttributeException();
}
total = total.add(fee.getCost());
}
for (Credit credit : feeCommand.get().getCredits()) {
if (!credit.hasDefaultAttributes()) {
throw new UnsupportedFeeAttributeException();
}
total = total.add(credit.getCost());
}
Money feeTotal;
try {
feeTotal = Money.of(feeCommand.get().getCurrency(), total);
} catch (ArithmeticException e) {
throw new CurrencyValueScaleException();
}
if (!feeTotal.getCurrencyUnit().equals(feesAndCredits.getCurrency())) {
throw new CurrencyUnitMismatchException();
}
// If more than one fees are required, always validate individual fees.
ImmutableMap<FeeType, Money> expectedFeeMap =
buildFeeMap(feesAndCredits.getFees(), feesAndCredits.getCurrency());
if (expectedFeeMap.size() > 1) {
ImmutableMap<FeeType, Money> providedFeeMap =
buildFeeMap(feeCommand.get().getFees(), feeCommand.get().getCurrency());
for (FeeType type : expectedFeeMap.keySet()) {
if (!providedFeeMap.containsKey(type)) {
throw new FeesMismatchException(type);
}
Money expectedCost = expectedFeeMap.get(type);
if (!providedFeeMap.get(type).isEqual(expectedCost)) {
throw new FeesMismatchException(type, expectedCost);
}
}
}
// Checking if total amount is expected. Extra fees that we are not expecting may be passed in.
// Or if there is only a single fee type expected.
if (!feeTotal.equals(feesAndCredits.getTotalCost())) {
throw new FeesMismatchException(feesAndCredits.getTotalCost());
}
}