Package net.sourceforge.javautil.classloader.source

Source Code of net.sourceforge.javautil.classloader.source.VirtualDirectoryClassSource$PackageNameVisitor

package net.sourceforge.javautil.classloader.source;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import net.sourceforge.javautil.classloader.impl.ClassInfo;
import net.sourceforge.javautil.classloader.impl.ClassSearchInfo;
import net.sourceforge.javautil.classloader.impl.PackageSearchInfo;
import net.sourceforge.javautil.common.ClassNameUtil;
import net.sourceforge.javautil.common.IOUtil;
import net.sourceforge.javautil.common.Refreshable;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualArtifact;
import net.sourceforge.javautil.common.io.VirtualArtifactException;
import net.sourceforge.javautil.common.io.VirtualArtifactNotFoundException;
import net.sourceforge.javautil.common.io.VirtualArtifactSystem;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.VirtualDirectoryVisitorContext;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.IVirtualPath;
import net.sourceforge.javautil.common.io.impl.ArtifactCollector;
import net.sourceforge.javautil.common.io.impl.DirectoryRoot;
import net.sourceforge.javautil.common.io.impl.DirectoryFile;
import net.sourceforge.javautil.common.io.impl.SimplePath;
import net.sourceforge.javautil.common.io.impl.SystemDirectory;
import net.sourceforge.javautil.common.visitor.IVisitorSimple;

/**
* A class source based on a {@link IVirtualDirectory}.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: VirtualDirectoryClassSource.java 2534 2010-11-05 04:18:32Z ponderator $
*/
public class VirtualDirectoryClassSource extends ClassSource implements Refreshable {
 
  public static final String MEMORY_REPOSITORY_VAS = "net.sf.javautil.classloader.memory";
  public static final String DEFAULT_MEMORY_REPOSITORY = "default";
 
  /**
   * @param repositoryName The repository name
   * @return True if the repository exists, otherwise false
   */
  public static boolean isExistsRepository (String repositoryName) {
    return VirtualArtifactSystem.get(MEMORY_REPOSITORY_VAS, true).isExists(new SimplePath(repositoryName));
  }
 
  /**
   * @param repositoryName The repository name
   * @param name The name of the jar
   * @return True if the jar exists in the specified repository, otherwise false
   */
  public static boolean isExistsJar (String repositoryName, String name) {
    return VirtualArtifactSystem.get(MEMORY_REPOSITORY_VAS, true).isExists(new SimplePath(repositoryName + "/" + name));
  }
 
  /**
   * @param repositoryName The repository to retreive
   * @param autoCreate True if the repository should be created if it does not already exist, otherwise false
   * @return The in memory repository
   */
  public static IVirtualDirectory getInMemoryRepository (String repositoryName, boolean autoCreate) {
    IVirtualDirectory repository = VirtualArtifactSystem.get(MEMORY_REPOSITORY_VAS, true).getDirectory(repositoryName, autoCreate);
    if (repository == null) throw new IllegalArgumentException("Could not find repository: " + repositoryName);
    return repository;
  }
 
  /**
   * @param repositoryName The repository from which to get the jar
   * @param name The name of the jar
   * @return The directory/jar
   */
  public static IVirtualDirectory getInMemoryJar (String repositoryName, String name) {
    IVirtualDirectory jar = getInMemoryRepository(repositoryName, false).getDirectory(name);
    if (jar == null) throw new IllegalArgumentException("Could not find repository jar: " + repositoryName + ":" + name);
    return jar;
  }
 
  /**
   * @param repositoryName The repository to remove
   */
  public static void removeInMemoryRepository (String repositoryName) {
    VirtualArtifactSystem.get(MEMORY_REPOSITORY_VAS, true).remove(repositoryName);
  }
 
  /**
   * This assumes the default repository: {@value #DEFAULT_MEMORY_REPOSITORY}.
   *
   * @see #getFromInMemoryRepository(String, String)
   */
  public static VirtualDirectoryClassSource getFromInMemoryRepository (String name) {
    return getFromInMemoryRepository(DEFAULT_MEMORY_REPOSITORY, name);
  }
 
  /**
   * @param repositoryName The repository in which to make the in memory jar
   * @param name The name of the jar
   * @return The previously made class source/in memory jar
   *
   * @see #createInMemoryJar(String, String, ZipInputStream)
   */
  public static VirtualDirectoryClassSource getFromInMemoryRepository (String repositoryName, String name) {
    return new VirtualDirectoryClassSource( getInMemoryJar(repositoryName, name) );
  }
 
