KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > webapp > parser > TagToComponentMap


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33
34 package com.icesoft.faces.webapp.parser;
35
36 import com.icesoft.jasper.xmlparser.ParserUtils;
37 import org.apache.commons.digester.Digester;
38 import org.apache.commons.digester.Rule;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.xml.sax.Attributes JavaDoc;
42
43 import java.io.FileInputStream JavaDoc;
44 import java.io.FileOutputStream JavaDoc;
45 import java.io.FileWriter JavaDoc;
46 import java.io.IOException JavaDoc;
47 import java.io.InputStream JavaDoc;
48 import java.io.ObjectInputStream JavaDoc;
49 import java.io.ObjectOutputStream JavaDoc;
50 import java.io.Serializable JavaDoc;
51 import java.io.Writer JavaDoc;
52 import java.util.Hashtable JavaDoc;
53
54 /**
55  * This class provides a map from TLD tag names to the tag processing class
56  * associated with the tag. The map is used by the parser to establish a
57  * ruleset for the digester to use when parsing a JSFX page.
58  *
59  * @author Steve Maryka
60  */

61 public class TagToComponentMap implements Serializable JavaDoc {
62
63     public static final String JavaDoc XHTML_COMPONENT_TYPE =
64             "com.icesoft.faces.XhtmlComponent";
65     public static final String JavaDoc XHTML_COMPONENT_CLASS =
66             "com.icesoft.faces.component.UIXhtmlComponent";
67     private static ClassLoader JavaDoc loader =
68             TagToComponentMap.class.getClassLoader();
69     private static final Log log = LogFactory.getLog(TagToComponentMap.class);
70
71     private Hashtable JavaDoc tagToComponentMap = new Hashtable JavaDoc();
72     private Writer JavaDoc faceletsTaglibXmlWriter;
73
74     private void setFaceletsTaglibXmlWriter(Writer JavaDoc writer) {
75         faceletsTaglibXmlWriter = writer;
76     }
77
78     /**
79      * Build the map from a serialized source.
80      *
81      * @param fis Input stream for the serialized data.
82      * @return The map
83      * @throws IOException
84      * @throws ClassNotFoundException
85      */

86     static TagToComponentMap loadFrom(InputStream JavaDoc fis)
87             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
88         try {
89             ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(fis);
90             return (TagToComponentMap) ois.readObject();
91         } catch (IOException JavaDoc e) {
92             log.error("Error building map from TLD tag names", e);
93             throw e;
94         } catch (ClassNotFoundException JavaDoc e) {
95             log.error("Error building map from TLD tag names", e);
96             throw e;
97         }
98         catch (Exception JavaDoc e) {
99             return new TagToComponentMap();
100         }
101     }
102
103     /**
104      * Getter for TagToComponentMap
105      *
106      * @return The tag to tag processing class map.
107      */

108     public Hashtable JavaDoc getTagToComponentMap() {
109         return tagToComponentMap;
110     }
111
112     /**
113      * Takes a TLD file, parses it and build up map from tag name to tag
114      * processing class.
115      *
116      * @param tldInput The TLD to process
117      * @throws IOException If digester barfs.
118      */

119     public void addTags(InputStream JavaDoc tldInput) throws IOException JavaDoc {
120
121         /*
122           Use the digester to parse input file looking for <tag> entries, extract the <name>
123           and extract the <tag-class> and build hash table for looking up component
124           classes based on a tag name.
125         */

126         Digester digester = new Digester();
127         digester.setNamespaceAware(true);
128         digester.setValidating(false);
129         digester.setEntityResolver(ParserUtils.entityResolver);
130         digester.setUseContextClassLoader(false);
131
132         /* Need to set the class loader to work. Not sure why.
133            May need to change when we move behind servlet container or Tomcat */

134         digester.setClassLoader(loader);
135
136         // This rule creates an element we can use to populate the map;
137
digester.addObjectCreate("*/tag",
138                                  "com.icesoft.faces.webapp.parser.TagToTagClassElement");
139         digester.addObjectCreate("*/uri", "java.lang.StringBuffer");
140
141         // This rule pushes everything into the hash table;
142
NameRule nRule =
143                 new NameRule(tagToComponentMap, faceletsTaglibXmlWriter);
144         digester.addRule("*/tag/tag-class", nRule);
145         digester.addRule("*/uri", nRule);
146
147         // These rules scoop the values from <name> and <tag-class> elements;
148
digester.addCallMethod("*/tag/name", "setTagName", 0);
149         digester.addCallMethod("*/tag/tag-class", "setTagClass", 0);
150         digester.addCallMethod("*/uri", "append", 0);
151
152         try {
153             digester.parse(tldInput);
154         } catch (Throwable JavaDoc e) {
155             IOException JavaDoc ioe = new IOException JavaDoc("Can't parse tld " + tldInput.toString());
156             ioe.initCause( e );
157             throw ioe;
158         }
159     }
160
161
162     /**
163      * Main method for when this class is run to build the serialized data from
164      * a set of TLDS.
165      *
166      * @param args The runtime arguements.
167      */

168     public static void main(String JavaDoc args[]) {
169
170         /* arg[0] is "new" to create serialzed data or 'old' to read serialized data
171            arg[1] is filename for serialized data;
172            arg[2...] are tld's to process */

173
174         FileInputStream JavaDoc tldFile = null;
175
176         TagToComponentMap map = new TagToComponentMap();
177
178         if (args[0].equals("new")) {
179             // Build new component map from tlds and serialize it;
180

181             for (int i = 2; i < args.length; i++) {
182                 try {
183                     tldFile = new FileInputStream JavaDoc(args[i]);
184                     map.addTags((InputStream JavaDoc) tldFile);
185                 }
186                 catch (IOException JavaDoc e) {
187                     e.printStackTrace();
188                     return;
189                 }
190             }
191
192             try {
193                 FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(args[1]);
194                 ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(fos);
195                 oos.writeObject(map);
196                 oos.flush();
197                 oos.close();
198             } catch (Exception JavaDoc e) {
199                 e.printStackTrace();
200             }
201         } else if (args[0].equals("old")) {
202             // Build component from serialized data;
203
try {
204                 FileInputStream JavaDoc fis = new FileInputStream JavaDoc(args[1]);
205                 ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(fis);
206                 map = (TagToComponentMap) ois.readObject();
207             } catch (Exception JavaDoc e) {
208                 e.printStackTrace();
209             }
210         } else if (args[0].equals("facelets")) {
211             // Build new component map from tld, and use that to
212
// generate a Facelets taglib.xml
213
// args[0] is command
214
// args[1] is output taglib.xml
215
// args[2] is input tld
216

217             try {
218                 FileWriter JavaDoc faceletsTaglibXmlWriter = new FileWriter JavaDoc(args[1]);
219                 String JavaDoc preamble =
220                         "<?xml version=\"1.0\"?>\n" +
221                         "<!DOCTYPE facelet-taglib PUBLIC\n" +
222                         " \"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN\"\n" +
223                         " \"http://java.sun.com/dtd/web-facesconfig_1_0.dtd\">\n\n" +
224                         "<facelet-taglib>\n";
225                 String JavaDoc trailer =
226                         "</facelet-taglib>\n";
227                 faceletsTaglibXmlWriter.write(preamble);
228
229                 map.setFaceletsTaglibXmlWriter(faceletsTaglibXmlWriter);
230                 tldFile = new FileInputStream JavaDoc(args[2]);
231                 map.addTags((InputStream JavaDoc) tldFile);
232
233                 faceletsTaglibXmlWriter.write(trailer);
234                 faceletsTaglibXmlWriter.flush();
235                 faceletsTaglibXmlWriter.close();
236             }
237             catch (IOException JavaDoc e) {
238                 e.printStackTrace();
239                 return;
240             }
241         }
242     }
243 }
244
245
246 /**
247  * A digest rule for reading tags and creating map elements.
248  */

249 final class NameRule extends Rule {
250     // A class for adding tag name to current element;
251

252     private Hashtable JavaDoc componentMap;
253     private Writer JavaDoc faceletsTaglibXmlWriter;
254     private String JavaDoc currentNamespace;
255
256     private static final Log log = LogFactory.getLog(NameRule.class);
257
258     /**
259      * Constructor.
260      *
261      * @param map The map being created.
262      * @param writer
263      */

264     public NameRule(Hashtable JavaDoc map, Writer JavaDoc writer) {
265         super();
266         componentMap = map;
267         faceletsTaglibXmlWriter = writer;
268         currentNamespace = null;
269     }
270
271     /**
272      * Do nothing in begin.
273      *
274      * @param attributes The tag attributes
275      * @throws Exception No exception thrown.
276      * @deprecated
277      */

278     public void begin(Attributes JavaDoc attributes) throws Exception JavaDoc {
279
280     }
281
282     /**
283      * Puts the element into the map.
284      *
285      * @param namespace Not used
286      * @param name Not used
287      */

288     public void end(String JavaDoc namespace, String JavaDoc name) {
289         if (name.equals("uri")) {
290             if (faceletsTaglibXmlWriter != null) {
291                 try {
292                     String JavaDoc ns = digester.peek().toString();
293                     boolean namespaceChanged =
294                             (ns != null && ns.length() > 0) &&
295                             (currentNamespace == null ||
296                              !currentNamespace.equals(ns));
297                     if (namespaceChanged) {
298                         currentNamespace = ns;
299                         String JavaDoc nsOutput =
300                                 " <namespace>" + currentNamespace +
301                                 "</namespace>\n";
302                         faceletsTaglibXmlWriter.write(nsOutput);
303                         System.out.print(nsOutput);
304                     }
305                 }
306                 catch (Exception JavaDoc e) {
307                     System.out.println(
308                             "Problem writing namespace to Facelets taglib.xml. Exception: " +
309                             e);
310                 }
311             }
312             return;
313         }
314
315         TagToTagClassElement elem = (TagToTagClassElement) digester.peek();
316
317         /* Don't want to duplicate tag entries. Need JSF tags to be first though */
318         if (componentMap.get(elem.getTagName()) != null) {
319             if (log.isDebugEnabled()) {
320                 log.debug("Duplicate Tag " + elem.getTagName() +
321                           " not processed");
322             }
323             return;
324         }
325
326         componentMap.put(elem.getTagName(), elem.getTagClass());
327         if (log.isDebugEnabled()) {
328             log.debug(
329                     "Adding " + elem.getTagName() + ": " + elem.getTagClass());
330         }
331
332         if (faceletsTaglibXmlWriter != null) {
333             try {
334                 String JavaDoc tagName = elem.getTagName();
335                 String JavaDoc tagClassStr = elem.getTagClass();
336                 if (tagName != null && tagClassStr != null &&
337                     tagClassStr.indexOf("com.icesoft") >= 0) {
338                     // We have to have special cases for any tags that
339
// are not UIComponents, but are instead simply tags
340
// Map from JSP tag TabChangeListenerTag to
341
// Facelets TabChangeListenerHandler
342
if (tagName.equals("tabChangeListener")) {
343                         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(256);
344                         sb.append("\t<tag>\n\t\t<tag-name>");
345                         sb.append(tagName);
346                         sb.append("</tag-name>\n\t\t<handler-class>");
347                         sb.append(
348                                 "com.icesoft.faces.facelets.TabChangeListenerHandler");
349                         sb.append("</handler-class>\n\t</tag>\n");
350                         faceletsTaglibXmlWriter.write(sb.toString());
351                         System.out.print(sb.toString());
352                     } else {
353                         Class JavaDoc tagClass = Class.forName(tagClassStr);
354                         Object JavaDoc tagObj = tagClass.newInstance();
355                         java.lang.reflect.Method JavaDoc getComponentTypeMeth =
356                                 tagClass.getMethod("getComponentType",
357                                                    new Class JavaDoc[]{});
358                         String JavaDoc componentType =
359                                 (String JavaDoc) getComponentTypeMeth.invoke(
360                                         tagObj, new Object JavaDoc[]{});
361                         java.lang.reflect.Method JavaDoc getRendererTypeMeth =
362                                 tagClass.getMethod("getRendererType",
363                                                    new Class JavaDoc[]{});
364                         String JavaDoc rendererType =
365                                 (String JavaDoc) getRendererTypeMeth.invoke(
366                                         tagObj, new Object JavaDoc[]{});
367
368                         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(256);
369                         sb.append("\t<tag>\n\t\t<tag-name>");
370                         sb.append(tagName);
371                         sb.append(
372                                 "</tag-name>\n\t\t<component>\n\t\t\t<component-type>");
373                         sb.append(componentType);
374                         sb.append("</component-type>\n");
375                         if (rendererType != null) {
376                             sb.append("\t\t\t<renderer-type>");
377                             sb.append(rendererType);
378                             sb.append("</renderer-type>\n");
379                         }
380                         sb.append("\t\t\t<handler-class>com.icesoft.faces.component.facelets.IceComponentHandler</handler-class>\n");
381                         sb.append("\t\t</component>\n\t</tag>\n");
382                         faceletsTaglibXmlWriter.write(sb.toString());
383                         System.out.print(sb.toString());
384                     }
385                 }
386             }
387             catch (Exception JavaDoc e) {
388                 System.out.println(
389                         "Problem writing tag to Facelets taglib.xml. Tag name: " +
390                         elem.getTagName() +
391                         ", Tag class: " + elem.getTagClass() +
392                         ", Exception: " + e);
393             }
394         }
395     }
396 }
397
Popular Tags