1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
package org.apache.myfaces.view.facelets.compiler; |
20 | |
|
21 | |
import java.io.IOException; |
22 | |
import java.io.InputStream; |
23 | |
import java.net.URL; |
24 | |
import java.net.URLConnection; |
25 | |
import javax.faces.context.ExternalContext; |
26 | |
import javax.xml.parsers.ParserConfigurationException; |
27 | |
import javax.xml.parsers.SAXParser; |
28 | |
import javax.xml.parsers.SAXParserFactory; |
29 | |
import org.apache.myfaces.config.ConfigFilesXmlValidationUtils; |
30 | |
import org.apache.myfaces.config.element.facelets.FaceletTagLibrary; |
31 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletBehaviorTagImpl; |
32 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletComponentTagImpl; |
33 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletConverterTagImpl; |
34 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletFunctionImpl; |
35 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletHandlerTagImpl; |
36 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletSourceTagImpl; |
37 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletTagImpl; |
38 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletTagLibraryImpl; |
39 | |
import org.apache.myfaces.config.impl.digester.elements.facelets.FaceletValidatorTagImpl; |
40 | |
import org.apache.myfaces.shared.config.MyfacesConfig; |
41 | |
import org.apache.myfaces.shared.util.ClassUtils; |
42 | |
import org.xml.sax.Attributes; |
43 | |
import org.xml.sax.InputSource; |
44 | |
import org.xml.sax.Locator; |
45 | |
import org.xml.sax.SAXException; |
46 | |
import org.xml.sax.SAXParseException; |
47 | |
import org.xml.sax.XMLReader; |
48 | |
import org.xml.sax.helpers.DefaultHandler; |
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | 0 | public class TagLibraryConfigUnmarshallerImpl |
54 | |
{ |
55 | |
|
56 | |
public static FaceletTagLibrary create(ExternalContext externalContext, URL url) throws IOException |
57 | |
{ |
58 | 0 | InputStream is = null; |
59 | 0 | FaceletTagLibrary t = null; |
60 | 0 | URLConnection conn = null; |
61 | |
try |
62 | |
{ |
63 | 0 | boolean schemaValidating = false; |
64 | |
|
65 | |
|
66 | 0 | if (MyfacesConfig.getCurrentInstance(externalContext).isValidateXML()) |
67 | |
{ |
68 | 0 | String version = ConfigFilesXmlValidationUtils.getFaceletTagLibVersion(url); |
69 | 0 | schemaValidating = "2.0".equals(version); |
70 | 0 | if (schemaValidating) |
71 | |
{ |
72 | 0 | ConfigFilesXmlValidationUtils.validateFaceletTagLibFile(url, externalContext, version); |
73 | |
} |
74 | |
} |
75 | |
|
76 | |
|
77 | 0 | LibraryHandler handler = new LibraryHandler(url); |
78 | 0 | SAXParser parser = createSAXParser(handler, externalContext, schemaValidating); |
79 | 0 | conn = url.openConnection(); |
80 | 0 | conn.setUseCaches(false); |
81 | 0 | is = conn.getInputStream(); |
82 | 0 | parser.parse(is, handler); |
83 | 0 | t = handler.getLibrary(); |
84 | |
} |
85 | 0 | catch (SAXException e) |
86 | |
{ |
87 | 0 | IOException ioe = new IOException("Error parsing [" + url + "]: "); |
88 | 0 | ioe.initCause(e); |
89 | 0 | throw ioe; |
90 | |
} |
91 | 0 | catch (ParserConfigurationException e) |
92 | |
{ |
93 | 0 | IOException ioe = new IOException("Error parsing [" + url + "]: "); |
94 | 0 | ioe.initCause(e); |
95 | 0 | throw ioe; |
96 | |
} |
97 | |
finally |
98 | |
{ |
99 | 0 | if (is != null) |
100 | |
{ |
101 | 0 | is.close(); |
102 | |
} |
103 | |
} |
104 | 0 | return t; |
105 | |
} |
106 | |
|
107 | |
private static final SAXParser createSAXParser(LibraryHandler handler, ExternalContext externalContext, |
108 | |
boolean schemaValidating) |
109 | |
throws SAXException, ParserConfigurationException |
110 | |
{ |
111 | 0 | SAXParserFactory factory = SAXParserFactory.newInstance(); |
112 | |
|
113 | 0 | if (MyfacesConfig.getCurrentInstance(externalContext).isValidateXML() && !schemaValidating) |
114 | |
{ |
115 | |
|
116 | 0 | factory.setNamespaceAware(false); |
117 | 0 | factory.setFeature("http://xml.org/sax/features/validation", true); |
118 | 0 | factory.setValidating(true); |
119 | |
} |
120 | |
else |
121 | |
{ |
122 | |
|
123 | 0 | factory.setNamespaceAware(true); |
124 | 0 | factory.setFeature("http://xml.org/sax/features/validation", false); |
125 | 0 | factory.setValidating(false); |
126 | |
} |
127 | |
|
128 | 0 | SAXParser parser = factory.newSAXParser(); |
129 | 0 | XMLReader reader = parser.getXMLReader(); |
130 | 0 | reader.setErrorHandler(handler); |
131 | 0 | reader.setEntityResolver(handler); |
132 | 0 | return parser; |
133 | |
} |
134 | |
|
135 | 0 | private static class LibraryHandler extends DefaultHandler |
136 | |
{ |
137 | |
private final URL source; |
138 | |
|
139 | |
private FaceletTagLibraryImpl library; |
140 | |
|
141 | |
private final StringBuffer buffer; |
142 | |
|
143 | |
private Locator locator; |
144 | |
|
145 | |
private String tagName; |
146 | |
|
147 | |
private String converterId; |
148 | |
|
149 | |
private String validatorId; |
150 | |
|
151 | |
private String behaviorId; |
152 | |
|
153 | |
private String componentType; |
154 | |
|
155 | |
private String rendererType; |
156 | |
|
157 | |
private String functionName; |
158 | |
|
159 | |
|
160 | |
private String handlerClass; |
161 | |
|
162 | |
|
163 | |
private String functionClass; |
164 | |
|
165 | |
private String functionSignature; |
166 | |
|
167 | |
private String resourceId; |
168 | |
|
169 | |
public LibraryHandler(URL source) |
170 | 0 | { |
171 | 0 | this.source = source; |
172 | 0 | this.buffer = new StringBuffer(64); |
173 | 0 | } |
174 | |
|
175 | |
public FaceletTagLibrary getLibrary() |
176 | |
{ |
177 | 0 | return this.library; |
178 | |
} |
179 | |
|
180 | |
private FaceletTagLibraryImpl getLibraryImpl() |
181 | |
{ |
182 | 0 | if (this.library == null) |
183 | |
{ |
184 | 0 | this.library = new FaceletTagLibraryImpl(); |
185 | |
} |
186 | 0 | return this.library; |
187 | |
} |
188 | |
|
189 | |
public void endElement(String uri, String localName, String qName) throws SAXException |
190 | |
{ |
191 | |
try |
192 | |
{ |
193 | 0 | if ("facelet-taglib".equals(qName)) |
194 | |
{ |
195 | |
|
196 | |
} |
197 | 0 | else if ("library-class".equals(qName)) |
198 | |
{ |
199 | 0 | getLibraryImpl().setLibraryClass(this.captureBuffer()); |
200 | |
} |
201 | 0 | else if ("short-name".equals(qName)) |
202 | |
{ |
203 | 0 | getLibraryImpl().setShortName(this.captureBuffer()); |
204 | |
} |
205 | 0 | else if ("namespace".equals(qName)) |
206 | |
{ |
207 | 0 | getLibraryImpl().setNamespace(this.captureBuffer()); |
208 | |
} |
209 | 0 | else if ("composite-library-name".equals(qName)) |
210 | |
{ |
211 | 0 | getLibraryImpl().setCompositeLibraryName(this.captureBuffer()); |
212 | |
} |
213 | 0 | else if ("component-type".equals(qName)) |
214 | |
{ |
215 | 0 | this.componentType = this.captureBuffer(); |
216 | |
} |
217 | 0 | else if ("renderer-type".equals(qName)) |
218 | |
{ |
219 | 0 | this.rendererType = this.captureBufferEmptyNull(); |
220 | |
} |
221 | 0 | else if ("tag-name".equals(qName)) |
222 | |
{ |
223 | 0 | this.tagName = this.captureBuffer(); |
224 | |
} |
225 | 0 | else if ("function-name".equals(qName)) |
226 | |
{ |
227 | 0 | this.functionName = this.captureBuffer(); |
228 | |
} |
229 | 0 | else if ("function-class".equals(qName)) |
230 | |
{ |
231 | |
|
232 | |
|
233 | 0 | this.functionClass = this.captureBuffer(); |
234 | |
} |
235 | 0 | else if ("description".equals(qName)) |
236 | |
{ |
237 | |
|
238 | |
} |
239 | 0 | else if ("display-name".equals(qName)) |
240 | |
{ |
241 | |
|
242 | |
} |
243 | 0 | else if ("icon".equals(qName)) |
244 | |
{ |
245 | |
|
246 | |
} |
247 | 0 | else if ("resource-id".equals(qName)) |
248 | |
{ |
249 | 0 | this.resourceId = this.captureBuffer(); |
250 | |
} |
251 | |
else |
252 | |
{ |
253 | |
|
254 | |
|
255 | |
|
256 | 0 | if (this.library == null) |
257 | |
{ |
258 | 0 | throw new IllegalStateException("No <namespace> element"); |
259 | |
} |
260 | 0 | else if (this.library.getNamespace() == null) |
261 | |
{ |
262 | 0 | throw new IllegalStateException("No <namespace> element"); |
263 | |
} |
264 | |
|
265 | |
|
266 | |
|
267 | 0 | if ("tag".equals(qName)) |
268 | |
{ |
269 | 0 | if (this.handlerClass != null) |
270 | |
{ |
271 | |
|
272 | 0 | getLibraryImpl().addTag( |
273 | |
new FaceletTagImpl(this.tagName, |
274 | |
new FaceletHandlerTagImpl(this.handlerClass)) ); |
275 | 0 | this.handlerClass = null; |
276 | |
} |
277 | |
} |
278 | 0 | else if ("handler-class".equals(qName)) |
279 | |
{ |
280 | |
|
281 | |
|
282 | 0 | this.handlerClass = this.captureBufferEmptyNull(); |
283 | |
} |
284 | 0 | else if ("component".equals(qName)) |
285 | |
{ |
286 | 0 | if (this.handlerClass != null) |
287 | |
{ |
288 | |
|
289 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
290 | |
new FaceletComponentTagImpl(this.componentType, this.rendererType, |
291 | |
this.handlerClass, null))); |
292 | 0 | this.handlerClass = null; |
293 | |
} |
294 | 0 | else if (this.resourceId != null) |
295 | |
{ |
296 | |
|
297 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
298 | |
new FaceletComponentTagImpl(null, null, null, this.resourceId))); |
299 | 0 | this.resourceId = null; |
300 | 0 | this.handlerClass = null; |
301 | |
} |
302 | |
else |
303 | |
{ |
304 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
305 | |
new FaceletComponentTagImpl(this.componentType, this.rendererType, null, null))); |
306 | 0 | this.handlerClass = null; |
307 | |
|
308 | |
} |
309 | |
} |
310 | 0 | else if ("converter-id".equals(qName)) |
311 | |
{ |
312 | 0 | this.converterId = this.captureBuffer(); |
313 | |
} |
314 | 0 | else if ("converter".equals(qName)) |
315 | |
{ |
316 | 0 | if (this.handlerClass != null) |
317 | |
{ |
318 | |
|
319 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
320 | |
new FaceletConverterTagImpl(this.converterId, this.handlerClass))); |
321 | 0 | this.handlerClass = null; |
322 | |
} |
323 | |
else |
324 | |
{ |
325 | |
|
326 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
327 | |
new FaceletConverterTagImpl(this.converterId))); |
328 | |
} |
329 | 0 | this.converterId = null; |
330 | |
} |
331 | 0 | else if ("validator-id".equals(qName)) |
332 | |
{ |
333 | 0 | this.validatorId = this.captureBuffer(); |
334 | |
} |
335 | 0 | else if ("validator".equals(qName)) |
336 | |
{ |
337 | 0 | if (this.handlerClass != null) |
338 | |
{ |
339 | |
|
340 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
341 | |
new FaceletValidatorTagImpl(this.validatorId, this.handlerClass))); |
342 | 0 | this.handlerClass = null; |
343 | |
} |
344 | |
else |
345 | |
{ |
346 | |
|
347 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
348 | |
new FaceletValidatorTagImpl(this.validatorId))); |
349 | |
} |
350 | 0 | this.validatorId = null; |
351 | |
} |
352 | 0 | else if ("behavior-id".equals(qName)) |
353 | |
{ |
354 | 0 | this.behaviorId = this.captureBuffer(); |
355 | |
} |
356 | 0 | else if ("behavior".equals(qName)) |
357 | |
{ |
358 | 0 | if (this.handlerClass != null) |
359 | |
{ |
360 | |
|
361 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
362 | |
new FaceletBehaviorTagImpl(this.behaviorId, this.handlerClass))); |
363 | 0 | this.handlerClass = null; |
364 | |
} |
365 | |
else |
366 | |
{ |
367 | |
|
368 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
369 | |
new FaceletBehaviorTagImpl(this.behaviorId))); |
370 | |
} |
371 | 0 | this.behaviorId = null; |
372 | |
} |
373 | 0 | else if ("source".equals(qName)) |
374 | |
{ |
375 | 0 | String path = this.captureBuffer(); |
376 | 0 | URL url = new URL(this.source, path); |
377 | |
|
378 | 0 | getLibraryImpl().addTag(new FaceletTagImpl(this.tagName, |
379 | |
new FaceletSourceTagImpl(url.toString()))); |
380 | 0 | } |
381 | 0 | else if ("function-signature".equals(qName)) |
382 | |
{ |
383 | 0 | this.functionSignature = this.captureBuffer(); |
384 | 0 | getLibraryImpl().addFunction( |
385 | |
new FaceletFunctionImpl(this.functionName, this.functionClass, functionSignature)); |
386 | |
|
387 | |
|
388 | |
} |
389 | |
} |
390 | |
} |
391 | 0 | catch (Exception e) |
392 | |
{ |
393 | 0 | throw new SAXParseException("Error Handling [" + this.source + "@" + this.locator.getLineNumber() |
394 | |
+ "," + this.locator.getColumnNumber() + "] <" + qName + ">", locator, e); |
395 | 0 | } |
396 | 0 | } |
397 | |
|
398 | |
private String captureBuffer() throws Exception |
399 | |
{ |
400 | 0 | String s = this.buffer.toString().trim(); |
401 | 0 | if (s.length() == 0) |
402 | |
{ |
403 | 0 | throw new Exception("Value Cannot be Empty"); |
404 | |
} |
405 | 0 | this.buffer.setLength(0); |
406 | 0 | return s; |
407 | |
} |
408 | |
|
409 | |
private String captureBufferEmptyNull() throws Exception |
410 | |
{ |
411 | 0 | String s = this.buffer.toString().trim(); |
412 | 0 | if (s.length() == 0) |
413 | |
{ |
414 | |
|
415 | 0 | s = null; |
416 | |
} |
417 | 0 | this.buffer.setLength(0); |
418 | 0 | return s; |
419 | |
} |
420 | |
|
421 | |
public InputSource resolveEntity(String publicId, String systemId) throws SAXException |
422 | |
{ |
423 | 0 | if ("-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN".equals(publicId)) |
424 | |
{ |
425 | 0 | URL url = ClassUtils.getResource("org/apache/myfaces/resource/facelet-taglib_1_0.dtd"); |
426 | 0 | return new InputSource(url.toExternalForm()); |
427 | |
} |
428 | 0 | return null; |
429 | |
} |
430 | |
|
431 | |
public void characters(char[] ch, int start, int length) throws SAXException |
432 | |
{ |
433 | 0 | this.buffer.append(ch, start, length); |
434 | 0 | } |
435 | |
|
436 | |
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException |
437 | |
{ |
438 | 0 | this.buffer.setLength(0); |
439 | 0 | if ("tag".equals(qName)) |
440 | |
{ |
441 | 0 | this.handlerClass = null; |
442 | 0 | this.componentType = null; |
443 | 0 | this.rendererType = null; |
444 | 0 | this.tagName = null; |
445 | |
} |
446 | 0 | else if ("function".equals(qName)) |
447 | |
{ |
448 | 0 | this.functionName = null; |
449 | 0 | this.functionClass = null; |
450 | 0 | this.functionSignature = null; |
451 | |
} |
452 | 0 | } |
453 | |
|
454 | |
public void error(SAXParseException e) throws SAXException |
455 | |
{ |
456 | 0 | throw new SAXException( |
457 | |
"Error Handling [" + this.source + "@" + e.getLineNumber() + "," + e.getColumnNumber() + "]", e); |
458 | |
} |
459 | |
|
460 | |
public void setDocumentLocator(Locator locator) |
461 | |
{ |
462 | 0 | this.locator = locator; |
463 | 0 | } |
464 | |
|
465 | |
public void fatalError(SAXParseException e) throws SAXException |
466 | |
{ |
467 | 0 | throw e; |
468 | |
} |
469 | |
|
470 | |
public void warning(SAXParseException e) throws SAXException |
471 | |
{ |
472 | 0 | throw e; |
473 | |
} |
474 | |
} |
475 | |
|
476 | |
} |