VirtualFile abstraction
thomas.diesler Feb 5, 2007 8:59 AMCarlo,
I notice with the latest EJB3 backport to jboss42 there are a lot referrences to VirtualFile commented out. This is of course correct because jboss-vfs.jar cannot be used in jboss42.
In jbossws we have a simmilar problem in our integration layers for the varios containers, wich we solved by introducing an UnifiedVirtualFile
/**
* An adaptor to a VirtualFile from jboss-vfs.jar
* jboss-vfs cannot be used in jboss-4.x because of its dependeny on jboss-common-core.jar
*
* @author Thomas.Diesler@jboss.org
* @since 05-May-2006
*/
public interface UnifiedVirtualFile extends Serializable
{
UnifiedVirtualFile findChild(String child) throws IOException;
URL toURL();
}
It turns out that we only need these two methods to find and read resources. There is a trivial implementation for jboss50 that delegates to a VirtualFile
/**
* A JBoss50 VirtualFile adaptor
*
* @author Thomas.Diesler@jboss.org
* @since 05-May-2006
*/
public class VirtualFileAdaptor implements UnifiedVirtualFile
{
private static final long serialVersionUID = 6547394037548338042L;
private VirtualFile root;
public VirtualFileAdaptor(VirtualFile root)
{
this.root = root;
}
public UnifiedVirtualFile findChild(String child) throws IOException
{
VirtualFile vf = root.findChild(child);
return new VirtualFileAdaptor(vf);
}
public URL toURL()
{
try
{
return root.toURL();
}
catch (Exception e)
{
return null;
}
}
}
and one for jboss42 that uses a resource class loader
/**
* The default file adapter loads resources through an associated classloader.
* If no classload is set, the the thread context classloader will be used.
*
* @author Heiko.Braun@jboss.org
* @since 25.01.2007
*/
public class ResourceLoaderAdapter implements UnifiedVirtualFile
{
private URL resourceURL;
private ClassLoader loader;
public ResourceLoaderAdapter()
{
this(Thread.currentThread().getContextClassLoader());
}
public ResourceLoaderAdapter(ClassLoader loader)
{
this.loader = loader;
}
private ResourceLoaderAdapter(ClassLoader loader, URL resourceURL)
{
this.resourceURL = resourceURL;
this.loader = loader;
}
public UnifiedVirtualFile findChild(String resourcePath) throws IOException
{
URL resourceURL = null;
if (resourcePath != null)
{
// Try the child as URL
try
{
resourceURL = new URL(resourcePath);
}
catch (MalformedURLException ex)
{
// ignore
}
// Try the filename as File
if (resourceURL == null)
{
try
{
File file = new File(resourcePath);
if (file.exists())
resourceURL = file.toURL();
}
catch (MalformedURLException e)
{
// ignore
}
}
// Try the filename as Resource
if (resourceURL == null)
{
try
{
resourceURL = loader.getResource(resourcePath);
}
catch (Exception ex)
{
// ignore
}
}
}
if (resourceURL == null)
throw new IOException("Cannot get URL for: " + resourcePath);
return new ResourceLoaderAdapter(loader, resourceURL);
}
public URL toURL()
{
if (null == this.resourceURL)
throw new IllegalStateException("UnifiedVirtualFile not initialized");
return resourceURL;
}
}
Maybe this would solve your abstraction problem as well.
cheers