Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » deployment » [javadoc | source]
    1   /*
    2    * JBoss, the OpenSource J2EE webOS
    3    *
    4    * Distributable under LGPL license.
    5    * See terms of license at gnu.org.
    6    */
    7   
    8   package org.jboss.deployment;
    9   
   10   import java.io.File;
   11   import java.io.IOException;
   12   import java.io.InputStream;
   13   import java.net.MalformedURLException;
   14   import java.net.URL;
   15   import java.util.Enumeration;
   16   import java.util.HashMap;
   17   import java.util.Iterator;
   18   import java.util.jar.JarEntry;
   19   import java.util.jar.JarFile;
   20   
   21   import org.jboss.metadata.MetaData;
   22   import org.jboss.metadata.XmlFileLoader;
   23   import org.jboss.mx.loading.LoaderRepositoryFactory;
   24   import org.jboss.mx.loading.LoaderRepositoryFactory.LoaderRepositoryConfig;
   25   import org.jboss.util.file.JarUtils;
   26   
   27   import org.w3c.dom.Element;
   28   
   29   /**
   30    * Enterprise Archive Deployer.
   31    *
   32    * @jmx:mbean name="jboss.j2ee:service=EARDeployer"
   33    *            extends="org.jboss.deployment.SubDeployerMBean"
   34    *
   35    * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
   36    * @author Scott.Stark@jboss.org
   37    * @version $Revision: 1.19.2.10 $
   38    */
   39   public class EARDeployer
   40      extends SubDeployerSupport
   41      implements EARDeployerMBean
   42   {
   43      public EARDeployer()
   44      {
   45         super();
   46      }
   47      
   48      public boolean accepts(DeploymentInfo di) 
   49      {
   50         String urlStr = di.url.getFile();
   51         return urlStr.endsWith("ear") || urlStr.endsWith("ear/");
   52      }
   53      
   54      public void init(DeploymentInfo di)
   55         throws DeploymentException
   56      {
   57         try
   58         {
   59            log.info("Init J2EE application: " + di.url);
   60   
   61            InputStream in = di.localCl.getResourceAsStream("META-INF/application.xml");
   62            if( in == null )
   63               throw new DeploymentException("No META-INF/application.xml found");
   64   
   65            /* Don't require validation of application.xml since an ear may
   66            just contain a jboss sar specified in the jboss-app.xml descriptor.
   67            */
   68            XmlFileLoader xfl = new XmlFileLoader(false);
   69            Element root = xfl.getDocument(in, "META-INF/application.xml").getDocumentElement();
   70            J2eeApplicationMetaData metaData = new J2eeApplicationMetaData(root);
   71            di.metaData = metaData;
   72            in.close();
   73   
   74            // Check for a jboss-app.xml descriptor
   75            in = di.localCl.getResourceAsStream("META-INF/jboss-app.xml");
   76            if( in != null )
   77            {
   78               Element jbossApp = xfl.getDocument(in, "META-INF/jboss-app.xml").getDocumentElement();
   79               in.close();
   80               // Import module/service archives to metadata
   81               metaData.importXml(jbossApp, true);
   82               // Check for a loader-repository for scoping
   83               Element loader = MetaData.getOptionalChild(jbossApp, "loader-repository");
   84               initLoaderRepository(di, loader);
   85            }
   86   
   87            // resolve the watch
   88            if (di.url.getProtocol().equals("file"))
   89            {
   90               File file = new File(di.url.getFile());
   91               
   92               // If not directory we watch the package
   93               if (!file.isDirectory())
   94               {
   95                  di.watch = di.url;
   96               }
   97               // If directory we watch the xml files
   98               else
   99               {
  100                  di.watch = new URL(di.url, "META-INF/application.xml");
  101               }
  102            }
  103            else
  104            {
  105               // We watch the top only, no directory support
  106               di.watch = di.url;
  107            }
  108            
  109            // Obtain the sub-deployment list
  110            File parentDir = null;
  111            HashMap extractedJars = new HashMap();
  112   
  113            if (di.isDirectory) 
  114            {
  115               parentDir = new File(di.localUrl.getFile());
  116            } 
  117            else
  118            {
  119               /* Extract each entry so that deployment modules can be processed
  120                and any manifest entries referenced by the ear modules are located
  121                in the same unpacked directory structure.
  122               */
  123               String urlPrefix = "jar:" + di.localUrl + "!/";
  124               JarFile jarFile = new JarFile(di.localUrl.getFile());
  125               // For each entry, test if deployable, if so
  126               // extract it and store the related URL in map
  127               for (Enumeration e = jarFile.entries(); e.hasMoreElements();)
  128               {
  129                  JarEntry entry = (JarEntry)e.nextElement();
  130                  String name = entry.getName();
  131                  try 
  132                  {
  133                     URL url = new URL(urlPrefix + name);
  134                     if (isDeployable(name, url))
  135                     {
  136                        // Obtain a jar url for the nested jar
  137                       URL nestedURL = JarUtils.extractNestedJar(url, this.tempDeployDir);
  138                       // and store in it in map
  139                       extractedJars.put(name, nestedURL);
  140                     }
  141                  }
  142                  catch (MalformedURLException mue)
  143                  {
  144                     log.warn("Jar entry invalid. Ignoring: " + name, mue);
  145                  }
  146                  catch (IOException ex)
  147                  {
  148                     log.warn("Failed to extract nested jar. Ignoring: " + name, ex);
  149                  }
  150               }
  151            }
  152   
  153            // Create subdeployments for the ear modules
  154            for (Iterator iter = metaData.getModules(); iter.hasNext(); )
  155            {
  156               J2eeModuleMetaData mod = (J2eeModuleMetaData)iter.next();
  157               String fileName = mod.getFileName();
  158               if (fileName != null && (fileName = fileName.trim()).length() > 0)
  159               {
  160                  DeploymentInfo sub = null;
  161                  if (di.isDirectory)
  162                  {
  163                     File f = new File(parentDir, fileName);
  164                     sub = new DeploymentInfo(f.toURL(), di, getServer());
  165                  }
  166                  else
  167                  {
  168                     // The nested jar url was placed into extractedJars above
  169                     URL nestedURL = (URL) extractedJars.get(fileName);
  170                     if( nestedURL == null )
  171                        throw new DeploymentException("Failed to find module file: "+fileName);
  172                     sub = new DeploymentInfo(nestedURL, di, getServer());
  173                  }
  174                  // Set the context-root on web modules
  175                  if( mod.isWeb() )
  176                     sub.webContext = mod.getWebContext();
  177                  log.debug("Deployment Info: " + sub + ", isDirectory: " + sub.isDirectory);
  178               }
  179            }
  180         }
  181         catch (DeploymentException e)
  182         {
  183            throw e;
  184         }
  185         catch (Exception e)
  186         {
  187            throw new DeploymentException("Error in accessing application metadata: ", e);
  188         }
  189   
  190         super.init(di);
  191      }
  192      
  193      public void start(DeploymentInfo di)
  194         throws DeploymentException
  195      {
  196         super.start (di);
  197         log.info ("Started J2EE application: " + di.url);
  198      }
  199   
  200   
  201      /**
  202       * Describe <code>destroy</code> method here.
  203       *
  204       * @param di a <code>DeploymentInfo</code> value
  205       * @exception DeploymentException if an error occurs
  206       */
  207      public void destroy(DeploymentInfo di) throws DeploymentException
  208      {
  209         log.info("Undeploying J2EE application, destroy step: " + di.url);
  210         super.destroy(di);
  211      }
  212   
  213      /** Build the ear scoped repository
  214       *
  215       * @param di the deployment info passed to deploy
  216       * @param loader the jboss-app/loader-repository element
  217       * @throws Exception
  218       */
  219      protected void initLoaderRepository(DeploymentInfo di, Element loader)
  220         throws Exception
  221      {
  222         if( loader == null )
  223            return;
  224   
  225         LoaderRepositoryConfig config = LoaderRepositoryFactory.parseRepositoryConfig(loader);
  226         di.setRepositoryInfo(config);
  227      }
  228   
  229      /**
  230       * Add -ds.xml and -service.xml as legitimate deployables.
  231       */
  232      protected boolean isDeployable(String name, URL url)
  233      {
  234         return super.isDeployable(name, url) || name.endsWith("-ds.xml") ||
  235            name.endsWith("-service.xml");
  236      }
  237   
  238      /** Override the default behavior of looking into the archive for deployables
  239       * as only those explicitly listed in the application.xml and jboss-app.xml
  240       * should be deployed.
  241       *
  242       * @param di
  243       */
  244      protected void processNestedDeployments(DeploymentInfo di)
  245      {
  246      }
  247   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » deployment » [javadoc | source]