package com.github.miniyk2012.coding2017.coderising.litestruts;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Logger;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.dom4j.Element;
public class Struts {
/** dom4j object model representation of a xml document. Note: We use the interface(!) not its implementation */
private static Document doc;
private static Element aElement;
private static Object object;
private static View view;
private static final Logger logger = Logger.getLogger(Struts.class.getName());
public static View runAction(String actionName, Map<String,String> parameters) throws Exception {
/*
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字段中。
*/
readXml();
String retValue = processAction(actionName, parameters);
view = generateView(retValue);
return view;
}
private static View generateView(String retValue) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
view = new View();
Map<String, String> map = getFields();
String jsp = getJsp(retValue);
view.setParameters(map);
view.setJsp(jsp);
return view;
}
private static String getJsp(String retValue) {
for (Iterator i = aElement.elementIterator( "result" ); i.hasNext();) {
Element result = (Element) i.next();
if (result.attributeValue("name").equals(retValue)) {
return result.getText();
}
}
return "";
}
/**
* @return
* @throws IntrospectionException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static Map<String, String> getFields()
throws IntrospectionException, IllegalAccessException, InvocationTargetException {
Map<String, String> map = new HashMap<>();
Class clazz = object.getClass();
Field[] fields = object.getClass().getDeclaredFields();//获得属性
for (Field field : fields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(),
clazz);
Method getMethod = pd.getReadMethod();//获得get方法
String value = (String) getMethod.invoke(object);//执行get方法返回一个Object
map.put(field.getName(), value);
}
return map;
}
private static void readXml() throws DocumentException, URISyntaxException {
URL url = Struts.class.getClassLoader().getResource("struts/struts.xml");
File aFile = new File(url.toURI());
SAXReader xmlReader = new SAXReader();
doc = xmlReader.read(aFile);
}
private static String processAction(String actionName, Map<String,String> parameters) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
generateObject(actionName);
setFields(parameters);
return doExecute();
}
/**
* @return
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static String doExecute() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Class<? extends Object> c = object.getClass();
Method method = c.getMethod("execute");
String ret = (String) method.invoke(object);
return ret;
}
/**
* @param parameters
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static void setFields(Map<String, String> parameters)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
for (Map.Entry<String, String> entry: parameters.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
key = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
Class<? extends Object> c = object.getClass();
Method method = c.getMethod(key, String.class);
method.invoke(object, value);
}
}
/**
* @param actionName
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
private static void generateObject(String actionName)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Element root = doc.getRootElement();
String className = null;
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element actionElement = (Element) i.next();
if (actionElement.attributeValue("name").equals(actionName)) {
aElement = actionElement;
className = actionElement.attributeValue("class");
break;
}
}
if (className == null) throw new InstantiationException("no such className");
object = Class.forName(className).newInstance();
}
public static void main(String args[]) throws Exception
{
// Map<String,String> params = new HashMap<String,String>();
// params.put("name","test");
// params.put("password","1234");
// View view = runAction("login", params);
// logger.info(view.toString());
System.out.println(Struts.class.getResource(""));
System.out.println(Struts.class.getResource("/"));
System.out.println(Struts.class.getClassLoader().getResource(""));
}
}