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.webapp.DefaultWarArchive;
32 import org.codehaus.cargo.module.webapp.WarArchive;
33 import org.codehaus.cargo.module.webapp.WebXmlUtils;
34 import org.jdom.JDOMException;
35 import org.xml.sax.SAXException;
36
37 /**
38 * Parse an WAR descriptor to extract meaninful information for Cactus,
39 * the results being stored in a {@link WarDeployableFile} object.
40 *
41 * @since Cactus 1.5
42 * @version $Id: WarParser.java 239003 2004-05-31 20:05:27Z vmassol $
43 */
44 public class WarParser
45 {
46 /**
47 * Parse an WAR descriptor to extract meaninful information for Cactus.
48 *
49 * @param theDeployableFile the file to parse and deploy
50 * @return the parse results as a {@link WarDeployableFile} object
51 */
52 public static final WarDeployableFile parse(File theDeployableFile)
53 {
54 WarDeployableFile deployable = new WarDeployableFile();
55
56 try
57 {
58 deployable.setFile(theDeployableFile);
59 deployable.setWarArchive(new DefaultWarArchive(
60 new FileInputStream(theDeployableFile)));
61 deployable.setTestContext(parseWebContext(theDeployableFile));
62 deployable.setServletRedirectorMapping(
63 parseServletRedirectorMapping(deployable.getWarArchive()));
64 deployable.setFilterRedirectorMapping(
65 parseFilterRedirectorMapping(deployable.getWarArchive()));
66 deployable.setJspRedirectorMapping(
67 parseJspRedirectorMapping(deployable.getWarArchive()));
68 }
69 catch (IOException e)
70 {
71 throw new CactusRuntimeException("Failed to parse deployment descriptor "
72 + "for WAR file [" + theDeployableFile + "].", e);
73 }
74 catch (ParserConfigurationException e)
75 {
76 throw new CactusRuntimeException("Failed to parse deployment descriptor "
77 + "for WAR file [" + theDeployableFile + "].", e);
78 }
79 catch (SAXException e)
80 {
81 throw new CactusRuntimeException("Failed to parse deployment descriptor "
82 + "for WAR file [" + theDeployableFile + "].", e);
83 }
84 catch (JDOMException e)
85 {
86 throw new CactusRuntimeException("Failed to parse deployment descriptor "
87 + "for WAR file [" + theDeployableFile + "].", e);
88 }
89
90 return deployable;
91 }
92
93 /**
94 * @param theDeployableFile the file to parse and deploy
95 * @return the test context that will be used to verify if the container
96 * is started or not
97 */
98 protected static String parseWebContext(File theDeployableFile)
99 {
100 String context = theDeployableFile.getName();
101 int warIndex = context.toLowerCase().lastIndexOf(".war");
102 if (warIndex >= 0)
103 {
104 context = context.substring(0, warIndex);
105 }
106 return context;
107 }
108
109 /**
110 * Find the first URL-pattern to which the Cactus servlet redirector is
111 * mapped in the deployment descriptor.
112 *
113 * @return the servlet redirector mapping if found or <code>null</code>
114 * if not found
115 * @param theWar the WAR descriptor that is parsed when looking for
116 * a Cactus servlet redirector mapping
117 * @throws IOException If there was a problem reading the deployment
118 * descriptor in the WAR
119 * @throws SAXException If the deployment descriptor of the WAR could not
120 * be parsed
121 * @throws ParserConfigurationException If there is an XML parser
122 * configration problem
123 * @throws JDOMException
124 */
125 static String parseServletRedirectorMapping(WarArchive theWar)
126 throws SAXException, IOException, ParserConfigurationException, JDOMException
127 {
128 Iterator servletNames = WebXmlUtils.getServletNamesForClass(theWar.getWebXml(),
129 "org.apache.cactus.server.ServletTestRedirector");
130 if (servletNames.hasNext())
131 {
132 // we iterate over all of the servlet names but return the first met only --//TODO to be fixed
133 while(servletNames.hasNext()) {
134 String name = (String) servletNames.next();
135 Iterator mappings = WebXmlUtils.getServletMappings(theWar.getWebXml(), name);
136 if (mappings.hasNext())
137 {
138 return (String) mappings.next();
139 }
140 }
141 }
142 return null;
143 }
144
145 /**
146 * Find the first URL-pattern to which the Cactus filter redirector is
147 * mapped in the deployment descriptor.
148 *
149 * @return the filter redirector mapping if found or <code>null</code>
150 * if not found
151 * @param theWar the WAR descriptor that is parsed when looking for
152 * a Cactus filter redirector mapping
153 * @throws IOException If there was a problem reading the deployment
154 * descriptor in the WAR
155 * @throws SAXException If the deployment descriptor of the WAR could not
156 * be parsed
157 * @throws ParserConfigurationException If there is an XML parser
158 * configration problem
159 * @throws JDOMException
160 */
161 static String parseFilterRedirectorMapping(WarArchive theWar)
162 throws IOException, SAXException, ParserConfigurationException, JDOMException
163 {
164 Iterator filterNames = WebXmlUtils.getFilterNamesForClass(theWar.getWebXml(),
165 "org.apache.cactus.server.FilterTestRedirector");
166 if (filterNames.hasNext())
167 {
168 // we only care about the first definition and the first mapping
169 String name = (String) filterNames.next();
170 Iterator mappings = WebXmlUtils.getFilterMappings(theWar.getWebXml(), name);
171 if (mappings.hasNext())
172 {
173 return (String) mappings.next();
174 }
175 }
176 return null;
177 }
178
179 /**
180 * Find the first URL-pattern to which the Cactus JSP redirector is
181 * mapped in the deployment descriptor.
182 *
183 * @return the JSP redirector mapping if found or <code>null</code>
184 * if not found
185 * @param theWar the WAR descriptor that is parsed when looking for
186 * a Cactus JSP redirector mapping
187 * @throws IOException If there was a problem reading the deployment
188 * descriptor in the WAR
189 * @throws SAXException If the deployment descriptor of the WAR could not
190 * be parsed
191 * @throws ParserConfigurationException If there is an XML parser
192 * configration problem
193 * @throws JDOMException
194 */
195 static String parseJspRedirectorMapping(WarArchive theWar)
196 throws IOException, SAXException, ParserConfigurationException, JDOMException
197 {
198 // To get the JSP redirector mapping, we must first get the full path to
199 // the corresponding JSP file in the WAR
200 String jspRedirectorPath = theWar.findResource("jspRedirector.jsp");
201 if (jspRedirectorPath != null)
202 {
203 jspRedirectorPath = "/" + jspRedirectorPath;
204 Iterator jspNames = WebXmlUtils.getServletNamesForClass(theWar.getWebXml(),
205 jspRedirectorPath);
206 if (jspNames.hasNext())
207 {
208 // we only care about the first definition and the first
209 // mapping
210 String name = (String) jspNames.next();
211 Iterator mappings =
212 WebXmlUtils.getServletMappings(theWar.getWebXml(),name);
213 if (mappings.hasNext())
214 {
215 return (String) mappings.next();
216 }
217 }
218 }
219 return null;
220 }
221 }