KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.apache.commons.digester.Digester;
37 import org.apache.commons.digester.Rule;
38 import org.apache.commons.digester.RuleSetBase;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.xml.sax.Attributes JavaDoc;
42 import org.xml.sax.helpers.AttributesImpl JavaDoc;
43
44 import javax.servlet.jsp.tagext.Tag JavaDoc;
45 import java.util.Enumeration JavaDoc;
46 import java.util.Hashtable JavaDoc;
47
48
49 /**
50  * This class provides a ruleset for the Apache Digester, that supports parsing
51  * of a JSFX page into a tree of JSP tag processing classes. This tree is then
52  * used in the parser to mimick the JSP lifecycle in order to produce the JSF
53  * component tree.
54  *
55  * @author Steve Maryka
56  */

57 public class ComponentRuleSet extends RuleSetBase {
58
59     /**
60      * The tag to tag processing class map.
61      */

62     private TagToComponentMap map;
63     private String JavaDoc viewTagClass;
64     private String JavaDoc ruleNamespace;
65     private static String JavaDoc TAG_NEST = "*/";
66     private static Class JavaDoc setPropertiesRuleClass = null;
67     private static boolean isJSF12 = false;
68
69     private static final Log log = LogFactory.getLog(ComponentRuleSet.class);
70
71     static {
72         try {
73             setPropertiesRuleClass =
74                     Class.forName(
75                             "org.apache.commons.digester.SetPropertiesRule");
76             setPropertiesRuleClass =
77                     Class.forName(
78                             "com.icesoft.faces.webapp.parser.ELSetPropertiesRule");
79             if (log.isDebugEnabled()) {
80                 log.debug(
81                         "ICEfaces using JSF 1.2 JSP tags.");
82             }
83             isJSF12 = true;
84         } catch (Throwable JavaDoc t) {
85             //many different throwables besides ClassNotFoundException
86
if (log.isDebugEnabled()) {
87                 log.debug(
88                         "No JSF 1.2 classes found. Running in JSF 1.1 environment");
89             }
90         }
91     }
92
93     /**
94      * Constructor
95      *
96      * @param mp The map from tags to tag processing classes
97      * @param namespaceURI
98      */

99     public ComponentRuleSet(TagToComponentMap mp, String JavaDoc namespaceURI) {
100         super();
101         map = mp;
102         ruleNamespace = namespaceURI;
103     }
104
105     /**
106      * Detect JSF 1.2 for special cases
107      *
108      * @return true if JSF 1.2 is being used
109      */

110     public static boolean isJSF12() {
111         return isJSF12;
112     }
113
114     /**
115      * Adds rules for each tag in the map.
116      *
117      * @param digester The digester to which rules are added.
118      */

119     public void addRuleInstances(Digester digester) {
120
121         Hashtable JavaDoc table = map.getTagToComponentMap();
122         Enumeration JavaDoc keys = table.keys();
123         TagRule tagRule = new TagRule();
124         XhtmlTagRule xhtmlTagRule = new XhtmlTagRule();
125
126         digester.setRuleNamespaceURI(ruleNamespace);
127
128         while (keys.hasMoreElements()) {
129             String JavaDoc key = (String JavaDoc) keys.nextElement();
130             String JavaDoc tagType = (String JavaDoc) table.get(key);
131
132             if (!key.equals("view")) {
133                 /* We don't want to create view object during parsing
134                    as it will be created as the root of the component tree
135                    prior to parsing */

136
137                 // Want to create tag object regardless of type;
138
digester.addObjectCreate(TAG_NEST + key, tagType);
139
140                 if (tagType.equals(XhtmlTag.class.getName())) {
141                     // Rules for Xhtml Tags;
142
digester.addObjectCreate(TAG_NEST + key,
143                                              "com.icesoft.faces.webapp.parser.TagWire");
144                     digester.addRule(TAG_NEST + key, xhtmlTagRule);
145                 } else {
146                     // Rules for JSF Tags;
147
try {
148                         digester.addRule(TAG_NEST + key,
149                                          (Rule) setPropertiesRuleClass
150                                                  .newInstance());
151                     } catch (Exception JavaDoc e) {
152                         if (log.isDebugEnabled()) {
153                             log.debug(e.getMessage(), e);
154                         }
155                     }
156                     digester.addObjectCreate(TAG_NEST + key,
157                                              "com.icesoft.faces.webapp.parser.TagWire");
158                     digester.addRule(TAG_NEST + key, tagRule);
159                 }
160             } else {
161                 // Capture the view tag class;
162
((JsfJspDigester) digester).setViewTagClassName(tagType);
163                 viewTagClass = tagType;
164             }
165         }
166     }
167
168
169     public String JavaDoc getViewTagClass() {
170         return viewTagClass;
171     }
172 }
173
174 /**
175  * Contains base functionality for all rules.
176  */

