generalli

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  之前一篇,我们说了一些测试用函数的接口类与实现类,这样相当于我们已经构造了我们想使用的函数。那么,如何让程序知道我们使用的是函数,并调用接口实现类进行处理后将结果放入我们想要的地方呢?

在这里,我们需要整理一下我们的思路。

  首先,我们可以通过正则表达式来匹配到我们的函数名称。其次,在得知函数名称的情况下,调用对应函数的接口实现类的方法去执行。最后,将值传递回我们需要填入的地方。

  在这里,我们先看看如何使用正则表达式来实现匹配函数名称。(我们使用函数的样式为“__funcName(args)”)("注意:这里是两个下划线(有人已经提醒我了。)")

protected Pattern funPattern = Pattern
            .compile("__(\\w*?)\\((([\\w\\\\\\/:\\.\\$]*,?)*)\\)");

  可以使用这个正则表达式来匹配【_funcName(args)】的形式。有关正则这里不再详细说明。

  关于正则表达式,这里再推荐一个网站。以便各位学习何使用:https://www.w3cschool.cn/regexp/x9hf1pq9.html

 

  在知道了函数名称之后,怎样调用对应函数的接口实现类的方法去执行呢?这里我们还是整理一下思路。

----->先找到当前项目路径下所有的类,然后过滤获取这个路径下所有子类或接口实现类。通过一个集合,将函数名与测试函数接口对应起来,存入集合。最后,通过调用接口实现类来获取值。

首先,我们来看一下classFinder的查找类。

public class classFinder {

    static ClassLoader classloader = Thread.currentThread().getContextClassLoader();  
    /** 
     * 获取同一路径下所有子类或接口实现类 
     *  
     * @param intf 
     * @return 
     * @throws IOException 
     * @throws ClassNotFoundException 
     */  
    public static List<Class<?>> getAllAssignedClass(Class<?> cls) {  
        List<Class<?>> classes = new ArrayList<Class<?>>();  
        for (Class<?> c : getClasses(cls)) {  
            if (cls.isAssignableFrom(c) && !cls.equals(c)) {  
                classes.add(c);  
            }  
        }  
        return classes;  
    }  
  
    /** 
     * 取得当前类路径下的所有类 
     *  
     * @param cls 
     * @return 
     * @throws IOException 
     * @throws ClassNotFoundException 
     */  
    public static List<Class<?>> getClasses(Class<?> cls) {  
        String pk = cls.getPackage().getName();  
        String path = pk.replace('.', '/');  
        try {
            String dirPath = URLDecoder.decode(classloader.getResource(path).getPath(),"utf-8");
            return getClasses(new File(dirPath), pk);
         } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
      return new ArrayList<Class<?>>();
    }  
  
    /** 
     * 迭代查找 
     *  
     * @param dir 
     * @param pk 
     * @return 
     * @throws ClassNotFoundException 
     */  
    private static List<Class<?>> getClasses(File dir, String pk) {  
        List<Class<?>> classes = new ArrayList<Class<?>>();  
        if (!dir.exists()) {  
            return classes;  
        }  
        for (File f : dir.listFiles()) {  
            if (f.isDirectory()) {  
                classes.addAll(getClasses(f, pk + "." + f.getName()));  
            }  
            String name = f.getName();  
            if (name.endsWith(".class")) {  
                try{
                classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6)));
                }catch(Exception ex){
                    //TODO console warn
                }
            }  
        }  
        return classes;  
    }  
}

       通过上面的查找类,我们可以获取到指定路径下的所有子类和接口实现类。

public class functionUtil {

    private static final Map<String, Class<? extends functionInterface>> functionsMap = new HashMap<String, Class<? extends functionInterface>>();
    static {
        //bodyfile 特殊处理,这个bodyfile主要是应对POST有上传文件的情况。
        functionsMap.put("bodyfile", null);
        List<Class<?>> clazzes = classFinder.getAllAssignedClass(functionInterface.class);
        clazzes.forEach((clazz) -> {
            try {
                // function
                functionInterface tempFunc = (functionInterface) clazz.newInstance();
                String referenceKey = tempFunc.getReferenceKey();
                if (referenceKey.length() > 0) { // ignore self
                    functionsMap.put(referenceKey, tempFunc.getClass());
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                //TODO 
            }
        });
    }
    
    public static boolean isFunction(String functionName){
        return functionsMap.containsKey(functionName);
    }
    
    public static String getValue(String functionName,String[] args){
        try {
            return functionsMap.get(functionName).newInstance().execute(args);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "";
        }
    }
}

  在这个functionUtil里面我们实现了将找到的接口实现类存入Map,并根据函数名来调用相应的函数执行,并返回执行后的结果。

 

posted on 2020-02-01 10:36  万春流  阅读(1130)  评论(0编辑  收藏  举报