package com.coderising.litestruts;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.coding.basic.Iterator;
public class Struts {
private static String url = "C:\\Users\\alioc\\workspace\\Homework\\src\\com\\coderising\\litestruts\\struts.xml";
private static int SET = 1;
private static int GET = -1;
/*
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字段中。
*/
public static View runAction(String actionName, Map<String,String> parameters) {
HashMap<String, HashMap<String, String>> xml = parseStrutsXml(url);
HashMap<String, String> login = xml.get(actionName);
String loginClassName = login.get("class");
System.out.println(loginClassName);
ClassLoader loader = ClassLoader.getSystemClassLoader();
try {
Class<?> clazz = Class.forName(loginClassName);
Object obj = clazz.newInstance();
java.util.Iterator<String> iter = parameters.keySet().iterator();
while(iter.hasNext()){
String key = iter.next();
String val = parameters.get(key);
Method method = clazz.getDeclaredMethod(getEncapsulateMethodName(SET, key), String.class);
method.invoke(obj, val);
}
Method executeMethod = clazz.getDeclaredMethod("execute");
String logResult = (String) executeMethod.invoke(obj);
if("success".equals(logResult)){
View view = new View();
view.setJsp(login.get("success"));
Method getMessageMethod = clazz.getDeclaredMethod(getEncapsulateMethodName(GET, "message"));
String message = (String) getMessageMethod.invoke(obj);
// Field messageField = clazz.getDeclaredField("message");
// messageField.setAccessible(true);
// String message = (String) messageField.get(clazz);
Map map = new HashMap<>();
map.put("message", message);
view.setParameters(map);
return view;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static HashMap<String, HashMap<String, String>> parseStrutsXml(String url){
HashMap<String, HashMap<String, String>> result = new HashMap<String, HashMap<String, String>>();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = dbf.newDocumentBuilder();
InputStream is = new FileInputStream(url);
Document doc = builder.parse(is);
Element root = doc.getDocumentElement();
NodeList actionNodes = root.getChildNodes();
for(int i = 0; i < actionNodes.getLength(); i ++){
Node actionNode = actionNodes.item(i);
if(actionNode.getNodeType() == Node.ELEMENT_NODE){
if(actionNode.getAttributes() != null){
HashMap<String, String> action = new HashMap<>();
String name = actionNode.getAttributes().getNamedItem("name").getNodeValue();
String clazz = actionNode.getAttributes().getNamedItem("class").getNodeValue();
result.put(name, action);
action.put("class", clazz);
NodeList resultNodes = actionNode.getChildNodes();
for(int j = 0; j < resultNodes.getLength(); j ++){
Node resultNode = resultNodes.item(j);
if(resultNode.getNodeType() == Node.ELEMENT_NODE){
String fieldName = resultNode.getAttributes().getNamedItem("name").getNodeValue();
String fieldValue = resultNode.getTextContent();
action.put(fieldName, fieldValue);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("--------------------");
System.out.println(result);
return result;
}
private static String getEncapsulateMethodName(int type, String methodName){
StringBuffer sb = new StringBuffer();
if(type < 0){
sb.append("get");
}else{
sb.append("set");
}
sb.append(methodName.substring(0, 1).toUpperCase());
sb.append(methodName.substring(1));
return sb.toString();
}
}