發表於 程式分享

java取得package下的class及function清單,供前端網頁選取時使用

1.先設定3個class

1) JBMethodItem

import java.util.LinkedList;
import java.util.List;

public class JBClassItem {
    private String className;
    private String classLongName;
    private List methodList = new LinkedList();
    
    public JBClassItem(String className, String classLongName) {
        super();
        this.className = className;
        this.classLongName = classLongName;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
    
    public String getClassLongName() {
        return classLongName;
    }

    public void setClassLongName(String classLongName) {
        this.classLongName = classLongName;
    }

    public List getMethodList() {
        return methodList;
    }

    public void setMethodList(List methodList) {
        this.methodList = methodList;
    }
    
    public void addMethodList(JBMethodItem jbMethodItem) {
        this.methodList.add(jbMethodItem);
    }

    @Override
    public String toString() {
        String sBuffer = "JBClassItem [className=" + className + ", classLongName=" + classLongName + ", methodList=";
        for (JBMethodItem jbMethodItem : methodList)
            sBuffer += jbMethodItem;
        sBuffer += "]";
        return sBuffer;
    }
}

2) JBMethodItem

import java.util.Iterator;
import java.util.LinkedHashMap;

public class JBMethodItem {
    private String methodName;
    private LinkedHashMap<Integer, JBParamItem> params = new LinkedHashMap<Integer, JBParamItem>();
    
    public JBMethodItem(String methodName) {
        super();
        this.methodName = methodName;
    }
    
    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }
    
    public LinkedHashMap<Integer, JBParamItem> getParams() {
        return params;
    }

    public void setParams(LinkedHashMap<Integer, JBParamItem> params) {
        this.params = params;
    }

    public void addParams(Integer paramIdx, String paramType) {
        JBParamItem paramItem = params.get(paramIdx);
        if (paramItem == null) {
            paramItem = new JBParamItem(paramIdx);
        }
        paramItem.setParamType(paramType);
        
        params.put(paramIdx, paramItem);
    }
    
    @Override
    public String toString() {
        String sBuffer = "JBMethodItem [methodName=" + methodName + ", params=";
        Iterator it = params.keySet().iterator();
        while (it.hasNext()) {      
            Integer iKey = (Integer) it.next();     
            JBParamItem jbParamItem = (JBParamItem) params.get(iKey);
            sBuffer += "\n" + jbParamItem;
        }
        sBuffer += "]";
        return sBuffer;
    }
}

3) JBParamItem

public class JBParamItem {
    private int paramIdx;
    private String paramType;
    
    public JBParamItem(int paramIdx) {
        super();
        this.paramIdx = paramIdx;
    }

    public int getParamIdx() {
        return paramIdx;
    }
    
    public void setParamIdx(int paramIdx) {
        this.paramIdx = paramIdx;
    }
    
    public String getParamType() {
        return paramType;
    }
    
    public void setParamType(String paramType) {
        this.paramType = paramType;
    }

    @Override
    public String toString() {
        return "JBParamItem [paramIdx=" + paramIdx + ", paramType=" + paramType + "]";
    }
}

2.主要程式碼

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.*;
....
....
public class JBMainMonitorAction extends BaseAction {
    @Override
    public String execute() throws Exception {
        //取得package下class 清單
        List jbClassItemList = retriveClassItemList(logger);
        for (JBClassItem jbClassItem : jbClassItemList)
            logger.debug(jbClassItem);
        request.setAttribute("jbClassItemList", jbClassItemList);
        
        return super.execute();
    }

