KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > AbstractWebContainer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.web;
23
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.net.URLClassLoader JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Collection JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.HashSet JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Set JavaDoc;
39 import java.util.jar.JarInputStream JavaDoc;
40 import java.util.zip.ZipEntry JavaDoc;
41
42 import javax.management.ObjectName JavaDoc;
43
44 import org.jboss.deployment.DeploymentException;
45 import org.jboss.deployment.DeploymentInfo;
46 import org.jboss.deployment.SubDeployerSupport;
47 import org.jboss.metadata.WebMetaData;
48 import org.jboss.metadata.XmlFileLoader;
49 import org.jboss.mx.loading.LoaderRepositoryFactory;
50 import org.jboss.mx.loading.LoaderRepositoryFactory.LoaderRepositoryConfig;
51 import org.jboss.mx.util.MBeanProxyExt;
52 import org.jboss.mx.util.ObjectNameFactory;
53 import org.jboss.system.ServiceControllerMBean;
54 import org.jboss.util.file.FilenameSuffixFilter;
55 import org.jboss.util.file.JarUtils;
56 import org.w3c.dom.Document JavaDoc;
57 import org.w3c.dom.Element JavaDoc;
58
59 /** A template pattern class for web container integration into JBoss. This class
60  should be subclasses by web container providers wishing to integrate their
61  container into a JBoss server.
62
63  @see org.jboss.web.AbstractWebDeployer
64
65  @deprecated see org.jboss.web.deployers.AbstractWarDeployer
66
67  @author Scott.Stark@jboss.org
68  @author Christoph.Jung@infor.de
69  @author Thomas.Diesler@arcor.de
70  @version $Revision: 57669 $
71  */

