package org.coding.two;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Struts {
private static final String METHOD_SET = "set";
private static final String METHOD_GET = "get";
private static Map<String, ActionBeanDefinition> actionDefinitionMap = new HashMap<String, ActionBeanDefinition>();
static {
//0
parseXml();
}
@SuppressWarnings("unchecked")
public static void parseXml(){
SAXReader reader = new SAXReader();
Document document = null;
String path = Struts.class.getClassLoader().getResource("").getPath();
try {
document = reader.read(path + ActionBeanDefinition.DEFAULT_RESOURCE);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
Element struts = document.getRootElement();
List<Element> actions = struts.elements(ActionBeanDefinition.TAG_ACTION);
for (Element element : actions) {
String name = element.attributeValue(ActionBeanDefinition.TAG_ACTION_ATTR_NAME);
String className = element.attributeValue(ActionBeanDefinition.TAG_ACTION_ATTR_CLASS);
List<Element> results = element.elements(ActionBeanDefinition.TAG_RESULT);
ActionBeanDefinition beanDefinition = new ActionBeanDefinition(name, className);
for (Element result : results) {
beanDefinition.putResult(result.attributeValue(ActionBeanDefinition.TAG_RESULT_ATTR_NAME), result.getTextTrim());
}
actionDefinitionMap.put(name, beanDefinition);
}
// System.out.println(actionDefinitionMap);
}
public static View runAction(String actionName, Map<String,String> parameters) {
/*
0. 读取配置文件struts.xml
1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
("name"="test" , "password"="1234") ,
那就应该调用 setName和setPassword方法
2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
3. 通过反射找到对象的所有getter方法(例如 getMessage),
通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
放到View对象的parameters
4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp,
放到View对象的jsp字段中。
*/
if(!actionDefinitionMap.containsKey(actionName)) {
throw new RuntimeException("does not exist action : " + actionName);
}
ActionBeanDefinition beanDefinition = actionDefinitionMap.get(actionName);
try {
//1
Class<?> bean = Class.forName(beanDefinition.getClassName());
Object instance = bean.newInstance();
Set<String> keySet = parameters.keySet();
for (String key : keySet) {
Method method = bean.getMethod(getSetMethodName(key), new Class[]{String.class});
method.invoke(instance, parameters.get(key));
}
// System.out.println(instance);
//2
Method method = bean.getMethod("execute");
Object result = method.invoke(instance);
//3
Method[] methods = bean.getMethods();
Map<String, Object> parameterss = new HashMap<String, Object>();
for (Method m : methods) {
String methodName = m.getName();
if(methodName.contains(METHOD_GET)) {
String para = getPropNameByMethoedName(methodName);
parameterss.put(para, m.invoke(instance));
}
}
View view = new View();
view.setParameters(parameterss);
// System.out.println(parameterss);
//4
String jsp = actionDefinitionMap.get(actionName).getResultMap().get(result);
view.setJsp(jsp);
return view;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private static String getPropNameByMethoedName(String methodName) {
String prop = null;
if(methodName.contains(METHOD_GET)){
String s = methodName.substring(3);
prop = s.substring(0, 1).toLowerCase() + s.substring(1);
}
return prop;
}
private static String getSetMethodName(String para) {
return METHOD_SET + para.substring(0, 1).toUpperCase() + para.substring(1);
}
}