All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.inject.internal.DuplicateMapKeyError Maven / Gradle / Ivy

There is a newer version: 7.0.0
Show newest version
package com.google.inject.internal;

import com.google.common.collect.Multimap;
import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.spi.ErrorDetail;
import java.util.Collection;
import java.util.Formatter;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Error reported by Guice when a duplicate key is found in a {@link MapBinder} that does not permit
 * duplicates.
 */
final class DuplicateMapKeyError extends InternalErrorDetail> {
  private final Key> mapKey;
  private final Multimap> duplicates;

  DuplicateMapKeyError(
      Key> mapKey, Multimap> duplicates, List sources) {
    super(ErrorId.DUPLICATE_MAP_KEY, getDuplicateKeysMessage(mapKey, duplicates), sources, null);
    this.mapKey = mapKey;
    this.duplicates = duplicates;
  }

  @Override
  protected final void formatDetail(List> others, Formatter formatter) {
    formatter.format("%n%s%n", Messages.bold("Duplicates:"));

    for (Map.Entry>> entry : duplicates.asMap().entrySet()) {
      formatter.format("  Key: \"%s\"%n", Messages.redBold(entry.getKey().toString()));
      formatter.format("  Bound at:%n");
      int index = 1;
      for (Binding binding : entry.getValue()) {
        formatter.format("    %-2s: ", index++);
        new SourceFormatter(
                binding.getSource(),
                formatter,
                /** omitPreposition= */
                true)
            .format();
      }
      formatter.format("%n");
    }

    formatter.format("%s%n", Messages.bold("MapBinder declared at:"));
    ErrorFormatter.formatSources(getSources(), formatter);
  }

  @Override
  public DuplicateMapKeyError withSources(List newSources) {
    return new DuplicateMapKeyError<>(mapKey, duplicates, newSources);
  }

  private static  String getDuplicateKeysMessage(
      Key> mapKey, Multimap> duplicates) {
    Set duplicateKeys = duplicates.keySet();
    String mapBinderKey = Messages.convert(mapKey).toString();
    String firstDuplicateKey = duplicateKeys.iterator().next().toString();
    if (duplicateKeys.size() == 1) {
      return String.format("Duplicate key \"%s\" found in %s.", firstDuplicateKey, mapBinderKey);
    } else {
      return String.format(
          "\"%s\" and %s other duplicate keys found in %s.",
          firstDuplicateKey, duplicateKeys.size() - 1, mapBinderKey);
    }
  }
}