package net.sourceforge.javautil.classloader.resolver.impl;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.javautil.classloader.resolver.IClassArtifactReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackage;
import net.sourceforge.javautil.classloader.resolver.IClassPackageDescriptor;
import net.sourceforge.javautil.classloader.resolver.IClassPackageReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRepositoryLocal;
import net.sourceforge.javautil.classloader.resolver.IClassPackageResolver;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageResolverImpl;
import net.sourceforge.javautil.classloader.source.ClassSource;
import net.sourceforge.javautil.classloader.source.VirtualDirectoryClassSource;
import net.sourceforge.javautil.classloader.source.ZipClassSource;
import net.sourceforge.javautil.classloader.util.ClassPackageUtil;
import net.sourceforge.javautil.common.ArchiveUtil;
import net.sourceforge.javautil.common.io.IVirtualArtifact;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.impl.SystemFile;
/**
* This represents the base for most maven repository implementations.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public abstract class ClassPackageRepositoryLocalAbstract implements IClassPackageRepositoryLocal {
protected Map<String, IClassPackageDescriptor> descriptorCache = Collections.synchronizedMap( new HashMap<String, IClassPackageDescriptor>() );
protected Map<String, Map<String, ClassSource>> sourceCache = Collections.synchronizedMap( new HashMap<String, Map<String, ClassSource>>() );
public void clearCachedInformation(IClassPackageReference reference) {
String id = this.createUniqueId(reference);
descriptorCache.remove(id);
sourceCache.remove(id);
}
@Override public IClassPackage getPackage(IClassPackageResolver resolver, IClassPackageReference reference) {
ClassSource src = this.getClassSource("main", resolver, reference);
return src == null ? null : new ClassPackageImpl(this, this.getDescriptor(resolver, reference), src);
}
public IClassPackageDescriptor getDescriptor(IClassPackageResolver resolver, IClassPackageReference reference) {
String id = this.createUniqueId(reference);
if (this.descriptorCache.containsKey(id)) return this.descriptorCache.get(id);
IClassPackageDescriptor descriptor = this.resolveDescriptor(resolver, reference);
this.descriptorCache.put(id, descriptor);
return descriptor;
}
public ClassSource getClassSource(String name, IClassPackageResolver resolver, IClassPackageReference reference) {
String id = this.createUniqueId(reference);
if (!this.sourceCache.containsKey(id)) this.sourceCache.put(id, new HashMap<String, ClassSource>());
if (this.sourceCache.get(id).containsKey(name)) return this.sourceCache.get(id).get(name);
ClassSource source = this.resolve(name, resolver, reference);
this.sourceCache.get(id).put(name, source);
return source;
}
public ClassSource getMainClassSource(IClassPackageResolver resolver, IClassPackageReference reference) {
return this.getClassSource("main", resolver, reference);
}
public void refresh() {
if (this.refreshRoot()) {
this.descriptorCache.clear();
this.sourceCache.clear();
}
}
/**
* @param reference The reference for which to make a unique id
* @return A unique key-id for associating with the reference
*/
protected String createUniqueId (IClassPackageReference reference) {
StringBuffer id = new StringBuffer();
id.append(reference.getGroupId()).append(":");
id.append(reference.getArtifactId());
if (reference.getVersion() != null) id.append(":").append(reference.getVersion().toVersionString());
if (reference.getClassifier() != null) id.append(":").append(reference.getClassifier());
return id.toString();
}
/**
* @param reference The reference for which to make a unique id
* @return A unique key-id for associating with the reference
*/
protected String createUniqueId (IClassArtifactReference reference) {
return reference.getGroupId() + ":" + reference.getArtifactId() + ":";
}
/**
* @param artifact The artifact in question
* @return A valid class source for the given artifact
*/
protected ClassSource getClassSource (IClassPackageReference reference, IVirtualArtifact artifact) {
if (artifact instanceof IVirtualFile) {
if (artifact instanceof SystemFile && ArchiveUtil.isArchive((IVirtualFile)artifact));
return new ZipClassSource( ((SystemFile)artifact).getRealArtifact() );
} else if (artifact instanceof IVirtualDirectory) {
VirtualDirectoryClassSource cs = new VirtualDirectoryClassSource( (IVirtualDirectory) artifact );
cs.setManifest( ClassPackageUtil.createVirtualManifest(reference) );
return cs;
}
throw new IllegalArgumentException("Cannot create class source from: " + artifact);
}
/**
* Refresh the root source of the packages in this repository
*
* @return True if the root source was actually refreshed, otherwise false
*/
protected abstract boolean refreshRoot ();
/**
* @param type The type of class source to resolve
* @param reference The reference for which to get class sources
* @return A valid class source for the reference and type or null if none could be found
*/
protected abstract ClassSource resolve (String type, IClassPackageResolver resolver, IClassPackageReference reference);
/**
* @param reference The reference for which to get a descriptor
* @return A valid descriptor for the reference or null if none could be found
*/
protected abstract IClassPackageDescriptor resolveDescriptor (IClassPackageResolver resolver, IClassPackageReference reference);
}