    /**
     * 取得package下class 清單
     * @throws IOException 
     * @throws ClassNotFoundException 
     */
    private static List retriveClassItemList(Logger logger) 
            throws ClassNotFoundException, IOException {
        List classItemList = new LinkedList();
        
        List classList = getClasses("com.tssco.util.job");
        for (Class classTmp : classList) {
            if (classTmp.getSuperclass().getSimpleName().compareToIgnoreCase("SuperMonTask") != 0)
                continue;

            JBClassItem jbClassItem = new JBClassItem(classTmp.getSimpleName(), classTmp.getName());            
            Method[] method = classTmp.getDeclaredMethods();
            for (int iIdx_m = 0; iIdx_m < method.length; iIdx_m++) {                 if (method[iIdx_m].getReturnType().toString().compareToIgnoreCase("boolean") != 0)                  continue;               List modNames = Arrays.asList(Modifier.toString(method[iIdx_m].getModifiers()).split("\\s"));               boolean bPublic = false;                int iElseCnt = 0;               for (String modifier : modNames) {                  if (modifier.compareToIgnoreCase("public") == 0)                        bPublic = true;                     else                        iElseCnt++;                 }               if (iElseCnt > 0 || bPublic == false)
                    continue;
                
                JBMethodItem jbMethodItem = new JBMethodItem(method[iIdx_m].getName());
                Class<?>[] paramList = method[iIdx_m].getParameterTypes();
                int paramIdx = 0;
                for (Class paramTmp : paramList) {
                    logger.info(paramTmp.getSimpleName());
                    jbMethodItem.addParams(++paramIdx, paramTmp.getSimpleName());
                }
                
                jbClassItem.addMethodList(jbMethodItem);
            }
            
            if (jbClassItem.getMethodList().size() > 0)
                classItemList.add(jbClassItem);
        }
        
        return classItemList;
    }
    
    private static List getClasses(String packageName) throws ClassNotFoundException, IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        assert classLoader != null;
        String path = packageName.replace('.', '/');
        Enumeration resources = classLoader.getResources(path);
        List dirs = new ArrayList();
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            dirs.add(new File(resource.getFile()));
        }
        ArrayList classes = new ArrayList();
        for (File directory : dirs) {
            classes.addAll(findClasses(directory, packageName));
        }
        return classes;
    }
    
    private static List findClasses(File directory, String packageName) throws ClassNotFoundException {
        List classes = new ArrayList();
        if (!directory.exists()) {
            return classes;
        }
        File[] files = directory.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                assert !file.getName().contains(".");
                classes.addAll(findClasses(file, packageName + "." + file.getName()));
            } else if (file.getName().endsWith(".class")) {
                classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
            }
        }
        return classes;
    }
}

3.前端javascript可加上此段讓互動時可以選取

1

   //取得package下class 清單
    var classMap = new Object();
<%
    List jbClassItemList = (List) request.getAttribute("jbClassItemList");
    for (JBClassItem jbClassItem : jbClassItemList) {
        String className = jbClassItem.getClassName();
        String classLongName = jbClassItem.getClassLongName();
        String methodMapName = "methodMap_" + className;
        out.println("var " + methodMapName + " = new Object();");
        List methodList = jbClassItem.getMethodList();
        for (JBMethodItem jbMethodItem : methodList) {
            String methodName = jbMethodItem.getMethodName();
            LinkedHashMap<Integer, JBParamItem> params = jbMethodItem.getParams();
            String paramListName = "paramList_" + className + "_" + methodName;
            out.println("var " + paramListName + " = [];");
            
            List paramList = new ArrayList(params.values());
            for (JBParamItem JBParamItem : paramList) {
                String paramType = JBParamItem.getParamType();
                if (paramType.compareTo("int") == 0)
                    paramType = "Integer";
                out.println(paramListName + ".push({'paramIdx': " + JBParamItem.getParamIdx() + 
                        ",'paramType': '" + paramType + "'});");
            }
%>
            <%= methodMapName %>['<%= methodName %>'] = {'name' : '<%= methodName %>', 'paramList' : <%= paramListName %>};
<%       } %>
        classMap['<%= classLongName %>'] = {'name' : '<%= className %>', 'longName' : '<%= classLongName %>', 
                    'methodMap' : <%= methodMapName %>};
<%   } %>

4.前端javascript就可取其值做應用了。