View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  
19  package org.apache.struts2.jasper.tagplugins.jstl.core;
20  
21  import org.apache.struts2.jasper.compiler.tagplugin.TagPlugin;
22  import org.apache.struts2.jasper.compiler.tagplugin.TagPluginContext;
23  import org.apache.struts2.jasper.tagplugins.jstl.Util;
24  
25  public class Set implements TagPlugin {
26  
27      public void doTag(TagPluginContext ctxt) {
28  
29          //the flags to indicate whether the attributes have been specified
30          boolean hasValue = false, hasVar = false, hasScope = false,
31                  hasTarget = false;
32  
33          //the scope name
34          String strScope;
35          //the id of the scope
36          int iScope;
37  
38          //initialize the flags
39          hasValue = ctxt.isAttributeSpecified("value");
40          hasVar = ctxt.isAttributeSpecified("var");
41          hasScope = ctxt.isAttributeSpecified("scope");
42          hasTarget = ctxt.isAttributeSpecified("target");
43  
44          //the temp variables name
45          String resultName = ctxt.getTemporaryVariableName();
46          String targetName = ctxt.getTemporaryVariableName();
47          String propertyName = ctxt.getTemporaryVariableName();
48  
49          //initialize the "result" which will be assigned to the var or target.property
50          ctxt.generateJavaSource("Object " + resultName + " = null;");
51          if (hasValue) {
52              ctxt.generateJavaSource(resultName + " = ");
53              ctxt.generateAttribute("value");
54              ctxt.generateJavaSource(";");
55          } else {
56              ctxt.dontUseTagPlugin();
57              return;
58          }
59  
60          //initialize the strScope
61          if (hasScope) {
62              strScope = ctxt.getConstantAttribute("scope");
63          } else {
64              strScope = "page";
65          }
66  
67          //get the iScope according to the strScope
68          iScope = Util.getScope(strScope);
69  
70          //if the attribute var has been specified then assign the result to the var;
71          if (hasVar) {
72              String strVar = ctxt.getConstantAttribute("var");
73              ctxt.generateJavaSource("if(null != " + resultName + "){");
74              ctxt.generateJavaSource("    pageContext.setAttribute(\"" + strVar + "\"," + resultName + "," + iScope + ");");
75              ctxt.generateJavaSource("} else {");
76              if (hasScope) {
77                  ctxt.generateJavaSource("    pageContext.removeAttribute(\"" + strVar + "\"," + iScope + ");");
78              } else {
79                  ctxt.generateJavaSource("    pageContext.removeAttribute(\"" + strVar + "\");");
80              }
81              ctxt.generateJavaSource("}");
82  
83              //else assign the result to the target.property
84          } else if (hasTarget) {
85  
86              //generate the temp variable name
87              String pdName = ctxt.getTemporaryVariableName();
88              String successFlagName = ctxt.getTemporaryVariableName();
89              String index = ctxt.getTemporaryVariableName();
90              String methodName = ctxt.getTemporaryVariableName();
91  
92              //initialize the property
93              ctxt.generateJavaSource("String " + propertyName + " = null;");
94              ctxt.generateJavaSource("if(");
95              ctxt.generateAttribute("property");
96              ctxt.generateJavaSource(" != null){");
97              ctxt.generateJavaSource("    " + propertyName + " = (");
98              ctxt.generateAttribute("property");
99              ctxt.generateJavaSource(").toString();");
100             ctxt.generateJavaSource("}");
101 
102             //initialize the target
103             ctxt.generateJavaSource("Object " + targetName + " = ");
104             ctxt.generateAttribute("target");
105             ctxt.generateJavaSource(";");
106 
107             //the target is ok
108             ctxt.generateJavaSource("if(" + targetName + " != null){");
109 
110             //if the target is a map, then put the result into the map with the key property
111             ctxt.generateJavaSource("    if(" + targetName + " instanceof java.util.Map){");
112             ctxt.generateJavaSource("        if(null != " + resultName + "){");
113             ctxt.generateJavaSource("            ((java.util.Map) " + targetName + ").put(" + propertyName + "," + resultName + ");");
114             ctxt.generateJavaSource("        }else{");
115             ctxt.generateJavaSource("            ((java.util.Map) " + targetName + ").remove(" + propertyName + ");");
116             ctxt.generateJavaSource("        }");
117 
118             //else assign the result to the target.property
119             ctxt.generateJavaSource("    }else{");
120             ctxt.generateJavaSource("        try{");
121 
122             //get all the property of the target
123             ctxt.generateJavaSource("            java.beans.PropertyDescriptor " + pdName + "[] = java.beans.Introspector.getBeanInfo(" + targetName + ".getClass()).getPropertyDescriptors();");
124 
125             //the success flag is to imply whether the assign is successful
126             ctxt.generateJavaSource("            boolean " + successFlagName + " = false;");
127 
128             //find the right property
129             ctxt.generateJavaSource("            for(int " + index + "=0;" + index + "<" + pdName + ".length;" + index + "++){");
130             ctxt.generateJavaSource("                if(" + pdName + "[" + index + "].getName().equals(" + propertyName + ")){");
131 
132             //get the "set" method;
133             ctxt.generateJavaSource("                    java.lang.reflect.Method " + methodName + " = " + pdName + "[" + index + "].getWriteMethod();");
134             ctxt.generateJavaSource("                    if(null == " + methodName + "){");
135             ctxt.generateJavaSource("                        throw new JspException(\"No setter method in &lt;set&gt; for property \"+" + propertyName + ");");
136             ctxt.generateJavaSource("                    }");
137 
138             //invoke the method through the reflection
139             ctxt.generateJavaSource("                    if(" + resultName + " != null){");
140             ctxt.generateJavaSource("                        " + methodName + ".invoke(" + targetName + ", new Object[]{(" + methodName + ".getParameterTypes()[0]).cast(" + resultName + ")});");
141             ctxt.generateJavaSource("                    }else{");
142             ctxt.generateJavaSource("                        " + methodName + ".invoke(" + targetName + ", new Object[]{null});");
143             ctxt.generateJavaSource("                    }");
144             ctxt.generateJavaSource("                    " + successFlagName + " = true;");
145             ctxt.generateJavaSource("                }");
146             ctxt.generateJavaSource("            }");
147             ctxt.generateJavaSource("            if(!" + successFlagName + "){");
148             ctxt.generateJavaSource("                throw new JspException(\"Invalid property in &lt;set&gt;:\"+" + propertyName + ");");
149             ctxt.generateJavaSource("            }");
150             ctxt.generateJavaSource("        }");
151 
152             //catch the el exception and throw it as a JspException
153             ctxt.generateJavaSource("        catch (IllegalAccessException ex) {");
154             ctxt.generateJavaSource("            throw new JspException(ex);");
155             ctxt.generateJavaSource("        } catch (java.beans.IntrospectionException ex) {");
156             ctxt.generateJavaSource("            throw new JspException(ex);");
157             ctxt.generateJavaSource("        } catch (java.lang.reflect.InvocationTargetException ex) {");
158             ctxt.generateJavaSource("            throw new JspException(ex);");
159             ctxt.generateJavaSource("        }");
160             ctxt.generateJavaSource("    }");
161             ctxt.generateJavaSource("}else{");
162             ctxt.generateJavaSource("    throw new JspException();");
163             ctxt.generateJavaSource("}");
164         }
165     }
166 
167 }