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