/* | |
* Licensed to the Apache Software Foundation (ASF) under one or more | |
* contributor license agreements. See the NOTICE file distributed with | |
* this work for additional information regarding copyright ownership. | |
* The ASF licenses this file to You under the Apache License, Version 2.0 | |
* (the "License"); you may not use this file except in compliance with | |
* the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.apache.struts2.jasper.tagplugins.jstl.core; | |
import org.apache.struts2.jasper.compiler.tagplugin.TagPlugin; | |
import org.apache.struts2.jasper.compiler.tagplugin.TagPluginContext; | |
import org.apache.struts2.jasper.tagplugins.jstl.Util; | |
public class Set implements TagPlugin { | |
public void doTag(TagPluginContext ctxt) { | |
//the flags to indicate whether the attributes have been specified | |
boolean hasValue = false, hasVar = false, hasScope = false, | |
hasTarget = false; | |
//the scope name | |
String strScope; | |
//the id of the scope | |
int iScope; | |
//initialize the flags | |
hasValue = ctxt.isAttributeSpecified("value"); | |
hasVar = ctxt.isAttributeSpecified("var"); | |
hasScope = ctxt.isAttributeSpecified("scope"); | |
hasTarget = ctxt.isAttributeSpecified("target"); | |
//the temp variables name | |
String resultName = ctxt.getTemporaryVariableName(); | |
String targetName = ctxt.getTemporaryVariableName(); | |
String propertyName = ctxt.getTemporaryVariableName(); | |
//initialize the "result" which will be assigned to the var or target.property | |
ctxt.generateJavaSource("Object " + resultName + " = null;"); | |
if(hasValue){ | |
ctxt.generateJavaSource(resultName + " = "); | |
ctxt.generateAttribute("value"); | |
ctxt.generateJavaSource(";"); | |
}else{ | |
ctxt.dontUseTagPlugin(); | |
return; | |
} | |
//initialize the strScope | |
if(hasScope){ | |
strScope = ctxt.getConstantAttribute("scope"); | |
}else{ | |
strScope = "page"; | |
} | |
//get the iScope according to the strScope | |
iScope = Util.getScope(strScope); | |
//if the attribute var has been specified then assign the result to the var; | |
if(hasVar){ | |
String strVar = ctxt.getConstantAttribute("var"); | |
ctxt.generateJavaSource("if(null != " + resultName + "){"); | |
ctxt.generateJavaSource(" pageContext.setAttribute(\"" + strVar + "\"," + resultName + "," + iScope + ");"); | |
ctxt.generateJavaSource("} else {"); | |
if(hasScope){ | |
ctxt.generateJavaSource(" pageContext.removeAttribute(\"" + strVar + "\"," + iScope + ");"); | |
}else{ | |
ctxt.generateJavaSource(" pageContext.removeAttribute(\"" + strVar + "\");"); | |
} | |
ctxt.generateJavaSource("}"); | |
//else assign the result to the target.property | |
}else if(hasTarget){ | |
//generate the temp variable name | |
String pdName = ctxt.getTemporaryVariableName(); | |
String successFlagName = ctxt.getTemporaryVariableName(); | |
String index = ctxt.getTemporaryVariableName(); | |
String methodName = ctxt.getTemporaryVariableName(); | |
//initialize the property | |
ctxt.generateJavaSource("String " + propertyName + " = null;"); | |
ctxt.generateJavaSource("if("); | |
ctxt.generateAttribute("property"); | |
ctxt.generateJavaSource(" != null){"); | |
ctxt.generateJavaSource(" " + propertyName + " = ("); | |
ctxt.generateAttribute("property"); | |
ctxt.generateJavaSource(").toString();"); | |
ctxt.generateJavaSource("}"); | |
//initialize the target | |
ctxt.generateJavaSource("Object " + targetName + " = "); | |
ctxt.generateAttribute("target"); | |
ctxt.generateJavaSource(";"); | |
//the target is ok | |
ctxt.generateJavaSource("if(" + targetName + " != null){"); | |
//if the target is a map, then put the result into the map with the key property | |
ctxt.generateJavaSource(" if(" + targetName + " instanceof java.util.Map){"); | |
ctxt.generateJavaSource(" if(null != " + resultName + "){"); | |
ctxt.generateJavaSource(" ((java.util.Map) " + targetName + ").put(" + propertyName + "," + resultName + ");"); | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" ((java.util.Map) " + targetName + ").remove(" + propertyName + ");"); | |
ctxt.generateJavaSource(" }"); | |
//else assign the result to the target.property | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" try{"); | |
//get all the property of the target | |
ctxt.generateJavaSource(" java.beans.PropertyDescriptor " + pdName + "[] = java.beans.Introspector.getBeanInfo(" + targetName + ".getClass()).getPropertyDescriptors();"); | |
//the success flag is to imply whether the assign is successful | |
ctxt.generateJavaSource(" boolean " + successFlagName + " = false;"); | |
//find the right property | |
ctxt.generateJavaSource(" for(int " + index + "=0;" + index + "<" + pdName + ".length;" + index + "++){"); | |
ctxt.generateJavaSource(" if(" + pdName + "[" + index + "].getName().equals(" + propertyName + ")){"); | |
//get the "set" method; | |
ctxt.generateJavaSource(" java.lang.reflect.Method " + methodName + " = " + pdName + "[" + index + "].getWriteMethod();"); | |
ctxt.generateJavaSource(" if(null == " + methodName + "){"); | |
ctxt.generateJavaSource(" throw new JspException(\"No setter method in <set> for property \"+" + propertyName + ");"); | |
ctxt.generateJavaSource(" }"); | |
//invoke the method through the reflection | |
ctxt.generateJavaSource(" if(" + resultName + " != null){"); | |
ctxt.generateJavaSource(" " + methodName + ".invoke(" + targetName + ", new Object[]{(" + methodName + ".getParameterTypes()[0]).cast(" + resultName + ")});"); | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" " + methodName + ".invoke(" + targetName + ", new Object[]{null});"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" " + successFlagName + " = true;"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" if(!" + successFlagName + "){"); | |
ctxt.generateJavaSource(" throw new JspException(\"Invalid property in <set>:\"+" + propertyName + ");"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
//catch the el exception and throw it as a JspException | |
ctxt.generateJavaSource(" catch (IllegalAccessException ex) {"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" } catch (java.beans.IntrospectionException ex) {"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" } catch (java.lang.reflect.InvocationTargetException ex) {"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource("}else{"); | |
ctxt.generateJavaSource(" throw new JspException();"); | |
ctxt.generateJavaSource("}"); | |
} | |
} | |
} |