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.BufferedInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.URL;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27 import java.security.AccessController;
28 import java.security.PrivilegedExceptionAction;
29 import java.security.PrivilegedActionException;
30 import java.util.Map;
31
32 import javax.el.ELException;
33 import javax.el.MethodExpression;
34 import javax.el.ValueExpression;
35 import javax.faces.FacesException;
36 import javax.faces.view.Location;
37 import javax.faces.view.facelets.FaceletException;
38 import javax.faces.view.facelets.FaceletHandler;
39 import javax.faces.view.facelets.Tag;
40 import javax.faces.view.facelets.TagAttribute;
41 import javax.faces.view.facelets.TagAttributes;
42 import javax.xml.parsers.ParserConfigurationException;
43 import javax.xml.parsers.SAXParser;
44 import javax.xml.parsers.SAXParserFactory;
45
46 import org.apache.myfaces.config.element.FaceletsProcessing;
47 import org.apache.myfaces.shared.util.ClassUtils;
48 import org.apache.myfaces.view.facelets.tag.TagAttributeImpl;
49 import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
50 import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
51 import org.apache.myfaces.view.facelets.tag.composite.ImplementationHandler;
52 import org.apache.myfaces.view.facelets.tag.composite.InterfaceHandler;
53 import org.apache.myfaces.view.facelets.tag.jsf.core.CoreLibrary;
54 import org.apache.myfaces.view.facelets.tag.ui.UILibrary;
55 import org.xml.sax.Attributes;
56 import org.xml.sax.InputSource;
57 import org.xml.sax.Locator;
58 import org.xml.sax.SAXException;
59 import org.xml.sax.SAXParseException;
60 import org.xml.sax.XMLReader;
61 import org.xml.sax.ext.LexicalHandler;
62 import org.xml.sax.helpers.DefaultHandler;
63
64
65
66
67
68
69
70
71
72 public final class SAXCompiler extends Compiler
73 {
74
75 private final static Pattern XML_DECLARATION = Pattern
76 .compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
77
78 private static class CompilationHandler extends DefaultHandler implements LexicalHandler
79 {
80
81 private final String alias;
82
83 private boolean inDocument = false;
84
85 private Locator locator;
86
87 private final CompilationManager unit;
88
89 private boolean consumingCDATA = false;
90 private boolean swallowCDATAContent = false;
91
92 public CompilationHandler(CompilationManager unit, String alias)
93 {
94 this.unit = unit;
95 this.alias = alias;
96 }
97
98 public void characters(char[] ch, int start, int length) throws SAXException
99 {
100 if (this.inDocument && (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
101 {
102 this.unit.writeText(new String(ch, start, length));
103 }
104 }
105
106 public void comment(char[] ch, int start, int length) throws SAXException
107 {
108 if (this.inDocument && !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
109 {
110 this.unit.writeComment(new String(ch, start, length));
111 }
112 }
113
114 protected TagAttributes createAttributes(Attributes attrs)
115 {
116 int len = attrs.getLength();
117 TagAttribute[] ta = new TagAttribute[len];
118 for (int i = 0; i < len; i++)
119 {
120 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
121 .getQName(i), attrs.getValue(i));
122 }
123 return new TagAttributesImpl(ta);
124 }
125
126 protected Location createLocation()
127 {
128 return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
129 }
130
131 public void endCDATA() throws SAXException
132 {
133 if (this.inDocument)
134 {
135 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
136 {
137 this.unit.writeInstruction("]]>");
138 }
139 else
140 {
141 this.consumingCDATA = false;
142 this.swallowCDATAContent = false;
143 }
144 }
145 }
146
147 public void endDTD() throws SAXException
148 {
149 this.inDocument = true;
150 }
151
152 public void endElement(String uri, String localName, String qName) throws SAXException
153 {
154 this.unit.popTag();
155 }
156
157 public void endEntity(String name) throws SAXException
158 {
159 }
160
161 public void endPrefixMapping(String prefix) throws SAXException
162 {
163 this.unit.popNamespace(prefix);
164 }
165
166 public void fatalError(SAXParseException e) throws SAXException
167 {
168 if (this.locator != null)
169 {
170 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
171 }
172 else
173 {
174 throw e;
175 }
176 }
177
178 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
179 {
180 if (this.inDocument)
181 {
182 this.unit.writeWhitespace(new String(ch, start, length));
183 }
184 }
185
186 public InputSource resolveEntity(String publicId, String systemId) throws SAXException
187 {
188 String dtd = "org/apache/myfaces/resource/default.dtd";
189
190
191
192
193 URL url = ClassUtils.getResource(dtd);
194 return new InputSource(url.toString());
195 }
196
197 public void setDocumentLocator(Locator locator)
198 {
199 this.locator = locator;
200 }
201
202 public void startCDATA() throws SAXException
203 {
204 if (this.inDocument)
205 {
206 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
207 {
208 this.unit.writeInstruction("<![CDATA[");
209 }
210 else
211 {
212 this.consumingCDATA = true;
213 this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
214 }
215 }
216 }
217
218 public void startDocument() throws SAXException
219 {
220 this.inDocument = true;
221 }
222
223 public void startDTD(String name, String publicId, String systemId) throws SAXException
224 {
225 if (this.inDocument && !unit.getFaceletsProcessingInstructions().isConsumeXmlDocType())
226 {
227 this.unit.writeDoctype(name, publicId, systemId);
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 }
247 this.inDocument = false;
248 }
249
250 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
251 {
252 this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
253 }
254
255 public void startEntity(String name) throws SAXException
256 {
257 }
258
259 public void startPrefixMapping(String prefix, String uri) throws SAXException
260 {
261 this.unit.pushNamespace(prefix, uri);
262 }
263
264 public void processingInstruction(String target, String data) throws SAXException
265 {
266 if (this.inDocument && !this.unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
267 {
268 StringBuffer sb = new StringBuffer(64);
269 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
270 this.unit.writeInstruction(sb.toString());
271 }
272 }
273 }
274
275
276
277
278
279
280 private static class ViewMetadataHandler extends DefaultHandler implements LexicalHandler
281 {
282
283 private final String alias;
284
285 private boolean inDocument = false;
286
287 private Locator locator;
288
289 private final CompilationManager unit;
290
291 private boolean inMetadata = false;
292 private int uiRemoveCount = 0;
293
294 private boolean consumingCDATA = false;
295 private boolean swallowCDATAContent = false;
296
297 public ViewMetadataHandler(CompilationManager unit, String alias)
298 {
299 this.unit = unit;
300 this.alias = alias;
301 }
302
303 public void characters(char[] ch, int start, int length) throws SAXException
304 {
305 if (this.inDocument && inMetadata && (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
306 {
307 this.unit.writeText(new String(ch, start, length));
308 }
309 }
310
311 public void comment(char[] ch, int start, int length) throws SAXException
312 {
313 if (this.inDocument && inMetadata && !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
314 {
315 this.unit.writeComment(new String(ch, start, length));
316 }
317 }
318
319 protected TagAttributes createAttributes(Attributes attrs)
320 {
321 int len = attrs.getLength();
322 TagAttribute[] ta = new TagAttribute[len];
323 for (int i = 0; i < len; i++)
324 {
325 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
326 .getQName(i), attrs.getValue(i));
327 }
328 return new TagAttributesImpl(ta);
329 }
330
331 protected Location createLocation()
332 {
333 return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
334 }
335
336 public void endCDATA() throws SAXException
337 {
338 if (this.inDocument && inMetadata)
339 {
340 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
341 {
342 this.unit.writeInstruction("]]>");
343 }
344 else
345 {
346 this.consumingCDATA = false;
347 this.swallowCDATAContent = false;
348 }
349 }
350 }
351
352 public void endDTD() throws SAXException
353 {
354 this.inDocument = true;
355 }
356
357 public void endElement(String uri, String localName, String qName) throws SAXException
358 {
359 if (inMetadata)
360 {
361 this.unit.popTag();
362 }
363 if ( (CoreLibrary.NAMESPACE.equals(uri) ||
364 CoreLibrary.ALIAS_NAMESPACE.equals(uri)))
365 {
366 if ("metadata".equals(localName))
367 {
368 this.inMetadata=false;
369 }
370 else if (!inMetadata && "view".equals(localName))
371 {
372 this.unit.popTag();
373 }
374 }
375 else if (UILibrary.NAMESPACE.equals(uri) ||
376 UILibrary.ALIAS_NAMESPACE.equals(uri))
377 {
378 if (!inMetadata && "remove".equals(localName))
379 {
380 this.uiRemoveCount--;
381 }
382 }
383 }
384
385 public void endEntity(String name) throws SAXException
386 {
387 }
388
389 public void endPrefixMapping(String prefix) throws SAXException
390 {
391 this.unit.popNamespace(prefix);
392 }
393
394 public void fatalError(SAXParseException e) throws SAXException
395 {
396 if (this.locator != null)
397 {
398 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
399 }
400 else
401 {
402 throw e;
403 }
404 }
405
406 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
407 {
408 if (this.inDocument && inMetadata)
409 {
410 this.unit.writeWhitespace(new String(ch, start, length));
411 }
412 }
413
414 public InputSource resolveEntity(String publicId, String systemId) throws SAXException
415 {
416 String dtd = "org/apache/myfaces/resource/default.dtd";
417
418
419
420
421 URL url = ClassUtils.getResource(dtd);
422 return new InputSource(url.toString());
423 }
424
425 public void setDocumentLocator(Locator locator)
426 {
427 this.locator = locator;
428 }
429
430 public void startCDATA() throws SAXException
431 {
432 if (this.inDocument && inMetadata)
433 {
434 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
435 {
436 this.unit.writeInstruction("<![CDATA[");
437 }
438 else
439 {
440 this.consumingCDATA = true;
441 this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
442 }
443 }
444 }
445
446 public void startDocument() throws SAXException
447 {
448 this.inDocument = true;
449 }
450
451 public void startDTD(String name, String publicId, String systemId) throws SAXException
452 {
453
454 this.inDocument = false;
455 }
456
457 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
458 {
459 if ( (CoreLibrary.NAMESPACE.equals(uri) ||
460 CoreLibrary.ALIAS_NAMESPACE.equals(uri)) && this.uiRemoveCount <= 0)
461 {
462 if ("metadata".equals(localName))
463 {
464 this.inMetadata=true;
465 }
466 else if (!inMetadata && "view".equals(localName))
467 {
468 this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
469 }
470 }
471 if (inMetadata)
472 {
473 this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
474 }
475 else if (UILibrary.NAMESPACE.equals(uri) ||
476 UILibrary.ALIAS_NAMESPACE.equals(uri))
477 {
478 if ("remove".equals(localName))
479 {
480 this.uiRemoveCount++;
481 }
482 }
483 }
484
485 public void startEntity(String name) throws SAXException
486 {
487 }
488
489 public void startPrefixMapping(String prefix, String uri) throws SAXException
490 {
491 this.unit.pushNamespace(prefix, uri);
492 }
493
494 public void processingInstruction(String target, String data) throws SAXException
495 {
496 if (inDocument && inMetadata && !unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
497 {
498 StringBuffer sb = new StringBuffer(64);
499 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
500 unit.writeInstruction(sb.toString());
501 }
502 }
503 }
504
505
506
507
508
509
510
511
512
513 private static class CompositeComponentMetadataHandler extends DefaultHandler implements LexicalHandler
514 {
515
516 private final String alias;
517
518 private boolean inDocument = false;
519
520 private Locator locator;
521
522 private final CompilationManager unit;
523
524 private boolean inCompositeInterface = false;
525
526 private boolean inCompositeImplementation = false;
527
528 private boolean consumingCDATA = false;
529 private boolean swallowCDATAContent = false;
530
531 public CompositeComponentMetadataHandler(CompilationManager unit, String alias)
532 {
533 this.unit = unit;
534 this.alias = alias;
535 }
536
537 public void characters(char[] ch, int start, int length) throws SAXException
538 {
539 if (this.inDocument && inCompositeInterface &&
540 (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
541 {
542 this.unit.writeText(new String(ch, start, length));
543 }
544 }
545
546 public void comment(char[] ch, int start, int length) throws SAXException
547 {
548 if (inDocument && inCompositeInterface &&
549 !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
550 {
551 this.unit.writeComment(new String(ch, start, length));
552 }
553 }
554
555 protected TagAttributes createAttributes(Attributes attrs)
556 {
557 int len = attrs.getLength();
558 TagAttribute[] ta = new TagAttribute[len];
559 for (int i = 0; i < len; i++)
560 {
561 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
562 .getQName(i), attrs.getValue(i));
563 }
564 return new TagAttributesImpl(ta);
565 }
566
567 protected Location createLocation()
568 {
569 return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
570 }
571
572 public void endCDATA() throws SAXException
573 {
574 if (this.inDocument && inCompositeInterface)
575 {
576 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
577 {
578 this.unit.writeInstruction("]]>");
579 }
580 else
581 {
582 this.consumingCDATA = false;
583 this.swallowCDATAContent = false;
584 }
585 }
586 }
587
588 public void endDTD() throws SAXException
589 {
590 this.inDocument = true;
591 }
592
593 public void endElement(String uri, String localName, String qName) throws SAXException
594 {
595 if (inCompositeInterface)
596 {
597 this.unit.popTag();
598 }
599 else if (inCompositeImplementation &&
600 (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri)) )
601 {
602 if ( "insertFacet".equals(localName) ||
603 "renderFacet".equals(localName) ||
604 "insertChildren".equals(localName) ||
605 ImplementationHandler.NAME.equals(localName))
606 {
607 this.unit.popTag();
608 }
609 }
610
611 if (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri))
612 {
613 if (InterfaceHandler.NAME.equals(localName))
614 {
615 this.inCompositeInterface=false;
616 }
617 else if (ImplementationHandler.NAME.equals(localName))
618 {
619 this.inCompositeImplementation=false;
620 }
621 }
622 }
623
624 public void endEntity(String name) throws SAXException
625 {
626 }
627
628 public void endPrefixMapping(String prefix) throws SAXException
629 {
630 this.unit.popNamespace(prefix);
631 }
632
633 public void fatalError(SAXParseException e) throws SAXException
634 {
635 if (this.locator != null)
636 {
637 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
638 }
639 else
640 {
641 throw e;
642 }
643 }
644
645 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
646 {
647 if (this.inDocument && inCompositeInterface)
648 {
649 this.unit.writeWhitespace(new String(ch, start, length));
650 }
651 }
652
653 public InputSource resolveEntity(String publicId, String systemId) throws SAXException
654 {
655 String dtd = "org/apache/myfaces/resource/default.dtd";
656
657
658
659
660 URL url = ClassUtils.getResource(dtd);
661 return new InputSource(url.toString());
662 }
663
664 public void setDocumentLocator(Locator locator)
665 {
666 this.locator = locator;
667 }
668
669 public void startCDATA() throws SAXException
670 {
671 if (this.inDocument && inCompositeInterface)
672 {
673 if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
674 {
675 this.unit.writeInstruction("<![CDATA[");
676 }
677 else
678 {
679 this.consumingCDATA = true;
680 this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
681 }
682 }
683 }
684
685 public void startDocument() throws SAXException
686 {
687 this.inDocument = true;
688 }
689
690 public void startDTD(String name, String publicId, String systemId) throws SAXException
691 {
692
693 this.inDocument = false;
694 }
695
696 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
697 {
698 if (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri))
699 {
700 if (InterfaceHandler.NAME.equals(localName))
701 {
702 this.inCompositeInterface=true;
703 }
704 else if (ImplementationHandler.NAME.equals(localName))
705 {
706 this.inCompositeImplementation=true;
707 }
708 }
709
710 if (inCompositeInterface)
711 {
712 this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
713 }
714 else if (inCompositeImplementation &&
715 (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri)))
716 {
717 if ("insertFacet".equals(localName) ||
718 "renderFacet".equals(localName) ||
719 "insertChildren".equals(localName) ||
720 ImplementationHandler.NAME.equals(localName) )
721 {
722 this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
723 }
724 }
725 }
726
727 public void startEntity(String name) throws SAXException
728 {
729 }
730
731 public void startPrefixMapping(String prefix, String uri) throws SAXException
732 {
733 this.unit.pushNamespace(prefix, uri);
734 }
735
736 public void processingInstruction(String target, String data) throws SAXException
737 {
738 if (inDocument && inCompositeInterface
739 && !unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
740 {
741 StringBuffer sb = new StringBuffer(64);
742 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
743 this.unit.writeInstruction(sb.toString());
744 }
745 }
746 }
747
748 public SAXCompiler()
749 {
750 super();
751 }
752
753 public FaceletHandler doCompile(URL src, String alias)
754 throws IOException, FaceletException, ELException, FacesException
755 {
756 CompilationManager mngr = null;
757 InputStream is = null;
758 String encoding = null;
759 try
760 {
761 is = new BufferedInputStream(src.openStream(), 1024);
762 mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
763 encoding = writeXmlDecl(is, mngr);
764 CompilationHandler handler = new CompilationHandler(mngr, alias);
765 SAXParser parser = this.createSAXParser(handler);
766 parser.parse(is, handler);
767 }
768 catch (SAXException e)
769 {
770 throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
771 }
772 catch (ParserConfigurationException e)
773 {
774 throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
775 }
776 finally
777 {
778 if (is != null)
779 {
780 is.close();
781 }
782 }
783 return new EncodingHandler(mngr.createFaceletHandler(), encoding);
784 }
785
786
787
788
789 @Override
790 protected FaceletHandler doCompileViewMetadata(URL src, String alias)
791 throws IOException, FaceletException, ELException, FacesException
792 {
793 CompilationManager mngr = null;
794 InputStream is = null;
795 String encoding = null;
796 try
797 {
798 is = new BufferedInputStream(src.openStream(), 1024);
799 mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
800 encoding = getXmlDecl(is, mngr);
801 final ViewMetadataHandler handler = new ViewMetadataHandler(mngr, alias);
802 final SAXParser parser = this.createSAXParser(handler);
803
804 if (System.getSecurityManager() != null)
805 {
806 try
807 {
808 final InputStream finalInputStream = is;
809 AccessController.doPrivileged(new PrivilegedExceptionAction()
810 {
811 public Object run() throws SAXException, IOException
812 {
813 parser.parse(finalInputStream, handler);
814 return null;
815 }
816 });
817 }
818 catch (PrivilegedActionException pae)
819 {
820 Exception e = pae.getException();
821 if(e instanceof SAXException)
822 {
823 throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
824 }
825 else if(e instanceof IOException)
826 {
827 throw (IOException)e;
828 }
829 }
830 }
831 else
832 {
833 parser.parse(is, handler);
834 }
835 }
836 catch (SAXException e)
837 {
838 throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
839 }
840 catch (ParserConfigurationException e)
841 {
842 throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
843 }
844 finally
845 {
846 if (is != null)
847 {
848 is.close();
849 }
850 }
851 return new EncodingHandler(mngr.createFaceletHandler(), encoding);
852 }
853
854
855
856
857 @Override
858 protected FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias)
859 throws IOException, FaceletException, ELException, FacesException
860 {
861 CompilationManager mngr = null;
862 InputStream is = null;
863 String encoding = null;
864 try
865 {
866 is = new BufferedInputStream(src.openStream(), 1024);
867 mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
868 encoding = getXmlDecl(is, mngr);
869 CompositeComponentMetadataHandler handler = new CompositeComponentMetadataHandler(mngr, alias);
870 SAXParser parser = this.createSAXParser(handler);
871 parser.parse(is, handler);
872 }
873 catch (SAXException e)
874 {
875 throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
876 }
877 catch (ParserConfigurationException e)
878 {
879 throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
880 }
881 finally
882 {
883 if (is != null)
884 {
885 is.close();
886 }
887 }
888 return new EncodingHandler(mngr.createFaceletHandler(), encoding);
889 }
890
891 @Override
892 protected FaceletHandler doCompileComponent(
893 String taglibURI, String tagName, Map<String, Object> attributes)
894 {
895 String alias = tagName;
896 CompilationManager mngr = new CompilationManager(alias, this, getDefaultFaceletsProcessingInstructions());
897 String prefix = "oamf";
898 mngr.pushNamespace(prefix, taglibURI);
899
900 boolean tagContainParams = (
901 ("include".equals(tagName) || "decorate".equals(tagName) || "composition".equals(tagName)) &&
902 (UILibrary.NAMESPACE.equals(taglibURI) || UILibrary.ALIAS_NAMESPACE.equals(taglibURI)) );
903
904 Location location = new Location(alias, 0, 0);
905 int len = attributes.size();
906 if (tagContainParams && attributes.containsKey("params"))
907 {
908 len = len-1;
909 }
910
911 TagAttribute[] ta = new TagAttribute[len];
912 int i = 0;
913 Map<String, Object> paramsMap = null;
914 for (Map.Entry<String, Object> entry : attributes.entrySet())
915 {
916 String stringValue = null;
917
918 if (tagContainParams && "params".equals(entry.getKey()))
919 {
920 paramsMap = (Map<String, Object>) entry.getValue();
921 }
922 else
923 {
924 if (entry.getValue() instanceof ValueExpression)
925 {
926 stringValue = ((ValueExpression)entry.getValue()).getExpressionString();
927 }
928 else if (entry.getValue() instanceof MethodExpression)
929 {
930 stringValue = ((MethodExpression)entry.getValue()).getExpressionString();
931 }
932 else if (entry.getValue() != null)
933 {
934 stringValue = entry.getValue().toString();
935 }
936 ta[i] = new TagAttributeImpl(location, "", entry.getKey(), entry.getKey(), stringValue);
937 i++;
938 }
939 }
940 mngr.pushTag(new Tag(location, taglibURI, tagName, "oamf:"+tagName, new TagAttributesImpl(ta)));
941
942 if (tagContainParams && paramsMap != null)
943 {
944 for (Map.Entry<String, Object> entry : paramsMap.entrySet())
945 {
946 TagAttribute[] tap = new TagAttribute[2];
947 String stringValue = null;
948 if (entry.getValue() instanceof ValueExpression)
949 {
950 stringValue = ((ValueExpression)entry.getValue()).getExpressionString();
951 }
952 else if (entry.getValue() instanceof MethodExpression)
953 {
954 stringValue = ((MethodExpression)entry.getValue()).getExpressionString();
955 }
956 else if (entry.getValue() != null)
957 {
958 stringValue = entry.getValue().toString();
959 }
960 tap[0] = new TagAttributeImpl(location, "", "name", "name", entry.getKey());
961 tap[1] = new TagAttributeImpl(location, "", "value", "value", stringValue);
962 mngr.pushTag(new Tag(location, UILibrary.NAMESPACE, "param", "oamf:param", new TagAttributesImpl(tap)));
963 mngr.popTag();
964 }
965 }
966 mngr.popTag();
967 mngr.popNamespace(prefix);
968
969 FaceletHandler handler = new DynamicComponentFacelet((NamespaceHandler) mngr.createFaceletHandler());
970 return handler;
971 }
972
973 protected FaceletsProcessingInstructions getDefaultFaceletsProcessingInstructions()
974 {
975 return FaceletsProcessingInstructions.getProcessingInstructions(FaceletsProcessing.PROCESS_AS_XHTML, false);
976 }
977
978 protected FaceletsProcessingInstructions getFaceletsProcessingInstructions(URL src, String alias)
979 {
980 String processAs = null;
981 boolean compressSpaces = false;
982 for (FaceletsProcessing entry : getFaceletsProcessingConfigurations())
983 {
984 if (src.getPath().endsWith(entry.getFileExtension()))
985 {
986 processAs = entry.getProcessAs();
987 compressSpaces = Boolean.valueOf(entry.getOamCompressSpaces());
988 break;
989 }
990 }
991 return FaceletsProcessingInstructions.getProcessingInstructions(processAs, compressSpaces);
992 }
993
994 protected static String writeXmlDecl(InputStream is, CompilationManager mngr) throws IOException
995 {
996 is.mark(128);
997 String encoding = null;
998 try
999 {
1000 byte[] b = new byte[128];
1001 if (is.read(b) > 0)
1002 {
1003 String r = new String(b);
1004 Matcher m = XML_DECLARATION.matcher(r);
1005 if (m.find())
1006 {
1007 if (!mngr.getFaceletsProcessingInstructions().isConsumeXmlDeclaration())
1008 {
1009 mngr.writeInstruction(m.group(0) + "\n");
1010 }
1011 if (m.group(3) != null)
1012 {
1013 encoding = m.group(3);
1014 }
1015 }
1016 }
1017 }
1018 finally
1019 {
1020 is.reset();
1021 }
1022 return encoding;
1023 }
1024
1025 protected static String getXmlDecl(InputStream is, CompilationManager mngr) throws IOException
1026 {
1027 is.mark(128);
1028 String encoding = null;
1029 try
1030 {
1031 byte[] b = new byte[128];
1032 if (is.read(b) > 0)
1033 {
1034 String r = new String(b);
1035 Matcher m = XML_DECLARATION.matcher(r);
1036 if (m.find() && m.group(3) != null)
1037 {
1038 encoding = m.group(3);
1039 }
1040 }
1041 }
1042 finally
1043 {
1044 is.reset();
1045 }
1046 return encoding;
1047 }
1048
1049 private SAXParser createSAXParser(DefaultHandler handler) throws SAXException,
1050 ParserConfigurationException
1051 {
1052 SAXParserFactory factory = SAXParserFactory.newInstance();
1053 factory.setNamespaceAware(true);
1054 factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
1055 factory.setFeature("http://xml.org/sax/features/validation", this.isValidating());
1056 factory.setValidating(this.isValidating());
1057 SAXParser parser = factory.newSAXParser();
1058 XMLReader reader = parser.getXMLReader();
1059 reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
1060 reader.setErrorHandler(handler);
1061 reader.setEntityResolver(handler);
1062 return parser;
1063 }
1064
1065 }