package com.coderising.litestruts;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class Struts {
public static View runAction(String actionName, Map<String,String> parameters) {
// 0. 读取配置文件struts.xml
Action action = matchAction(parseXml("/com/coderising/litestruts/struts.xml"), actionName);
try {
// 1. 根据actionName找到相对应的class, 通过反射实例化(创建对象),
// 根据parameters中的数据,调用对象的setter方法
Class<?> clazz = Class.forName(action.getClassName());
Object instance = clazz.newInstance();
for (String key : parameters.keySet()){
try {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(key, clazz);
Method setMethod = propertyDescriptor.getWriteMethod();
setMethod.invoke(instance, parameters.get(key));
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
// 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
Method exectueMethod = null;
String result = null;
try {
exectueMethod = clazz.getMethod("execute");
result = (String)exectueMethod.invoke(instance);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// 3. 通过反射找到对象的所有getter方法(例如 getMessage),
// 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
// 放到View对象的parameters
Map<String, Object> hashMap = new HashMap<String, Object>();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields){
String name = field.getName();
try {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, clazz);
Method getMethod = propertyDescriptor.getReadMethod();
Object res = getMethod.invoke(instance);
hashMap.put(name, res);
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
// 4. 根据struts.xml中的 <result> 配置,以及execute的返回值, 确定哪一个jsp,
// 放到View对象的jsp字段中。
View view = new View();
view.setJsp((String)action.getResults().get(result));
view.setParameters(hashMap);
return view;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private static Element parseXml(String resourcePath){
InputStream resourceAsStream = Struts.class.getResourceAsStream(resourcePath);
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(resourceAsStream);
Element rootElement = document.getRootElement();
return rootElement;
} catch (DocumentException e) {
e.printStackTrace();
}
throw new RuntimeException("fail to parse xml");
}
private static Action matchAction(Element rootElement, String actionName){
List actions = rootElement.elements("action");
Iterator iterator = actions.iterator();
Action action = new Action();
while (iterator.hasNext()){
Element actionElement = (Element) iterator.next();
String nameAttributeValue = actionElement.attributeValue("name");
if (actionName.equals(nameAttributeValue)){
action.setName(nameAttributeValue);
action.setClassName(actionElement.attributeValue("class"));
List results = actionElement.elements("result");
Map<String, String> resultMap = new HashMap<String, String>();
Iterator it = results.iterator();
while (it.hasNext()){
Element resultElement = (Element)it.next();
resultMap.put(resultElement.attributeValue("name"), (String)resultElement.getData());
}
action.setResults(resultMap);
}
}
return action;
}
}