Package net.sourceforge.javautil.classloader.resolver

Source Code of net.sourceforge.javautil.classloader.resolver.ClassPackageResolverContext

package net.sourceforge.javautil.classloader.resolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import net.sourceforge.javautil.classloader.resolver.ClassPackageResolverNetworkNode.Type;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageDependencyReferenceImpl;
import net.sourceforge.javautil.classloader.source.ClassSource;

/**
* This is the root of an entire resolution process. This network based resolution composite IS NOT thread safe.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class ClassPackageResolverContext {
 
  protected Logger log = Logger.getLogger(ClassPackageResolverContext.class.getName());

  protected Map<String, ClassPackageResolverNetworkNode> index = new HashMap<String, ClassPackageResolverNetworkNode>();
  protected List<IClassPackageDependencyReference> stack = new ArrayList<IClassPackageDependencyReference>();
  protected List<IClassPackageDescriptor> descriptorStack = new ArrayList<IClassPackageDescriptor>();
 
  protected boolean resolveDependencies = true;
 
  public ClassPackageResolverContext () {}
  public ClassPackageResolverContext (IClassPackageDescriptor descriptor) {
    this.descriptorStack.add(descriptor);
  }
  public ClassPackageResolverContext (IClassPackageReference reference) {
    this.stack.add(new ClassPackageDependencyReferenceImpl(reference));
  }
 
  /**
   * @return The current node being resolved
   */
  public IClassPackageDependencyReference getCurrentDependency () { return stack.size() == 0 ? null : stack.get(0); }
 
  /**
   * @return The parent dependency that is referencing the {@link #getCurrentDependency()}, or null if on first level
   */
  public IClassPackageDependencyReference getParentDependency () { return stack.size() <= 1 ? null : stack.get(1); }
 
  /**
   * @return The descriptor related to the {@link #getCurrentDependency()}, or null if no descriptor was provided
   */
  public IClassPackageDescriptor getDescriptor () { return this.descriptorStack.size() == 0 ? null : descriptorStack.get(0); }
 
  public boolean isResolveDependencies() { return resolveDependencies; }
  public void setResolveDependencies(boolean resolveDependencies) {
    this.resolveDependencies = resolveDependencies;
  }
 
  public int getStackSize () {
    return this.stack.size();
  }
 
  /**
   * @return A list, possibly empty, of all non-null descriptors provided
   */
  public Set<IClassPackageDescriptor> getDescriptors () {
    Set<IClassPackageDescriptor> descriptors = new HashSet<IClassPackageDescriptor>();
    for (IClassPackageDescriptor desc : this.descriptorStack) {
      if (desc != null) descriptors.add(desc);
    }
    return descriptors;
  }
 
  /**
   * @param reference The reference in question
   * @return A node with already resolved information if available, otherwise false
   */
  public ClassPackageResolverNetworkNode getResolved (IClassArtifactReference reference) { return index.get(reference.toArtifactString()); }
 
  /**
   * This can be used to detect circular references.
   *
   * @param reference The reference in question
   * @return True if a reference to this artifact is already on the stack, otherwise false
   */
  public boolean isInStack (IClassArtifactReference reference) {
    if (stack.size() > 1) {
      for (int i=1; i<stack.size(); i++) {
        if (reference.compareTo(stack.get(i)) == 0) return true;
      }
    }
    return false;
  }
 
  /**
   * @param reference The reference in question
   * @return True if the reference has been excluded by one of the nodes in the stack, otherwise false
   */
  public boolean isExcluded (IClassArtifactReference reference) {
    for (int s=0; s<stack.size(); s++) {
      IClassPackageDependencyReference node = stack.get(s);
      for (int i=0; i<node.getExclusions().size(); i++) {
        if (node.getExclusions().get(i).compareTo(reference) == 0) return true;
      }
    }
    return false;
  }
 
  /**
   * @param reference The reference for the new node
   * @param descriptor The descriptor used for this, or null if not provided
   * @return This for chaining purposes
   */
  public ClassPackageResolverContext pushNode (IClassPackageDependencyReference reference, IClassPackageDescriptor descriptor) {
    this.stack.add(0, reference);
    this.descriptorStack.add(0, descriptor);
    return this;
  }
 
  /**
   * This will remove the top-most node from the stack.
   *
   * @return This for chaining purposes
   */
  public ClassPackageResolverContext popNode () {
    this.stack.remove(0);
    this.descriptorStack.remove(0);
    return this;
  }

  public List<ClassPackageResolverNetworkNode> getAvailable () {
    List<ClassPackageResolverNetworkNode> nodes = new ArrayList<ClassPackageResolverNetworkNode>();
   
    for (ClassPackageResolverNetworkNode node : index.values()) {
      if (node.getType() != Type.Unavailable) nodes.add(node);
    }
   
    return nodes;
  }
 
  public List<ClassPackageResolverNetworkNode> getDownloadable () {
    List<ClassPackageResolverNetworkNode> nodes = new ArrayList<ClassPackageResolverNetworkNode>();
   
    for (ClassPackageResolverNetworkNode node : index.values()) {
      if (node.getType() == Type.Downloadable) nodes.add(node);
    }
   
    return nodes;
  }
 
  public void remove (ClassPackageResolverNetworkNode node) {
    index.remove(node.getReference().toArtifactString());
    for (ClassPackageResolverNetworkNode dependency : node.getDependencies()) {
      dependency.getRelationships().remove(node);
      if (dependency.getRelationships().size() == 0) remove(dependency);
    }
  }
 
  public void relate (ClassPackageResolverNetworkNode node) {
    if (stack.size() <= 1) node.setPrimary(true);
    else {
      node.getRelationships().add( index.get(stack.get(1).toArtifactString()) );
      index.get(stack.get(1).toArtifactString()).getDependencies().add(node);
    }
  }
 
  public void setAvailable (IClassPackageResolver resolver, IClassPackageRepositoryLocal repository, ClassSource resolution, IClassPackageDescriptor descriptor) {
    ClassPackageResolverNetworkNode node = new ClassPackageResolverNetworkNode(this, this.getCurrentDependency());
    node.setType(Type.Available);
    node.setResolution(resolution);
    node.setDescriptor(descriptor);
    this.register(node);
  }
 
  public void setDownloadable (IClassPackageResolver resolver, IClassPackageRepositoryLocalImportable local, IClassPackageRepositoryRemote remote) {
    ClassPackageResolverNetworkNode node = new ClassPackageResolverNetworkNode(this, this.getCurrentDependency());
    node.setType(Type.Downloadable);
    node.setLocal(local);
    node.setRemote(remote);
    this.register(node);
  }
 
  public void setUnavailable () {
    ClassPackageResolverNetworkNode node = new ClassPackageResolverNetworkNode(this, this.getCurrentDependency());
    node.setType(Type.Unavailable);
    this.register(node);
   
    log.warning("Could not resolve: " + this.getCurrentDependency());
  }
 
  protected void register (ClassPackageResolverNetworkNode node) {
    if (this.index.containsKey(node.getReference().toArtifactString()))
      throw new ClassPackageException(node.getReference(), "For node: " + node.getReference() + "/" + node + " there is already an index: " +
        this.index.get(node.getReference().toArtifactString()));
   
    this.index.put(node.getReference().toArtifactString(), node);
    this.relate(node);
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.classloader.resolver.ClassPackageResolverContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.