예제 #1
0
 public void testAsMultimapCaches() {
   ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
   ImmutableSetMultimap<String, Integer> multimap1 = map.asMultimap();
   ImmutableSetMultimap<String, Integer> multimap2 = map.asMultimap();
   assertEquals(1, multimap1.asMap().size());
   assertSame(multimap1, multimap2);
 }
예제 #2
0
  private static <K, V> ImmutableSetMultimap<K, V> copyOf(
      Multimap<? extends K, ? extends V> multimap, Comparator<? super V> valueComparator) {
    checkNotNull(multimap); // eager for GWT
    if (multimap.isEmpty() && valueComparator == null) {
      return of();
    }

    if (multimap instanceof ImmutableSetMultimap) {
      @SuppressWarnings("unchecked") // safe since multimap is not writable
      ImmutableSetMultimap<K, V> kvMultimap = (ImmutableSetMultimap<K, V>) multimap;
      if (!kvMultimap.isPartialView()) {
        return kvMultimap;
      }
    }

    ImmutableMap.Builder<K, ImmutableSet<V>> builder = ImmutableMap.builder();
    int size = 0;

    for (Entry<? extends K, ? extends Collection<? extends V>> entry :
        multimap.asMap().entrySet()) {
      K key = entry.getKey();
      Collection<? extends V> values = entry.getValue();
      ImmutableSet<V> set =
          (valueComparator == null)
              ? ImmutableSet.copyOf(values)
              : ImmutableSortedSet.copyOf(valueComparator, values);
      if (!set.isEmpty()) {
        builder.put(key, set);
        size += set.size();
      }
    }

    return new ImmutableSetMultimap<K, V>(builder.build(), size, valueComparator);
  }
예제 #3
0
 private ImmutableSetMultimap<V, K> invert() {
   Builder<V, K> builder = builder();
   for (Entry<K, V> entry : entries()) {
     builder.put(entry.getValue(), entry.getKey());
   }
   ImmutableSetMultimap<V, K> invertedMultimap = builder.build();
   invertedMultimap.inverse = this;
   return invertedMultimap;
 }
  /**
   * Filters SchemaContext for yang modules
   *
   * @param delegate original SchemaContext
   * @param rootModules modules (yang schemas) to be available and all their dependencies (modules
   *     importing rootModule and whole chain of their imports)
   * @param additionalModuleIds (additional) modules (yang schemas) to be available and whole chain
   *     of their imports
   */
  public FilteringSchemaContextProxy(
      final SchemaContext delegate,
      final Collection<ModuleId> rootModules,
      final Set<ModuleId> additionalModuleIds) {

    Preconditions.checkArgument(rootModules != null, "Base modules cannot be null.");
    Preconditions.checkArgument(additionalModuleIds != null, "Additional modules cannot be null.");

    final Builder<Module> filteredModulesBuilder = new Builder<>();

    final SetMultimap<URI, Module> nsMap =
        Multimaps.newSetMultimap(new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
    final SetMultimap<String, Module> nameMap =
        Multimaps.newSetMultimap(new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);

    ImmutableMap.Builder<ModuleIdentifier, String> identifiersToSourcesBuilder =
        ImmutableMap.builder();

    // preparing map to get all modules with one name but difference in revision
    final TreeMultimap<String, Module> nameToModulesAll = getStringModuleTreeMultimap();

    nameToModulesAll.putAll(getStringModuleMap(delegate));

    // in case there is a particular dependancy to view filteredModules/yang models
    // dependancy is checked for module name and imports
    processForRootModules(delegate, rootModules, filteredModulesBuilder);

    // adding additional modules
    processForAdditionalModules(delegate, additionalModuleIds, filteredModulesBuilder);

    filteredModulesBuilder.addAll(
        getImportedModules(
            Maps.uniqueIndex(delegate.getModules(), ModuleId.MODULE_TO_MODULE_ID),
            filteredModulesBuilder.build(),
            nameToModulesAll));

    /**
     * Instead of doing this on each invocation of getModules(), pre-compute it once and keep it
     * around -- better than the set we got in.
     */
    this.filteredModules = filteredModulesBuilder.build();

    for (final Module module : filteredModules) {
      nameMap.put(module.getName(), module);
      nsMap.put(module.getNamespace(), module);
      identifiersToSourcesBuilder.put(module, module.getSource());
    }

    namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
    nameToModules = ImmutableSetMultimap.copyOf(nameMap);
    identifiersToSources = identifiersToSourcesBuilder.build();
  }
예제 #5
0
 public void testAsMultimap() {
   ImmutableMap<String, Integer> map =
       ImmutableMap.of("one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
   ImmutableSetMultimap<String, Integer> expected =
       ImmutableSetMultimap.of("one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
   assertEquals(expected, map.asMultimap());
 }
예제 #6
0
  @Test
  public void testForMultimap_domain() {
    Navigator<String> navigator =
        Navigators.forMultimap(ImmutableSetMultimap.of("a", "a1", "a", "a2", "b", "b"));

    assertEquals(ImmutableSet.of("a", "b"), ImmutableSet.copyOf(navigator.domain()));
  }
예제 #7
0
 /**
  * Returns an immutable multimap containing the given entries, in order. Repeated occurrences of
  * an entry (according to {@link Object#equals}) after the first are ignored.
  */
 public static <K, V> ImmutableSetMultimap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
   ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
   builder.put(k1, v1);
   builder.put(k2, v2);
   builder.put(k3, v3);
   return builder.build();
 }
예제 #8
0
  /** {@inheritDoc} */
  @Override
  public ImmutableSetMultimap<String, String> getPermissions(
      List<Authorizable> authorizables, List<String> groups) {
    Roles roles = rolesReference.get();
    String database = null;
    Boolean isURI = false;
    for (Authorizable authorizable : authorizables) {
      if (authorizable instanceof Database) {
        database = authorizable.getName();
      }
      if (authorizable instanceof AccessURI) {
        isURI = true;
      }
    }

    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("Getting permissions for {} via {}", groups, database);
    }
    ImmutableSetMultimap.Builder<String, String> resultBuilder = ImmutableSetMultimap.builder();
    for (String group : groups) {
      resultBuilder.putAll(group, roles.getRoles(database, group, isURI));
    }
    ImmutableSetMultimap<String, String> result = resultBuilder.build();
    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("result = " + result);
    }
    return result;
  }
예제 #9
0
 public static OwnersReport emptyReport() {
   return new OwnersReport(
       ImmutableSetMultimap.<TargetNode<?>, Path>of(),
       Sets.<Path>newHashSet(),
       Sets.<String>newHashSet(),
       Sets.<String>newHashSet());
 }
예제 #10
0
  @VisibleForTesting
  static ImmutableSetMultimap<PartitionKeyToTraceId, Long> entriesThatIncreaseGap(
      ConcurrentMap<PartitionKeyToTraceId, Pair<Long>> sharedState,
      ImmutableSetMultimap<PartitionKeyToTraceId, Long> updates) {
    ImmutableSet.Builder<PartitionKeyToTraceId> toUpdate = ImmutableSet.builder();

    // Enter a loop that affects shared state when an update widens the time interval for a key.
    for (Map.Entry<PartitionKeyToTraceId, Long> input : updates.entries()) {
      PartitionKeyToTraceId key = input.getKey();
      long timestamp = input.getValue();
      for (; ; ) {
        Pair<Long> oldRange = sharedState.get(key);
        if (oldRange == null) {
          // Initial state is where this key has a single timestamp.
          oldRange = sharedState.putIfAbsent(key, Pair.create(timestamp, timestamp));

          // If there was no previous value, we need to update the index
          if (oldRange == null) {
            toUpdate.add(key);
            break;
          }
        }

        long first = timestamp < oldRange._1 ? timestamp : oldRange._1;
        long last = timestamp > oldRange._2 ? timestamp : oldRange._2;

        Pair<Long> newRange = Pair.create(first, last);
        if (oldRange.equals(newRange)) {
          break; // the current timestamp is contained
        } else if (sharedState.replace(key, oldRange, newRange)) {
          toUpdate.add(key); // The range was extended
          break;
        }
      }
    }

    // When the loop completes, we'll know one of our updates widened the interval of a trace, if
    // it is the first or last timestamp. By ignoring those between an existing interval, we can
    // end up with less Cassandra writes.
    Builder<PartitionKeyToTraceId, Long> result = ImmutableSetMultimap.builder();
    for (PartitionKeyToTraceId needsUpdate : toUpdate.build()) {
      Pair<Long> firstLast = sharedState.get(needsUpdate);
      if (updates.containsEntry(needsUpdate, firstLast._1)) result.put(needsUpdate, firstLast._1);
      if (updates.containsEntry(needsUpdate, firstLast._2)) result.put(needsUpdate, firstLast._2);
    }
    return result.build();
  }
예제 #11
0
  @Test
  public void testGetExecutableCommand() {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(ruleResolver);

    // prebuilt_jar //third_party/generator:generator
    PrebuiltJarBuilder.createBuilder(
            BuildTargetFactory.newInstance("//third_party/generator:generator"))
        .setBinaryJar(PATH_TO_GENERATOR_JAR)
        .build(ruleResolver);

    // prebuilt_jar //third_party/guava:guava
    BuildRule guava =
        PrebuiltJarBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third_party/guava:guava"))
            .setBinaryJar(PATH_TO_GUAVA_JAR)
            .build(ruleResolver);

    // java_library //java/com/facebook/base:base
    BuildRule libraryRule =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/facebook/base:base"))
            .addSrc(Paths.get("java/com/facebook/base/Base.java"))
            .addDep(guava.getBuildTarget())
            .build(ruleResolver);

    BuildRuleParams params =
        new FakeBuildRuleParamsBuilder(
                BuildTargetFactory.newInstance("//java/com/facebook/base:Main"))
            .setDeps(ImmutableSortedSet.of(libraryRule))
            .build();
    // java_binary //java/com/facebook/base:Main
    JavaBinary javaBinary =
        ruleResolver.addToIndex(
            new JavaBinary(
                params,
                new SourcePathResolver(ruleResolver),
                "com.facebook.base.Main",
                null,
                /* merge manifests */ true,
                null,
                /* blacklist */ ImmutableSet.<String>of(),
                new DefaultDirectoryTraverser(),
                ImmutableSetMultimap.<JavaLibrary, Path>of()));

    // Strip the trailing "." from the absolute path to the current directory.
    final String basePath = new File(".").getAbsolutePath().replaceFirst("\\.$", "");

    // Each classpath entry is specified via its absolute path so that the executable command can be
    // run from a /tmp directory, if necessary.
    String expectedClasspath = basePath + javaBinary.getPathToOutput();

    List<String> expectedCommand = ImmutableList.of("java", "-jar", expectedClasspath);
    assertEquals(expectedCommand, javaBinary.getExecutableCommand().getCommandPrefix(pathResolver));

    assertFalse(
        "Library rules that are used exclusively by genrules should not be part of the classpath.",
        expectedClasspath.contains(PATH_TO_GENERATOR_JAR.toString()));
  }
예제 #12
0
 @Override
 public boolean contains(@Nullable Object object) {
   if (object instanceof Entry) {
     Entry<?, ?> entry = (Entry<?, ?>) object;
     return multimap.containsEntry(entry.getKey(), entry.getValue());
   }
   return false;
 }
예제 #13
0
 @Test
 public void testClosureAlwaysIncludesStart() {
   Navigator<String> navigator = Navigators.forMultimap(ImmutableSetMultimap.<String, String>of());
   assertEquals(ImmutableSet.of("A"), ImmutableSet.copyOf(Navigators.closure(navigator, "A")));
   assertEquals(
       ImmutableSet.of("A"),
       ImmutableSet.copyOf(Navigators.closureOfMany(navigator, ImmutableList.of("A"))));
 }
예제 #14
0
 public OwnersReport(
     SetMultimap<TargetNode<?>, Path> owners,
     Set<Path> inputsWithNoOwners,
     Set<String> nonExistentInputs,
     Set<String> nonFileInputs) {
   this.owners = ImmutableSetMultimap.copyOf(owners);
   this.inputsWithNoOwners = ImmutableSet.copyOf(inputsWithNoOwners);
   this.nonExistentInputs = ImmutableSet.copyOf(nonExistentInputs);
   this.nonFileInputs = ImmutableSet.copyOf(nonFileInputs);
 }
예제 #15
0
  ImmutableSet<ListenableFuture<?>> index(List<Span> spans) {
    // First parse each span into partition keys used to support query requests
    Builder<PartitionKeyToTraceId, Long> parsed = ImmutableSetMultimap.builder();
    for (Span span : spans) {
      Long timestamp = guessTimestamp(span);
      if (timestamp == null) continue;
      for (String partitionKey : index.partitionKeys(span)) {
        parsed.put(
            new PartitionKeyToTraceId(index.table(), partitionKey, span.traceId),
            1000 * (timestamp / 1000)); // index precision is millis
      }
    }

    // The parsed results may include inserts that already occur, or are redundant as they don't
    // impact QueryRequest.endTs or QueryRequest.loopback. For example, a parsed timestamp could
    // be between timestamps of rows that already exist for a particular trace.
    ImmutableSetMultimap<PartitionKeyToTraceId, Long> maybeInsert = parsed.build();

    ImmutableSetMultimap<PartitionKeyToTraceId, Long> toInsert;
    if (sharedState == null) { // special-case when caching is disabled.
      toInsert = maybeInsert;
    } else {
      // Optimized results will be smaller when the input includes traces with local spans, or when
      // other threads indexed the same trace.
      toInsert = entriesThatIncreaseGap(sharedState, maybeInsert);

      if (maybeInsert.size() > toInsert.size() && LOG.isDebugEnabled()) {
        int delta = maybeInsert.size() - toInsert.size();
        LOG.debug("optimized out {}/{} inserts into {}", delta, maybeInsert.size(), index.table());
      }
    }

    // For each entry, insert a new row in the index table asynchronously
    ImmutableSet.Builder<ListenableFuture<?>> result = ImmutableSet.builder();
    for (Map.Entry<PartitionKeyToTraceId, Long> entry : toInsert.entries()) {
      BoundStatement bound =
          bindWithName(prepared, boundName)
              .setLong("trace_id", entry.getKey().traceId)
              .setBytesUnsafe("ts", timestampCodec.serialize(entry.getValue()));
      if (indexTtl != null) {
        bound.setInt("ttl_", indexTtl);
      }
      index.bindPartitionKey(bound, entry.getKey().partitionKey);
      result.add(session.executeAsync(bound));
    }
    return result.build();
  }
  /** Returns documents grouped by partitions. */
  SetMultimap<Object, Document> getDocumentsByPartition(List<Document> documents) {
    final SetMultimap<Object, Document> index = HashMultimap.create();
    for (Document document : documents) {
      final Collection<Object> partitions = document.getField(partitionIdFieldName);
      for (Object partition : partitions) {
        index.put(partition, document);
      }
    }

    return ImmutableSetMultimap.copyOf(index);
  }
예제 #17
0
 private ImmutableSetMultimap<String, String> parsePermissions(
     @Nullable String database, Ini.Section rolesSection, Ini.Section groupsSection) {
   ImmutableSetMultimap.Builder<String, String> resultBuilder = ImmutableSetMultimap.builder();
   Multimap<String, String> roleNameToPrivilegeMap = HashMultimap.create();
   List<? extends RoleValidator> validators =
       Lists.newArrayList(
           new ServersAllIsInvalid(),
           new DatabaseMustMatch(),
           new DatabaseRequiredInRole(),
           new ServerNameMustMatch(serverName));
   for (Map.Entry<String, String> entry : rolesSection.entrySet()) {
     String roleName = Strings.nullToEmpty(entry.getKey()).trim();
     String roleValue = Strings.nullToEmpty(entry.getValue()).trim();
     boolean invalidConfiguration = false;
     if (roleName.isEmpty()) {
       LOGGER.warn("Empty role name encountered in {}", resourcePath);
       invalidConfiguration = true;
     }
     if (roleValue.isEmpty()) {
       LOGGER.warn("Empty role value encountered in {}", resourcePath);
       invalidConfiguration = true;
     }
     if (roleNameToPrivilegeMap.containsKey(roleName)) {
       LOGGER.warn("Role {} defined twice in {}", roleName, resourcePath);
     }
     Set<String> roles = PermissionUtils.toPermissionStrings(roleValue);
     if (!invalidConfiguration && roles != null) {
       for (String role : roles) {
         for (RoleValidator validator : validators) {
           validator.validate(database, role.trim());
         }
       }
       roleNameToPrivilegeMap.putAll(roleName, roles);
     }
   }
   Splitter roleSplitter = ROLE_SPLITTER.omitEmptyStrings().trimResults();
   for (Map.Entry<String, String> entry : groupsSection.entrySet()) {
     String groupName = Strings.nullToEmpty(entry.getKey()).trim();
     String groupPrivileges = Strings.nullToEmpty(entry.getValue()).trim();
     Collection<String> resolvedGroupPrivileges = Sets.newHashSet();
     for (String roleName : roleSplitter.split(groupPrivileges)) {
       if (roleNameToPrivilegeMap.containsKey(roleName)) {
         resolvedGroupPrivileges.addAll(roleNameToPrivilegeMap.get(roleName));
       } else {
         LOGGER.warn(
             "Role {} for group {} does not exist in privileges section in {}",
             new Object[] {roleName, groupName, resourcePath});
       }
     }
     resultBuilder.putAll(groupName, resolvedGroupPrivileges);
   }
   return resultBuilder.build();
 }
예제 #18
0
  public static int countLoadedChunks(
      ICommandSender sender, EntityPlayerMP player, boolean details, LoadedChunksVisitor visitor) {
    MinecraftServer server = ForgeTools.server;
    int total = 0;
    for (WorldServer s : server.worldServers) {
      World tmp = ((World) s);
      ImmutableSetMultimap<ChunkCoordIntPair, ForgeChunkManager.Ticket> forcedChunks =
          tmp.getPersistentChunks();
      Set loadedChunks = new LinkedHashSet<ChunkCoordIntPair>();
      for (ChunkCoordIntPair c : forcedChunks.keys()) {
        for (ForgeChunkManager.Ticket t : forcedChunks.get(c)) {
          loadedChunks = Sets.union(t.getChunkList(), loadedChunks);
        }
      }
      total += loadedChunks.size();

      boolean playerInWorld =
          (player != null) ? s.getWorldInfo().equals(player.worldObj.getWorldInfo()) : false;
      visitor.visit(sender, player, details, playerInWorld, s, loadedChunks.size());
    }
    return total;
  }
예제 #19
0
 ImmutableMultimap<Service.State, Service> servicesByState() {
   ImmutableSetMultimap.Builder<Service.State, Service> builder = ImmutableSetMultimap.builder();
   this.monitor.enter();
   try {
     for (Map.Entry<Service.State, Service> entry : this.servicesByState.entries()) {
       if (!(entry.getValue() instanceof ServiceManager.NoOpService)) {
         builder.put(entry.getKey(), entry.getValue());
       }
     }
   } finally {
     this.monitor.leave();
   }
   return builder.build();
 }
  @Test
  public void testMultiFSPolicy() throws Exception {
    File globalPolicyFile = new File(Files.createTempDir(), "global-policy.ini");
    File dbPolicyFile = new File(Files.createTempDir(), "db11-policy.ini");

    // Create global policy file
    PolicyFile dbPolicy =
        new PolicyFile()
            .addPermissionsToRole("db11_role", "server=server1->db=db11")
            .addRolesToGroup("group1", "db11_role");

    dbPolicy.write(dbPolicyFile);
    Path dbPolicyPath = new Path(etc, "db11-policy.ini");

    // create per-db policy file
    PolicyFile globalPolicy =
        new PolicyFile()
            .addPermissionsToRole("admin_role", "server=server1")
            .addRolesToGroup("admin_group", "admin_role")
            .addGroupsToUser("db", "admin_group");
    globalPolicy.addDatabase("db11", dbPolicyPath.toUri().toString());
    globalPolicy.write(globalPolicyFile);

    PolicyFiles.copyFilesToDir(fileSystem, etc, globalPolicyFile);
    PolicyFiles.copyFilesToDir(fileSystem, etc, dbPolicyFile);
    DBPolicyFileBackend multiFSEngine =
        new DBPolicyFileBackend(globalPolicyFile.getPath(), "server1");

    List<Authorizable> dbAuthorizables = Lists.newArrayList();
    dbAuthorizables.add(new Server("server1"));
    dbAuthorizables.add(new Database("db11"));
    List<String> dbGroups = Lists.newArrayList();
    dbGroups.add("group1");
    ImmutableSetMultimap<String, String> dbPerms =
        multiFSEngine.getPermissions(dbAuthorizables, dbGroups);
    Assert.assertEquals("No DB permissions found", 1, dbPerms.size());
  }
예제 #21
0
  /**
   * Tests the mappings from given types to specific concrete instances of an empty collection,
   * preferring immutable types where possible. The tests take a cast, just to ensure the type is
   * assignable to the concrete type, since in collections various sub-types can be considered equal
   * even if they're different concrete types.
   */
  public void testEmptyCollections() {
    // Special cased types.
    assertThat((ImmutableSet<?>) emptyAggregationFor(field("immutableSet")))
        .isEqualTo(ImmutableSet.of());
    assertThat((Set<?>) emptyAggregationFor(field("set"))).isEqualTo(ImmutableSet.of());
    assertThat((Collection<?>) emptyAggregationFor(field("collection")))
        .isEqualTo(ImmutableSet.of());
    assertThat((Iterable<?>) emptyAggregationFor(field("iterable"))).isEqualTo(ImmutableSet.of());
    assertThat((ImmutableList<?>) emptyAggregationFor(field("immutableList")))
        .isEqualTo(ImmutableList.of());
    assertThat((List<?>) emptyAggregationFor(field("list"))).isEqualTo(ImmutableList.of());
    assertThat((ImmutableMap<?, ?>) emptyAggregationFor(field("immutableMap")))
        .isEqualTo(ImmutableMap.of());
    assertThat((Map<?, ?>) emptyAggregationFor(field("map"))).isEqualTo(ImmutableMap.of());
    assertThat((ImmutableMultimap<?, ?>) emptyAggregationFor(field("immutableMultimap")))
        .isEqualTo(ImmutableMultimap.of());
    assertThat((Multimap<?, ?>) emptyAggregationFor(field("multimap")))
        .isEqualTo(ImmutableMultimap.of());
    assertThat((ImmutableListMultimap<?, ?>) emptyAggregationFor(field("immutableListMultimap")))
        .isEqualTo(ImmutableListMultimap.of());
    assertThat((ListMultimap<?, ?>) emptyAggregationFor(field("listMultimap")))
        .isEqualTo(ImmutableListMultimap.of());
    assertThat((ImmutableSetMultimap<?, ?>) emptyAggregationFor(field("immutableSetMultimap")))
        .isEqualTo(ImmutableSetMultimap.of());
    assertThat((SetMultimap<?, ?>) emptyAggregationFor(field("setMultimap")))
        .isEqualTo(ImmutableSetMultimap.of());

    // Types that can be created via newInstance();
    assertThat((ArrayList<?>) emptyAggregationFor(field("arrayList"))).isEqualTo(new ArrayList<>());
    assertThat((LinkedList<?>) emptyAggregationFor(field("linkedList")))
        .isEqualTo(new LinkedList<>());
    assertThat((HashSet<?>) emptyAggregationFor(field("hashSet"))).isEqualTo(new HashSet<>());
    assertThat((TreeSet<?>) emptyAggregationFor(field("treeSet"))).isEqualTo(new TreeSet<>());
    assertThat((HashMap<?, ?>) emptyAggregationFor(field("hashMap"))).isEqualTo(new HashMap<>());
    assertThat((TreeMap<?, ?>) emptyAggregationFor(field("treeMap"))).isEqualTo(new TreeMap<>());
  }
  @Test
  public void shouldFindNeededDependenciesFromSymbols() throws IOException, InterruptedException {
    ProjectWorkspace workspace =
        TestDataHelper.createProjectWorkspaceForScenario(this, "symbol_finder", temporaryFolder);
    workspace.setUp();

    ProjectFilesystem projectFilesystem = new ProjectFilesystem(temporaryFolder.getRootPath());
    ImmutableMap<String, String> environment = ImmutableMap.copyOf(System.getenv());

    Config rawConfig =
        Config.createDefaultConfig(
            projectFilesystem.getRootPath(),
            ImmutableMap.<String, ImmutableMap<String, String>>of());
    BuckConfig config =
        new BuckConfig(
            rawConfig, projectFilesystem, Architecture.detect(), Platform.detect(), environment);
    ImmutableSet<Description<?>> allDescriptions =
        DefaultKnownBuildRuleTypes.getDefaultKnownBuildRuleTypes(projectFilesystem)
            .getAllDescriptions();
    BuckEventBus buckEventBus = BuckEventBusFactory.newInstance();

    MissingSymbolsHandler missingSymbolsHandler =
        MissingSymbolsHandler.create(
            projectFilesystem,
            allDescriptions,
            config,
            buckEventBus,
            new TestConsole(),
            DEFAULT_JAVAC_OPTIONS,
            environment);

    MissingSymbolEvent missingSymbolEvent =
        MissingSymbolEvent.create(
            BuildTargetFactory.newInstance(workspace.getDestPath(), "//java/com/example/b:b"),
            "com.example.a.A",
            MissingSymbolEvent.SymbolType.Java);

    ImmutableSetMultimap<BuildTarget, BuildTarget> neededDeps =
        missingSymbolsHandler.getNeededDependencies(ImmutableList.of(missingSymbolEvent));

    assertEquals(
        "MissingSymbolsHandler failed to find the needed dependency.",
        neededDeps,
        ImmutableSetMultimap.of(
            BuildTargetFactory.newInstance(workspace.getDestPath(), "//java/com/example/b:b"),
            BuildTargetFactory.newInstance(workspace.getDestPath(), "//java/com/example/a:a")));
  }
예제 #23
0
 private ImmutableSetMultimap<String, String> parseIni(String database, Ini ini) {
   Ini.Section privilegesSection = ini.getSection(ROLES);
   boolean invalidConfiguration = false;
   if (privilegesSection == null) {
     LOGGER.warn("Section {} empty for {}", ROLES, resourcePath);
     invalidConfiguration = true;
   }
   Ini.Section groupsSection = ini.getSection(GROUPS);
   if (groupsSection == null) {
     LOGGER.warn("Section {} empty for {}", GROUPS, resourcePath);
     invalidConfiguration = true;
   }
   if (!invalidConfiguration) {
     return parsePermissions(database, privilegesSection, groupsSection);
   }
   return ImmutableSetMultimap.of();
 }
  @Override
  public Multimap<ModelActionRole, ModelAction> getActions(
      ModelReference<?> subject, ModelRuleDescriptor descriptor) {
    return ImmutableSetMultimap.<ModelActionRole, ModelAction>builder()
        .put(
            ModelActionRole.Discover,
            DirectNodeInputUsingModelAction.of(
                subject,
                descriptor,
                Arrays.<ModelReference<?>>asList(
                    ModelReference.of(ManagedProxyFactory.class),
                    ModelReference.of(TypeConverter.class)),
                new BiAction<MutableModelNode, List<ModelView<?>>>() {
                  @Override
                  public void execute(MutableModelNode modelNode, List<ModelView<?>> modelViews) {
                    ManagedProxyFactory proxyFactory =
                        getInstance(modelViews.get(0), ManagedProxyFactory.class);
                    TypeConverter typeConverter = getInstance(modelViews, 1, TypeConverter.class);
                    for (StructSchema<?> viewSchema : bindings.getAllViewSchemas()) {
                      addProjection(modelNode, viewSchema, proxyFactory, typeConverter);
                    }
                  }
                }))
        .put(
            ModelActionRole.Create,
            DirectNodeInputUsingModelAction.of(
                subject,
                descriptor,
                Arrays.<ModelReference<?>>asList(
                    ModelReference.of(ModelSchemaStore.class),
                    ModelReference.of(NodeInitializerRegistry.class)),
                new BiAction<MutableModelNode, List<ModelView<?>>>() {
                  @Override
                  public void execute(MutableModelNode modelNode, List<ModelView<?>> modelViews) {
                    ModelSchemaStore schemaStore =
                        getInstance(modelViews, 0, ModelSchemaStore.class);
                    NodeInitializerRegistry nodeInitializerRegistry =
                        getInstance(modelViews, 1, NodeInitializerRegistry.class);

                    addPropertyLinks(modelNode, schemaStore, nodeInitializerRegistry);
                    initializePrivateData(modelNode);
                  }
                }))
        .build();
  }
예제 #25
0
  @Override
  public <A extends Args> BuildRule createBuildRule(
      TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, A args) {

    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    ImmutableMap<String, SourcePath> nativeLibraries =
        JavaLibraryRules.getNativeLibraries(targetGraph, params.getDeps(), cxxPlatform);
    BuildRuleParams binaryParams = params;

    // If we're packaging native libraries, we'll build the binary JAR in a separate rule and
    // package it into the final fat JAR, so adjust it's params to use a flavored target.
    if (!nativeLibraries.isEmpty()) {
      binaryParams =
          params.copyWithChanges(
              BuildTarget.builder(params.getBuildTarget())
                  .addFlavors(FAT_JAR_INNER_JAR_FLAVOR)
                  .build(),
              params.getDeclaredDeps(),
              params.getExtraDeps());
    }

    // Construct the build rule to build the binary JAR.
    ImmutableSetMultimap<JavaLibrary, Path> transitiveClasspathEntries =
        Classpaths.getClasspathEntries(binaryParams.getDeps());
    BuildRule rule =
        new JavaBinary(
            binaryParams.appendExtraDeps(transitiveClasspathEntries.keys()),
            pathResolver,
            args.mainClass.orNull(),
            args.manifestFile.orNull(),
            args.mergeManifests.or(true),
            args.metaInfDirectory.orNull(),
            args.blacklist.or(ImmutableSortedSet.<String>of()),
            new DefaultDirectoryTraverser(),
            transitiveClasspathEntries,
            javaBinOverride);

    // If we're packaging native libraries, construct the rule to build the fat JAR, which packages
    // up the original binary JAR and any required native libraries.
    if (!nativeLibraries.isEmpty()) {
      BuildRule innerJarRule = rule;
      resolver.addToIndex(innerJarRule);
      SourcePath innerJar = new BuildTargetSourcePath(innerJarRule.getBuildTarget());
      rule =
          new JarFattener(
              params.appendExtraDeps(
                  Suppliers.<Iterable<BuildRule>>ofInstance(
                      pathResolver.filterBuildRuleInputs(
                          ImmutableList.<SourcePath>builder()
                              .add(innerJar)
                              .addAll(nativeLibraries.values())
                              .build()))),
              pathResolver,
              javacOptions,
              innerJar,
              nativeLibraries,
              javaBinOverride);
    }

    return rule;
  }
예제 #26
0
 /** Returns an immutable multimap containing a single entry. */
 public static <K, V> ImmutableSetMultimap<K, V> of(K k1, V v1) {
   ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
   builder.put(k1, v1);
   return builder.build();
 }
예제 #27
0
  static OwnersReport buildOwnersReport(
      CommandRunnerParams params,
      ParserConfig parserConfig,
      BuildFileTree buildFileTree,
      Iterable<String> arguments,
      boolean guessForDeletedEnabled)
      throws IOException, InterruptedException, BuildFileParseException, BuildTargetException {
    final Path rootPath = params.getCell().getFilesystem().getRootPath();
    Preconditions.checkState(rootPath.isAbsolute());
    Map<Path, List<TargetNode<?>>> targetNodes = Maps.newHashMap();
    OwnersReport report = OwnersReport.emptyReport();

    for (Path filePath : getArgumentsAsPaths(rootPath, arguments)) {
      Optional<Path> basePath = buildFileTree.getBasePathOfAncestorTarget(filePath);
      if (!basePath.isPresent()) {
        report =
            report.updatedWith(
                new OwnersReport(
                    ImmutableSetMultimap.<TargetNode<?>, Path>of(),
                    /* inputWithNoOwners */ ImmutableSet.of(filePath),
                    Sets.<String>newHashSet(),
                    Sets.<String>newHashSet()));
        continue;
      }

      Path buckFile = basePath.get().resolve(parserConfig.getBuildFileName());
      Preconditions.checkState(params.getCell().getFilesystem().exists(buckFile));

      // Parse buck files and load target nodes.
      if (!targetNodes.containsKey(buckFile)) {
        try {
          targetNodes.put(
              buckFile,
              params
                  .getParser()
                  .getOrLoadTargetNodes(
                      buckFile,
                      parserConfig,
                      params.getBuckEventBus(),
                      params.getConsole(),
                      params.getEnvironment()));
        } catch (BuildFileParseException | BuildTargetException e) {
          Path targetBasePath = MorePaths.relativize(rootPath, rootPath.resolve(basePath.get()));
          String targetBaseName = "//" + MorePaths.pathWithUnixSeparators(targetBasePath);

          params
              .getConsole()
              .getStdErr()
              .format("Could not parse build targets for %s", targetBaseName);
          throw e;
        }
      }

      for (TargetNode<?> targetNode : targetNodes.get(buckFile)) {
        report =
            report.updatedWith(
                generateOwnersReport(
                    params,
                    targetNode,
                    ImmutableList.of(filePath.toString()),
                    guessForDeletedEnabled));
      }
    }
    return report;
  }
예제 #28
0
 @Override
 public ImmutableSetMultimap<JavaLibrary, Path> getOutputClasspathEntries() {
   return ImmutableSetMultimap.<JavaLibrary, Path>of(
       this, getResolver().getAbsolutePath(getBinaryJar()));
 }
  public static void findPlugins(boolean scanClasspath) throws IOException {
    SetMultimap<Object, String> found = LinkedHashMultimap.create();
    Set<String> pluginClasses = null;

    VanillaLaunch.getLogger().info("Searching for plugins...");

    if (scanClasspath) {
      VanillaLaunch.getLogger().info("Scanning classpath for plugins...");

      ClassLoader loader = VanillaLaunch.class.getClassLoader();
      if (loader instanceof URLClassLoader) {
        pluginClasses = PluginScanner.scanClassPath((URLClassLoader) loader);
        found.putAll("classpath", pluginClasses);
      } else {
        VanillaLaunch.getLogger()
            .error(
                "Cannot search for plugins on classpath: Unsupported class loader: {}",
                loader.getClass());
      }
    }

    Path pluginsDir = SpongeLaunch.getPluginsDir();
    if (Files.exists(pluginsDir)) {
      if (pluginClasses == null) {
        pluginClasses = new HashSet<>();
      }

      List<Path> paths;
      try (DirectoryStream<Path> dir =
          Files.newDirectoryStream(SpongeLaunch.getPluginsDir(), ARCHIVE_FILTER)) {
        paths = Lists.newArrayList(dir);
      }

      Collections.sort(paths);

      for (Path path : paths) {
        // Search for plugins in the JAR
        try (JarFile jar = new JarFile(path.toFile())) {
          Set<String> plugins = PluginScanner.scanZip(path, jar);

          Iterator<String> itr = plugins.iterator();
          while (itr.hasNext()) {
            String plugin = itr.next();
            if (!pluginClasses.add(plugin)) {
              VanillaLaunch.getLogger()
                  .warn("Skipping duplicate plugin class {} from {}", plugin, path);
              itr.remove();
            }
          }

          if (!plugins.isEmpty()) {
            found.putAll(path, plugins);

            // Look for access transformers
            PluginAccessTransformers.register(path, jar);
          }
        } catch (IOException e) {
          VanillaLaunch.getLogger().error("Failed to scan plugin JAR: {}", path, e);
        }
      }
    } else {
      // Create plugin folder
      Files.createDirectories(pluginsDir);
    }

    plugins = ImmutableSetMultimap.copyOf(found);
    VanillaLaunch.getLogger().info("{} plugin(s) found", plugins.size());
  }
예제 #30
0
/**
 * Supplies an arbitrary "default" instance for a wide range of types, often useful in testing
 * utilities.
 *
 * <p>Covers arrays, enums and common types defined in {@code java.lang}, {@code java.lang.reflect},
 * {@code java.io}, {@code java.nio}, {@code java.math}, {@code java.util}, {@code
 * java.util.concurrent}, {@code java.util.regex}, {@code com.google.common.base}, {@code
 * com.google.common.collect} and {@code com.google.common.primitives}. In addition, if the type
 * exposes at least one public static final constant of the same type, one of the constants will be
 * used; or if the class exposes a public parameter-less constructor then it will be "new"d and
 * returned.
 *
 * <p>All default instances returned by {@link #get} are generics-safe. Clients won't get type
 * errors for using {@code get(Comparator.class)} as a {@code Comparator<Foo>}, for example.
 * Immutable empty instances are returned for collection types; {@code ""} for string; {@code 0} for
 * number types; reasonable default instance for other stateless types. For mutable types, a fresh
 * instance is created each time {@code get()} is called.
 *
 * @author Kevin Bourrillion
 * @author Ben Yu
 * @since 12.0
 */
@Beta
public final class ArbitraryInstances {

  private static final Ordering<Field> BY_FIELD_NAME =
      new Ordering<Field>() {
        @Override
        public int compare(Field left, Field right) {
          return left.getName().compareTo(right.getName());
        }
      };

  /**
   * Returns a new {@code MatchResult} that corresponds to a successful match. Apache Harmony (used
   * in Android) requires a successful match in order to generate a {@code MatchResult}:
   * http://goo.gl/5VQFmC
   */
  private static MatchResult newMatchResult() {
    Matcher matcher = Pattern.compile(".").matcher("X");
    matcher.find();
    return matcher.toMatchResult();
  }

  private static final ClassToInstanceMap<Object> DEFAULTS =
      ImmutableClassToInstanceMap.builder()
          // primitives
          .put(Object.class, "")
          .put(Number.class, 0)
          .put(UnsignedInteger.class, UnsignedInteger.ZERO)
          .put(UnsignedLong.class, UnsignedLong.ZERO)
          .put(BigInteger.class, BigInteger.ZERO)
          .put(BigDecimal.class, BigDecimal.ZERO)
          .put(CharSequence.class, "")
          .put(String.class, "")
          .put(Pattern.class, Pattern.compile(""))
          .put(MatchResult.class, newMatchResult())
          .put(TimeUnit.class, TimeUnit.SECONDS)
          .put(Charset.class, Charsets.UTF_8)
          .put(Currency.class, Currency.getInstance(Locale.US))
          .put(Locale.class, Locale.US)
          // common.base
          .put(CharMatcher.class, CharMatcher.NONE)
          .put(Joiner.class, Joiner.on(','))
          .put(Splitter.class, Splitter.on(','))
          .put(Optional.class, Optional.absent())
          .put(Predicate.class, Predicates.alwaysTrue())
          .put(Equivalence.class, Equivalence.equals())
          .put(Ticker.class, Ticker.systemTicker())
          .put(Stopwatch.class, Stopwatch.createUnstarted())
          // io types
          .put(InputStream.class, new ByteArrayInputStream(new byte[0]))
          .put(ByteArrayInputStream.class, new ByteArrayInputStream(new byte[0]))
          .put(Readable.class, new StringReader(""))
          .put(Reader.class, new StringReader(""))
          .put(StringReader.class, new StringReader(""))
          .put(Buffer.class, ByteBuffer.allocate(0))
          .put(CharBuffer.class, CharBuffer.allocate(0))
          .put(ByteBuffer.class, ByteBuffer.allocate(0))
          .put(ShortBuffer.class, ShortBuffer.allocate(0))
          .put(IntBuffer.class, IntBuffer.allocate(0))
          .put(LongBuffer.class, LongBuffer.allocate(0))
          .put(FloatBuffer.class, FloatBuffer.allocate(0))
          .put(DoubleBuffer.class, DoubleBuffer.allocate(0))
          .put(File.class, new File(""))
          .put(ByteSource.class, ByteSource.empty())
          .put(CharSource.class, CharSource.empty())
          .put(ByteSink.class, NullByteSink.INSTANCE)
          .put(CharSink.class, NullByteSink.INSTANCE.asCharSink(Charsets.UTF_8))
          // All collections are immutable empty. So safe for any type parameter.
          .put(Iterator.class, ImmutableSet.of().iterator())
          .put(PeekingIterator.class, Iterators.peekingIterator(ImmutableSet.of().iterator()))
          .put(ListIterator.class, ImmutableList.of().listIterator())
          .put(Iterable.class, ImmutableSet.of())
          .put(Collection.class, ImmutableList.of())
          .put(ImmutableCollection.class, ImmutableList.of())
          .put(List.class, ImmutableList.of())
          .put(ImmutableList.class, ImmutableList.of())
          .put(Set.class, ImmutableSet.of())
          .put(ImmutableSet.class, ImmutableSet.of())
          .put(SortedSet.class, ImmutableSortedSet.of())
          .put(ImmutableSortedSet.class, ImmutableSortedSet.of())
          .put(NavigableSet.class, Sets.unmodifiableNavigableSet(Sets.newTreeSet()))
          .put(Map.class, ImmutableMap.of())
          .put(ImmutableMap.class, ImmutableMap.of())
          .put(SortedMap.class, ImmutableSortedMap.of())
          .put(ImmutableSortedMap.class, ImmutableSortedMap.of())
          .put(NavigableMap.class, Maps.unmodifiableNavigableMap(Maps.newTreeMap()))
          .put(Multimap.class, ImmutableMultimap.of())
          .put(ImmutableMultimap.class, ImmutableMultimap.of())
          .put(ListMultimap.class, ImmutableListMultimap.of())
          .put(ImmutableListMultimap.class, ImmutableListMultimap.of())
          .put(SetMultimap.class, ImmutableSetMultimap.of())
          .put(ImmutableSetMultimap.class, ImmutableSetMultimap.of())
          .put(
              SortedSetMultimap.class,
              Multimaps.unmodifiableSortedSetMultimap(TreeMultimap.create()))
          .put(Multiset.class, ImmutableMultiset.of())
          .put(ImmutableMultiset.class, ImmutableMultiset.of())
          .put(SortedMultiset.class, ImmutableSortedMultiset.of())
          .put(ImmutableSortedMultiset.class, ImmutableSortedMultiset.of())
          .put(BiMap.class, ImmutableBiMap.of())
          .put(ImmutableBiMap.class, ImmutableBiMap.of())
          .put(Table.class, ImmutableTable.of())
          .put(ImmutableTable.class, ImmutableTable.of())
          .put(RowSortedTable.class, Tables.unmodifiableRowSortedTable(TreeBasedTable.create()))
          .put(ClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build())
          .put(ImmutableClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build())
          .put(Comparable.class, ByToString.INSTANCE)
          .put(Comparator.class, AlwaysEqual.INSTANCE)
          .put(Ordering.class, AlwaysEqual.INSTANCE)
          .put(Range.class, Range.all())
          .put(MapConstraint.class, MapConstraints.notNull())
          .put(MapDifference.class, Maps.difference(ImmutableMap.of(), ImmutableMap.of()))
          .put(
              SortedMapDifference.class,
              Maps.difference(ImmutableSortedMap.of(), ImmutableSortedMap.of()))
          // reflect
          .put(AnnotatedElement.class, Object.class)
          .put(GenericDeclaration.class, Object.class)
          .put(Type.class, Object.class)
          .build();

  /**
   * type -> implementation. Inherently mutable interfaces and abstract classes are mapped to their
   * default implementations and are "new"d upon get().
   */
  private static final ConcurrentMap<Class<?>, Class<?>> implementations = Maps.newConcurrentMap();

  private static <T> void setImplementation(Class<T> type, Class<? extends T> implementation) {
    checkArgument(type != implementation, "Don't register %s to itself!", type);
    checkArgument(
        !DEFAULTS.containsKey(type), "A default value was already registered for %s", type);
    checkArgument(
        implementations.put(type, implementation) == null,
        "Implementation for %s was already registered",
        type);
  }

  static {
    setImplementation(Appendable.class, StringBuilder.class);
    setImplementation(BlockingQueue.class, LinkedBlockingDeque.class);
    setImplementation(BlockingDeque.class, LinkedBlockingDeque.class);
    setImplementation(ConcurrentMap.class, ConcurrentHashMap.class);
    setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class);
    setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class);
    setImplementation(Deque.class, ArrayDeque.class);
    setImplementation(OutputStream.class, ByteArrayOutputStream.class);
    setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class);
    setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class);
    setImplementation(Queue.class, ArrayDeque.class);
    setImplementation(Random.class, Dummies.DeterministicRandom.class);
    setImplementation(
        ScheduledThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class);
    setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class);
    setImplementation(Writer.class, StringWriter.class);
    setImplementation(Runnable.class, Dummies.DummyRunnable.class);
    setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class);
    setImplementation(Executor.class, Dummies.DummyExecutor.class);
  }

  @SuppressWarnings("unchecked") // it's a subtype map
  @Nullable
  private static <T> Class<? extends T> getImplementation(Class<T> type) {
    return (Class<? extends T>) implementations.get(type);
  }

  private static final Logger logger = Logger.getLogger(ArbitraryInstances.class.getName());

  /**
   * Returns an arbitrary instance for {@code type}, or {@code null} if no arbitrary instance can be
   * determined.
   */
  @Nullable
  public static <T> T get(Class<T> type) {
    T defaultValue = DEFAULTS.getInstance(type);
    if (defaultValue != null) {
      return defaultValue;
    }
    Class<? extends T> implementation = getImplementation(type);
    if (implementation != null) {
      return get(implementation);
    }
    if (type.isEnum()) {
      T[] enumConstants = type.getEnumConstants();
      return (enumConstants.length == 0) ? null : enumConstants[0];
    }
    if (type.isArray()) {
      return createEmptyArray(type);
    }
    T jvmDefault = Defaults.defaultValue(Primitives.unwrap(type));
    if (jvmDefault != null) {
      return jvmDefault;
    }
    if (Modifier.isAbstract(type.getModifiers()) || !Modifier.isPublic(type.getModifiers())) {
      return arbitraryConstantInstanceOrNull(type);
    }
    final Constructor<T> constructor;
    try {
      constructor = type.getConstructor();
    } catch (NoSuchMethodException e) {
      return arbitraryConstantInstanceOrNull(type);
    }
    constructor.setAccessible(true); // accessibility check is too slow
    try {
      return constructor.newInstance();
    } catch (InstantiationException impossible) {
      throw new AssertionError(impossible);
    } catch (IllegalAccessException impossible) {
      throw new AssertionError(impossible);
    } catch (InvocationTargetException e) {
      logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause());
      return arbitraryConstantInstanceOrNull(type);
    }
  }

  @Nullable
  private static <T> T arbitraryConstantInstanceOrNull(Class<T> type) {
    Field[] fields = type.getDeclaredFields();
    Arrays.sort(fields, BY_FIELD_NAME);
    for (Field field : fields) {
      if (Modifier.isPublic(field.getModifiers())
          && Modifier.isStatic(field.getModifiers())
          && Modifier.isFinal(field.getModifiers())) {
        if (field.getGenericType() == field.getType() && type.isAssignableFrom(field.getType())) {
          field.setAccessible(true);
          try {
            T constant = type.cast(field.get(null));
            if (constant != null) {
              return constant;
            }
          } catch (IllegalAccessException impossible) {
            throw new AssertionError(impossible);
          }
        }
      }
    }
    return null;
  }

  private static <T> T createEmptyArray(Class<T> arrayType) {
    return arrayType.cast(Array.newInstance(arrayType.getComponentType(), 0));
  }

  // Internal implementations of some classes, with public default constructor that get() needs.
  private static final class Dummies {

    public static final class InMemoryPrintStream extends PrintStream {
      public InMemoryPrintStream() {
        super(new ByteArrayOutputStream());
      }
    }

    public static final class InMemoryPrintWriter extends PrintWriter {
      public InMemoryPrintWriter() {
        super(new StringWriter());
      }
    }

    public static final class DeterministicRandom extends Random {
      public DeterministicRandom() {
        super(0);
      }
    }

    public static final class DummyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
      public DummyScheduledThreadPoolExecutor() {
        super(1);
      }
    }

    public static final class DummyCountDownLatch extends CountDownLatch {
      public DummyCountDownLatch() {
        super(0);
      }
    }

    public static final class DummyRunnable implements Runnable, Serializable {
      @Override
      public void run() {}
    }

    public static final class DummyThreadFactory implements ThreadFactory, Serializable {
      @Override
      public Thread newThread(Runnable r) {
        return new Thread(r);
      }
    }

    public static final class DummyExecutor implements Executor, Serializable {
      @Override
      public void execute(Runnable command) {}
    }
  }

  private static final class NullByteSink extends ByteSink implements Serializable {
    private static final NullByteSink INSTANCE = new NullByteSink();

    @Override
    public OutputStream openStream() {
      return ByteStreams.nullOutputStream();
    }
  }

  // Compare by toString() to satisfy 2 properties:
  // 1. compareTo(null) should throw NullPointerException
  // 2. the order is deterministic and easy to understand, for debugging purpose.
  private static final class ByToString implements Comparable<Object>, Serializable {
    private static final ByToString INSTANCE = new ByToString();

    @Override
    public int compareTo(Object o) {
      return toString().compareTo(o.toString());
    }

    @Override
    public String toString() {
      return "BY_TO_STRING";
    }

    private Object readResolve() {
      return INSTANCE;
    }
  }

  // Always equal is a valid total ordering. And it works for any Object.
  private static final class AlwaysEqual extends Ordering<Object> implements Serializable {
    private static final AlwaysEqual INSTANCE = new AlwaysEqual();

    @Override
    public int compare(Object o1, Object o2) {
      return 0;
    }

    @Override
    public String toString() {
      return "ALWAYS_EQUAL";
    }

    private Object readResolve() {
      return INSTANCE;
    }
  }

  private ArbitraryInstances() {}
}