KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > java > JspSetProperty


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.jsp.java;
30
31 import com.caucho.jsp.JspParseException;
32 import com.caucho.util.BeanUtil;
33 import com.caucho.vfs.WriteStream;
34 import com.caucho.xml.QName;
35
36 import java.beans.BeanInfo JavaDoc;
37 import java.beans.Introspector JavaDoc;
38 import java.beans.PropertyDescriptor JavaDoc;
39 import java.beans.PropertyEditor JavaDoc;
40 import java.beans.PropertyEditorManager JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.lang.reflect.Method JavaDoc;
43 import java.util.logging.Level JavaDoc;
44
45 /**
46  * Represents a Java scriptlet.
47  */

48 public class JspSetProperty extends JspContainerNode {
49   private static final QName NAME = new QName("name");
50   private static final QName PROPERTY = new QName("property");
51   private static final QName PARAM = new QName("param");
52   private static final QName VALUE = new QName("value");
53   
54   private String JavaDoc _name;
55   private String JavaDoc _property;
56   private String JavaDoc _param;
57   
58   /**
59    * Adds an attribute.
60    */

61   public void addAttribute(QName name, String JavaDoc value)
62     throws JspParseException
63   {
64     if (NAME.equals(name))
65       _name = value;
66     else if (PROPERTY.equals(name))
67       _property = value;
68     else if (PARAM.equals(name))
69       _param = value;
70     else if (VALUE.equals(name))
71       super.addAttribute(name, value);
72     else
73       throw error(L.l("`{0}' is an invalid attribute in <jsp:setProperty>",
74                       name.getName()));
75   }
76
77   /**
78    * Generates the XML text representation for the tag validation.
79    *
80    * @param os write stream to the generated XML.
81    */

82   public void printXml(WriteStream os)
83     throws IOException JavaDoc
84   {
85     os.print("<jsp:setProperty name=\"" + _name + "\"");
86     os.print(" property=\"" + _property + "\"/>");
87   }
88
89   /**
90    * Generates the code for the scriptlet
91    *
92    * @param out the output writer for the generated java.
93    */

94   public void generate(JspJavaWriter out)
95     throws Exception JavaDoc
96   {
97     if (_name == null)
98       throw error(L.l("<jsp:setProperty> expects a `name' attribute."));
99
100     if (_property == null)
101       throw error(L.l("<jsp:setProperty> expects a `property' attribute."));
102
103     Object JavaDoc value = getAttribute("value");
104
105     if (value == null) {
106       generateSetParamProperty(out, _name, _property, _param);
107       return;
108     }
109
110     Class JavaDoc cl = _gen.getClass(_name);
111   
112     if (cl == null)
113       throw error(L.l("`{0}' is an unknown bean in <jsp:setProperty>. All beans must be declared in a <jsp:useBean>.", _name));
114
115     PropertyDescriptor JavaDoc []pds = Introspector.getBeanInfo(cl).getPropertyDescriptors();
116     for (int i = 0; i < pds.length; i++) {
117       if (pds[i].getName().equals(_property) &&
118           pds[i].getWriteMethod() != null &&
119           pds[i].getPropertyEditorClass() != null) {
120         generateSetParameter(out, _name, (String JavaDoc) value,
121                              pds[i].getWriteMethod(),
122                              pds[i].getPropertyEditorClass());
123         return;
124       }
125     }
126
127     Method JavaDoc setMethod = BeanUtil.getSetMethod(cl, _property);
128     if (setMethod == null)
129       throw error(L.l("bean `{0}' has no set property `{1}'",
130                       _name, _property));
131     
132     generateSetParameter(out, _name, value, setMethod, true,
133              "pageContext", false, null);
134   }
135
136   private void generateSetParamProperty(JspJavaWriter out,
137                                         String JavaDoc name, String JavaDoc property,
138                     String JavaDoc param)
139     throws Exception JavaDoc
140   {
141     boolean foundProp = property.equals("*");
142     Class JavaDoc cl = _gen.getClass(name);
143     if (cl == null)
144       throw error(L.l("{0} unknown variable `{1}'",
145                       "jsp:setProperty", name));
146
147     out.println("{");
148     out.pushDepth();
149     out.println("java.lang.String _jspParam;");
150     try {
151       Class JavaDoc beanClass = cl;
152       BeanInfo JavaDoc info = Introspector.getBeanInfo(beanClass);
153       Method JavaDoc []methods = beanClass.getMethods();
154       boolean hasParams = false;
155       for (int i = 0; i < methods.length; i++) {
156         Method JavaDoc setMethod = methods[i];
157
158         String JavaDoc methodName = setMethod.getName();
159
160         if (! methodName.startsWith("set"))
161           continue;
162         
163         String JavaDoc propName = methodNameToPropertyName(info, methodName);
164
165         if (propName == null)
166           continue;
167
168     if (! property.equals("*") && ! propName.equals(property))
169       continue;
170
171     Class JavaDoc []params = setMethod.getParameterTypes();
172     if (params.length != 1)
173       continue;
174     
175     if (hasBetterMethod(methods, setMethod))
176       continue;
177
178         Class JavaDoc paramType = params[0];
179     String JavaDoc type = paramType.getName();
180     String JavaDoc tail = null;
181         boolean isArray = false;
182
183         String JavaDoc p = param;
184         if (p == null)
185           p = propName;
186
187         if (! paramType.isArray())
188           tail = stringToValue(paramType, "_jspParam");
189
190         PropertyEditor JavaDoc editor;
191
192         if (tail != null) {
193         }
194         else if (paramType.isArray()) {
195           Class JavaDoc compType = paramType.getComponentType();
196           if (! hasParams)
197             out.println("java.lang.String []_jspParams;");
198           hasParams = true;
199       out.println("_jspParams = request.getParameterValues(\"" + p + "\");");
200           isArray = true;
201           
202           if (String JavaDoc.class.equals(compType) || Object JavaDoc.class.equals(compType)) {
203             foundProp = true;
204             out.println("if (_jspParams != null)");
205             out.println(" " + name + "." + methodName + "(_jspParams);");
206           }
207           else if ((tail = stringToValue(compType, "_jspParams[_jsp_i]")) != null) {
208             foundProp = true;
209             out.println("if (_jspParams != null) {");
210             out.println(" " + compType.getName() + " []_jsp_values = " +
211                     " new " + compType.getName() + "[_jspParams.length];");
212             out.println(" for (int _jsp_i = _jspParams.length - 1; _jsp_i >= 0; _jsp_i--)");
213             out.println(" _jsp_values[_jsp_i] = " + tail + ";");
214             out.println(" " + name + "." + methodName + "(_jsp_values);");
215             out.println("}");
216           }
217           else if ((editor = PropertyEditorManager.findEditor(paramType)) != null) {
218             foundProp = true;
219             out.println("if (_jspParams != null) {");
220             out.println(" " + compType.getName() + " []_jsp_values = " +
221                     " new " + compType.getName() + "[_jspParams.length];");
222             out.println(" java.beans.PropertyEditor _editor = "+
223                     " java.beans.PropertyEditorManager.findEditor(" +
224                     compType.getName() + ".class);");
225             out.println(" for (int _jsp_i = _jspParams.length - 1; _jsp_i >= 0; _jsp_i--) {");
226             out.println(" _editor.setAsText(_jspParams[_jsp_i]);");
227             
228             out.println(" _jsp_values[_jsp_i] = (" + compType.getName() + ") _editor.getValue();");
229             
230             out.println(" " + name + "." + methodName + "(_jsp_values);");
231             out.println("}");
232           }
233         }
234
235         if (isArray) {
236         }
237     else if (tail != null) {
238       out.println("_jspParam = request.getParameter(\"" + p + "\");");
239       out.println("if (_jspParam != null && ! _jspParam.equals(\"\"))");
240       out.println(" " + name + "." + methodName + "(" + tail + ");");
241       foundProp = true;
242     }
243         else if ((editor = PropertyEditorManager.findEditor(paramType)) != null) {
244       out.println("_jspParam = request.getParameter(\"" + p + "\");");
245       out.println("if (_jspParam != null && ! _jspParam.equals(\"\")) {");
246           out.println(" java.beans.PropertyEditor _editor = "+
247                   " java.beans.PropertyEditorManager.findEditor(" +
248                   paramType.getName() + ".class);");
249           out.println(" _editor.setAsText(_jspParam);");
250       out.println(" " + name + "." + methodName + "((" + paramType.getName() + ") _editor.getValue());");
251           out.println("}");
252           foundProp = true;
253         }
254       }
255     } catch (Exception JavaDoc e) {
256       log.log(Level.FINER, e.toString(), e);
257       
258       throw error(L.l("{0} can't find class `{1}'",
259                       "jsp:setProperty", name));
260     }
261     
262     if (! foundProp)
263       throw error(L.l("bean `{0}' has no property named `{1}'",
264                       name, property));
265       
266     out.popDepth();
267     out.println("}");
268   }
269
270   /**
271    * Returns true if there's a better method to set.
272    */

273   private boolean hasBetterMethod(Method JavaDoc []methods, Method JavaDoc setMethod)
274   {
275     Class JavaDoc []setParam = setMethod.getParameterTypes();
276
277     if (setParam[0].equals(String JavaDoc.class))
278       return false;
279     
280     for (int i = 0; i < methods.length; i++) {
281       Method JavaDoc method = methods[i];
282
283       if (method == setMethod)
284     continue;
285
286       if (! method.getName().equals(setMethod.getName()))
287     continue;
288
289       Class JavaDoc []param = method.getParameterTypes();
290       
291       if (param.length != 1)
292     continue;
293
294       if (param[0].equals(String JavaDoc.class))
295     return true;
296     }
297
298     return false;
299   }
300
301   private String JavaDoc methodNameToPropertyName(BeanInfo JavaDoc info, String JavaDoc methodName)
302   {
303     PropertyDescriptor JavaDoc []pds = info.getPropertyDescriptors();
304     
305     for (int i = 0; i < pds.length; i++) {
306       Method JavaDoc setter = pds[i].getWriteMethod();
307
308       if (setter != null && setter.getName().equals(methodName))
309         return pds[i].getName();
310     }
311
312     return BeanUtil.methodNameToPropertyName(methodName);
313   }
314 }
315
Popular Tags