package net.sourceforge.javautil.common.io;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.javautil.common.CollectionUtil;
import net.sourceforge.javautil.common.StringUtil;
import net.sourceforge.javautil.common.io.impl.Directory;
import net.sourceforge.javautil.common.io.impl.DirectoryFileLinked;
import net.sourceforge.javautil.common.io.impl.DirectoryRoot;
import net.sourceforge.javautil.common.io.impl.SimplePath;
import net.sourceforge.javautil.common.io.impl.ISystemArtifact;
/**
* This represents a 'system' or dedicated 'area' considered as a 'root'
* for {@link IVirtualArtifact}'s.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: VirtualArtifactSystem.java 2685 2010-12-25 04:36:33Z ponderator $
*/
public final class VirtualArtifactSystem extends DirectoryRoot {
/**
* The {@value #VAS_PROTOCOL} protocol used by the {@link IVirtualArtifact} framework for URL resolution.
*/
public static final String VAS_PROTOCOL = "vas";
/**
* The roots of the VAS
*/
private static Map<String, VirtualArtifactSystem> roots = Collections.synchronizedMap( new LinkedHashMap<String, VirtualArtifactSystem>() );
/**
* @param name The name of the root VAS
* @param create True if the root should be created if it does not already exist, otherwise false
* @return The VAS if it exists or was created otherwise null
*/
public static VirtualArtifactSystem get (String name, boolean create) {
if (!roots.containsKey(name) && create) {
synchronized (roots) {
if (!roots.containsKey(name)) {
roots.put(name, new VirtualArtifactSystem(name));
}
}
}
return roots.get(name);
}
/**
* @param artifact The artifact in question
* @return True if the artifact is directly linked to a {@link VirtualArtifactSystem}, otherwise false
*/
public static boolean isMounted (IVirtualArtifact artifact) {
return getSystemFor(artifact) != null;
}
/**
* @param artifact The artifact in question
* @return The VAS the artifact is linked to, otherwise false
*/
public static VirtualArtifactSystem getSystemFor (IVirtualArtifact artifact) {
while (artifact.getOwner() != null) {
if (artifact.getOwner() instanceof VirtualArtifactSystem) return (VirtualArtifactSystem) artifact.getOwner();
artifact = artifact.getOwner();
}
return null;
}
/**
* @param url The URL to use for lookup
* @return The artifact pointed to by the URL, or null if it is not a VAS url or could not be found
*/
public static IVirtualArtifact getArtifactFor (URL url) {
if (url.getProtocol().equals( VAS_PROTOCOL )) {
IVirtualPath path = new SimplePath(url.getPath());
if (path.getPartCount() == 0) return null;
VirtualArtifactSystem vas = get(path.getPart(0), false);
if (vas != null) {
try {
return vas.getArtifact(new SimplePath( CollectionUtil.shift(path.getParts()) ));
} catch (VirtualArtifactException e) {
return null;
}
}
}
return null;
}
protected final String vasName;
private VirtualArtifactSystem (String name) { this.vasName = name; }
/**
* @return The {@link VirtualArtifactSystem} name this system is mounted to
*/
public String getVASName() { return vasName; }
@Override public IVirtualArtifact getArtifact(String name) {
return wrap( super.getArtifact(name) );
}
protected IVirtualArtifact wrap (IVirtualArtifact artifact) {
if (artifact == null) return null;
if ( !this.isSystemArtifact(artifact) && getSystemFor(artifact) != this ) {
if (artifact instanceof IVirtualFile) {
artifact = new DirectoryFileLinked(this, (IVirtualFile) artifact);
} else {
artifact = new DirectoryLinked((IVirtualDirectory)artifact);
}
}
return artifact;
}
/**
* @param artifact The artifact in question
* @return True if the artifact points to a system artifact, otherwise false
*/
protected boolean isSystemArtifact (IVirtualArtifact artifact) {
if (artifact instanceof Directory) {
} else
while (artifact instanceof VirtualArtifactWrapped) {
artifact = ((VirtualArtifactWrapped)artifact).getDelegate();
}
return artifact instanceof ISystemArtifact;
}
private class DirectoryLinked extends VirtualDirectoryWrapped {
public DirectoryLinked(IVirtualDirectory delegate) {
super(delegate);
}
@Override public IVirtualArtifact getArtifact(String name) {
return wrap( super.getArtifact(name) );
}
}
}