/*************************************** * * * JBoss: The OpenSource J2EE WebOS * * * * Distributable under LGPL license. * * See terms of license at gnu.org. * * * ***************************************/ package org.jboss.deployment; import java.io.File; import java.io.FileFilter; import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import javax.management.MBeanServer; import javax.management.ObjectName; /** * This deployer exists to prevent deployment of packages whose deployers are not yet * deployed. It will accept only jar/zip format files or directories that don't * have a META-INF directory, or if they do, don't have any .xml files there. It * assumes any package with a META-INF/*.xml file needs a specialized deployer. * * JARDeployerMBean.java is generated by XDoclet. * * @todo find a way to scan just the META-INF files, not the whole jar. * * Created: Mon Mar 4 12:58:19 2002 * * @author Scott.Stark@jboss.org * @author David Jencks * @version $Revision: 1.7.2.5 $ * * @jmx:mbean name="jboss.system:service=JARDeployer" * extends="org.jboss.deployment.SubDeployerMBean" */ public class JARDeployer extends SubDeployerSupport implements JARDeployerMBean { // ServiceMBeanSupport methods protected ObjectName getObjectName(MBeanServer server, ObjectName name) throws javax.management.MalformedObjectNameException { return name == null ? OBJECT_NAME : name; } protected void stopService() { // This can't be run right now since the JARDeployer is started before the MainDeployer, // so the MainDeployer is stopped first... so the JARDeployer can't unregister. // super.stopService(); } // SubDeployer implementation /** * The accepts method is called by MainDeployer to * determine which deployer is suitable for a DeploymentInfo. * * @todo find a way to scan just the META-INF files, not the whole jar. * * @param sdi a DeploymentInfo value * @return a boolean value */ public boolean accepts(DeploymentInfo di) { boolean trace = log.isTraceEnabled(); try { if (di.isXML || di.isScript) { return false; } // end of if () URL wdDir = di.localCl.findResource("WEB-INF/"); if (wdDir != null) { return false; } // end of if () // Since a META-INF directory exists within rt.jar, we can't just do a // getResource (it will always return rt.jar's version). // The method we want is findResource, but it is marked protected in // ClassLoader. Fortunately, URLClassLoader exposes it which makes // this hack possible. Anybody have a better way to check a URL // for the existance of a META-INF?? URL ddDir; try { ddDir = di.localCl.findResource("META-INF/"); if (ddDir == null) { log.debug("No META-INF or WEB-INF resource found, assuming it if for us"); return true; } } catch (ClassCastException e) { // assume there is a META-INF... ddDir = new URL(di.url, "META-INF/"); } if (ddDir.getProtocol().equals("file")) { log.trace("File protocol: "+ddDir); File file = new File(ddDir.getFile()); if (!file.exists()) { log.warn("File not found: " + file); return true; } // Scan for any xml files in the META-INF dir File[] entries = file.listFiles( new FileFilter() { public boolean accept(File pathname) { return pathname.toString().endsWith(".xml"); } } ); log.debug("XML entries found: " + entries.length); return entries.length == 0; } // end of if () else if (ddDir.getProtocol().equals("jar") == true) { log.trace("jar protocol: " + ddDir); JarFile jarFile = null; try { URLConnection con = ddDir.openConnection(); JarURLConnection jarConn = (JarURLConnection) con; /* Need to set caching to false otherwise closing the jarfile ends up conflicting with other users of the cached jar. */ jarConn.setUseCaches(false); jarFile = jarConn.getJarFile(); } catch (Exception e) { log.warn("Looking inside jar failed; ignoring", e); if( jarFile != null ) jarFile.close(); jarFile = null; return false; } // Scan for any xml files in the META-INF dir boolean accepts = true; for (Enumeration e = jarFile.entries(); e.hasMoreElements();) { JarEntry entry = (JarEntry)e.nextElement(); String name = entry.getName(); if (trace) { log.trace("Looking at entry: " + name); } // end of if () if (name.startsWith("META-INF/") && name.endsWith(".xml")) { accepts = false; break; } // end of if () } // end of for jarFile.close(); jarFile = null; log.debug("No xml files found"); return accepts; } // end of if () else { log.debug("Unrecognized protocol: " + ddDir.getProtocol()); } // end of else return false; } catch (Exception e) { return false; } } }