2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

1   /* 
2    * ========================================================================
3    * 
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * 
19   * ========================================================================
20   */
21  package org.apache.cactus.integration.api.deployable;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.util.Iterator;
27  
28  import javax.xml.parsers.ParserConfigurationException;
29  
30  import org.apache.cactus.integration.api.exceptions.CactusRuntimeException;
31  import org.codehaus.cargo.module.application.ApplicationXml;
32  import org.codehaus.cargo.module.application.DefaultEarArchive;
33  import org.codehaus.cargo.module.application.EarArchive;
34  import org.codehaus.cargo.module.webapp.WarArchive;
35  import org.jdom.JDOMException;
36  import org.xml.sax.SAXException;
37  
38  /**
39   * Parse an EAR descriptor to extract meaninful information for Cactus,
40   * the results being stored in a {@link EarDeployableFile} object. 
41   * 
42   * @since Cactus 1.5
43   * @version $Id: EarParser.java 239003 2004-05-31 20:05:27Z vmassol $
44   */
45  public class EarParser
46  {
47      /**
48       * Parse an EAR descriptor to extract meaninful information for Cactus.
49       * 
50       * @param theDeployableFile the file to parse and deploy
51       * @return the parse results as a {@link EarDeployableFile} object
52       */
53      public static final EarDeployableFile parse(File theDeployableFile)
54      {
55          EarDeployableFile deployable = new EarDeployableFile();
56  
57          try
58          {
59              deployable.setFile(theDeployableFile);
60  
61              EarArchive earArchive = new DefaultEarArchive(
62                  new FileInputStream(theDeployableFile));
63              String webUri = getUriOfCactifiedWebModule(earArchive);
64              if (webUri == null)
65              {
66                  throw new CactusRuntimeException("Could not find cactified web "
67                      + "module in the [" + theDeployableFile + "] EAR.");
68              }
69  
70              WarArchive warArchive = earArchive.getWebModule(webUri);
71              if (warArchive == null)
72              {
73                  throw new CactusRuntimeException("Could not find the WAR [" + webUri
74                      + "] in the [" + theDeployableFile + "] EAR.");
75              }
76              
77              deployable.setWarArchive(warArchive);
78              deployable.setTestContext(parseTestContext(earArchive, webUri));
79              deployable.setServletRedirectorMapping(
80                  WarParser.parseServletRedirectorMapping(
81                      deployable.getWarArchive()));
82              deployable.setFilterRedirectorMapping(
83                  WarParser.parseFilterRedirectorMapping(
84                      deployable.getWarArchive()));
85              deployable.setJspRedirectorMapping(
86                  WarParser.parseJspRedirectorMapping(
87                      deployable.getWarArchive()));
88          }
89          catch (IOException e)
90          {
91              throw new CactusRuntimeException("Failed to parse deployment descriptor "
92                  + "for EAR file [" + theDeployableFile + "].", e);
93          }
94          catch (ParserConfigurationException e)
95          {
96              throw new CactusRuntimeException("Failed to parse deployment descriptor "
97                  + "for EAR file [" + theDeployableFile + "].", e);
98          }
99          catch (SAXException e)
100         {
101             throw new CactusRuntimeException("Failed to parse deployment descriptor "
102                 + "for EAR file [" + theDeployableFile + "].", e);
103         }
104         catch (JDOMException e)
105         {
106             throw new CactusRuntimeException("Failed to parse deployment descriptor "
107                 + "for EAR file [" + theDeployableFile + "].", e);
108         }
109         
110         return deployable;
111     }   
112 
113     /**
114      * Find the test context from the EAR archive. 
115      * 
116      * @return the test context
117      * @param theEar the EAR archive from which to extract the test context
118      * @param theWebUri the WAR URI of the WAR file in the EAR from which to
119      *        extract the test context
120      * @throws IOException If there was a problem reading the  deployment
121      *         descriptor in the WAR
122      * @throws SAXException If the deployment descriptor of the WAR could not
123      *         be parsed
124      * @throws ParserConfigurationException If there is an XML parser
125      *         configration problem
126      * @throws JDOMException 
127      */
128     public static final String parseTestContext(EarArchive theEar, 
129         String theWebUri) 
130         throws ParserConfigurationException, IOException, SAXException, JDOMException
131     {
132         String context = theEar.getApplicationXml()
133             .getWebModuleContextRoot(theWebUri);
134         if (context == null)
135         {
136             // The application.xml does not define a <context-root> element.
137             // This is wrong!
138             throw new CactusRuntimeException("Your application.xml must define a "
139                 + "<context-root> element in the <web> module definition.");
140         }
141 
142         // Remove leading "/" if there is one.
143         if (context.startsWith("/"))
144         {
145             context = context.substring(1);
146         }
147 
148         return context;
149     }
150     
151     /**
152      * Finds the web module in the EAR that contains the servlet test 
153      * redirector, and returns the web-uri of the module found.
154      * 
155      * <em>A web-app is considered cactified when it contains at least a 
156      * mapping for the Cactus servlet test redirector</em>
157      * 
158      * @return The URI of the cactified web-module, or <code>null</code> if no
159      *         cactified web-app could be found
160      * @param theEar the EAR archive from which to extract the web URI 
161      * @throws IOException If there was a problem reading the  deployment
162      *         descriptor in the WAR
163      * @throws SAXException If the deployment descriptor of the WAR could not
164      *         be parsed
165      * @throws ParserConfigurationException If there is an XML parser
166      *         configration problem
167      * @throws JDOMException 
168      */
169     protected static final String getUriOfCactifiedWebModule(EarArchive theEar)
170         throws SAXException, IOException, ParserConfigurationException, JDOMException
171     {
172         ApplicationXml applicationXml = theEar.getApplicationXml();
173         for (Iterator i = applicationXml.getWebModuleUris(); i.hasNext();)
174         {
175             String webUri = (String) i.next();
176             WarArchive war = theEar.getWebModule(webUri);
177             if ((war != null) 
178                 && (WarParser.parseServletRedirectorMapping(war) != null))
179             {
180                 return webUri;
181             }
182         }
183         return null;
184     }
185 }