1 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 ; 37 import java.beans.Introspector ; 38 import java.beans.PropertyDescriptor ; 39 import java.beans.PropertyEditor ; 40 import java.beans.PropertyEditorManager ; 41 import java.io.IOException ; 42 import java.lang.reflect.Method ; 43 import java.util.logging.Level ; 44 45 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 _name; 55 private String _property; 56 private String _param; 57 58 61 public void addAttribute(QName name, String 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 82 public void printXml(WriteStream os) 83 throws IOException 84 { 85 os.print("<jsp:setProperty name=\"" + _name + "\""); 86 os.print(" property=\"" + _property + "\"/>"); 87 } 88 89 94 public void generate(JspJavaWriter out) 95 throws Exception 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 value = getAttribute("value"); 104 105 if (value == null) { 106 generateSetParamProperty(out, _name, _property, _param); 107 return; 108 } 109 110 Class 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 []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 ) value, 121 pds[i].getWriteMethod(), 122 pds[i].getPropertyEditorClass()); 123 return; 124 } 125 } 126 127 Method 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 name, String property, 138 String param) 139 throws Exception 140 { 141 boolean foundProp = property.equals("*"); 142 Class 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 beanClass = cl; 152 BeanInfo info = Introspector.getBeanInfo(beanClass); 153 Method []methods = beanClass.getMethods(); 154 boolean hasParams = false; 155 for (int i = 0; i < methods.length; i++) { 156 Method setMethod = methods[i]; 157 158 String methodName = setMethod.getName(); 159 160 if (! methodName.startsWith("set")) 161 continue; 162 163 String propName = methodNameToPropertyName(info, methodName); 164 165 if (propName == null) 166 continue; 167 168 if (! property.equals("*") && ! propName.equals(property)) 169 continue; 170 171 Class []params = setMethod.getParameterTypes(); 172 if (params.length != 1) 173 continue; 174 175 if (hasBetterMethod(methods, setMethod)) 176 continue; 177 178 Class paramType = params[0]; 179 String type = paramType.getName(); 180 String tail = null; 181 boolean isArray = false; 182 183 String p = param; 184 if (p == null) 185 p = propName; 186 187 if (! paramType.isArray()) 188 tail = stringToValue(paramType, "_jspParam"); 189 190 PropertyEditor editor; 191 192 if (tail != null) { 193 } 194 else if (paramType.isArray()) { 195 Class 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 .class.equals(compType) || Object .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 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 273 private boolean hasBetterMethod(Method []methods, Method setMethod) 274 { 275 Class []setParam = setMethod.getParameterTypes(); 276 277 if (setParam[0].equals(String .class)) 278 return false; 279 280 for (int i = 0; i < methods.length; i++) { 281 Method method = methods[i]; 282 283 if (method == setMethod) 284 continue; 285 286 if (! method.getName().equals(setMethod.getName())) 287 continue; 288 289 Class []param = method.getParameterTypes(); 290 291 if (param.length != 1) 292 continue; 293 294 if (param[0].equals(String .class)) 295 return true; 296 } 297 298 return false; 299 } 300 301 private String methodNameToPropertyName(BeanInfo info, String methodName) 302 { 303 PropertyDescriptor []pds = info.getPropertyDescriptors(); 304 305 for (int i = 0; i < pds.length; i++) { 306 Method 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 |