package com.coderising.litestruts; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.coderising.parser.XmlParser; import com.coderising.parser.XmlParser.eNode; public class Struts { 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字段中。 */ String path = "src/com/coderising/litestruts/struts.xml"; File rootFile = new File(""); File rootDir = new File(rootFile.getAbsolutePath()); File configFile = findFile(rootDir, "struts.xml"); if(configFile != null){ //System.out.println("find: " + configFile.getAbsolutePath()); path = configFile.getAbsolutePath(); } View retView = new View(); XmlParser parser = new XmlParser(path); //parser.dump(); List<eNode> branchNodesList = parser.getActionNodeList(); try { for(eNode node : branchNodesList){ //System.out.println(node); String classPath = node.attributeMap.get("class"); Class<?> actionObjectClass = getClassObj(classPath); if(actionObjectClass != null){ Constructor<?> actionConstructorObject = createClass(actionObjectClass); Object newInstance = null; newInstance = actionConstructorObject.newInstance(); Method[] methods = actionObjectClass.getDeclaredMethods(); // for(Method m : methods){ // System.out.println("method: " + m.getName()); // } Iterator<Entry<String, String>> itr = parameters.entrySet().iterator(); while(itr.hasNext()){ Entry<String, String> call = itr.next(); //System.out.println(call.getKey() + " " + call.getValue()); String key = call.getKey(); String val = call.getValue(); String setMethodName = "set" + Character.toUpperCase(key.charAt(0)) + key.substring(1); Method setMethod = getMethod(actionObjectClass, setMethodName, String.class); if(newInstance != null){ setMethod.invoke(newInstance, val); } } Method exeMethod = actionObjectClass.getDeclaredMethod("execute", null); Class<?> returnType = exeMethod.getReturnType(); Object returnValue = exeMethod.invoke(newInstance, null); HashMap<Object, Object> viewHashParam = new HashMap<>(); for(Method m:methods){ if(m.getName().startsWith("get")){ Object v = m.invoke(newInstance, null); String getMethodName = m.getName().substring(3); getMethodName = Character.toLowerCase(getMethodName.charAt(0)) + getMethodName.substring(1); //System.out.println("get method: " + getMethodName); viewHashParam.put(getMethodName, v); } } String viewStr = null; for(eNode resultNode : node.subNodes){ String nameAttr = resultNode.attributeMap.get("name") ; if(nameAttr.equals(returnValue)){ //System.out.println("node: " + resultNode.element_name + " " + resultNode.attributeMap.get("name") + " matches"); for(eNode jspNode : resultNode.subNodes){ if(jspNode.isLeaf){ viewStr = jspNode.element_raw_content; //System.out.println("jsp str: " + viewStr); break; } } } } retView.setJsp(viewStr); retView.setParameters(viewHashParam); } } } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException | NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } return retView; } public static Class<?> getClassObj(String classPath){ Class<?> classObject = null; try { classObject = Class.forName(classPath); } catch (ClassNotFoundException e) { //System.err.println(e.getMessage()); } return classObject; } public static Constructor<?> createClass(Class<?> classObject){ Constructor<?> constructor = null; try { constructor = classObject.getConstructor(); } catch (NoSuchMethodException | SecurityException e) { e.printStackTrace(); } return constructor; } public static Method getMethod(Class<?> clazz, String methodName, Class<?> paramClass){ Method ret = null; try { ret = clazz.getMethod(methodName, paramClass); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } return ret; } public static void main(String[] args){ //System.out.println("absolute path: " + absPath); Map<String,String> params = new HashMap<String,String>(); params.put("name","test"); params.put("password","1234"); String actionName = "login"; View view = Struts.runAction(actionName,params); } public static File findFile(File targetDir, String targetFileName){ //System.out.println("targetDir: " + targetDir.getAbsolutePath() + " " + targetDir.isDirectory()); File configFile = null; File[] files = targetDir.listFiles(); if(files != null){ for(File f: files){ //System.out.println("test: " + f.getName()); if(f.isDirectory()){ //System.out.println("Dir: " + f.getName()); configFile = findFile(f, targetFileName); if(configFile != null){ break; } } else{ //System.out.println("File: " + f.getName()); if(f.getAbsolutePath().endsWith(targetFileName)){ configFile = f; break; } } } } return configFile; } public static FilenameFilter createFilter(String targetName){ return new FilenameFilter(){ @Override public boolean accept(File dir, String name) { // TODO Auto-generated method stub System.out.println("testing: " + dir + " name: " + name); return name.endsWith(targetName); } }; } public static List<File> getDirectories(File targetFile){ List<File> childDirs = new LinkedList<>(); if(targetFile.isDirectory()){ File[] files = targetFile.listFiles(); for(File f: files){ if(f.isDirectory()) childDirs.add(f); } } return childDirs; } }