001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jsp.java;
031:
032: import com.caucho.jsp.*;
033: import com.caucho.config.*;
034: import com.caucho.util.*;
035: import com.caucho.xml.QName;
036: import com.caucho.vfs.*;
037:
038: import javax.servlet.jsp.tagext.*;
039: import javax.faces.component.*;
040: import javax.faces.event.*;
041: import javax.el.*;
042: import java.lang.reflect.*;
043: import java.util.*;
044: import java.io.*;
045:
046: /**
047: * Represents f:view
048: */
049: public class JsfViewRoot extends JsfNode {
050: private JspNode _next;
051:
052: private ArrayList<Attr> _attrList = new ArrayList<Attr>();
053:
054: /**
055: * Adds an attribute.
056: */
057: public void addAttribute(QName qName, String value)
058: throws JspParseException {
059: String name = qName.getName();
060:
061: if (name.equals("afterPhase"))
062: name = "afterPhaseListener";
063: else if (name.equals("beforePhase"))
064: name = "beforePhaseListener";
065:
066: String setterName = ("set"
067: + Character.toUpperCase(name.charAt(0)) + name
068: .substring(1));
069:
070: Method method = findSetter(UIViewRoot.class, setterName);
071:
072: if (method != null) {
073: _attrList.add(new Attr(name, method, value));
074: } else {
075: super .addAttribute(qName, value);
076: }
077: }
078:
079: /**
080: * Adds a JspAttribute attribute.
081: *
082: * @param name the name of the attribute.
083: * @param value the value of the attribute.
084: */
085: public void addAttribute(QName qName, JspAttribute value)
086: throws JspParseException {
087: String name = qName.getName();
088:
089: if (name.equals("afterPhase"))
090: name = "afterPhaseListener";
091: else if (name.equals("beforePhase"))
092: name = "beforePhaseListener";
093:
094: if (value.isStatic()) {
095: addAttribute(qName, value.getStaticText().trim());
096: } else {
097: String setterName = ("set"
098: + Character.toUpperCase(name.charAt(0)) + name
099: .substring(1));
100:
101: Method method = findSetter(UIViewRoot.class, setterName);
102:
103: if (method != null) {
104: _attrList.add(new Attr(name, method, value));
105: } else {
106: super .addAttribute(qName, value);
107: }
108: }
109: }
110:
111: /**
112: * Generates the XML text representation for the tag validation.
113: *
114: * @param os write stream to the generated XML.
115: */
116: public void printXml(WriteStream os) throws IOException {
117: if (_next != null)
118: _next.printXml(os);
119: }
120:
121: /**
122: * Returns the variable containing the jsf parent
123: */
124: @Override
125: public String getJsfVar() {
126: return _var;
127: }
128:
129: /**
130: * Returns the variable containing the jsf body
131: */
132: @Override
133: public String getJsfBodyVar() {
134: return _bodyVar;
135: }
136:
137: /**
138: * generates prologue data.
139: */
140: @Override
141: public void generatePrologue(JspJavaWriter out) throws Exception {
142: super .generatePrologue(out);
143:
144: _var = "_jsp_comp" + _gen.uniqueId();
145:
146: _bodyVar = "_jsp_body" + _gen.uniqueId();
147:
148: out
149: .println("com.caucho.jsp.BodyContentImpl "
150: + _bodyVar
151: + " = (com.caucho.jsp.BodyContentImpl) pageContext.pushBody();");
152: out.println("out = " + _bodyVar + ";");
153:
154: out.println("javax.faces.component.UIViewRoot " + _var
155: + " = null;");
156: }
157:
158: /**
159: * Generates the code for a custom tag.
160: *
161: * @param out the output writer for the generated java.
162: */
163: public void generate(JspJavaWriter out) throws Exception {
164: String className = "javax.faces.component.UIViewRoot";
165:
166: long digest = calculateDigest();
167: // XXX: eventually use pre-allocated long
168:
169: out.print(_var + " = ");
170: out
171: .print("com.caucho.jsp.jsf.JsfTagUtil.findRoot(_jsp_faces_context, request, "
172: + digest + "L);");
173:
174: if (isJsfParentRequired())
175: out.println("request.setAttribute(\"caucho.jsf.parent\""
176: + ", new com.caucho.jsp.jsf.JsfComponentTag("
177: + _var + ", true, " + _bodyVar + "));");
178:
179: for (int i = 0; i < _attrList.size(); i++) {
180: Attr attr = (Attr) _attrList.get(i);
181:
182: Method method = attr.getMethod();
183: Class type = null;
184:
185: if (method != null)
186: type = method.getParameterTypes()[0];
187:
188: JspAttribute jspAttr = attr.getAttr();
189: String value = attr.getValue();
190:
191: if (jspAttr != null) {
192: generateSetParameter(out, _var, jspAttr, method, true,
193: null, false, null);
194: } else if ((value.indexOf("#{") >= 0
195: && !ValueExpression.class.isAssignableFrom(type) && !MethodExpression.class
196: .isAssignableFrom(type))) {
197: out.print(_var + ".setValueExpression(\""
198: + attr.getName() + "\", ");
199:
200: String exprVar = "_caucho_value_expr_"
201: + _gen.addValueExpr(value, type.getName());
202:
203: out.println(exprVar + ");");
204: } else if (attr.getName().equals("beforePhaseListener")
205: || attr.getName().equals("afterPhaseListener")) {
206: String exprVar = "_caucho_method_expr_"
207: + _gen
208: .addMethodExpr(value,
209: "void foo(javax.faces.event.PhaseEvent)");
210:
211: out.println(_var + "." + method.getName() + "("
212: + exprVar + ");");
213: } else {
214: out.print(_var + "." + method.getName() + "(");
215:
216: out.print(generateParameterValue(type, value, true,
217: null, false));
218:
219: out.println(");");
220: }
221: }
222:
223: out.println("response.setLocale(" + _var + ".getLocale());");
224:
225: generateChildren(out);
226:
227: out
228: .println("com.caucho.jsp.jsf.JsfTagUtil.afterRoot(_jsp_faces_context, request, response);");
229:
230: if (_bodyVar != null) {
231: out.println("out = pageContext.popBody();");
232: out.println("pageContext.releaseBody(" + _bodyVar + ");");
233: }
234: }
235:
236: private long calculateDigest() {
237: long digest = 0;
238:
239: for (PersistentDependency pDepend : _gen.getDependList()) {
240: if (pDepend instanceof Depend) {
241: Depend depend = (Depend) pDepend;
242:
243: digest = 65521 * digest + depend.getDigest();
244: }
245: }
246:
247: return digest;
248: }
249: }
|