All Downloads are FREE. Search and download functionalities are using the official Maven repository.

blade.kit.resource.AbstractClassReader Maven / Gradle / Ivy

/**
 * Copyright (c) 2015, biezhi 王爵 ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package blade.kit.resource;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Set;

import blade.kit.Assert;
import blade.kit.CollectionKit;
import blade.kit.log.Logger;

/**
 * 抽象类读取器
 *
 * @author	biezhi
 * @since	1.0
 */
public abstract class AbstractClassReader implements ClassReader {

	private static final Logger LOGGER = Logger.getLogger(AbstractClassReader.class);
	
	@Override
	public Set> getClass(String packageName, boolean recursive) {
		return this.getClassByAnnotation(packageName, null, null, recursive);
	}

	/**
	 * 默认实现以文件形式的读取
	 */
	@Override
	public Set> getClass(String packageName, Class parent, boolean recursive) {
        return this.getClassByAnnotation(packageName, parent,  null, recursive);
	}
	
	/**
	 * 根据条件获取class
	 * @param packageName
	 * @param packagePath
	 * @param parent
	 * @param annotation
	 * @param recursive
	 * @return
	 */
	private Set> findClassByPackage(final String packageName, final String packagePath, final Class parent, final Class annotation, final boolean recursive, Set> classes) {
		// 获取此包的目录 建立一个File
        File dir = new File(packagePath);
        // 如果不存在或者 也不是目录就直接返回
        if ((!dir.exists()) || (!dir.isDirectory())) {
        	LOGGER.warn("包 " + packageName + " 不存在!");
        }
        // 如果存在 就获取包下的所有文件 包括目录
        File[] dirfiles = accept(dir, recursive);
        // 循环所有文件
        if(null != dirfiles && dirfiles.length > 0){
        	for (File file : dirfiles) {
                // 如果是目录 则继续扫描
                if (file.isDirectory()) {
                	findClassByPackage(packageName + "." + file.getName(), file.getAbsolutePath(), parent, annotation, recursive, classes);
                } else {
                    // 如果是java类文件 去掉后面的.class 只留下类名
                    String className = file.getName().substring(0, file.getName().length() - 6);
                    try {
                    	Class clazz = Class.forName(packageName + '.' + className);
                    	if(null != parent && null != annotation){
                    		if(null != clazz.getSuperclass() && clazz.getSuperclass().equals(parent) && 
                    				null != clazz.getAnnotation(annotation)){
                    			classes.add(clazz);
                    		}
                    		continue;
                    	}
                    	if(null != parent){
                    		if(null != clazz.getSuperclass() && clazz.getSuperclass().equals(parent)){
                    			classes.add(clazz);
                    		} else {
                    			if(null != clazz.getInterfaces() && clazz.getInterfaces().length > 0 && clazz.getInterfaces()[0].equals(parent)){
                        			classes.add(clazz);
                        		}
							}
                    		continue;
                    	}
                    	if(null != annotation){
                    		if(null != clazz.getAnnotation(annotation)){
                    			classes.add(clazz);
                    		}
                    		continue;
                    	}
                        classes.add(clazz);
                    } catch (ClassNotFoundException e) {
                    	LOGGER.error("在扫描用户定义视图时从jar包获取文件出错,找不到.class类文件:" + e.getMessage());
                    }
                }
            }
        }
        return classes;
    }
	
	/**
	 * 过滤文件规则
	 * @param file
	 * @param recursive
	 * @return
	 */
	private File[] accept(File file, final boolean recursive){
		File[] dirfiles = file.listFiles(new FileFilter() {
            // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
            public boolean accept(File file) {
                return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
            }
        });
		return dirfiles;
	}
	
	@Override
	public Set> getClassByAnnotation(String packageName, Class annotation, boolean recursive) {
		return this.getClassByAnnotation(packageName, null, annotation, recursive);
	}

	@Override
	public Set> getClassByAnnotation(String packageName, Class parent, Class annotation, boolean recursive) {
		Assert.notBlank(packageName);
		Set> classes = CollectionKit.newHashSet();
        // 获取包的名字 并进行替换
        String packageDirName = packageName.replace('.', '/');
        // 定义一个枚举的集合 并进行循环来处理这个目录下的URL
        Enumeration dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            // 循环迭代下去
            while (dirs.hasMoreElements()) {
                // 获取下一个元素
                URL url = dirs.nextElement();
				// 获取包的物理路径
				String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
				Set> subClasses = findClassByPackage(packageName, filePath, parent, annotation, recursive, classes);
				if(subClasses.size() > 0){
					classes.addAll(subClasses);
				}
            }
        } catch (IOException e) {
        	LOGGER.error(e.getMessage());
        }
        return classes;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy