1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.commons.resourcehandler.webapp.config.impl;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URL;
24 import java.net.URLConnection;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import javax.faces.FacesException;
29 import javax.faces.context.ExternalContext;
30 import javax.faces.context.FacesContext;
31 import javax.xml.parsers.ParserConfigurationException;
32 import javax.xml.parsers.SAXParser;
33 import javax.xml.parsers.SAXParserFactory;
34
35 import org.apache.myfaces.commons.resourcehandler.webapp.config.WebRegistration;
36 import org.apache.myfaces.commons.resourcehandler.webapp.config.element.impl.FilterRegistrationImpl;
37 import org.apache.myfaces.commons.resourcehandler.webapp.config.element.impl.ServletRegistrationImpl;
38 import org.xml.sax.Attributes;
39 import org.xml.sax.InputSource;
40 import org.xml.sax.Locator;
41 import org.xml.sax.SAXException;
42 import org.xml.sax.SAXParseException;
43 import org.xml.sax.XMLReader;
44 import org.xml.sax.helpers.DefaultHandler;
45
46
47
48
49
50
51 public class WebXmlConfigParser
52 {
53 private static final String WEB_XML_PATH = "/WEB-INF/web.xml";
54
55 public static WebRegistration getWebRegistrationFromParsedWebXml(FacesContext facesContext)
56 {
57 try
58 {
59 URL url = facesContext.getExternalContext().getResource(WEB_XML_PATH);
60 if (url != null)
61 {
62 WebRegistration mrc = parseFile(facesContext, url);
63 return mrc;
64 }
65 else
66 {
67 return null;
68 }
69 }
70 catch (IOException e) {
71 throw new FacesException("Cannot parse /WEB-INF/web.xml file ");
72 }
73 }
74
75 private static WebRegistration parseFile(FacesContext facesContext, URL configFileUrl) throws IOException
76 {
77 InputStream is = null;
78 URLConnection conn = null;
79 try
80 {
81 ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
82 boolean schemaValidating = false;
83
84
85 WebConfigHandler handler = new WebConfigHandler(configFileUrl);
86 SAXParser parser = createSAXParser(handler, externalContext, schemaValidating);
87 conn = configFileUrl.openConnection();
88 conn.setUseCaches(false);
89 is = conn.getInputStream();
90 parser.parse(is, handler);
91 return handler.getWebConfigProvider();
92 }
93 catch (SAXException e)
94 {
95 IOException ioe = new IOException("Error parsing [" + configFileUrl + "]: ");
96 ioe.initCause(e);
97 throw ioe;
98 }
99 catch (ParserConfigurationException e)
100 {
101 IOException ioe = new IOException("Error parsing [" + configFileUrl + "]: ");
102 ioe.initCause(e);
103 throw ioe;
104 }
105 finally
106 {
107 if (is != null)
108 is.close();
109 }
110 }
111
112 private static final SAXParser createSAXParser(WebConfigHandler handler, ExternalContext externalContext, boolean schemaValidating) throws SAXException,
113 ParserConfigurationException
114 {
115 SAXParserFactory factory = SAXParserFactory.newInstance();
116
117
118 factory.setNamespaceAware(true);
119 factory.setFeature("http://xml.org/sax/features/validation", false);
120 factory.setValidating(false);
121
122 SAXParser parser = factory.newSAXParser();
123 XMLReader reader = parser.getXMLReader();
124 reader.setErrorHandler(handler);
125 reader.setEntityResolver(handler);
126 return parser;
127 }
128
129 private static class WebConfigHandler extends DefaultHandler
130 {
131 private final URL source;
132
133 private final StringBuffer buffer;
134
135 private Locator locator;
136
137 private WebRegistrationImpl config;
138
139 private String servletName;
140
141 private String servletClassName;
142
143 private List<String> urlPatterns;
144
145 private String filterName;
146
147 private String filterClassName;
148
149 private List<String> servletNameMappings;
150
151 public WebConfigHandler(URL source)
152 {
153 this.source = source;
154 this.buffer = new StringBuffer(64);
155 this.config = null;
156 }
157
158 public WebRegistration getWebConfigProvider()
159 {
160 return this.config;
161 }
162
163 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
164 {
165 this.buffer.setLength(0);
166 if ("web-app".equals(qName))
167 {
168 this.config = new WebRegistrationImpl();
169 this.urlPatterns = new ArrayList<String>();
170 this.servletNameMappings = new ArrayList<String>();
171 }
172 else if ("servlet".equals(qName))
173 {
174 this.servletName = null;
175 this.servletClassName = null;
176 }
177 else if ("servlet-mapping".equals(qName))
178 {
179 this.servletName = null;
180 this.urlPatterns.clear();
181 }
182 else if ("filter".equals(qName))
183 {
184 this.filterName = null;
185 this.filterClassName = null;
186 }
187 else if ("filter-mapping".equals(qName))
188 {
189 this.filterName = null;
190 this.urlPatterns.clear();
191 this.servletNameMappings.clear();
192 }
193 }
194
195 public void endElement(String uri, String localName, String qName) throws SAXException
196 {
197 try
198 {
199 if (this.config == null)
200 {
201 return;
202 }
203
204 if ("servlet".equals(localName))
205 {
206 ServletRegistrationImpl sr = (ServletRegistrationImpl) this.config.getServletRegistration(this.servletName);
207 if (sr == null)
208 {
209 sr = new ServletRegistrationImpl(this.servletName, this.servletClassName);
210 }
211 else
212 {
213 sr.setClassName(this.servletClassName);
214 }
215 this.config.getServletRegistrations().put(this.servletName, sr);
216 }
217 else if ("servlet-name".equals(localName))
218 {
219 servletName = captureBuffer();
220 }
221 else if ("servlet-class".equals(localName))
222 {
223 servletClassName = captureBuffer();
224 }
225 else if ("filter".equals(localName))
226 {
227 FilterRegistrationImpl sr = (FilterRegistrationImpl) this.config.getFilterRegistration(this.filterName);
228 if (sr == null)
229 {
230 sr = new FilterRegistrationImpl(this.filterName, this.filterClassName);
231 }
232 else
233 {
234 sr.setClassName(this.filterClassName);
235 }
236 this.config.getFilterRegistrations().put(this.filterName, sr);
237 }
238 else if ("filter-name".equals(localName))
239 {
240 filterName = captureBuffer();
241 }
242 else if ("filter-class".equals(localName))
243 {
244 filterClassName = captureBuffer();
245 }
246 else if ("servlet-mapping".equals(localName))
247 {
248 ServletRegistrationImpl sr = (ServletRegistrationImpl) this.config.getServletRegistration(this.servletName);
249 if (sr == null)
250 {
251 sr = new ServletRegistrationImpl(this.servletName);
252 this.config.getServletRegistrations().put(this.servletName, sr);
253 }
254 for (String url: urlPatterns)
255 {
256 sr.addMapping(url);
257 }
258 }
259 else if ("filter-mapping".equals(localName))
260 {
261 FilterRegistrationImpl sr = (FilterRegistrationImpl) this.config.getFilterRegistration(this.filterName);
262 if (sr == null)
263 {
264 sr = new FilterRegistrationImpl(this.filterName);
265 this.config.getFilterRegistrations().put(this.filterName, sr);
266 }
267 for (String url: urlPatterns)
268 {
269 sr.addUrlNameMapping(url);
270 }
271 for (String name : servletNameMappings)
272 {
273 sr.addServletNameMapping(name);
274 }
275 urlPatterns.clear();
276 servletNameMappings.clear();
277 }
278 else if ("url-pattern".equals(localName))
279 {
280 urlPatterns.add(captureBuffer());
281 }
282 }
283 catch (Exception e)
284 {
285 SAXException saxe = new SAXException("Error Handling [" + this.source + "@"
286 + this.locator.getLineNumber() + "," + this.locator.getColumnNumber() + "] <" + qName + ">");
287 saxe.initCause(e);
288 throw saxe;
289 }
290 }
291
292 public void characters(char[] ch, int start, int length) throws SAXException
293 {
294 this.buffer.append(ch, start, length);
295 }
296
297 private String captureBuffer() throws Exception
298 {
299 String s = this.buffer.toString().trim();
300 if (s.length() == 0)
301 {
302 throw new Exception("Value Cannot be Empty");
303 }
304 this.buffer.setLength(0);
305 return s;
306 }
307
308 public InputSource resolveEntity(String publicId, String systemId) throws SAXException
309 {
310 return null;
311 }
312
313 public void error(SAXParseException e) throws SAXException
314 {
315 SAXException saxe = new SAXException("Error Handling [" + this.source + "@" + e.getLineNumber() + ","
316 + e.getColumnNumber() + "]");
317 saxe.initCause(e);
318 throw saxe;
319 }
320
321 public void setDocumentLocator(Locator locator)
322 {
323 this.locator = locator;
324 }
325
326 public void fatalError(SAXParseException e) throws SAXException
327 {
328 throw e;
329 }
330
331 public void warning(SAXParseException e) throws SAXException
332 {
333 throw e;
334 }
335 }
336
337 }