View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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  
28  import javax.el.ELException;
29  import javax.faces.FacesException;
30  import javax.faces.view.Location;
31  import javax.faces.view.facelets.FaceletException;
32  import javax.faces.view.facelets.FaceletHandler;
33  import javax.faces.view.facelets.Tag;
34  import javax.faces.view.facelets.TagAttribute;
35  import javax.faces.view.facelets.TagAttributes;
36  import javax.xml.parsers.ParserConfigurationException;
37  import javax.xml.parsers.SAXParser;
38  import javax.xml.parsers.SAXParserFactory;
39  
40  import org.apache.myfaces.shared.util.ClassUtils;
41  import org.apache.myfaces.view.facelets.tag.TagAttributeImpl;
42  import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
43  import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
44  import org.apache.myfaces.view.facelets.tag.composite.ImplementationHandler;
45  import org.apache.myfaces.view.facelets.tag.composite.InterfaceHandler;
46  import org.apache.myfaces.view.facelets.tag.jsf.core.CoreLibrary;
47  import org.xml.sax.Attributes;
48  import org.xml.sax.InputSource;
49  import org.xml.sax.Locator;
50  import org.xml.sax.SAXException;
51  import org.xml.sax.SAXParseException;
52  import org.xml.sax.XMLReader;
53  import org.xml.sax.ext.LexicalHandler;
54  import org.xml.sax.helpers.DefaultHandler;
55  
56  /**
57   * Compiler implementation that uses SAX
58   * 
59   * @see org.apache.myfaces.view.facelets.compiler.Compiler
60   * 
61   * @author Jacob Hookom
62   * @version $Id: SAXCompiler.java 1187700 2011-10-22 12:19:37Z bommel $
63   */
64  public final class SAXCompiler extends Compiler
65  {
66  
67      private final static Pattern XmlDeclaration = Pattern
68              .compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
69  
70      private static class CompilationHandler extends DefaultHandler implements LexicalHandler
71      {
72  
73          private final String alias;
74  
75          private boolean inDocument = false;
76  
77          private Locator locator;
78  
79          private final CompilationManager unit;
80  
81          public CompilationHandler(CompilationManager unit, String alias)
82          {
83              this.unit = unit;
84              this.alias = alias;
85          }
86  
87          public void characters(char[] ch, int start, int length) throws SAXException
88          {
89              if (this.inDocument)
90              {
91                  this.unit.writeText(new String(ch, start, length));
92              }
93          }
94  
95          public void comment(char[] ch, int start, int length) throws SAXException
96          {
97              if (this.inDocument)
98              {
99                  this.unit.writeComment(new String(ch, start, length));
100             }
101         }
102 
103         protected TagAttributes createAttributes(Attributes attrs)
104         {
105             int len = attrs.getLength();
106             TagAttribute[] ta = new TagAttribute[len];
107             for (int i = 0; i < len; i++)
108             {
109                 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
110                         .getQName(i), attrs.getValue(i));
111             }
112             return new TagAttributesImpl(ta);
113         }
114 
115         protected Location createLocation()
116         {
117             return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
118         }
119 
120         public void endCDATA() throws SAXException
121         {
122             if (this.inDocument)
123             {
124                 this.unit.writeInstruction("]]>");
125             }
126         }
127 
128         public void endDocument() throws SAXException
129         {
130             super.endDocument();
131         }
132 
133         public void endDTD() throws SAXException
134         {
135             this.inDocument = true;
136         }
137 
138         public void endElement(String uri, String localName, String qName) throws SAXException
139         {
140             this.unit.popTag();
141         }
142 
143         public void endEntity(String name) throws SAXException
144         {
145         }
146 
147         public void endPrefixMapping(String prefix) throws SAXException
148         {
149             this.unit.popNamespace(prefix);
150         }
151 
152         public void fatalError(SAXParseException e) throws SAXException
153         {
154             if (this.locator != null)
155             {
156                 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
157             }
158             else
159             {
160                 throw e;
161             }
162         }
163 
164         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
165         {
166             if (this.inDocument)
167             {
168                 this.unit.writeWhitespace(new String(ch, start, length));
169             }
170         }
171 
172         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
173         {
174             String dtd = "org/apache/myfaces/resource/default.dtd";
175             /*
176              * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
177              * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
178              */
179             URL url = ClassUtils.getResource(dtd);
180             return new InputSource(url.toString());
181         }
182 
183         public void setDocumentLocator(Locator locator)
184         {
185             this.locator = locator;
186         }
187 
188         public void startCDATA() throws SAXException
189         {
190             if (this.inDocument)
191             {
192                 this.unit.writeInstruction("<![CDATA[");
193             }
194         }
195 
196         public void startDocument() throws SAXException
197         {
198             this.inDocument = true;
199         }
200 
201         public void startDTD(String name, String publicId, String systemId) throws SAXException
202         {
203             if (this.inDocument)
204             {
205                 StringBuffer sb = new StringBuffer(64);
206                 sb.append("<!DOCTYPE ").append(name);
207                 if (publicId != null)
208                 {
209                     sb.append(" PUBLIC \"").append(publicId).append("\"");
210                     if (systemId != null)
211                     {
212                         sb.append(" \"").append(systemId).append("\"");
213                     }
214                 }
215                 else if (systemId != null)
216                 {
217                     sb.append(" SYSTEM \"").append(systemId).append("\"");
218                 }
219                 sb.append(" >\n");
220                 this.unit.writeInstruction(sb.toString());
221             }
222             this.inDocument = false;
223         }
224 
225         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
226         {
227             this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
228         }
229 
230         public void startEntity(String name) throws SAXException
231         {
232         }
233 
234         public void startPrefixMapping(String prefix, String uri) throws SAXException
235         {
236             this.unit.pushNamespace(prefix, uri);
237         }
238 
239         public void processingInstruction(String target, String data) throws SAXException
240         {
241             if (this.inDocument)
242             {
243                 StringBuffer sb = new StringBuffer(64);
244                 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
245                 this.unit.writeInstruction(sb.toString());
246             }
247         }
248     }
249     
250     /**
251      * Like CompilationHandler but does not take into account everything outside f:metadata tag 
252      * 
253      * @since 2.0
254      */
255     private static class ViewMetadataHandler extends DefaultHandler implements LexicalHandler
256     {
257 
258         private final String alias;
259 
260         private boolean inDocument = false;
261 
262         private Locator locator;
263 
264         private final CompilationManager unit;
265         
266         private boolean inMetadata = false;
267 
268         public ViewMetadataHandler(CompilationManager unit, String alias)
269         {
270             this.unit = unit;
271             this.alias = alias;
272         }
273 
274         public void characters(char[] ch, int start, int length) throws SAXException
275         {
276             if (this.inDocument && inMetadata)
277             {
278                 this.unit.writeText(new String(ch, start, length));
279             }
280         }
281 
282         public void comment(char[] ch, int start, int length) throws SAXException
283         {
284             if (this.inDocument && inMetadata)
285             {
286                 this.unit.writeComment(new String(ch, start, length));
287             }
288         }
289 
290         protected TagAttributes createAttributes(Attributes attrs)
291         {
292             int len = attrs.getLength();
293             TagAttribute[] ta = new TagAttribute[len];
294             for (int i = 0; i < len; i++)
295             {
296                 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
297                         .getQName(i), attrs.getValue(i));
298             }
299             return new TagAttributesImpl(ta);
300         }
301 
302         protected Location createLocation()
303         {
304             return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
305         }
306 
307         public void endCDATA() throws SAXException
308         {
309             if (this.inDocument && inMetadata)
310             {
311                 this.unit.writeInstruction("]]>");
312             }
313         }
314 
315         public void endDocument() throws SAXException
316         {
317             super.endDocument();
318         }
319 
320         public void endDTD() throws SAXException
321         {
322             this.inDocument = true;
323         }
324 
325         public void endElement(String uri, String localName, String qName) throws SAXException
326         {
327             if (inMetadata)
328             {
329                 this.unit.popTag();
330             }
331             if (CoreLibrary.Namespace.equals(uri) && "metadata".equals(localName))
332             {
333                 this.inMetadata=false;
334             }            
335         }
336 
337         public void endEntity(String name) throws SAXException
338         {
339         }
340 
341         public void endPrefixMapping(String prefix) throws SAXException
342         {
343             this.unit.popNamespace(prefix);
344         }
345 
346         public void fatalError(SAXParseException e) throws SAXException
347         {
348             if (this.locator != null)
349             {
350                 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
351             }
352             else
353             {
354                 throw e;
355             }
356         }
357 
358         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
359         {
360             if (this.inDocument && inMetadata)
361             {
362                 this.unit.writeWhitespace(new String(ch, start, length));
363             }
364         }
365 
366         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
367         {
368             String dtd = "org/apache/myfaces/resource/default.dtd";
369             /*
370              * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
371              * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
372              */
373             URL url = ClassUtils.getResource(dtd);
374             return new InputSource(url.toString());
375         }
376 
377         public void setDocumentLocator(Locator locator)
378         {
379             this.locator = locator;
380         }
381 
382         public void startCDATA() throws SAXException
383         {
384             if (this.inDocument && inMetadata)
385             {
386                 this.unit.writeInstruction("<![CDATA[");
387             }
388         }
389 
390         public void startDocument() throws SAXException
391         {
392             this.inDocument = true;
393         }
394 
395         public void startDTD(String name, String publicId, String systemId) throws SAXException
396         {
397             // metadata does not require output doctype
398             this.inDocument = false;
399         }
400 
401         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
402         {
403             if (CoreLibrary.Namespace.equals(uri) && "metadata".equals(localName))
404             {
405                 this.inMetadata=true;
406             }
407             if (inMetadata)
408             {
409                 this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
410             }
411         }
412 
413         public void startEntity(String name) throws SAXException
414         {
415         }
416 
417         public void startPrefixMapping(String prefix, String uri) throws SAXException
418         {
419             this.unit.pushNamespace(prefix, uri);
420         }
421 
422         public void processingInstruction(String target, String data) throws SAXException
423         {
424             if (this.inDocument && inMetadata)
425             {
426                 StringBuffer sb = new StringBuffer(64);
427                 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
428                 this.unit.writeInstruction(sb.toString());
429             }
430         }        
431     }
432     
433     /**
434      * Like CompilationHandler but does not take into account everything outside cc:interface or cc:implementation tag.
435      *  
436      * Note inside cc:implementation it only takes into account cc:insertChildren, cc:insertFacet and cc:renderFacet,
437      * all other tags, comments or text are just skipped.
438      * 
439      * @since 2.0.1
440      */
441     private static class CompositeComponentMetadataHandler extends DefaultHandler implements LexicalHandler
442     {
443 
444         private final String alias;
445 
446         private boolean inDocument = false;
447 
448         private Locator locator;
449 
450         private final CompilationManager unit;
451         
452         private boolean inCompositeInterface = false;
453         
454         private boolean inCompositeImplementation = false;
455 
456         public CompositeComponentMetadataHandler(CompilationManager unit, String alias)
457         {
458             this.unit = unit;
459             this.alias = alias;
460         }
461 
462         public void characters(char[] ch, int start, int length) throws SAXException
463         {
464             if (this.inDocument && inCompositeInterface)
465             {
466                 this.unit.writeText(new String(ch, start, length));
467             }
468         }
469 
470         public void comment(char[] ch, int start, int length) throws SAXException
471         {
472             if (this.inDocument && inCompositeInterface)
473             {
474                 this.unit.writeComment(new String(ch, start, length));
475             }
476         }
477 
478         protected TagAttributes createAttributes(Attributes attrs)
479         {
480             int len = attrs.getLength();
481             TagAttribute[] ta = new TagAttribute[len];
482             for (int i = 0; i < len; i++)
483             {
484                 ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
485                         .getQName(i), attrs.getValue(i));
486             }
487             return new TagAttributesImpl(ta);
488         }
489 
490         protected Location createLocation()
491         {
492             return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
493         }
494 
495         public void endCDATA() throws SAXException
496         {
497             if (this.inDocument && inCompositeInterface)
498             {
499                 this.unit.writeInstruction("]]>");
500             }
501         }
502 
503         public void endDocument() throws SAXException
504         {
505             super.endDocument();
506         }
507 
508         public void endDTD() throws SAXException
509         {
510             this.inDocument = true;
511         }
512 
513         public void endElement(String uri, String localName, String qName) throws SAXException
514         {
515             if (inCompositeInterface)
516             {
517                 this.unit.popTag();
518             }
519             else if (inCompositeImplementation && CompositeLibrary.NAMESPACE.equals(uri))
520             {
521                 if ( "insertFacet".equals(localName) ||
522                      "renderFacet".equals(localName) ||
523                      "insertChildren".equals(localName) || 
524                      ImplementationHandler.NAME.equals(localName))
525                 {
526                     this.unit.popTag();
527                 }
528             }
529             
530             if (CompositeLibrary.NAMESPACE.equals(uri))
531             {
532                 if (InterfaceHandler.NAME.equals(localName))
533                 {
534                     this.inCompositeInterface=false;
535                 }
536                 else if (ImplementationHandler.NAME.equals(localName))
537                 {
538                     this.inCompositeImplementation=false;
539                 }
540             }
541         }
542 
543         public void endEntity(String name) throws SAXException
544         {
545         }
546 
547         public void endPrefixMapping(String prefix) throws SAXException
548         {
549             this.unit.popNamespace(prefix);
550         }
551 
552         public void fatalError(SAXParseException e) throws SAXException
553         {
554             if (this.locator != null)
555             {
556                 throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
557             }
558             else
559             {
560                 throw e;
561             }
562         }
563 
564         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
565         {
566             if (this.inDocument && inCompositeInterface)
567             {
568                 this.unit.writeWhitespace(new String(ch, start, length));
569             }
570         }
571 
572         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
573         {
574             String dtd = "org/apache/myfaces/resource/default.dtd";
575             /*
576              * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
577              * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
578              */
579             URL url = ClassUtils.getResource(dtd);
580             return new InputSource(url.toString());
581         }
582 
583         public void setDocumentLocator(Locator locator)
584         {
585             this.locator = locator;
586         }
587 
588         public void startCDATA() throws SAXException
589         {
590             if (this.inDocument && inCompositeInterface)
591             {
592                 this.unit.writeInstruction("<![CDATA[");
593             }
594         }
595 
596         public void startDocument() throws SAXException
597         {
598             this.inDocument = true;
599         }
600 
601         public void startDTD(String name, String publicId, String systemId) throws SAXException
602         {
603             // metadata does not require output doctype
604             this.inDocument = false;
605         }
606 
607         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
608         {
609             if (CompositeLibrary.NAMESPACE.equals(uri))
610             {
611                 if (InterfaceHandler.NAME.equals(localName))
612                 {
613                     this.inCompositeInterface=true;
614                 }
615                 else if (ImplementationHandler.NAME.equals(localName))
616                 {
617                     this.inCompositeImplementation=true;
618                 }
619             }
620             
621             if (inCompositeInterface)
622             {
623                 this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
624             }
625             else if (inCompositeImplementation && CompositeLibrary.NAMESPACE.equals(uri))
626             {
627                 if ("insertFacet".equals(localName)    ||
628                     "renderFacet".equals(localName)    ||
629                     "insertChildren".equals(localName) ||
630                     ImplementationHandler.NAME.equals(localName)   )
631                 {
632                     this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
633                 }
634             }
635         }
636 
637         public void startEntity(String name) throws SAXException
638         {
639         }
640 
641         public void startPrefixMapping(String prefix, String uri) throws SAXException
642         {
643             this.unit.pushNamespace(prefix, uri);
644         }
645 
646         public void processingInstruction(String target, String data) throws SAXException
647         {
648             if (this.inDocument && inCompositeInterface)
649             {
650                 StringBuffer sb = new StringBuffer(64);
651                 sb.append("<?").append(target).append(' ').append(data).append("?>\n");
652                 this.unit.writeInstruction(sb.toString());
653             }
654         }        
655     }
656 
657     public SAXCompiler()
658     {
659         super();
660     }
661 
662     public FaceletHandler doCompile(URL src, String alias) throws IOException, FaceletException, ELException,
663             FacesException
664     {
665         CompilationManager mngr = null;
666         InputStream is = null;
667         String encoding = null;
668         try
669         {
670             is = new BufferedInputStream(src.openStream(), 1024);
671             mngr = new CompilationManager(alias, this);
672             encoding = writeXmlDecl(is, mngr);
673             CompilationHandler handler = new CompilationHandler(mngr, alias);
674             SAXParser parser = this.createSAXParser(handler);
675             parser.parse(is, handler);
676         }
677         catch (SAXException e)
678         {
679             throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
680         }
681         catch (ParserConfigurationException e)
682         {
683             throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
684         }
685         finally
686         {
687             if (is != null)
688             {
689                 is.close();
690             }
691         }
692         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
693     }
694 
695     /**
696      * @since 2.0
697      */
698     @Override
699     protected FaceletHandler doCompileViewMetadata(URL src, String alias)
700             throws IOException, FaceletException, ELException, FacesException
701     {
702         CompilationManager mngr = null;
703         InputStream is = null;
704         String encoding = null;
705         try
706         {
707             is = new BufferedInputStream(src.openStream(), 1024);
708             mngr = new CompilationManager(alias, this);
709             encoding = getXmlDecl(is, mngr);
710             ViewMetadataHandler handler = new ViewMetadataHandler(mngr, alias);
711             SAXParser parser = this.createSAXParser(handler);
712             parser.parse(is, handler);
713         }
714         catch (SAXException e)
715         {
716             throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
717         }
718         catch (ParserConfigurationException e)
719         {
720             throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
721         }
722         finally
723         {
724             if (is != null)
725             {
726                 is.close();
727             }
728         }
729         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
730     }
731 
732     /**
733      * @since 2.0.1
734      */
735     @Override
736     protected FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias)
737             throws IOException, FaceletException, ELException, FacesException
738     {
739         CompilationManager mngr = null;
740         InputStream is = null;
741         String encoding = null;
742         try
743         {
744             is = new BufferedInputStream(src.openStream(), 1024);
745             mngr = new CompilationManager(alias, this);
746             encoding = getXmlDecl(is, mngr);
747             CompositeComponentMetadataHandler handler = new CompositeComponentMetadataHandler(mngr, alias);
748             SAXParser parser = this.createSAXParser(handler);
749             parser.parse(is, handler);
750         }
751         catch (SAXException e)
752         {
753             throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
754         }
755         catch (ParserConfigurationException e)
756         {
757             throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
758         }
759         finally
760         {
761             if (is != null)
762             {
763                 is.close();
764             }
765         }
766         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
767     }
768 
769     protected static final String writeXmlDecl(InputStream is, CompilationManager mngr) throws IOException
770     {
771         is.mark(128);
772         String encoding = null;
773         try
774         {
775             byte[] b = new byte[128];
776             if (is.read(b) > 0)
777             {
778                 String r = new String(b);
779                 Matcher m = XmlDeclaration.matcher(r);
780                 if (m.find())
781                 {
782                     mngr.writeInstruction(m.group(0) + "\n");
783                     if (m.group(3) != null)
784                     {
785                         encoding = m.group(3);
786                     }
787                 }
788             }
789         }
790         finally
791         {
792             is.reset();
793         }
794         return encoding;
795     }
796     
797     protected static final String getXmlDecl(InputStream is, CompilationManager mngr) throws IOException
798     {
799         is.mark(128);
800         String encoding = null;
801         try
802         {
803             byte[] b = new byte[128];
804             if (is.read(b) > 0)
805             {
806                 String r = new String(b);
807                 Matcher m = XmlDeclaration.matcher(r);
808                 if (m.find())
809                 {
810                     //mngr.writeInstruction(m.group(0) + "\n");
811                     if (m.group(3) != null)
812                     {
813                         encoding = m.group(3);
814                     }
815                 }
816             }
817         }
818         finally
819         {
820             is.reset();
821         }
822         return encoding;
823     }
824 
825     private final SAXParser createSAXParser(DefaultHandler handler) throws SAXException,
826             ParserConfigurationException
827     {
828         SAXParserFactory factory = SAXParserFactory.newInstance();
829         factory.setNamespaceAware(true);
830         factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
831         factory.setFeature("http://xml.org/sax/features/validation", this.isValidating());
832         factory.setValidating(this.isValidating());
833         SAXParser parser = factory.newSAXParser();
834         XMLReader reader = parser.getXMLReader();
835         reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
836         reader.setErrorHandler(handler);
837         reader.setEntityResolver(handler);
838         return parser;
839     }
840 
841 }