package com.coding.litestruts;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Struts {
private static Struts instance = new Struts();
@SuppressWarnings("unchecked")
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字段中。
*/
Map<String, Action> actions = instance.parseXml();
Action action = actions.get(actionName);
View view = new View();
view.setParameters(new HashMap<>());
if (action != null) {
try {
Class clazz = Class.forName(action.getClazz());
Object actionObj = clazz.newInstance();
for (String s : parameters.keySet()) {
Method method = clazz.getDeclaredMethod("set" + captureName(s), String.class);
method.invoke(actionObj, parameters.get(s));
}
Method method = clazz.getDeclaredMethod("execute");
Object o = method.invoke(actionObj);
if (o != null) {
String flag = o.toString();
for (Result res : action.getResultList()) {
if (flag.equals(res.getName())) {
view.setJsp(res.getPage());
}
}
}
Method[] methods = clazz.getDeclaredMethods();
for (Method m : methods) {
if (m.getName().startsWith("get")) {
view.getParameters().put(m.getName().substring(3).toLowerCase(), m.invoke(actionObj));
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
return view;
}
private Map<String, Action> parseXml() {
Map<String, Action> actionMap = new HashMap<>();
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser pullParser = factory.newPullParser();
pullParser.setInput(getClass().getClassLoader().getResourceAsStream("struts.xml"), null);
int event = pullParser.getEventType();
String tag = null;
Action action = null;
Result result = null;
while (event != XmlPullParser.END_DOCUMENT) {
switch (event) {
case XmlPullParser.TEXT:
String s = pullParser.getText();
if (result != null) {
result.setPage(s);
}
break;
case XmlPullParser.START_TAG:
tag = pullParser.getName();
if ("action".equals(tag)) {
String name = pullParser.getAttributeValue(null, "name");
String clazz = pullParser.getAttributeValue(null, "class");
action = new Action(name, clazz);
actionMap.put(name, action);
}
else if ("result".equals(tag)) {
String name = pullParser.getAttributeValue(null, "name");
result = new Result(name, "");
if (action != null) {
action.addResultList(result);
}
}
break;
case XmlPullParser.END_TAG:
if ("action".equals(tag)) {
action = null;
}
else if ("result".equals(tag)) {
result = null;
}
tag = null;
break;
}
event = pullParser.next();
}
}
catch (Exception e) {
e.printStackTrace();
}
return actionMap;
}
private static String captureName(String name) {
char[] cs = name.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
}