72 public abstract class AbstractWebContainer extends SubDeployerSupport
73    implements AbstractWebContainerMBean
74 {
75    public static final String JavaDoc DEPLOYER = "org.jboss.web.AbstractWebContainer.deployer";
76    public static final String JavaDoc WEB_APP = "org.jboss.web.AbstractWebContainer.webApp";
77    public static final String JavaDoc WEB_MODULE = "org.jboss.web.AbstractWebContainer.webModule";
78    public static final String JavaDoc ERROR = "org.jboss.web.AbstractWebContainer.error";
79
80    public static interface WebDescriptorParser
81    {
82       /** This method is called as part of subclass performDeploy() method implementations
83        to parse the web-app.xml and jboss-web.xml deployment descriptors from a
84        war deployment. The method creates the ENC(java:comp/env) env-entry,
85        resource-ref, ejb-ref, etc element values. The creation of the env-entry
86        values does not require a jboss-web.xml descriptor. The creation of the
87        resource-ref and ejb-ref elements does require a jboss-web.xml descriptor
88        for the JNDI name of the deployed resources/EJBs.
89
90        Because the ENC context is private to the web application, the web
91        application class loader is used to identify the ENC. The class loader
92        is used because each war typically requires a unique class loader to
93        isolate the web application classes/resources. This means that the
94        ClassLoader passed to this method must be the thread context ClassLoader
95        seen by the server/jsp pages during init/destroy/service/etc. method
96        invocations if these methods interace with the JNDI ENC context.
97
98        @param loader the ClassLoader for the web application. May not be null.
99        @param metaData the WebMetaData from the WebApplication object passed to
100        the performDeploy method.
101        */

102       public void parseWebAppDescriptors(ClassLoader JavaDoc loader, WebMetaData metaData) throws Exception JavaDoc;
103
104       /** Get the DeploymentInfo for the war the triggered the deployment process.
105        * The returned reference may be updated to affect the state of the
106        * JBoss DeploymentInfo object. This can be used to assign ObjectNames
107        * of MBeans created by the container.
108        * @return The DeploymentInfo for the war being deployed.
109        */

110       public DeploymentInfo getDeploymentInfo();
111    }
112
113    /** The suffixes we accept, along with their relative order */
114    private static final String JavaDoc[] DEFAULT_ENHANCED_SUFFIXES = new String JavaDoc[] {
115          "500:.war"
116    };
117    
118    /** A mapping of deployed warUrl strings to the WebApplication object */
119    protected HashMap JavaDoc deploymentMap = new HashMap JavaDoc();
120    /** The parent class loader first model flag */
121    protected boolean java2ClassLoadingCompliance = false;
122    /** A flag indicating if war archives should be unpacked */
123    protected boolean unpackWars = true;
124    /** A flag indicating if local dirs with WEB-INF/web.xml should be treated as wars
125     */

126    protected boolean acceptNonWarDirs = false;
127
128    /** If true, ejb-links that don't resolve don't cause an error (fallback to jndi-name) */
129    protected boolean lenientEjbLink = false;
130
131    /** The default security-domain name to use */
132    protected String JavaDoc defaultSecurityDomain = "java:/jaas/other";
133    /** The request attribute name under which the JAAS Subject is store */
134    private String JavaDoc subjectAttributeName = null;
135    /** The ServiceController used to control web app startup dependencies */
136    protected ServiceControllerMBean serviceController;
137
138    public AbstractWebContainer()
139    {
140       setEnhancedSuffixes(DEFAULT_ENHANCED_SUFFIXES);
141    }
142
143    /** Get the flag indicating if the normal Java2 parent first class loading
144     * model should be used over the servlet 2.3 web container first model.
145     * @return true for parent first, false for the servlet 2.3 model
146     * @jmx:managed-attribute
147     */

148    public boolean getJava2ClassLoadingCompliance()
149    {
150       return java2ClassLoadingCompliance;
151    }
152
153    /** Set the flag indicating if the normal Java2 parent first class loading
154     * model should be used over the servlet 2.3 web container first model.
155     * @param flag true for parent first, false for the servlet 2.3 model
156     * @jmx:managed-attribute
157     */

158    public void setJava2ClassLoadingCompliance(boolean flag)
159    {
160       java2ClassLoadingCompliance = flag;
161    }
162
163    /** Set the flag indicating if war archives should be unpacked. This may
164     * need to be set to false as long extraction paths under deploy can
165     * show up as deployment failures on some platforms.
166     *
167     * @jmx:managed-attribute
168     * @return true is war archives should be unpacked
169     */

170    public boolean getUnpackWars()
171    {
172       return unpackWars;
173    }
174
175    /** Get the flag indicating if war archives should be unpacked. This may
176     * need to be set to false as long extraction paths under deploy can
177     * show up as deployment failures on some platforms.
178     *
179     * @jmx:managed-attribute
180     * @param flag , true is war archives should be unpacked
181     */

182    public void setUnpackWars(boolean flag)
183    {
184       this.unpackWars = flag;
185    }
186
187    /**
188     * Get the flag indicating if local dirs with WEB-INF/web.xml should be
189     * treated as wars
190     * @return true if local dirs with WEB-INF/web.xml should be treated as wars
191     * @jmx.managed-attribute
192     */

193    public boolean getAcceptNonWarDirs()
194    {
195       return acceptNonWarDirs;
196    }
197    /**
198     * Set the flag indicating if local dirs with WEB-INF/web.xml should be
199     * treated as wars
200     * @param flag - true if local dirs with WEB-INF/web.xml should be treated as wars
201     * @jmx.managed-attribute
202     */

203    public void setAcceptNonWarDirs(boolean flag)
204    {
205       this.acceptNonWarDirs = flag;
206    }
207
208    /**
209     * Get the flag indicating if ejb-link errors should be ignored
210     * in favour of trying the jndi-name in jboss-web.xml
211     * @return the LenientEjbLink flag
212     *
213     * @jmx:managed-attribute
214     */

215    public boolean getLenientEjbLink()
216    {
217       return lenientEjbLink;
218    }
219
220    /**
221     * Set the flag indicating if ejb-link errors should be ignored
222     * in favour of trying the jndi-name in jboss-web.xml
223     *
224     * @jmx:managed-attribute
225     */

226    public void setLenientEjbLink(boolean flag)
227    {
228       lenientEjbLink = flag;
229    }
230
231    /** Get the default security domain implementation to use if a war
232     * does not declare a security-domain.
233     *
234     * @return jndi name of the security domain binding to use.
235     * @jmx:managed-attribute
236     */

237    public String JavaDoc getDefaultSecurityDomain()
238    {
239       return defaultSecurityDomain;
240    }
241    /** Set the default security domain implementation to use if a war
242     * does not declare a security-domain.
243     *
244     * @param defaultSecurityDomain - jndi name of the security domain binding
245     * to use.
246     * @jmx:managed-attribute
247     */

248    public void setDefaultSecurityDomain(String JavaDoc defaultSecurityDomain)
249    {
250       this.defaultSecurityDomain = defaultSecurityDomain;
251    }
252
253    /** Get the session attribute number under which the caller Subject is stored
254     * @jmx:managed-attribute
255     */

256    public String JavaDoc getSubjectAttributeName()
257    {
258       return subjectAttributeName;
259    }
260    /** Set the session attribute number under which the caller Subject is stored
261     * @jmx:managed-attribute
262     */

263    public void setSubjectAttributeName(String JavaDoc subjectAttributeName)
264    {
265       this.subjectAttributeName = subjectAttributeName;
266    }
267
268
269    public abstract AbstractWebDeployer getDeployer(DeploymentInfo di) throws Exception JavaDoc;
270
271    public boolean accepts(DeploymentInfo sdi)
272    {
273      // Should be checking for .war and .war/
274
boolean accepts = super.accepts(sdi);
275
276      if (accepts == false && acceptNonWarDirs == true)
277      {
278         // Check for a local unpacked directory with a /WEB-INF/web.xml
279
if (sdi.url.getProtocol().equalsIgnoreCase("file"))
280         {
281            File JavaDoc webXml = new File JavaDoc(sdi.url.getFile(), "WEB-INF/web.xml");
282            accepts = webXml.exists();
283         }
284      }
285      return accepts;
286    }
287
288    public synchronized void init(DeploymentInfo di)
289       throws DeploymentException
290    {
291       log.debug("Begin init");
292       this.server = di.getServer();
293       try
294       {
295          if (di.url.getPath().endsWith("/"))
296          {
297             // the URL is a unpacked collection, watch the deployment descriptor
298
di.watch = new URL JavaDoc(di.url, "WEB-INF/web.xml");
299          }
300          else
301          {
302             // just watch the original URL
303
di.watch = di.url;
304          }
305
306          // We need to unpack the WAR if it has webservices.xml, because we need
307
// to manipulate th web.xml before deploying to the web container
308
boolean unpackWebservice = di.localCl.findResource("WEB-INF/webservices.xml") != null;
309          // With JSR-181 annotated JSE endpoints we need to do it as well even if there is no webservices.xml
310
unpackWebservice |= server.isRegistered(ObjectNameFactory.create("jboss.ws:service=ServiceEndpointManager"));
311
312          // Make sure the war is unpacked if unpackWars is true
313
File JavaDoc warFile = new File JavaDoc(di.localUrl.getFile());
314          if (warFile.isDirectory() == false && (unpackWars || unpackWebservice))
315          {
316             // After findResource we cannot rename the WAR anymore, because
317
// some systems keep an open reference to the file :(
318
String JavaDoc prefix = warFile.getCanonicalPath();
319             prefix = prefix.substring(0, prefix.lastIndexOf(".war"));
320             File JavaDoc expWarFile = new File JavaDoc(prefix + "-exp.war");
321             if( expWarFile.mkdir() == false )
322                throw new DeploymentException("Was unable to mkdir: "+expWarFile);
323             log.debug("Unpacking war to: "+expWarFile);
324             FileInputStream JavaDoc fis = new FileInputStream JavaDoc(warFile);
325             JarUtils.unjar(fis, expWarFile);
326             fis.close();
327             log.debug("Replaced war with unpacked contents");
328             if (warFile.delete() == false)
329                log.debug("Was unable to delete war file");
330             else
331                log.debug("Deleted war archive");
332             // Reset the localUrl to end in a '/'
333
di.localUrl = expWarFile.toURL();
334             // Reset the localCl to point to the file
335
URL JavaDoc[] localCl = new URL JavaDoc[]{di.localUrl};
336             di.localCl = new URLClassLoader JavaDoc(localCl);
337          }
338
339          WebMetaData metaData = new WebMetaData();
340          metaData.setResourceClassLoader(di.localCl);
341          metaData.setJava2ClassLoadingCompliance(this.java2ClassLoadingCompliance);
342          di.metaData = metaData;
343
344          String JavaDoc webContext = di.webContext;
345          if( webContext != null )
346          {
347             if( webContext.length() > 0 && webContext.charAt(0) != '/' )
348                webContext = "/" + webContext;
349          }
350          // Get the war URL
351
URL JavaDoc warURL = di.localUrl != null ? di.localUrl : di.url;
352          log.debug("webContext: " + webContext);
353          log.debug("warURL: " + warURL);
354
355          // Parse the web.xml and jboss-web.xml descriptors
356
parseMetaData(webContext, warURL, di.shortName, metaData);
357
358          // Check for a loader-repository
359
LoaderRepositoryConfig config = metaData.getLoaderConfig();
360          if (config != null)
361             di.setRepositoryInfo(config);
362
363          // Generate an event for the initialization
364
super.init(di);
365       }
366       catch (DeploymentException e)
367       {
368          log.debug("Problem in init ", e);
369          throw e;
370       }
371       catch (Exception JavaDoc e)
372       {
373          log.error("Problem in init ", e);
374          throw new DeploymentException(e);
375       }
376
377       log.debug("End init");
378    }
379
380    /** Create a WebModule service, register it under the name
381     "jboss.web.deployment:war="+di.shortName
382     and invoke the ServiceController.create(jmxname, depends) using the depends
383     found in the WebMetaData.
384
385     @param di - The deployment info for the war
386     @throws DeploymentException
387     */

388    public void create(DeploymentInfo di) throws DeploymentException
389    {
390       log.debug("create, " + di.shortName);
391       try
392       {
393          // initialize the annotations loader
394
URL JavaDoc loaderURL = (di.localUrl != null ? di.localUrl : di.url);
395          File JavaDoc warFile = new File JavaDoc(di.localUrl.getFile());
396          if (warFile.isDirectory())
397          {
398             List JavaDoc urlList = new ArrayList JavaDoc();
399             urlList.add(new URL JavaDoc(loaderURL + "WEB-INF/classes/"));
400             
401             File JavaDoc libDir = new File JavaDoc(warFile, "WEB-INF/lib/");
402             String JavaDoc[] jarArr = libDir.list(new FilenameSuffixFilter(".jar"));
403             for (int i = 0; jarArr != null && i < jarArr.length; i++)
404             {
405                String JavaDoc urlStr = loaderURL + "WEB-INF/lib/" + jarArr[i];
406                urlList.add(new URL JavaDoc(urlStr));
407             }
408             URL JavaDoc[] urlArr = new URL JavaDoc[urlList.size()];
409             urlList.toArray(urlArr);
410             di.annotationsCl = new URLClassLoader JavaDoc(urlArr, di.ucl);
411          }
412          else
413          {
414             List JavaDoc urlList = new ArrayList JavaDoc();
415             urlList.add(new URL JavaDoc(warFile + "!WEB-INF/classes"));
416             
417             FileInputStream JavaDoc fis = new FileInputStream JavaDoc(warFile);
418             JarInputStream JavaDoc jin = new JarInputStream JavaDoc(fis);
419             ZipEntry JavaDoc entry = jin.getNextEntry();
420             while (entry != null)
421             {
422                String JavaDoc entryName = entry.getName();
423                if (entryName.startsWith("WEB-INF/lib"))
424                {
425                   urlList.add(new URL JavaDoc(warFile + "!" + entryName));
426                }
427                entry = jin.getNextEntry();
428             }
429             jin.close();
430             
431             URL JavaDoc[] urlArr = new URL JavaDoc[urlList.size()];
432             urlList.toArray(urlArr);
433             di.annotationsCl = new URLClassLoader JavaDoc(urlArr, di.ucl);
434          }
435
436          AbstractWebDeployer deployer = getDeployer(di);
437          di.context.put(DEPLOYER, deployer);
438          WebMetaData metaData = (WebMetaData) di.metaData;
439          processMetaData(di);
440          Collection JavaDoc depends = metaData.getDepends();
441          WebModule module = new WebModule(di, this, deployer);
442          ObjectName JavaDoc jmxName = new ObjectName JavaDoc("jboss.web.deployment:war="
443             + di.shortName + ",id="+di.hashCode());
444          server.registerMBean(module, jmxName);
445          di.context.put(WEB_MODULE, jmxName);
446          serviceController.create(jmxName, depends);
447          // Generate an event for the create
448
super.create(di);
449       }
450       catch(Exception JavaDoc e)
451       {
452          throw new DeploymentException("Failed to create web module", e);
453       }
454    }
455
456    /**
457     * This allows the container to perform any specific metadata processing before the WebModule is deployed
458     * The container can analyze dependencies on PUs, datasources, eJBs, etc... and add to the depends list of Metadata
459     *
460     * @param di
461     * @param metadata
462     */

463    protected void processMetaData(DeploymentInfo di)
464    {
465       // complete
466
}
467
468    /** Invokes the ServiceController.start(jmxName) to start the WebModule
469     after its dependencies are satisfied.
470
471     @param di - The deployment info for the war
472     @throws DeploymentException
473     */

474    public synchronized void start(DeploymentInfo di) throws DeploymentException
475    {
476       ObjectName JavaDoc jmxName = (ObjectName JavaDoc) di.context.get(WEB_MODULE);
477       try
478       {
479          serviceController.start(jmxName);
480       }
481       catch (DeploymentException e)
482       {
483          throw e;
484       }
485       catch(Exception JavaDoc e)
486       {
487          throw new DeploymentException("Unable to start web module", e);
488       }
489       // Check for a deployment error
490
DeploymentException e = (DeploymentException) di.context.get(ERROR);
491       if( e != null )
492          throw e;
493
494       // Generate an event for the startup
495
super.start(di);
496    }
497
498    /** Invokes the ServiceController.start(jmxName) to stop the WebModule
499     and its dependents.
500
501     @param di - The deployment info for the war
502     @throws DeploymentException
503     */

504    public synchronized void stop(DeploymentInfo di)
505       throws DeploymentException
506    {
507       ObjectName JavaDoc jmxName = (ObjectName JavaDoc) di.context.get(WEB_MODULE);
508       try
509       {
510          if (jmxName != null)
511             serviceController.stop(jmxName);
512       }
513       catch (DeploymentException e)
514       {
515          throw e;
516       }
517       catch(Exception JavaDoc e)
518       {
519          throw new DeploymentException("Unable to stop web module", e);
520       }
521       // Generate an event for the shutdown
522
super.stop(di);
523    }
524
525    /** Invokes the ServiceController.destroy(jmxName) to destroy the WebModule
526     and its dependents.
527
528     @param di - The deployment info for the war
529     @throws DeploymentException
530     */

531    public synchronized void destroy(DeploymentInfo di)
532       throws DeploymentException
533    {
534       ObjectName JavaDoc jmxName = (ObjectName JavaDoc) di.context.get(WEB_MODULE);
535       try
536       {
537          if( jmxName != null )
538          {
539             try
540             {
541                serviceController.destroy(jmxName);
542             }
543             finally
544             {
545                serviceController.remove(jmxName);
546             }
547          }
548       }
549       catch (DeploymentException e)
550       {
551          throw e;
552       }
553       catch(Exception JavaDoc e)
554       {
555          throw new DeploymentException("Unable to stop web module", e);
556       }
557       // Generate an event for the shutdown
558
super.destroy(di);
559    }
560
561    /** See if a war is deployed.
562     @jmx:managed-operation
563     */

564    public boolean isDeployed(String JavaDoc warUrl)
565    {
566       return deploymentMap.containsKey(warUrl);
567    }
568
569    public void addDeployedApp(URL JavaDoc warURL, WebApplication webApp)
570    {
571       deploymentMap.put(warURL, webApp);
572    }
573    /** Get the WebApplication object for a deployed war.
574     @param warUrl the war url string as originally passed to deploy().
575     @return The WebApplication created during the deploy step if the
576     warUrl is valid, null if no such deployment exists.
577     */

578    public WebApplication getDeployedApp(String JavaDoc warUrl)
579    {
580       WebApplication appInfo = (WebApplication) deploymentMap.get(warUrl);
581       return appInfo;
582    }
583    public WebApplication removeDeployedApp(URL JavaDoc warURL)
584    {
585       WebApplication appInfo = (WebApplication) deploymentMap.remove(warURL);
586       return appInfo;
587    }
588
589    /** Returns the applications deployed by the web container subclasses.
590     @jmx:managed-attribute
591     @return An Iterator of WebApplication objects for the deployed wars.
592     */

593    public Iterator JavaDoc getDeployedApplications()
594    {
595       return deploymentMap.values().iterator();
596    }
597
598    /** An accessor for any configuration element set via setConfig. This
599     method always returns null and must be overriden by subclasses to
600     return a valid value.
601     @jmx:managed-attribute
602     */

603    public Element JavaDoc getConfig()
604    {
605       return null;
606    }
607
608    /** This method is invoked to import an arbitrary XML configuration tree.
609     Subclasses should override this method if they support such a configuration
610     capability. This implementation does nothing.
611     @jmx:managed-attribute
612     */

613    public void setConfig(Element JavaDoc config)
614    {
615    }
616
617    /** Use reflection to access a URL[] getURLs method so that non-URLClassLoader
618     *class loaders that support this method can provide info.
619     */

620    public static URL JavaDoc[] getClassLoaderURLs(ClassLoader JavaDoc cl)
621    {
622       URL JavaDoc[] urls = {};
623       try
624       {
625          Class JavaDoc returnType = urls.getClass();
626          Class JavaDoc[] parameterTypes = {};
627          Method JavaDoc getURLs = cl.getClass().getMethod("getURLs", parameterTypes);
628          if( returnType.isAssignableFrom(getURLs.getReturnType()) )
629          {
630             Object JavaDoc[] args = {};
631             urls = (URL JavaDoc[]) getURLs.invoke(cl, args);
632          }
633          if( urls == null || urls.length == 0 )
634          {
635             getURLs = cl.getClass().getMethod("getAllURLs", parameterTypes);
636             if( returnType.isAssignableFrom(getURLs.getReturnType()) )
637             {
638                Object JavaDoc[] args = {};
639                urls = (URL JavaDoc[]) getURLs.invoke(cl, args);
640             }
641          }
642       }
643       catch(Exception JavaDoc ignore)
644       {
645       }
646       return urls;
647    }
648    
649    /** A utility method that walks up the ClassLoader chain starting at
650     the given loader and queries each ClassLoader for a 'URL[] getURLs()'
651     method from which a complete classpath of URL strings is built.
652     */

653    public String JavaDoc[] getCompileClasspath(ClassLoader JavaDoc loader)
654    {
655       HashSet JavaDoc tmp = new HashSet JavaDoc();
656       ClassLoader JavaDoc cl = loader;
657       while( cl != null )
658       {
659          URL JavaDoc[] urls = getClassLoaderURLs(cl);
660          addURLs(tmp, urls);
661          cl = cl.getParent();
662       }
663       try
664       {
665          URL JavaDoc[] globalUrls = (URL JavaDoc[])server.getAttribute(LoaderRepositoryFactory.DEFAULT_LOADER_REPOSITORY,
666                                                          "URLs");
667          addURLs(tmp, globalUrls);
668       }
669       catch (Exception JavaDoc e)
670       {
671          log.warn("Could not get global URL[] from default loader repository!");
672       } // end of try-catch
673
log.trace("JSP CompileClasspath: " + tmp);
674       String JavaDoc[] cp = new String JavaDoc[tmp.size()];
675       tmp.toArray(cp);
676       return cp;
677    }
678
679    /** WARs do not have nested deployments
680     * @param di
681     */

682    protected void processNestedDeployments(DeploymentInfo di) throws DeploymentException
683    {
684    }
685
686    protected void startService() throws Exception JavaDoc
687    {
688       serviceController = (ServiceControllerMBean)
689          MBeanProxyExt.create(ServiceControllerMBean.class,
690                               ServiceControllerMBean.OBJECT_NAME,
691                               server);
692       super.startService();
693    }
694
695    /** This method creates a context-root string from either the
696       WEB-INF/jboss-web.xml context-root element is one exists, or the
697       filename portion of the warURL. It is called if the DeploymentInfo
698       webContext value is null which indicates a standalone war deployment.
699       A war name of ROOT.war is handled as a special case of a war that
700       should be installed as the default web context.
701     */

702    protected void parseMetaData(String JavaDoc ctxPath, URL JavaDoc warURL, String JavaDoc warName,
703       WebMetaData metaData)
704       throws DeploymentException
705    {
706       InputStream JavaDoc jbossWebIS = null;
707       InputStream JavaDoc webIS = null;
708
709       // Parse the war deployment descriptors, web.xml and jboss-web.xml
710
try
711       {
712          // See if the warUrl is a directory
713
File JavaDoc warDir = new File JavaDoc(warURL.getFile());
714          if( warURL.getProtocol().equals("file") && warDir.isDirectory() == true )
715          {
716             File JavaDoc webDD = new File JavaDoc(warDir, "WEB-INF/web.xml");
717             if( webDD.exists() == true )
718                webIS = new FileInputStream JavaDoc(webDD);
719             File JavaDoc jbossWebDD = new File JavaDoc(warDir, "WEB-INF/jboss-web.xml");
720             if( jbossWebDD.exists() == true )
721                jbossWebIS = new FileInputStream JavaDoc(jbossWebDD);
722          }
723          else
724          {
725             // First check for a WEB-INF/web.xml and a WEB-INF/jboss-web.xml
726
InputStream JavaDoc warIS = warURL.openStream();
727             java.util.zip.ZipInputStream JavaDoc zipIS = new java.util.zip.ZipInputStream JavaDoc(warIS);
728             java.util.zip.ZipEntry JavaDoc entry;
729             byte[] buffer = new byte[512];
730             int bytes;
731             while( (entry = zipIS.getNextEntry()) != null )
732             {
733                if( entry.getName().equals("WEB-INF/web.xml") )
734                {
735                   ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
736                   while( (bytes = zipIS.read(buffer)) > 0 )
737                   {
738                      baos.write(buffer, 0, bytes);
739                   }
740                   webIS = new ByteArrayInputStream JavaDoc(baos.toByteArray());
741                }
742                else if( entry.getName().equals("WEB-INF/jboss-web.xml") )
743                {
744                   ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
745                   while( (bytes = zipIS.read(buffer)) > 0 )
746                   {
747                      baos.write(buffer, 0, bytes);
748                   }
749                   jbossWebIS = new ByteArrayInputStream JavaDoc(baos.toByteArray());
750                }
751             }
752             zipIS.close();
753          }
754
755          XmlFileLoader xmlLoader = new XmlFileLoader();
756          String JavaDoc warURI = warURL.toExternalForm();
757          try
758          {
759             if( webIS != null )
760             {
761                Document JavaDoc webDoc = xmlLoader.getDocument(webIS, warURI+"/WEB-INF/web.xml");
762                Element JavaDoc web = webDoc.getDocumentElement();
763                metaData.importXml(web);
764             }
765          }
766          catch(Exception JavaDoc e)
767          {
768             throw new DeploymentException("Failed to parse WEB-INF/web.xml", e);
769          }
770          try
771          {
772             if( jbossWebIS != null )
773             {
774                Document JavaDoc jbossWebDoc = xmlLoader.getDocument(jbossWebIS, warURI+"/WEB-INF/jboss-web.xml");
775                Element JavaDoc jbossWeb = jbossWebDoc.getDocumentElement();
776                metaData.importXml(jbossWeb);
777             }
778          }
779          catch(Exception JavaDoc e)
780          {
781             throw new DeploymentException("Failed to parse WEB-INF/jboss-web.xml", e);
782          }
783
784       }
785       catch(DeploymentException e)
786       {
787          throw e;
788       }
789       catch(Exception JavaDoc e)
790       {
791          log.warn("Failed to parse descriptors for war("+warURL+")", e);
792       }
793
794       // Build a war root context from the war name if one was not specified
795
String JavaDoc webContext = ctxPath;
796       if( webContext == null )
797          webContext = metaData.getContextRoot();
798       if( webContext == null )
799       {
800          // Build the context from the war name, strip the .war suffix
801
webContext = warName;
802          webContext = webContext.replace('\\', '/');
803          if( webContext.endsWith("/") )
804             webContext = webContext.substring(0, webContext.length()-1);
805          int prefix = webContext.lastIndexOf('/');
806          if( prefix > 0 )
807             webContext = webContext.substring(prefix+1);
808          int suffix = webContext.lastIndexOf(".war");
809          if( suffix > 0 )
810             webContext = webContext.substring(0, suffix);
811           // Strip any '<int-value>.' prefix
812
int index = 0;
813           for(; index < webContext.length(); index ++)
814           {
815              char c = webContext.charAt(index);
816              if( Character.isDigit(c) == false && c != '.' )
817                 break;
818           }
819           webContext = webContext.substring(index);
820       }
821
822       // Servlet containers are anal about the web context starting with '/'
823
if( webContext.length() > 0 && webContext.charAt(0) != '/' )
824          webContext = "/" + webContext;
825       // And also the default root context must be an empty string, not '/'
826
else if( webContext.equals("/") )
827          webContext = "";
828       metaData.setContextRoot(webContext);
829    }
830
831    private void addURLs(Set JavaDoc urlSet, URL JavaDoc[] urls)
832    {
833       for(int u = 0; u < urls.length; u ++)
834       {
835          URL JavaDoc url = urls[u];
836          urlSet.add(url.toExternalForm());
837       }
838    }
839 }
840
Popular Tags