  /**
   * This will simple wrap the input stream passed with a {@link ZipInputStream}.
   *
   * @see #createInMemoryJar(String, String, ZipInputStream)
   */
  public static VirtualDirectoryClassSource createInMemoryJar (String repositoryName, String name, InputStream input) {
    return createInMemoryJar(repositoryName, name, new ZipInputStream(input));
  }
 
  /**
   * @param repositoryName The name of the in memory repository where the jar will be created
   * @param name The name of the jar
   * @param input The input from which to read the jar
   * @return A class source pointing to the in memory jar
   */
  public static VirtualDirectoryClassSource createInMemoryJar (String repositoryName, String name, ZipInputStream input) {
    IVirtualDirectory directory = getInMemoryRepository(repositoryName, true).getDirectory(name, true);
    try {
      ZipEntry entry = null;
      do {
        entry = input.getNextEntry();
        if (entry != null) {
          if (entry.getName().endsWith("/")) {
            directory.createDirectory(new SimplePath(entry.getName()));
          } else
            directory.createFile(new SimplePath(entry.getName()), IOUtil.read(input, null, false));
        }
      } while (entry != null);
    } catch (IOException e) {
      throw ThrowableManagerRegistry.caught(e);
    } finally {
      try { input.close(); } catch (IOException e) {
        ThrowableManagerRegistry.caught(e);
      }
    }
    return new VirtualDirectoryClassSource(directory);
  }

  public static final Pattern pathSeparator = Pattern.compile("[/\\\\]");
 
  protected final IVirtualDirectory directory;
  protected final List<String> packages = new ArrayList<String>(5);
 
  protected boolean searched = false;
  protected long lastModified = System.currentTimeMillis();
 
  protected Manifest manifest;
 
  public VirtualDirectoryClassSource(IVirtualDirectory directory) {
    super(directory.getPath().toString("/"));
    this.directory = directory;
  }

  public Manifest getManifest() {
    if (this.manifest != null) return this.manifest;
    return super.getManifest();
  }
 
  /**
   * This allows one to set an override for the manifest file returned for this class source.
   *
   * @param manifest The manifest file override
   *
   * @see #getManifest()
   */
  public void setManifest(Manifest manifest) { this.manifest = manifest; }

  /**
   * @return The directory this class source is based on
   */
  public IVirtualDirectory getDirectory() { return directory; }

  @Override public IVirtualArtifact getVirtualArtifact() { return directory; }

  @Override public long getLastModified() { return this.directory.getRecursiveLastModified(); }

  @Override public long getLastModifiedClass() {
    Set<IVirtualFile> classFiles = this.directory.accept( (ArtifactCollector<IVirtualFile>)
        new ArtifactCollector()
          .setIncludeDirectories(false)
          .addInclusionPatternFilter(Pattern.compile(".*\\.class"))
          .setCollectionDefault(false)
      ).getCollected();
   
    long stamp = -1;
   
    for (IVirtualFile file : classFiles) {
      if (file.getLastModified() > stamp) stamp = file.getLastModified();
    }
   
    return stamp;
  }

  @Override public ClassInfo getClassInfo(ClassSearchInfo info) throws ClassNotFoundException {
    try {
      return new ClassInfo(info, this);
    } catch (VirtualArtifactNotFoundException e) {
      throw new ClassNotFoundException(info.getFullClassName());
    }
  }

  @Override public Collection<String> getResourceNames() {
    return directory.accept(new ClassFileVisitor(false)).names;
  }

  @Override public Collection<String> getClassNames() {
    return directory.accept(new ClassFileVisitor(true)).names;
  }

  @Override public List<String> getClassNamesForPackage(PackageSearchInfo info) {
    IVirtualArtifact pkgdir = this.getPathedArtifact(info.getPackagePath());
    List<String> classNames = new ArrayList<String>();
   
    if (pkgdir instanceof IVirtualDirectory) {
      Iterator<IVirtualArtifact> artifacts = ((IVirtualDirectory)pkgdir).getArtifacts();
      while (artifacts.hasNext()) {
        IVirtualArtifact artifact = artifacts.next();
        if (ClassNameUtil.isClassSource( artifact.getName() )) {
          IVirtualPath relative = directory.getRelativePath(artifact);
          classNames.add( ClassNameUtil.toClassName(relative.toString("/")) );
        }
      }
    }
   
    return classNames;
  }

  @Override public Collection<String> getPackages() {
    PackageNameVisitor pkgs = new PackageNameVisitor();
    directory.accept(pkgs);
    return pkgs.packages;
  }

