visualweb.jsfsupport/src/org/netbeans/modules/visualweb/jsfsupport/container/JsfTagSupport.java
author deva@netbeans.org
Mon, 07 Apr 2008 16:45:17 -0700
changeset 3026 c2525170412f
parent 2470 3ef77efc0995
permissions -rw-r--r--
Additional fix for #131899
1) EncodingComponentBeanInfo didn't have id descriptor because of which id was not generated for encoding component
2) Rendered and component type names were not correct in EncodingTag.java
3) Removed unnecessary code in JsfTagSupport.java
     1 /*
     2  * To change this template, choose Tools | Templates | Licenses | Default License
     3  * and open the template in the editor.
     4  */
     5 package org.netbeans.modules.visualweb.jsfsupport.container;
     6 
     7 import java.io.ByteArrayInputStream;
     8 import java.io.IOException;
     9 import java.net.URL;
    10 import java.util.ArrayList;
    11 import java.util.Enumeration;
    12 import java.util.HashMap;
    13 import java.util.List;
    14 import java.util.Map;
    15 import java.util.zip.ZipEntry;
    16 import java.util.zip.ZipFile;
    17 import javax.faces.webapp.UIComponentTagBase;
    18 import javax.xml.parsers.DocumentBuilder;
    19 import javax.xml.parsers.DocumentBuilderFactory;
    20 import javax.xml.parsers.ParserConfigurationException;
    21 import org.openide.filesystems.FileObject;
    22 import org.openide.filesystems.FileUtil;
    23 import org.openide.filesystems.URLMapper;
    24 import org.openide.util.Exceptions;
    25 import org.openide.util.NbBundle;
    26 import org.w3c.dom.Document;
    27 import org.w3c.dom.Element;
    28 import org.w3c.dom.Node;
    29 import org.w3c.dom.NodeList;
    30 import org.xml.sax.EntityResolver;
    31 import org.xml.sax.InputSource;
    32 import org.xml.sax.SAXException;
    33 
    34 /**
    35  * A Support class to find the JSF component corresponding to the JSP tag and TagLib URI
    36  * @author Winston Prakash
    37  */
    38 public class JsfTagSupport {
    39 
    40     private Map<String, TagInfo> tagInfoMap = new HashMap<String, TagInfo>();
    41     private Map<String, ComponentInfo> componentInfoMap = new HashMap<String, ComponentInfo>();
    42     // Static map of Taglib URI and taglib and faces-config locations in a jar
    43     private static Map<String, TagLibFacesConfigInfo> statictTaglibFacesConfigLocationMap = new HashMap<String, TagLibFacesConfigInfo>();
    44     // Cache of Taglib URI and JSF tag support 
    45     private static Map<String, JsfTagSupport> cachedTagLibraryInfoMap = new HashMap<String, JsfTagSupport>();
    46     private static Object lock = new Object();
    47 
    48     /**
    49      * This method should be called only once when the designtime JSF container is initialzed,
    50      * passing the project classloader. The classpath (jars) of the classloader is scanned for
    51      * TLD files and faces config files. Their locations are cached for later use 
    52      * @param classLoader
    53      */
    54     public static synchronized void initialize(ClassLoader classLoader) {
    55         try {
    56             Enumeration<URL> urls = classLoader.getResources("META-INF/faces-config.xml");
    57             while (urls.hasMoreElements()) {
    58                 addTaglibFacesConfigMapEntry(urls.nextElement());
    59             }
    60 
    61             // Bug Fix 124610 - Unfortunately the JSF RI component informations are not kept
    62             // in the standard location (META-INF/faces-config.xml)
    63             URL facesConfigUrl =  classLoader.getResource("com/sun/faces/jsf-ri-runtime.xml");
    64             URL tagLibUrl = new URL(facesConfigUrl.toString().split("!")[0] + "!/META-INF/html_basic.tld");
    65             String taglibUri = "http://java.sun.com/jsf/html";
    66             TagLibFacesConfigInfo tagLibFacesConfigInfo = new TagLibFacesConfigInfo(taglibUri);
    67             tagLibFacesConfigInfo.addTagLibUrl(tagLibUrl);
    68             tagLibFacesConfigInfo.addFacesConfigUrl(facesConfigUrl);
    69             statictTaglibFacesConfigLocationMap.put(taglibUri, tagLibFacesConfigInfo);
    70             
    71             tagLibUrl = new URL(facesConfigUrl.toString().split("!")[0] + "!/META-INF/jsf_core.tld");
    72             taglibUri = "http://java.sun.com/jsf/core";
    73             tagLibFacesConfigInfo = new TagLibFacesConfigInfo(taglibUri);
    74             tagLibFacesConfigInfo.addTagLibUrl(tagLibUrl);
    75             tagLibFacesConfigInfo.addFacesConfigUrl(facesConfigUrl);
    76             statictTaglibFacesConfigLocationMap.put(taglibUri, tagLibFacesConfigInfo);            
    77         } catch (Exception ex) {
    78             Exceptions.printStackTrace(ex);
    79         }
    80     }
    81 
    82     private static void addTaglibFacesConfigMapEntry(URL facesConfigUrl) throws IOException, ParserConfigurationException, SAXException {
    83         FileObject facesConfigFileObject = URLMapper.findFileObject(facesConfigUrl);
    84         String zipFilePath = FileUtil.toFile(FileUtil.getArchiveFile(facesConfigFileObject)).getAbsolutePath();
    85         ZipFile in = new ZipFile(zipFilePath);
    86         Enumeration<? extends ZipEntry> entries = in.entries();
    87         while (entries.hasMoreElements()) {
    88             ZipEntry entry = entries.nextElement();
    89             if (entry.getName().endsWith(".tld")) {
    90                 URL tagLibUrl = new URL(facesConfigUrl.toString().split("!")[0] + "!/" + entry.getName());
    91                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    92                 factory.setValidating(false);
    93                 DocumentBuilder documentBuilder = factory.newDocumentBuilder();
    94                 documentBuilder.setEntityResolver(new EmptyEntityResolver());
    95                 Document tagLibdocument = documentBuilder.parse(tagLibUrl.openStream());
    96                 NodeList tagNodes = tagLibdocument.getElementsByTagName("uri");
    97                 // Scan the TLD file to find the taglib URI
    98                 String taglibUri = tagNodes.item(0).getTextContent().trim();
    99 
   100                 TagLibFacesConfigInfo tagLibFacesConfigInfo = new TagLibFacesConfigInfo(taglibUri);
   101                 tagLibFacesConfigInfo.addTagLibUrl(tagLibUrl);
   102                 tagLibFacesConfigInfo.addFacesConfigUrl(facesConfigUrl);
   103 
   104                 statictTaglibFacesConfigLocationMap.put(taglibUri, tagLibFacesConfigInfo);
   105             }
   106         }
   107     }
   108 
   109     /** 
   110      *Factory Method to get TagLibrarySupport for a particular taglibUri and ClassLoader
   111      */
   112     public static JsfTagSupport getInstance(
   113             String taglibUri) throws JsfTagSupportException, SAXException, ParserConfigurationException, IOException {
   114         synchronized (lock) {
   115             if (!cachedTagLibraryInfoMap.containsKey(taglibUri)) {
   116                 cachedTagLibraryInfoMap.put(taglibUri, new JsfTagSupport(taglibUri));
   117             }
   118 
   119         }
   120         return cachedTagLibraryInfoMap.get(taglibUri);
   121     }
   122 
   123     public Object getTagHandler(
   124             ClassLoader classLoader, String tagName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
   125         TagInfo tagInfo = tagInfoMap.get(tagName);
   126         return classLoader.loadClass(tagInfo.getTagClass()).newInstance();
   127     }
   128 
   129     public Object getComponent(
   130             ClassLoader classLoader, String tagName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
   131         UIComponentTagBase componentTag = (UIComponentTagBase) getTagHandler(classLoader, tagName);
   132         String componentType = componentTag.getComponentType();
   133         ComponentInfo componentInfo = componentInfoMap.get(componentType);
   134         String componentClass = componentInfo.getComponentClass();
   135         return classLoader.loadClass(componentClass).newInstance();
   136     }
   137 
   138     public String getComponentClass(
   139             ClassLoader classLoader, String tagName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
   140         if(tagName.equals("view") || tagName.equals("subview") || tagName.equals("verbatim")) {
   141             return null;
   142         }
   143         UIComponentTagBase componentTag = (UIComponentTagBase) getTagHandler(classLoader, tagName);
   144         String componentType = componentTag.getComponentType();
   145         ComponentInfo componentInfo = componentInfoMap.get(componentType);
   146         return componentInfo.getComponentClass();
   147     }
   148 
   149     private JsfTagSupport(String taglibUri) throws JsfTagSupportException, SAXException, ParserConfigurationException, IOException {
   150         TagLibFacesConfigInfo tagLibFacesConfigInfo = statictTaglibFacesConfigLocationMap.get(taglibUri);
   151 
   152         if (tagLibFacesConfigInfo != null) {
   153             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   154             factory.setValidating(false);
   155             List<URL> tagLibUrlList = tagLibFacesConfigInfo.getTagLibUrls();
   156             for (URL tagLibUrl : tagLibUrlList) {
   157                 // Create the builder and parse XML data from input stream
   158                 DocumentBuilder documentBuilder = factory.newDocumentBuilder();
   159                 documentBuilder.setEntityResolver(new EmptyEntityResolver());
   160                 Document tagLibdocument = documentBuilder.parse(tagLibUrl.openStream());
   161                 parseTagLibary(tagLibdocument);
   162             }
   163 
   164             List<URL> facesConfigUrlList = tagLibFacesConfigInfo.getFacesConfigUrls();
   165             for (URL facesConfigUrl : facesConfigUrlList) {
   166                 // Create the builder and parse XML data from input stream
   167                 DocumentBuilder documentBuilder = factory.newDocumentBuilder();
   168                 documentBuilder.setEntityResolver(new EmptyEntityResolver());
   169                 Document facesConfigdocument = documentBuilder.parse(facesConfigUrl.openStream());
   170                 parseFacesConfig(facesConfigdocument);
   171             }
   172         } else {
   173             throw new JsfTagSupportException(NbBundle.getMessage(JsfTagSupport.class, "UNRECOGNIZED_TAGLIB") + taglibUri);
   174         }
   175     }
   176 
   177     private Map<String, ComponentInfo> parseFacesConfig(Document facesConfigdocument) {
   178         NodeList componentNodes = facesConfigdocument.getElementsByTagName("component");
   179         for (int i = 0; i <
   180                 componentNodes.getLength(); i++) {
   181             ComponentInfo componentInfo = new ComponentInfo(componentNodes.item(i));
   182             componentInfoMap.put(componentInfo.getComponentType(), componentInfo);
   183         }
   184 
   185         return componentInfoMap;
   186     }
   187 
   188     private void parseTagLibary(Document tagLibdocument) {
   189         NodeList tagNodes = tagLibdocument.getElementsByTagName("tag");
   190         for (int i = 0; i <
   191                 tagNodes.getLength(); i++) {
   192             TagInfo tagInfo = new TagInfo(tagNodes.item(i));
   193             tagInfoMap.put(tagInfo.getName(), tagInfo);
   194         }
   195     }
   196 
   197     private static class TagLibFacesConfigInfo {
   198 
   199         private String taglibUri;
   200         private List<URL> tagLibUrls = new ArrayList<URL>(3);
   201         private List<URL> facesConfigUrls = new ArrayList<URL>(3);
   202 
   203         TagLibFacesConfigInfo(String taglibUri) {
   204             this.taglibUri = taglibUri;
   205         }
   206 
   207         public void addTagLibUrl(URL taglib) {
   208             tagLibUrls.add(taglib);
   209         }
   210 
   211         public List<URL> getTagLibUrls() {
   212             return tagLibUrls;
   213         }
   214 
   215         public void addFacesConfigUrl(URL facesConfig) {
   216             facesConfigUrls.add(facesConfig);
   217         }
   218 
   219         public List<URL> getFacesConfigUrls() {
   220             return facesConfigUrls;
   221         }
   222     }
   223 
   224     private static class TagInfo {
   225 
   226         private String tagName;
   227         private String tagClass;
   228 
   229         TagInfo(Node tagNode) {
   230             Node nameNode = ((Element) tagNode).getElementsByTagName("name").item(0);
   231             tagName = nameNode.getTextContent().trim();
   232             Node tagClassNode = ((Element) tagNode).getElementsByTagName("tag-class").item(0);
   233             tagClass = tagClassNode.getTextContent().trim();
   234         }
   235 
   236         public String getName() {
   237             return tagName;
   238         }
   239 
   240         public String getTagClass() {
   241             return tagClass;
   242         }
   243     }
   244 
   245     private static class ComponentInfo {
   246 
   247         private String componentType;
   248         private String componentClass;
   249 
   250         ComponentInfo(Node componentNode) {
   251             Node componentTypeNode = ((Element) componentNode).getElementsByTagName("component-type").item(0);
   252             componentType = componentTypeNode.getTextContent().trim();
   253             Node componentClassNode = ((Element) componentNode).getElementsByTagName("component-class").item(0);
   254             componentClass = componentClassNode.getTextContent().trim();
   255         }
   256 
   257         public String getComponentType() {
   258             return componentType;
   259         }
   260 
   261         public String getComponentClass() {
   262             return componentClass;
   263         }
   264     }
   265     
   266     private static class EmptyEntityResolver implements EntityResolver {
   267          public InputSource resolveEntity(String pubid, String sysid) {
   268             return new InputSource(new ByteArrayInputStream(new byte[0]));
   269         }
   270     }
   271 }