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