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

tech.guyi.ipojo.compile.lib.classes.ClassScanner Maven / Gradle / Ivy

There is a newer version: 1.0.0.4
Show newest version
package tech.guyi.ipojo.compile.lib.classes;

import com.google.gson.Gson;
import javassist.CtClass;
import javassist.bytecode.annotation.BooleanMemberValue;
import javassist.bytecode.annotation.IntegerMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
import org.apache.commons.io.IOUtils;
import javassist.ClassPool;
import javassist.NotFoundException;
import tech.guyi.ipojo.compile.lib.compile.entry.CompileClass;
import tech.guyi.ipojo.compile.lib.compile.entry.ComponentEntry;
import tech.guyi.ipojo.compile.lib.compile.entry.ComponentInfo;
import tech.guyi.ipojo.compile.lib.configuration.Compile;
import tech.guyi.ipojo.compile.lib.configuration.entry.Dependency;
import tech.guyi.ipojo.compile.lib.cons.AnnotationNames;
import tech.guyi.ipojo.compile.lib.utils.AnnotationUtils;
import tech.guyi.ipojo.compile.lib.utils.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.*;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;

public class ClassScanner {

    private final Gson gson = new Gson();

    private JarFile getJarFile(String path) throws IOException {
        return ((JarURLConnection)new URL(String.format("jar:file:%s!/",path)).openConnection()).getJarFile();
    }

    private Set getClassFile(File root,Set files){
        if (root.isDirectory()){
            Optional.ofNullable(root.listFiles())
                    .ifPresent(fs -> {
                        for (File file : fs) {
                            this.getClassFile(file,files);
                        }
                    });
        }else if (root.isFile() && root.getName().endsWith(".class")){
            files.add(root);
        }
        return files;
    }

    public Set scan(ClassPool pool, Compile compile) throws IOException, NotFoundException {
        String path = compile.getProject().getWork();
        Set files = this.getClassFile(new File(path),new HashSet<>());

        Set components = new HashSet<>();

        for (File file : files) {
            String absolute = file.getAbsolutePath().replace("\\","/");
            components.add(new CompileClass(pool.get(
                    absolute
                            .replace(path,"")
                            .replace("/",".")
                            .replace(".class","")
            )));
        }

        for (Dependency dependency : compile.getProject().getDependencies()) {
            Optional dependencyPath = dependency.get(compile.getProject());
            if (dependencyPath.isPresent()){
                JarFile jar = this.getJarFile(dependencyPath.get());
                ZipEntry entry = jar.getEntry("component.info");
                if (entry != null){
                    ComponentInfo componentInfo = this.gson.fromJson(IOUtils.toString(jar.getInputStream(entry)),ComponentInfo.class);
                    if (!componentInfo.getName().equals(compile.getName())){
                        compile.getModules().add(componentInfo.getName());
                        if (componentInfo.getComponents() != null){
                            for (ComponentEntry component : componentInfo.getComponents()) {
                                CtClass classes = pool.get(component.getClasses());
                                components.add(new CompileClass(classes,false,true,component.isProxy()));
                            }
                        }
                        if (componentInfo.getUseComponents() != null){
                            for (ComponentEntry component : componentInfo.getUseComponents()) {
                                compile.addUseComponent(pool.get(component.getClasses()));
                            }
                        }
                    }
                }
            }
        }

        return components;
    }

    public Set getComponent(ClassPool pool, Compile compile) throws IOException, NotFoundException {
        return this.scan(pool,compile)
                .stream()
                .map(component -> AnnotationUtils.getAnnotation(component.getClasses(), AnnotationNames.Component)
                        .map(annotation -> {
                            AnnotationUtils.getAnnotationValue(annotation,"proxy")
                                    .map(value -> (BooleanMemberValue) value)
                                    .map(BooleanMemberValue::getValue)
                                    .ifPresent(component::setProxy);
                            AnnotationUtils.getAnnotationValue(annotation,"order")
                                    .map(value -> (IntegerMemberValue) value)
                                    .map(IntegerMemberValue::getValue)
                                    .ifPresent(component::setOrder);
                            AnnotationUtils.getAnnotationValue(annotation,"name")
                                    .map(value -> (StringMemberValue) value)
                                    .map(StringMemberValue::getValue)
                                    .filter(name -> !StringUtils.isEmpty(name))
                                    .ifPresent(component::setName);
                            return component;
                        })
                        .orElse(null))
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy