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

com.blade.ioc.reader.AbstractClassReader Maven / Gradle / Ivy

There is a newer version: 2.0.15.RELEASE
Show newest version
package com.blade.ioc.reader;

import com.blade.ioc.ClassReader;
import com.blade.ioc.bean.ClassInfo;
import com.blade.ioc.bean.Scanner;
import com.blade.kit.BladeKit;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

/**
 * Abstract Class Reader
 *
 * @author biezhi
 * @since 1.0
 */
@Slf4j
public abstract class AbstractClassReader implements ClassReader {

    @Override
    public Set readClasses(Scanner scanner) {
        return this.getClassByAnnotation(scanner.getPackageName(), scanner.getParent(), scanner.getAnnotation(), scanner.isRecursive());
    }

    /**
     * Get class by condition
     *
     * @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) throws ClassNotFoundException {

        // Get the directory of this package to create a File
        File dir = new File(packagePath);
        // If not exist or is not a direct return to the directory
        if ((!dir.exists()) || (!dir.isDirectory())) {
            log.warn("The package [{}] not found.", packageName);
        }
        // If present, get all the files under the package include the directory
        File[] dirFiles = accept(dir, recursive);
        // Loop all files
        if (null != dirFiles && dirFiles.length > 0) {
            for (File file : dirFiles) {
                // If it is a directory, continue scanning
                if (file.isDirectory()) {
                    findClassByPackage(packageName + '.' + file.getName(), file.getAbsolutePath(), parent, annotation, recursive, classes);
                } else {
                    // If the java class file is removed later. Class only leave the class name
                    String   className = file.getName().substring(0, file.getName().length() - 6);
                    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(new ClassInfo(clazz));
                        }
                        continue;
                    }
                    if (null != parent) {
                        if (null != clazz.getSuperclass() && clazz.getSuperclass().equals(parent)) {
                            classes.add(new ClassInfo(clazz));
                        } else {
                            if (null != clazz.getInterfaces() && clazz.getInterfaces().length > 0 && clazz.getInterfaces()[0].equals(parent)) {
                                classes.add(new ClassInfo(clazz));
                            }
                        }
                        continue;
                    }
                    if (null != annotation) {
                        if (null != clazz.getAnnotation(annotation)) {
                            classes.add(new ClassInfo(clazz));
                        }
                        continue;
                    }
                    classes.add(new ClassInfo(clazz));
                }
            }
        }
        return classes;
    }

    /**
     * Filter the file rules
     *
     * @param file
     * @param recursive
     * @return
     */
    private File[] accept(File file, final boolean recursive) {
        // Custom filtering rules If you can loop (include subdirectories) or is the end of the file. Class (compiled java class file)
        return file.listFiles(file1 -> (recursive && file1.isDirectory()) || (file1.getName().endsWith(".class")));
    }

    public Set getClassByAnnotation(String packageName, Class parent, Class annotation, boolean recursive) {
        Set classes = new HashSet<>();
        // Get the name of the package and replace it
        String packageDirName = packageName.replace('.', '/');
        // Defines an enumerated collection and loops to process the URL in this directory
        Enumeration dirs;
        try {
            dirs = this.getClass().getClassLoader().getResources(packageDirName);
            // Loop iterations down
            while (dirs.hasMoreElements()) {
                URL            url        = dirs.nextElement();
                String         filePath   = new URI(url.getFile()).getPath();
                Set subClasses = findClassByPackage(packageName, filePath, parent, annotation, recursive, classes);
                if (BladeKit.isNotEmpty(subClasses)) {
                    classes.addAll(subClasses);
                }
            }
        } catch (IOException | URISyntaxException e) {
            log.error(e.getMessage(), e);
        } catch (ClassNotFoundException e) {
            log.error("Add user custom view class error Can't find such Class files.");
        }
        return classes;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy