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

com.google.security.fences.inheritance.InheritanceGraph Maven / Gradle / Ivy

There is a newer version: 1.9-beta
Show newest version
package com.google.security.fences.inheritance;

import java.util.Map;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;

/**
 * A lazy-ish graph of sub/super-type relationships between Java classes.
 */
public final class InheritanceGraph {
  private final Map classNodes;
  private final Function fallback;

  InheritanceGraph(
      Map classNodes,
      Function fallback) {
    this.classNodes = Maps.newLinkedHashMap(classNodes);
    this.fallback = fallback;
  }

  /**
   * Returns the named node.
   *
   * @param name an internal class name like {@code com/example/MyClass}.
   */
  public Optional named(String name) {
    ClassNode node = classNodes.get(name);
    if (node == null && !classNodes.containsKey(name)) {
      classNodes.put(name, node = fallback.apply(name));
    }
    return Optional.fromNullable(node);
  }

  /** A builder that uses the pre-baked system class graph. */
  public static Builder builder() {
    return new Builder(SystemInheritanceGraph.LAZY_LOADER);
  }

  static Builder builder(Function fallback) {
    return new Builder(fallback);
  }

  /** A builder for {InheritanceGraph}s. */
  public static final class Builder {
    private final Map classNodes = Maps.newLinkedHashMap();
    private final Function lazyLoadSystemClass;

    Builder(final Function lazyLoadSystemClass) {
      this.lazyLoadSystemClass = lazyLoadSystemClass;
    }

    /**
     * Defines a relationship between name and its super-interfaces.
     */
    public Builder declare(
        String name, int access, Optional superClassName,
        Iterable interfaceNames,
        Iterable methods,
        Iterable fields) {
      ClassNode node = classNodes.get(name);
      if (node != null) {
        // Assume that subsequent declarations are from masked class-files on
        // the same class-path.
      } else {
        node = new ClassNode(
            name, access, superClassName, interfaceNames, methods, fields);
        classNodes.put(name, node);
      }
      return this;
    }

    /** Single use builder.  State is cleared after call to build(). */
    public InheritanceGraph build() {
      return new InheritanceGraph(classNodes, lazyLoadSystemClass);
    }
  }

  /** All the names of class declared, or lazily fetched. */
  public Iterable allDeclaredNames() {
    return ImmutableList.copyOf(classNodes.keySet());
  }

  /** All the names of class declared, or lazily fetched. */
  public Iterable allDeclaredNodes() {
    return ImmutableList.copyOf(classNodes.values());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy