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