1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
package org.apache.myfaces.shared_impl.webapp.webxml; |
20 | |
|
21 | |
import java.io.IOException; |
22 | |
import java.io.InputStream; |
23 | |
import java.net.URL; |
24 | |
|
25 | |
import javax.faces.FacesException; |
26 | |
import javax.faces.context.ExternalContext; |
27 | |
import javax.xml.parsers.DocumentBuilder; |
28 | |
import javax.xml.parsers.DocumentBuilderFactory; |
29 | |
|
30 | |
import org.apache.commons.logging.Log; |
31 | |
import org.apache.commons.logging.LogFactory; |
32 | |
import org.apache.myfaces.shared_impl.util.ClassUtils; |
33 | |
import org.apache.myfaces.shared_impl.util.xml.MyFacesErrorHandler; |
34 | |
import org.apache.myfaces.shared_impl.util.xml.XmlUtils; |
35 | |
import org.w3c.dom.Document; |
36 | |
import org.w3c.dom.Element; |
37 | |
import org.w3c.dom.Node; |
38 | |
import org.w3c.dom.NodeList; |
39 | |
import org.xml.sax.EntityResolver; |
40 | |
import org.xml.sax.InputSource; |
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | 0 | public class WebXmlParser |
47 | |
{ |
48 | 0 | private static final Log log = LogFactory.getLog(WebXmlParser.class); |
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
private static final String WEB_XML_PATH = "/WEB-INF/web.xml"; |
58 | |
|
59 | |
private static final String WEB_APP_2_2_J2EE_SYSTEM_ID = "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"; |
60 | |
private static final String WEB_APP_2_2_SYSTEM_ID = "http://java.sun.com/dtd/web-app_2_2.dtd"; |
61 | |
private static final String WEB_APP_2_2_RESOURCE = "javax/servlet/resources/web-app_2_2.dtd"; |
62 | |
|
63 | |
private static final String WEB_APP_2_3_SYSTEM_ID = "http://java.sun.com/dtd/web-app_2_3.dtd"; |
64 | |
private static final String WEB_APP_2_3_RESOURCE = "javax/servlet/resources/web-app_2_3.dtd"; |
65 | |
|
66 | |
private ExternalContext _context; |
67 | |
private org.apache.myfaces.shared_impl.webapp.webxml.WebXml _webXml; |
68 | |
|
69 | |
public WebXmlParser(ExternalContext context) |
70 | 0 | { |
71 | 0 | _context = context; |
72 | 0 | } |
73 | |
|
74 | |
public WebXml parse() |
75 | |
{ |
76 | 0 | _webXml = new WebXml(); |
77 | |
|
78 | |
try |
79 | |
{ |
80 | 0 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
81 | 0 | dbf.setIgnoringElementContentWhitespace(true); |
82 | 0 | dbf.setIgnoringComments(true); |
83 | 0 | dbf.setNamespaceAware(true); |
84 | 0 | dbf.setValidating(false); |
85 | |
|
86 | |
|
87 | 0 | DocumentBuilder db = dbf.newDocumentBuilder(); |
88 | 0 | db.setEntityResolver(new _EntityResolver()); |
89 | 0 | db.setErrorHandler(new MyFacesErrorHandler(log)); |
90 | |
|
91 | 0 | InputSource is = createContextInputSource(null, WEB_XML_PATH); |
92 | |
|
93 | 0 | if(is==null) |
94 | |
{ |
95 | 0 | URL url = _context.getResource(WEB_XML_PATH); |
96 | 0 | log.debug("No web-xml found at : "+(url==null?" null ":url.toString())); |
97 | 0 | return _webXml; |
98 | |
} |
99 | |
|
100 | 0 | Document document = db.parse(is); |
101 | |
|
102 | 0 | Element webAppElem = document.getDocumentElement(); |
103 | 0 | if (webAppElem == null || |
104 | |
!webAppElem.getNodeName().equals("web-app")) |
105 | |
{ |
106 | 0 | throw new FacesException("No valid web-app root element found!"); |
107 | |
} |
108 | |
|
109 | 0 | readWebApp(webAppElem); |
110 | |
|
111 | 0 | return _webXml; |
112 | |
} |
113 | 0 | catch (Exception e) |
114 | |
{ |
115 | 0 | log.fatal("Unable to parse web.xml", e); |
116 | 0 | throw new FacesException(e); |
117 | |
} |
118 | |
} |
119 | |
|
120 | |
public static long getWebXmlLastModified(ExternalContext context) |
121 | |
{ |
122 | |
try { |
123 | 0 | URL url = context.getResource(WEB_XML_PATH); |
124 | 0 | if (url != null) |
125 | 0 | return url.openConnection().getLastModified(); |
126 | 0 | } catch (IOException e) { |
127 | 0 | log.error("Could not find web.xml in path " + WEB_XML_PATH); |
128 | 0 | } |
129 | 0 | return 0L; |
130 | |
} |
131 | |
|
132 | |
|
133 | |
private InputSource createContextInputSource(String publicId, String systemId) |
134 | |
{ |
135 | 0 | InputStream inStream = _context.getResourceAsStream(systemId); |
136 | 0 | if (inStream == null) |
137 | |
{ |
138 | |
|
139 | 0 | return null; |
140 | |
} |
141 | 0 | InputSource is = new InputSource(inStream); |
142 | 0 | is.setPublicId(publicId); |
143 | 0 | is.setSystemId(systemId); |
144 | |
|
145 | |
|
146 | |
|
147 | 0 | return is; |
148 | |
} |
149 | |
|
150 | |
private InputSource createClassloaderInputSource(String publicId, String systemId) |
151 | |
{ |
152 | 0 | InputStream inStream = ClassUtils.getContextClassLoader().getResourceAsStream(systemId); |
153 | 0 | if (inStream == null) |
154 | |
{ |
155 | 0 | inStream = this.getClass().getClassLoader().getResourceAsStream(systemId); |
156 | |
} |
157 | 0 | if (inStream == null) |
158 | |
{ |
159 | |
|
160 | 0 | return null; |
161 | |
} |
162 | 0 | InputSource is = new InputSource(inStream); |
163 | 0 | is.setPublicId(publicId); |
164 | 0 | is.setSystemId(systemId); |
165 | |
|
166 | |
|
167 | |
|
168 | |
|
169 | 0 | return is; |
170 | |
} |
171 | |
|
172 | 0 | private class _EntityResolver implements EntityResolver |
173 | |
{ |
174 | |
public InputSource resolveEntity(String publicId, String systemId) throws IOException |
175 | |
{ |
176 | 0 | if (systemId == null) |
177 | |
{ |
178 | 0 | throw new UnsupportedOperationException("systemId must not be null"); |
179 | |
} |
180 | |
|
181 | 0 | if (systemId.equals(WebXmlParser.WEB_APP_2_2_SYSTEM_ID) || |
182 | |
systemId.equals(WebXmlParser.WEB_APP_2_2_J2EE_SYSTEM_ID)) |
183 | |
{ |
184 | |
|
185 | 0 | return createClassloaderInputSource(publicId, WebXmlParser.WEB_APP_2_2_RESOURCE); |
186 | |
} |
187 | 0 | else if (systemId.equals(WebXmlParser.WEB_APP_2_3_SYSTEM_ID)) |
188 | |
{ |
189 | |
|
190 | 0 | return createClassloaderInputSource(publicId, WebXmlParser.WEB_APP_2_3_RESOURCE); |
191 | |
} |
192 | |
else |
193 | |
{ |
194 | |
|
195 | 0 | return createContextInputSource(publicId, systemId); |
196 | |
} |
197 | |
} |
198 | |
|
199 | |
} |
200 | |
|
201 | |
|
202 | |
private void readWebApp(Element webAppElem) |
203 | |
{ |
204 | 0 | NodeList nodeList = webAppElem.getChildNodes(); |
205 | 0 | for (int i = 0, len = nodeList.getLength(); i < len; i++) |
206 | |
{ |
207 | 0 | Node n = nodeList.item(i); |
208 | 0 | if (n.getNodeType() == Node.ELEMENT_NODE) |
209 | |
{ |
210 | 0 | if (n.getNodeName().equals("servlet")) |
211 | |
{ |
212 | 0 | readServlet((Element)n); |
213 | |
} |
214 | 0 | if (n.getNodeName().equals("servlet-mapping")) |
215 | |
{ |
216 | 0 | readServletMapping((Element)n); |
217 | |
} |
218 | 0 | if (n.getNodeName().equals("filter")) |
219 | |
{ |
220 | 0 | readFilter((Element)n); |
221 | |
} |
222 | 0 | if (n.getNodeName().equals("filter-mapping")) |
223 | |
{ |
224 | 0 | readFilterMapping((Element)n); |
225 | |
} |
226 | |
} |
227 | |
else |
228 | |
{ |
229 | 0 | if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType()); |
230 | |
} |
231 | |
} |
232 | 0 | } |
233 | |
|
234 | |
private void readServlet(Element servletElem) |
235 | |
{ |
236 | 0 | String servletName = null; |
237 | 0 | String servletClass = null; |
238 | 0 | NodeList nodeList = servletElem.getChildNodes(); |
239 | 0 | for (int i = 0, len = nodeList.getLength(); i < len; i++) |
240 | |
{ |
241 | 0 | Node n = nodeList.item(i); |
242 | 0 | if (n.getNodeType() == Node.ELEMENT_NODE) |
243 | |
{ |
244 | 0 | if (n.getNodeName().equals("servlet-name")) |
245 | |
{ |
246 | 0 | servletName = XmlUtils.getElementText((Element)n); |
247 | |
} |
248 | 0 | else if (n.getNodeName().equals("servlet-class")) |
249 | |
{ |
250 | 0 | servletClass = org.apache.myfaces.shared_impl.util.xml.XmlUtils.getElementText((Element)n).trim(); |
251 | |
} |
252 | 0 | else if (n.getNodeName().equals("description") || n.getNodeName().equals("load-on-startup") || n.getNodeName().equals("init-param")) |
253 | |
{ |
254 | |
|
255 | |
} |
256 | |
else |
257 | |
{ |
258 | 0 | if (log.isDebugEnabled()) log.debug("Ignored element '" + n.getNodeName() + "' as child of '" + servletElem.getNodeName() + "'."); |
259 | |
} |
260 | |
} |
261 | |
else |
262 | |
{ |
263 | 0 | if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType()); |
264 | |
} |
265 | |
} |
266 | 0 | _webXml.addServlet(servletName, servletClass); |
267 | 0 | } |
268 | |
|
269 | |
|
270 | |
private void readServletMapping(Element servletMappingElem) |
271 | |
{ |
272 | 0 | String servletName = null; |
273 | 0 | String urlPattern = null; |
274 | 0 | NodeList nodeList = servletMappingElem.getChildNodes(); |
275 | 0 | for (int i = 0, len = nodeList.getLength(); i < len; i++) |
276 | |
{ |
277 | 0 | Node n = nodeList.item(i); |
278 | 0 | if (n.getNodeType() == Node.ELEMENT_NODE) |
279 | |
{ |
280 | 0 | if (n.getNodeName().equals("servlet-name")) |
281 | |
{ |
282 | 0 | servletName = org.apache.myfaces.shared_impl.util.xml.XmlUtils.getElementText((Element)n); |
283 | |
} |
284 | 0 | else if (n.getNodeName().equals("url-pattern")) |
285 | |
{ |
286 | 0 | urlPattern = org.apache.myfaces.shared_impl.util.xml.XmlUtils.getElementText((Element)n).trim(); |
287 | |
} |
288 | |
else |
289 | |
{ |
290 | 0 | if (log.isDebugEnabled()) log.debug("Ignored element '" + n.getNodeName() + "' as child of '" + servletMappingElem.getNodeName() + "'."); |
291 | |
} |
292 | |
} |
293 | |
else |
294 | |
{ |
295 | 0 | if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType()); |
296 | |
} |
297 | |
} |
298 | 0 | urlPattern = urlPattern.trim(); |
299 | 0 | _webXml.addServletMapping(servletName, urlPattern); |
300 | 0 | } |
301 | |
|
302 | |
private void readFilter(Element filterElem) |
303 | |
{ |
304 | 0 | String filterName = null; |
305 | 0 | String filterClass = null; |
306 | 0 | NodeList nodeList = filterElem.getChildNodes(); |
307 | 0 | for (int i = 0, len = nodeList.getLength(); i < len; i++) |
308 | |
{ |
309 | 0 | Node n = nodeList.item(i); |
310 | 0 | if (n.getNodeType() == Node.ELEMENT_NODE) |
311 | |
{ |
312 | 0 | if (n.getNodeName().equals("filter-name")) |
313 | |
{ |
314 | 0 | filterName = XmlUtils.getElementText((Element)n).trim(); |
315 | |
} |
316 | 0 | else if (n.getNodeName().equals("filter-class")) |
317 | |
{ |
318 | 0 | filterClass = org.apache.myfaces.shared_impl.util.xml.XmlUtils.getElementText((Element)n).trim(); |
319 | |
} |
320 | 0 | else if (n.getNodeName().equals("description") || n.getNodeName().equals("init-param")) |
321 | |
{ |
322 | |
|
323 | |
} |
324 | |
else |
325 | |
{ |
326 | 0 | if (log.isDebugEnabled()) log.debug("Ignored element '" + n.getNodeName() + "' as child of '" + filterElem.getNodeName() + "'."); |
327 | |
} |
328 | |
} |
329 | |
else |
330 | |
{ |
331 | 0 | if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType()); |
332 | |
} |
333 | |
} |
334 | 0 | _webXml.addFilter(filterName, filterClass); |
335 | 0 | } |
336 | |
|
337 | |
|
338 | |
private void readFilterMapping(Element filterMappingElem) |
339 | |
{ |
340 | 0 | String filterName = null; |
341 | 0 | String urlPattern = null; |
342 | 0 | NodeList nodeList = filterMappingElem.getChildNodes(); |
343 | 0 | for (int i = 0, len = nodeList.getLength(); i < len; i++) |
344 | |
{ |
345 | 0 | Node n = nodeList.item(i); |
346 | 0 | if (n.getNodeType() == Node.ELEMENT_NODE) |
347 | |
{ |
348 | 0 | if (n.getNodeName().equals("filter-name")) |
349 | |
{ |
350 | 0 | filterName = org.apache.myfaces.shared_impl.util.xml.XmlUtils.getElementText((Element)n).trim(); |
351 | |
} |
352 | 0 | else if (n.getNodeName().equals("url-pattern")) |
353 | |
{ |
354 | 0 | urlPattern = org.apache.myfaces.shared_impl.util.xml.XmlUtils.getElementText((Element)n).trim(); |
355 | |
} |
356 | 0 | else if (n.getNodeName().equals("servlet-name")) |
357 | |
{ |
358 | |
|
359 | |
} |
360 | |
else |
361 | |
{ |
362 | 0 | if (log.isDebugEnabled()) log.debug("Ignored element '" + n.getNodeName() + "' as child of '" + filterMappingElem.getNodeName() + "'."); |
363 | |
} |
364 | |
} |
365 | |
else |
366 | |
{ |
367 | 0 | if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType()); |
368 | |
} |
369 | |
} |
370 | 0 | _webXml.addFilterMapping(filterName, urlPattern); |
371 | 0 | } |
372 | |
} |