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