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 org.apache.myfaces.config.ConfigFilesXmlValidationUtils;
22  import org.apache.myfaces.shared.config.MyfacesConfig;
23  import org.apache.myfaces.shared.util.ArrayUtils;
24  import org.apache.myfaces.shared.util.ClassUtils;
25  import org.apache.myfaces.shared.util.StringUtils;
26  import org.apache.myfaces.shared.util.WebConfigParamUtils;
27  import org.apache.myfaces.spi.FaceletConfigResourceProvider;
28  import org.apache.myfaces.spi.FaceletConfigResourceProviderFactory;
29  import org.apache.myfaces.view.facelets.tag.AbstractTagLibrary;
30  import org.apache.myfaces.view.facelets.tag.TagLibrary;
31  import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentResourceTagHandler;
32  import org.apache.myfaces.view.facelets.tag.composite.CompositeResouceWrapper;
33  import org.apache.myfaces.view.facelets.util.ParameterCheck;
34  import org.apache.myfaces.view.facelets.util.ReflectionUtil;
35  import org.xml.sax.Attributes;
36  import org.xml.sax.InputSource;
37  import org.xml.sax.Locator;
38  import org.xml.sax.SAXException;
39  import org.xml.sax.SAXParseException;
40  import org.xml.sax.XMLReader;
41  import org.xml.sax.helpers.DefaultHandler;
42  
43  import javax.faces.FacesException;
44  import javax.faces.application.Resource;
45  import javax.faces.application.ResourceHandler;
46  import javax.faces.application.ViewHandler;
47  import javax.faces.context.ExternalContext;
48  import javax.faces.context.FacesContext;
49  import javax.faces.view.facelets.ComponentConfig;
50  import javax.faces.view.facelets.FaceletHandler;
51  import javax.faces.view.facelets.Tag;
52  import javax.faces.view.facelets.TagConfig;
53  import javax.faces.view.facelets.TagHandler;
54  import javax.xml.parsers.ParserConfigurationException;
55  import javax.xml.parsers.SAXParser;
56  import javax.xml.parsers.SAXParserFactory;
57  import java.io.IOException;
58  import java.io.InputStream;
59  import java.lang.reflect.Method;
60  import java.net.URL;
61  import java.net.URLConnection;
62  import java.util.Collection;
63  import java.util.logging.Level;
64  import java.util.logging.Logger;
65  import java.util.regex.Pattern;
66  
67  /**
68   * Handles creating a {@link org.apache.myfaces.view.facelets.tag.TagLibrary TagLibrary}
69   * from a {@link java.net.URL URL} source.
70   * 
71   * @author Jacob Hookom
72   * @version $Id: TagLibraryConfig.java 1449029 2013-02-22 13:33:15Z lofwyr $
73   */
74  public final class TagLibraryConfig
75  {
76  
77      //private final static String SUFFIX = ".taglib.xml";
78  
79      //protected final static Logger log = Logger.getLogger("facelets.compiler");
80      protected final static Logger log = Logger.getLogger(TagLibraryConfig.class.getName());
81  
82      private static class TagLibraryImpl extends AbstractTagLibrary
83      {
84          private String _compositeLibraryName;
85          
86          private final ResourceHandler _resourceHandler;
87          private Pattern _acceptPatterns;
88          private String _extension;
89          private String[] _defaultSuffixesArray;
90          
91          public TagLibraryImpl(FacesContext facesContext, String namespace)
92          {
93              super(namespace);
94              _compositeLibraryName = null;
95              _resourceHandler = facesContext.getApplication().getResourceHandler();
96              ExternalContext externalContext = facesContext.getExternalContext();
97              
98              _acceptPatterns = loadAcceptPattern(externalContext);
99  
100             _extension = loadFaceletExtension(externalContext);
101             
102             String defaultSuffixes = WebConfigParamUtils.getStringInitParameter(externalContext,
103                     ViewHandler.DEFAULT_SUFFIX_PARAM_NAME, ViewHandler.DEFAULT_SUFFIX );
104             
105             _defaultSuffixesArray = StringUtils.splitShortString(defaultSuffixes, ' ');
106             
107             boolean faceletsExtensionFound = false;
108             for (String ext : _defaultSuffixesArray)
109             {
110                 if (_extension.equals(ext))
111                 {
112                     faceletsExtensionFound = true;
113                     break;
114                 }
115             }
116             if (!faceletsExtensionFound)
117             {
118                 _defaultSuffixesArray = (String[]) ArrayUtils.concat(_defaultSuffixesArray, new String[]{_extension});
119             }
120         }
121         
122         /**
123          * Load and compile a regular expression pattern built from the Facelet view mapping parameters.
124          * 
125          * @param context
126          *            the application's external context
127          * 
128          * @return the compiled regular expression
129          */
130         private Pattern loadAcceptPattern(ExternalContext context)
131         {
132             assert context != null;
133 
134             String mappings = context.getInitParameter(ViewHandler.FACELETS_VIEW_MAPPINGS_PARAM_NAME);
135             if (mappings == null)
136             {
137                 return null;
138             }
139 
140             // Make sure the mappings contain something
141             mappings = mappings.trim();
142             if (mappings.length() == 0)
143             {
144                 return null;
145             }
146 
147             return Pattern.compile(toRegex(mappings));
148         }
149 
150         private String loadFaceletExtension(ExternalContext context)
151         {
152             assert context != null;
153 
154             String suffix = context.getInitParameter(ViewHandler.FACELETS_SUFFIX_PARAM_NAME);
155             if (suffix == null)
156             {
157                 suffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
158             }
159             else
160             {
161                 suffix = suffix.trim();
162                 if (suffix.length() == 0)
163                 {
164                     suffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
165                 }
166             }
167 
168             return suffix;
169         }
170         
171         /**
172          * Convert the specified mapping string to an equivalent regular expression.
173          * 
174          * @param mappings
175          *            le mapping string
176          * 
177          * @return an uncompiled regular expression representing the mappings
178          */
179         private String toRegex(String mappings)
180         {
181             assert mappings != null;
182 
183             // Get rid of spaces
184             mappings = mappings.replaceAll("\\s", "");
185 
186             // Escape '.'
187             mappings = mappings.replaceAll("\\.", "\\\\.");
188 
189             // Change '*' to '.*' to represent any match
190             mappings = mappings.replaceAll("\\*", ".*");
191 
192             // Split the mappings by changing ';' to '|'
193             mappings = mappings.replaceAll(";", "|");
194 
195             return mappings;
196         }
197         
198         public boolean handles(String resourceName)
199         {
200             if (resourceName == null)
201             {
202                 return false;
203             }
204             // Check extension first as it's faster than mappings
205             if (resourceName.endsWith(_extension))
206             {
207                 // If the extension matches, it's a Facelet viewId.
208                 return true;
209             }
210 
211             // Otherwise, try to match the view identifier with the facelet mappings
212             return _acceptPatterns != null && _acceptPatterns.matcher(resourceName).matches();
213         }
214         
215         @Override
216         public boolean containsTagHandler(String ns, String localName)
217         {
218             boolean result = super.containsTagHandler(ns, localName);
219             
220             if (!result && _compositeLibraryName != null && containsNamespace(ns))
221             {
222                 for (String defaultSuffix : _defaultSuffixesArray)
223                 {
224                     String resourceName = localName + defaultSuffix;
225                     if (handles(resourceName))
226                     {
227                         Resource compositeComponentResource = _resourceHandler.createResource(
228                                 resourceName, _compositeLibraryName);
229                         
230                         if (compositeComponentResource != null)
231                         {
232                             URL url = compositeComponentResource.getURL();
233                             return (url != null);
234                         }
235                     }
236                 }
237             }
238             return result;
239         }
240         
241         @Override
242         public TagHandler createTagHandler(String ns, String localName,
243                 TagConfig tag) throws FacesException
244         {
245             TagHandler tagHandler = super.createTagHandler(ns, localName, tag);
246             
247             if (tagHandler == null && _compositeLibraryName != null && containsNamespace(ns))
248             {
249                 for (String defaultSuffix : _defaultSuffixesArray)
250                 {
251                     String resourceName = localName + defaultSuffix;
252                     if (handles(resourceName))
253                     {
254                         // MYFACES-3308 If a composite component exists, it requires to 
255                         // be always resolved. In other words, it should always exists a default.
256                         // The call here for resourceHandler.createResource, just try to get
257                         // the Resource and if it does not exists, it just returns null.
258                         // The intention of this code is just create an instance and pass to
259                         // CompositeComponentResourceTagHandler. Then, its values 
260                         // (resourceName, libraryName) will be used to derive the real instance
261                         // to use in a view, based on the locale used.
262                         Resource compositeComponentResource = new CompositeResouceWrapper(
263                             _resourceHandler.createResource(resourceName, _compositeLibraryName));
264                         
265                         if (compositeComponentResource != null)
266                         {
267                             ComponentConfig componentConfig = new ComponentConfigWrapper(tag,
268                                     "javax.faces.NamingContainer", null);
269                             
270                             return new CompositeComponentResourceTagHandler(
271                                     componentConfig, compositeComponentResource);
272                         }
273                     }
274                 }
275             }
276             return tagHandler;
277         }
278 
279         public void setCompositeLibrary(String compositeLibraryName)
280         {
281             _compositeLibraryName = compositeLibraryName;
282         }
283 
284         public void putConverter(String name, String id)
285         {
286             ParameterCheck.notNull("name", name);
287             ParameterCheck.notNull("id", id);
288             this.addConverter(name, id);
289         }
290 
291         public void putConverter(String name, String id, Class<? extends TagHandler> handlerClass)
292         {
293             ParameterCheck.notNull("name", name);
294             ParameterCheck.notNull("id", id);
295             ParameterCheck.notNull("handlerClass", handlerClass);
296             this.addConverter(name, id, handlerClass);
297         }
298 
299         public void putValidator(String name, String id)
300         {
301             ParameterCheck.notNull("name", name);
302             ParameterCheck.notNull("id", id);
303             this.addValidator(name, id);
304         }
305 
306         public void putValidator(String name, String id, Class<? extends TagHandler> handlerClass)
307         {
308             ParameterCheck.notNull("name", name);
309             ParameterCheck.notNull("id", id);
310             ParameterCheck.notNull("handlerClass", handlerClass);
311             this.addValidator(name, id, handlerClass);
312         }
313 
314         public void putTagHandler(String name, Class<? extends TagHandler> type)
315         {
316             ParameterCheck.notNull("name", name);
317             ParameterCheck.notNull("type", type);
318             this.addTagHandler(name, type);
319         }
320 
321         public void putComponent(String name, String componentType, String rendererType)
322         {
323             ParameterCheck.notNull("name", name);
324             ParameterCheck.notNull("componentType", componentType);
325             this.addComponent(name, componentType, rendererType);
326         }
327 
328         public void putComponent(String name, String componentType, String rendererType, 
329                                  Class<? extends TagHandler> handlerClass)
330         {
331             ParameterCheck.notNull("name", name);
332             ParameterCheck.notNull("componentType", componentType);
333             ParameterCheck.notNull("handlerClass", handlerClass);
334             this.addComponent(name, componentType, rendererType, handlerClass);
335         }
336 
337         public void putUserTag(String name, URL source)
338         {
339             ParameterCheck.notNull("name", name);
340             ParameterCheck.notNull("source", source);
341             this.addUserTag(name, source);
342         }
343 
344         public void putFunction(String name, Method method)
345         {
346             ParameterCheck.notNull("name", name);
347             ParameterCheck.notNull("method", method);
348             this.addFunction(name, method);
349         }
350         
351         public void putBehavior(String name, String id)
352         {
353             ParameterCheck.notNull("name", name);
354             ParameterCheck.notNull("id", id);
355             this.addBehavior(name, id);
356         }
357         
358         public void putBehavior(String name, String id, Class<? extends TagHandler> handlerClass)
359         {
360             ParameterCheck.notNull("name", name);
361             ParameterCheck.notNull("id", id);
362             ParameterCheck.notNull("handlerClass", handlerClass);
363             this.addBehavior(name, id, handlerClass);
364         }
365     }
366     
367     private static class ComponentConfigWrapper implements ComponentConfig
368     {
369 
370         protected final TagConfig parent;
371 
372         protected final String componentType;
373 
374         protected final String rendererType;
375 
376         public ComponentConfigWrapper(TagConfig parent, String componentType,
377                 String rendererType)
378         {
379             this.parent = parent;
380             this.componentType = componentType;
381             this.rendererType = rendererType;
382         }
383 
384         public String getComponentType()
385         {
386             return this.componentType;
387         }
388 
389         public String getRendererType()
390         {
391             return this.rendererType;
392         }
393 
394         public FaceletHandler getNextHandler()
395         {
396             return this.parent.getNextHandler();
397         }
398 
399         public Tag getTag()
400         {
401             return this.parent.getTag();
402         }
403 
404         public String getTagId()
405         {
406             return this.parent.getTagId();
407         }
408     }    
409     
410     private static class LibraryHandler extends DefaultHandler
411     {
412         private final URL source;
413         
414         private final FacesContext facesContext;
415 
416         private TagLibrary library;
417 
418         private final StringBuffer buffer;
419 
420         private Locator locator;
421 
422         private String tagName;
423 
424         private String converterId;
425 
426         private String validatorId;
427         
428         private String behaviorId;
429 
430         private String componentType;
431 
432         private String rendererType;
433 
434         private String functionName;
435 
436         private Class<? extends TagHandler> handlerClass;
437 
438         private Class<?> functionClass;
439 
440         private String functionSignature;
441         
442         private String compositeLibraryName;
443         
444         public LibraryHandler(FacesContext facesContext, URL source)
445         {
446             this.source = source;
447             this.buffer = new StringBuffer(64);
448             this.facesContext = facesContext;
449         }
450 
451         public TagLibrary getLibrary()
452         {
453             return this.library;
454         }
455 
456         public void endElement(String uri, String localName, String qName) throws SAXException
457         {
458             try
459             {
460                 if ("facelet-taglib".equals(qName))
461                 {
462                     // Nothing to do
463                 }                
464                 else if ("library-class".equals(qName))
465                 {
466                     this.processLibraryClass();
467                 }
468                 else if ("namespace".equals(qName))
469                 {
470                     this.library = new TagLibraryImpl(facesContext, this.captureBuffer());
471                     if (this.compositeLibraryName != null)
472                     {
473                         ((TagLibraryImpl)this.library).setCompositeLibrary(compositeLibraryName);
474                     }
475                 }
476                 else if ("composite-library-name".equals(qName))
477                 {
478                     this.compositeLibraryName = this.captureBuffer();
479                     if (this.library != null)
480                     {
481                         ((TagLibraryImpl)this.library).setCompositeLibrary(compositeLibraryName);
482                     }
483                 }
484                 else if ("component-type".equals(qName))
485                 {
486                     this.componentType = this.captureBuffer();
487                 }
488                 else if ("renderer-type".equals(qName))
489                 {
490                     this.rendererType = this.captureBuffer();
491                 }
492                 else if ("tag-name".equals(qName))
493                 {
494                     this.tagName = this.captureBuffer();
495                 }
496                 else if ("function-name".equals(qName))
497                 {
498                     this.functionName = this.captureBuffer();
499                 }
500                 else if ("function-class".equals(qName))
501                 {
502                     String className = this.captureBuffer();
503                     this.functionClass = createClass(Object.class, className);
504                 }
505                 else if ("description".equals(qName))
506                 {
507                     //Not used
508                 }
509                 else if ("display-name".equals(qName))
510                 {
511                     //Not used
512                 }
513                 else if ("icon".equals(qName))
514                 {
515                     //Not used
516                 }                
517                 else
518                 {
519                     // Make sure there we've seen a namespace element
520                     // before trying any of the following elements to avoid
521                     // obscure NPEs
522                     if (this.library == null)
523                     {
524                         throw new IllegalStateException("No <namespace> element");
525                     }
526 
527                     TagLibraryImpl impl = (TagLibraryImpl) this.library;
528 
529                     if ("tag".equals(qName))
530                     {
531                         if (this.handlerClass != null)
532                         {
533                             impl.putTagHandler(this.tagName, this.handlerClass);
534                         }
535                     }
536                     else if ("handler-class".equals(qName))
537                     {
538                         String cName = this.captureBuffer();
539                         this.handlerClass = createClass(TagHandler.class, cName);
540                     }
541                     else if ("component".equals(qName))
542                     {
543                         if (this.handlerClass != null)
544                         {
545                             impl.putComponent(this.tagName, this.componentType, this.rendererType, this.handlerClass);
546                             this.handlerClass = null;
547                         }
548                         else
549                         {
550                             impl.putComponent(this.tagName, this.componentType, this.rendererType);
551                         }
552                     }
553                     else if ("converter-id".equals(qName))
554                     {
555                         this.converterId = this.captureBuffer();
556                     }
557                     else if ("converter".equals(qName))
558                     {
559                         if (this.handlerClass != null)
560                         {
561                             impl.putConverter(this.tagName, this.converterId, handlerClass);
562                             this.handlerClass = null;
563                         }
564                         else
565                         {
566                             impl.putConverter(this.tagName, this.converterId);
567                         }
568                         this.converterId = null;
569                     }
570                     else if ("validator-id".equals(qName))
571                     {
572                         this.validatorId = this.captureBuffer();
573                     }
574                     else if ("validator".equals(qName))
575                     {
576                         if (this.handlerClass != null)
577                         {
578                             impl.putValidator(this.tagName, this.validatorId, handlerClass);
579                             this.handlerClass = null;
580                         }
581                         else
582                         {
583                             impl.putValidator(this.tagName, this.validatorId);
584                         }
585                         this.validatorId = null;
586                     }
587                     else if ("behavior-id".equals(qName))
588                     {
589                         this.behaviorId = this.captureBuffer();
590                     }
591                     else if ("behavior".equals(qName))
592                     {
593                         if (this.handlerClass != null)
594                         {
595                             impl.putBehavior(this.tagName, this.behaviorId, handlerClass);
596                             this.handlerClass = null;
597                         }
598                         else
599                         {
600                             impl.putBehavior(this.tagName, this.behaviorId);
601                         }
602                         this.behaviorId = null;
603                     }
604                     else if ("source".equals(qName))
605                     {
606                         String path = this.captureBuffer();
607                         URL url = new URL(this.source, path);
608                         impl.putUserTag(this.tagName, url);
609                     }
610                     else if ("function-signature".equals(qName))
611                     {
612                         this.functionSignature = this.captureBuffer();
613                         Method m = createMethod(this.functionClass, this.functionSignature);
614                         impl.putFunction(this.functionName, m);
615                     }
616                 }
617             }
618             catch (Exception e)
619             {
620                 throw new SAXParseException("Error Handling [" + this.source + "@" + this.locator.getLineNumber()
621                         + "," + this.locator.getColumnNumber() + "] <" + qName + ">", locator, e);
622             }
623         }
624 
625         private String captureBuffer() throws Exception
626         {
627             String s = this.buffer.toString().trim();
628             if (s.length() == 0)
629             {
630                 throw new Exception("Value Cannot be Empty");
631             }
632             this.buffer.setLength(0);
633             return s;
634         }
635 
636         @SuppressWarnings("unchecked")
637         private static <T> Class<? extends T> createClass(Class<T> type, String name) throws Exception
638         {
639             Class<? extends T> factory = (Class<? extends T>)ReflectionUtil.forName(name);
640             if (!type.isAssignableFrom(factory))
641             {
642                 throw new Exception(name + " must be an instance of " + type.getName());
643             }
644             return factory;
645         }
646 
647         private static Method createMethod(Class<?> type, String s) throws Exception
648         {
649             int pos = s.indexOf(' ');
650             if (pos == -1)
651             {
652                 throw new Exception("Must Provide Return Type: " + s);
653             }
654             else
655             {
656                 int pos2 = s.indexOf('(', pos + 1);
657                 if (pos2 == -1)
658                 {
659                     throw new Exception("Must provide a method name, followed by '(': " + s);
660                 }
661                 else
662                 {
663                     String mn = s.substring(pos + 1, pos2).trim();
664                     pos = s.indexOf(')', pos2 + 1);
665                     if (pos == -1)
666                     {
667                         throw new Exception("Must close parentheses, ')' missing: " + s);
668                     }
669                     else
670                     {
671                         String[] ps = s.substring(pos2 + 1, pos).trim().split(",");
672                         Class<?>[] pc;
673                         if (ps.length == 1 && "".equals(ps[0]))
674                         {
675                             pc = new Class[0];
676                         }
677                         else
678                         {
679                             pc = new Class[ps.length];
680                             for (int i = 0; i < pc.length; i++)
681                             {
682                                 pc[i] = ReflectionUtil.forName(ps[i].trim());
683                             }
684                         }
685                         try
686                         {
687                             return type.getMethod(mn, pc);
688                         }
689                         catch (NoSuchMethodException e)
690                         {
691                             throw new Exception("No Function Found on type: " + type.getName() + " with signature: "
692                                     + s);
693                         }
694 
695                     }
696 
697                 }
698             }
699         }
700 
701         private void processLibraryClass() throws Exception
702         {
703             String name = this.captureBuffer();
704             Class<?> type = createClass(TagLibrary.class, name);
705             this.library = (TagLibrary) type.newInstance();
706         }
707 
708         public InputSource resolveEntity(String publicId, String systemId) throws SAXException
709         {
710             if ("-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN".equals(publicId))
711             {
712                 URL url = ClassUtils.getResource("org/apache/myfaces/resource/facelet-taglib_1_0.dtd");
713                 return new InputSource(url.toExternalForm());
714             }
715             return null;
716         }
717 
718         public void characters(char[] ch, int start, int length) throws SAXException
719         {
720             this.buffer.append(ch, start, length);
721         }
722 
723         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
724         {
725             this.buffer.setLength(0);
726             if ("tag".equals(qName))
727             {
728                 this.handlerClass = null;
729                 this.componentType = null;
730                 this.rendererType = null;
731                 this.tagName = null;
732             }
733             else if ("function".equals(qName))
734             {
735                 this.functionName = null;
736                 this.functionClass = null;
737                 this.functionSignature = null;
738             }
739         }
740 
741         public void error(SAXParseException e) throws SAXException
742         {
743             throw new SAXException(
744                     "Error Handling [" + this.source + "@" + e.getLineNumber() + "," + e.getColumnNumber() + "]", e);
745         }
746 
747         public void setDocumentLocator(Locator locator)
748         {
749             this.locator = locator;
750         }
751 
752         public void fatalError(SAXParseException e) throws SAXException
753         {
754             throw e;
755         }
756 
757         public void warning(SAXParseException e) throws SAXException
758         {
759             throw e;
760         }
761     }
762 
763     public TagLibraryConfig()
764     {
765         super();
766     }
767 
768     public static TagLibrary create(FacesContext facesContext, URL url) throws IOException
769     {
770         InputStream is = null;
771         TagLibrary t = null;
772         URLConnection conn = null;
773         try
774         {
775             ExternalContext externalContext = facesContext.getExternalContext();
776             boolean schemaValidating = false;
777 
778             // validate XML
779             if (MyfacesConfig.getCurrentInstance(externalContext).isValidateXML())
780             {
781                 String version = ConfigFilesXmlValidationUtils.getFaceletTagLibVersion(url);
782                 schemaValidating = "2.0".equals(version);
783                 if (schemaValidating)
784                 {
785                     ConfigFilesXmlValidationUtils.validateFaceletTagLibFile(url, externalContext, version);
786                 }
787             }
788             
789             // parse file
790             LibraryHandler handler = new LibraryHandler(facesContext, url);
791             SAXParser parser = createSAXParser(handler, externalContext, schemaValidating);
792             conn = url.openConnection();
793             conn.setUseCaches(false);
794             is = conn.getInputStream();
795             parser.parse(is, handler);
796             t = handler.getLibrary();
797         }
798         catch (SAXException e)
799         {
800             IOException ioe = new IOException("Error parsing [" + url + "]: ");
801             ioe.initCause(e);
802             throw ioe;
803         }
804         catch (ParserConfigurationException e)
805         {
806             IOException ioe = new IOException("Error parsing [" + url + "]: ");
807             ioe.initCause(e);
808             throw ioe;
809         }
810         finally
811         {
812             if (is != null)
813             {
814                 is.close();
815             }
816         }
817         return t;
818     }
819 
820     public void loadImplicit(FacesContext facesContext, Compiler compiler) throws IOException
821     {
822         //URL[] urls = Classpath.search(cl, "META-INF/", SUFFIX);
823         //for (int i = 0; i < urls.length; i++)
824         ExternalContext externalContext = facesContext.getExternalContext();
825         FaceletConfigResourceProvider provider = FaceletConfigResourceProviderFactory.
826             getFacesConfigResourceProviderFactory(externalContext).
827                 createFaceletConfigResourceProvider(externalContext);
828         Collection<URL> urls = provider.getFaceletTagLibConfigurationResources(externalContext);
829         for (URL url : urls)
830         {
831             try
832             {
833                 //TagLibrary tl = create(urls[i]);
834                 TagLibrary tl = create(facesContext, url);
835                 if (tl != null)
836                 {
837                     compiler.addTagLibrary(tl);
838                 }
839                 if (log.isLoggable(Level.FINE))
840                 {
841                     //log.fine("Added Library from: " + urls[i]);
842                     log.fine("Added Library from: " + url);
843                 }
844             }
845             catch (Exception e)
846             {
847                 //log.log(Level.SEVERE, "Error Loading Library: " + urls[i], e);
848                 log.log(Level.SEVERE, "Error Loading Library: " + url, e);
849             }
850         }
851     }
852 
853     private static final SAXParser createSAXParser(LibraryHandler handler, ExternalContext externalContext,
854                                                    boolean schemaValidating)
855             throws SAXException, ParserConfigurationException
856     {
857         SAXParserFactory factory = SAXParserFactory.newInstance();
858 
859         if (MyfacesConfig.getCurrentInstance(externalContext).isValidateXML() && !schemaValidating)
860         {
861             // DTD validating
862             factory.setNamespaceAware(false);
863             factory.setFeature("http://xml.org/sax/features/validation", true);
864             factory.setValidating(true);
865         }
866         else
867         {
868             //Just parse it and do not validate, because it is not necessary.
869             factory.setNamespaceAware(true);
870             factory.setFeature("http://xml.org/sax/features/validation", false);
871             factory.setValidating(false);
872         }
873 
874         SAXParser parser = factory.newSAXParser();
875         XMLReader reader = parser.getXMLReader();
876         reader.setErrorHandler(handler);
877         reader.setEntityResolver(handler);
878         return parser;
879     }
880 
881 }