//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("}");
}