  @Override public URL getResource(String resourceName) {
    try {
      return this.getPathedArtifact(resourceName).getURL();
    } catch (VirtualArtifactNotFoundException e) {
      return null;
    }
  }

  @Override public ClassSource clone() throws CloneNotSupportedException {
    VirtualDirectoryClassSource vds = new VirtualDirectoryClassSource( this.directory );
    vds.setManifest(manifest);
    return vds;
  }

  @Override public URL getURL() { return directory.getURL(); }

  @Override public boolean hasClass(ClassSearchInfo info) {
    try {
      return this.getClassInfo(info) != null;
    } catch (ClassNotFoundException e) {
      return false;
    }
  }

  @Override public boolean hasPackage(PackageSearchInfo info) {
    return this.hasParentPackage(info.getPackageName());
  }

  @Override public boolean hasParentPackage(String packageName) {
    try {
      return directory.getArtifact(new SimplePath(packageName, "\\.")) instanceof IVirtualDirectory;
    } catch (VirtualArtifactNotFoundException e) {
      return false;
    }
  }

  @Override public boolean hasParentResource(String parentResource) {
    try {
      return this.getPathedArtifact(parentResource) instanceof IVirtualDirectory;
    } catch (VirtualArtifactNotFoundException e) {
      return false;
    }
  }

  @Override public boolean hasResource(String resourceName) {
    try {
      return this.getPathedArtifact(resourceName) != null;
    } catch (VirtualArtifactNotFoundException e) {
      return false;
    }
  }

  @Override public boolean hasSearchedAll() { return this.searched; }

  @Override public boolean isHasBeenModified() {
    return this.getLastModified() > this.lastModified;
  }

  @Override public boolean isHasClassesBeenModified() {
    return this.getLastModifiedClass() > this.lastModified;
  }

  @Override public byte[] loadInternal(ClassSearchInfo info) throws ClassNotFoundException {
    try {
      return IOUtil.read(((IVirtualFile)this.getArtifact(info)).getInputStream(), this.getBuffer());
    } catch (IOException e) {
      throw ThrowableManagerRegistry.caught(e);
    } catch (VirtualArtifactNotFoundException e) {
      throw new ClassNotFoundException(info.getFullClassName(), e);
    }
  }
 
  private IVirtualArtifact getPathedArtifact (String path) { return directory.getArtifact(this.getPath(path)); }
 
  private IVirtualArtifact getArtifact (ClassSearchInfo info) { return directory.getArtifact(this.getPath(info.getClassPath())); }
 
  private IVirtualPath getPath (String path) { return new SimplePath(path, pathSeparator); }
 
  public void refresh() {
    this.lastModified = this.directory.getRecursiveLastModified();
    this.packages.clear();
    this.searched = false;
  }

  @Override public void reload() {
    this.refresh();
  }

  /**
   * A class name collector.
   *
   * @author elponderador
   * @author $Author: ponderator $
   * @version $Id: VirtualDirectoryClassSource.java 2534 2010-11-05 04:18:32Z ponderator $
   */
  public class ClassFileVisitor implements IVisitorSimple<VirtualDirectoryVisitorContext> {
   
    protected boolean classes = true;
    private List<String> names = new ArrayList<String>();

    public ClassFileVisitor(boolean classes) { this.classes = classes; }

    public void visit(VirtualDirectoryVisitorContext ctx) {
      if (classes && ctx.getVisited().getName().contains("-")) { ctx.skip(); return; }
     
      boolean isClass = ClassNameUtil.isClassSource(ctx.getVisited().getName());
      if (classes && isClass) names.add(ClassNameUtil.toClassName( directory.getRelativePath(ctx.getVisited()).toString("/") ));
      else if (!classes && !isClass) names.add(directory.getRelativePath(ctx.getVisited()).toString("/"));
    }
   
  }

  /**
   * A package name collector.
   *
   * @author elponderador
   * @author $Author: ponderator $
   * @version $Id: VirtualDirectoryClassSource.java 2534 2010-11-05 04:18:32Z ponderator $
   */
  public class PackageNameVisitor implements IVisitorSimple<VirtualDirectoryVisitorContext> {
   
    private List<String> packages = new ArrayList<String>();

    public void visit(VirtualDirectoryVisitorContext ctx) {
      if (ctx.getVisited().getName().contains("-")) { ctx.skip(); return; }
     
      if (ctx.getVisited() instanceof IVirtualDirectory && ctx.getVisited() != directory)
        packages.add(ClassNameUtil.toPackageName( directory.getRelativePath(ctx.getVisited()).toString("/") ));
    }
   
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.classloader.source.VirtualDirectoryClassSource$PackageNameVisitor

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.