KickJava   Java API By Example, From Geeks To Geeks.

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


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.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 import javax.faces.FacesException;
40 import javax.faces.component.UIComponent;
41 import javax.faces.component.UIViewRoot;
42 import javax.faces.context.FacesContext;
43 import javax.faces.webapp.UIComponentBodyTag;
44 import javax.faces.webapp.UIComponentTag;
45 import javax.servlet.jsp.JspException JavaDoc;
46 import javax.servlet.jsp.JspWriter JavaDoc;
47 import javax.servlet.jsp.PageContext JavaDoc;
48 import javax.servlet.jsp.tagext.Tag JavaDoc;
49 import java.io.IOException JavaDoc;
50 import java.io.InputStream JavaDoc;
51 import java.io.PrintWriter JavaDoc;
52 import java.io.Reader JavaDoc;
53 import java.util.HashSet JavaDoc;
54 import java.util.Iterator JavaDoc;
55 import java.util.Set JavaDoc;
56
57 /**
58  * This is the JSFX parser. It digests a JSFX file into a tag processing tree,
59  * and then executes the JSP tag processing lifecycle over that tree to produce
60  * the JSF component tree.
61  * <p/>
62  * A parser is initialized with a list of tags that it processes. This list of
63  * tags comes from a serialized version of a TagToComponentMap, which is passed
64  * in as an application initialization parameter. The parser should be created
65  * and initialized by the ViewHandler implementation for the application. Once
66  * it is initialized, the parser can parse a jsf jsp and initialize the
67  * component tree for the page. The parser relies on the apache Digester, and a
68  * set of rules created in the ComponentRuleSet class.
69  *
70  * @author Steve Maryka
71  */

72 public class Parser {
73     private static final Log log = LogFactory.getLog(Parser.class);
74     private JsfJspDigester digester;
75
76     public Parser(InputStream JavaDoc fis) throws IOException JavaDoc {
77         // Create digester and add rules;
78
digester = new JsfJspDigester();
79         digester.setNamespaceAware(true);
80         digester.setValidating(false);
81         digester.setUseContextClassLoader(false);
82         digester.setClassLoader(this.getClass().getClassLoader());
83
84         try {
85             TagToComponentMap map = TagToComponentMap.loadFrom(fis);
86             digester.addRuleSet(new ComponentRuleSet(map, ""));
87         } catch (ClassNotFoundException JavaDoc e) {
88             throw new IOException JavaDoc(e.getMessage());
89         }
90     }
91
92     /**
93      * The main parsing logic. Creates a Digester to parse page into a tag
94      * processing tree, and then executes the JSP lifecycle across that tree.
95      * The end result is a JSF component rooted with a UIViewRoot component.
96      *
97      * @param page The Reader for the page.
98      * @param context
99      * @throws java.io.IOException If stream IO fails.
100      * @throws org.xml.sax.SAXException If digester encounters invalid XML.
101      */

102     public void parse(Reader JavaDoc page, FacesContext context)
103             throws java.io.IOException JavaDoc, org.xml.sax.SAXException JavaDoc {
104         // Need a mock pageContext
105
StubPageContext pageContext = new StubPageContext();
106         //Get rid of old view root
107
StubHttpServletResponse response = new StubHttpServletResponse();
108         pageContext.initialize(null, null, response, null, false, 1024, false);
109         Set JavaDoc componentIds = new HashSet JavaDoc();
110
111         //placeholder tag and wire
112
XhtmlTag rootTag = new XhtmlTag();
113         rootTag.setTagName("ICEtag");
114         rootTag.setParent(null);
115         TagWire rootWire = new TagWire();
116         rootWire.setTag(rootTag);
117
118         synchronized (this) {
119             digester.clear();
120             digester.push(rootTag);
121             digester.push(rootWire);
122             digester.parse(page);
123         }
124
125         try {
126             String JavaDoc viewTagClassName = digester.getViewTagClassName();
127             if (null == viewTagClassName)
128                 throw new IllegalStateException JavaDoc(
129                         "ICEfaces parser unable to determine JSF implementation ViewTag class.");
130             Tag viewTag = (Tag) Class.forName(viewTagClassName).newInstance();
131             viewTag.setParent(null);
132             rootWire.setTag(viewTag);
133
134             executeJspLifecycle(rootWire, pageContext, context, componentIds);
135             pageContext.removeAttribute(
136                     "javax.faces.webapp.COMPONENT_TAG_STACK",
137                     PageContext.REQUEST_SCOPE);
138         } catch (Exception JavaDoc e) {
139             log.error("Failed to execute JSP lifecycle.", e);
140             throw new FacesException("Failed to execute JSP lifecycle.", e);
141         }
142     }
143
144     /**
145      * This member mimicks the JSP tag processing lifecyle across the tag
146      * processing tree to produce the JSF component tree.
147      *
148      * @param wire The tag's wire
149      * @param pageContext The page context
150      * @param facesContext The faces context
151      * @param componentIds
152      * @throws JspException
153      */

154     public void executeJspLifecycle(TagWire wire, PageContext JavaDoc pageContext,
155                                     FacesContext facesContext, Set JavaDoc componentIds)
156             throws JspException JavaDoc {
157         // Start of lifecycle;
158
boolean processingViewTag = false;
159         Tag tag = wire.getTag();
160         tag.setPageContext(pageContext);
161         // Start tag processing;
162
tag.doStartTag();
163
164         if (tag instanceof UIComponentTag) {
165             UIComponentTag compTag = (UIComponentTag) tag;
166             UIComponent myComponent = compTag.getComponentInstance();
167
168             if (myComponent != null) {
169                 if (myComponent instanceof UIViewRoot) {
170                     myComponent.setId("_view");
171                     processingViewTag = true;
172                 }
173
174                 String JavaDoc componentId = myComponent.getClientId(facesContext);
175                 if (componentIds.contains(componentId))
176                     throw new IllegalStateException JavaDoc(
177                             "Duplicate component ID : " + componentId);
178                 componentIds.add(componentId);
179             }
180         }
181
182         // Now process tag children;
183
Iterator JavaDoc children = wire.getChildren().iterator();
184         while (children.hasNext()) {
185             TagWire childWire = (TagWire) children.next();
186             executeJspLifecycle(childWire, pageContext, facesContext,
187                                 componentIds);
188         }
189         //Do tag body processing. This is not full-fledged body processing. It only calls the doAfterBody() member
190
if (!processingViewTag && tag instanceof UIComponentBodyTag) {
191             UIComponentBodyTag bodyTag = (UIComponentBodyTag) tag;
192             if (bodyTag.getBodyContent() == null) {
193                 //body content of custom tag should not be null, so create one in here to satisfy the
194
//checking in jsf 1.0 impl.
195
JspWriter JavaDoc jspWriter =
196                         new JspWriterImpl(new PrintWriter JavaDoc(System.out));
197                 BodyContentImpl imp = new BodyContentImpl(jspWriter);
198                 bodyTag.setBodyContent(imp);
199             }
200             bodyTag.doAfterBody();
201         }
202         // Do end tag processing;
203
tag.doEndTag();
204     }
205 }
206
Popular Tags