177 abstract class BaseRule extends Rule {
178
179     /**
180      * Constructor
181      */

182     public BaseRule() {
183         super();
184     }
185
186     /**
187      * Body processing for the rule. The body text for this tag gets trimmed
188      * up, and an outputTextTag is created to hold the body text.
189      *
190      * @param namespace Namespace provided by digester.
191      * @param name Name provided by digester.
192      * @param text The body text.
193      */

194     public void body(String JavaDoc namespace, String JavaDoc name, String JavaDoc text) {
195
196         String JavaDoc bodyText = text.trim();
197         if (bodyText.length() > 0) {
198             TagWire wire = (TagWire) digester.peek();
199             Tag JavaDoc child = (Tag JavaDoc) digester.peek(1);
200             IceOutputTextTag bodyTextTag = new IceOutputTextTag();
201             TagWire newWire = new TagWire();
202             bodyTextTag.setValue(bodyText);
203             wireUpTheTag((Tag JavaDoc) bodyTextTag, child, newWire, wire);
204         }
205     }
206
207     /**
208      * Because Tag processing classes themselves don't support a tree structure,
209      * a wiring class is used to hold the tree together. This member wires up
210      * the tree appropriately.
211      *
212      * @param child The child Tag
213      * @param parent The parent Tag
214      * @param childWire The child Wire
215      * @param parentWire The parent Wire
216      */

217     protected void wireUpTheTag(Tag JavaDoc child, Tag JavaDoc parent,
218                                 TagWire childWire, TagWire parentWire) {
219
220         child.setParent(parent);
221         childWire.setTag(child);
222         parentWire.addChild(childWire);
223     }
224
225     /**
226      * This function peeks into the digester to see if there is body text
227      * assiciated with the parent. If there is, an Output Text tag is created
228      * to hold that body text.
229      *
230      * @param parent The parent Tag.
231      * @param parentWire The parent Wire.
232      */

233     protected void dealWithPreceedingBodyText(Tag JavaDoc parent, TagWire parentWire) {
234         /* This function peeks into the digester to see if there is body text
235            associated with the parent. If there is, an OutputText component is
236            created to hold that body text */

237
238         // In this version we create an IceOutputTextTag and wire it in;
239

240         String JavaDoc bodyText = ((JsfJspDigester) digester).stealParentBodyText();
241         if (bodyText != null) {
242             IceOutputTextTag bodyTextTag = new IceOutputTextTag();
243             TagWire wire = new TagWire();
244             bodyTextTag.setValue(bodyText);
245             wireUpTheTag((Tag JavaDoc) bodyTextTag, parent, wire, parentWire);
246         }
247     }
248 }
249
250 /**
251  * This class provides the rule for processing JSF tags. The tag attributes are
252  * saved and the tag is wired into the tag processing tree.
253  */

254 final class TagRule extends BaseRule {
255
256     /**
257      * Constructor.
258      */

259     public TagRule() {
260         super();
261     }
262
263     /**
264      * The begin processing for the rule. Saves attributes, deals with parent
265      * body text, and wires up tag processing tree.
266      *
267      * @param attributes Attributes for the Tag.
268      * @throws Exception No exception is thrown.
269      */

270     public void begin(Attributes JavaDoc attributes) throws Exception JavaDoc {
271
272         // Get all the important bits off the digester stack;
273
TagWire wire = (TagWire) digester.peek();
274         Tag JavaDoc child = (Tag JavaDoc) digester.peek(1);
275         TagWire parentWire = (TagWire) digester.peek(2);
276         Tag JavaDoc parent = (Tag JavaDoc) digester.peek(3);
277
278         Attributes JavaDoc cloned = clone(attributes);
279         wire.setAttributes(cloned);
280
281         // Deal with preceeding body text;
282
dealWithPreceedingBodyText(parent, parentWire);
283
284         // Wire up the tree;
285
wireUpTheTag(child, parent, wire, parentWire);
286     }
287
288     /**
289      * Create clone of attributes.
290      *
291      * @param attributes Attributes to clone.
292      * @return Cloned attributes.
293      */

294     private Attributes JavaDoc clone(Attributes JavaDoc attributes) {
295         Attributes JavaDoc clone = new AttributesImpl JavaDoc(attributes);
296         for (int i = 0; i < clone.getLength(); i++) {
297             String JavaDoc name = attributes.getQName(i);
298             String JavaDoc value = attributes.getValue(name);
299             ((AttributesImpl JavaDoc) clone).setLocalName(i, name);
300             ((AttributesImpl JavaDoc) clone).setValue(i, value);
301         }
302         return clone;
303     }
304 }
305
306 /**
307  * A rule for processing Xhtml Tags. Need to save the tag name for future
308  * processing.
309  */

310 final class XhtmlTagRule extends BaseRule {
311
312     /**
313      * Constructor.
314      */

315     public XhtmlTagRule() {
316         super();
317     }
318
319     /**
320      * Begin processing for the rule. Saves attributes, saves tag name, deals
321      * with parent's preceeding body text, and wires up the tag processing
322      * tree.
323      *
324      * @param attributes Attributes for the tag.
325      * @throws Exception No exception is thrown.
326      */

327     public void begin(Attributes JavaDoc attributes) throws Exception JavaDoc {
328
329         // Get all the important bits off the digester stack;
330
TagWire wire = (TagWire) digester.peek();
331         XhtmlTag child = (XhtmlTag) digester.peek(1);
332         TagWire parentWire = (TagWire) digester.peek(2);
333         Tag JavaDoc parent = (Tag JavaDoc) digester.peek(3);
334
335         // Save attributes;
336
child.setAttributes((Attributes JavaDoc) (new AttributesImpl JavaDoc(attributes)));
337
338         // Save the tag;
339
child.setTagName(new String JavaDoc(digester.getCurrentElementName()));
340
341         // Deal with preceeding body text;
342
dealWithPreceedingBodyText(parent, parentWire);
343
344         // Wire up the tree;
345
wireUpTheTag((Tag JavaDoc) child, parent, wire, parentWire);
346     }
347 }
348
Popular Tags