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

com.adrninistrator.javacg.parser.AbstractJarEntryParser Maven / Gradle / Ivy

package com.adrninistrator.javacg.parser;

import com.adrninistrator.javacg.conf.JavaCGConfInfo;
import com.adrninistrator.javacg.dto.jar.JarInfo;
import com.adrninistrator.javacg.util.JavaCGFileUtil;
import com.adrninistrator.javacg.util.JavaCGLogUtil;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

/**
 * @author adrninistrator
 * @date 2022/9/14
 * @description: 解析jar包中的文件,基类
 */
public abstract class AbstractJarEntryParser {

    protected String simpleClassName = this.getClass().getSimpleName();

    protected JavaCGConfInfo javaCGConfInfo;

    /*
        保存jar包或目录的名称对应的jar包信息
        key     jar包或目录的名称
        value   jar包信息
     */
    protected Map jarInfoMap;

    // 处理class文件时,缓存当前处理的文件的第一层目录名及对应jar包信息
    protected String lastFirstDirName;

    // 最近一次处理的jar信息
    protected JarInfo lastJarInfo;

    protected AbstractJarEntryParser(JavaCGConfInfo javaCGConfInfo, Map jarInfoMap) {
        this.javaCGConfInfo = javaCGConfInfo;
        this.jarInfoMap = jarInfoMap;
    }

    /**
     * 解析指定的jar包
     *
     * @param jarFilePath
     * @return
     */
    public boolean parse(String jarFilePath) {
        // 初始化
        init();

        String jarEntryName = null;
        try (JarInputStream jarInputStream = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFilePath), 1024 * 32))) {
            JarEntry jarEntry;
            while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
                if (jarEntry.isDirectory()) {
                    continue;
                }

                jarEntryName = jarEntry.getName();

                if (JavaCGLogUtil.isDebugPrintFlag()) {
                    JavaCGLogUtil.debugPrint(simpleClassName + " 处理文件: " + jarEntryName);
                }

                // 获取当前处理的jar包信息
                if (!handleCurrentJarInfo(jarEntryName)) {
                    return false;
                }

                // 处理jar包中任意类型的文件
                if (!handleEntry(jarInputStream, jarEntryName)) {
                    return false;
                }
            }

            return true;
        } catch (Exception e) {
            System.err.println(simpleClassName + " 处理jar包中的文件出现问题: " + jarEntryName);
            e.printStackTrace();
            return false;
        }
    }

    // 初始化
    protected void init() {
    }

    /**
     * 处理jar包中任意类型的文件
     *
     * @param jarInputStream
     * @param jarEntryName
     * @return true: 处理成功 false: 处理失败
     */
    protected abstract boolean handleEntry(JarInputStream jarInputStream, String jarEntryName) throws IOException;

    /**
     * 尝试处理jar包中的class文件
     *
     * @param inputStream
     * @param jarEntryName
     * @return true: 是class文件 false: 不是class文件
     */
    protected boolean tryHandleClassEntry(InputStream inputStream, String jarEntryName) throws IOException {
        if (!JavaCGFileUtil.isClassFile(jarEntryName)) {
            return false;
        }

        JavaClass javaClass = new ClassParser(inputStream, jarEntryName).parse();
        // 处理jar包中的class文件
        handleClassEntry(javaClass, jarEntryName);
        return true;
    }

    /**
     * 处理jar包中的class文件
     *
     * @param javaClass
     * @param jarEntryName
     * @return true: 处理成功 false: 处理失败
     */
    protected boolean handleClassEntry(JavaClass javaClass, String jarEntryName) throws IOException {
        return true;
    }

    /**
     * 获取当前处理的jar包信息
     *
     * @param jarEntryName
     * @return true: 处理成功 false: 处理失败
     */
    private boolean handleCurrentJarInfo(String jarEntryName) {
        if (jarInfoMap.size() == 1) {
            // 只有一个jar包,从Map取第一个Entry
            if (lastJarInfo == null) {
                // 第一次处理当前jar包
                for (Map.Entry entry : jarInfoMap.entrySet()) {
                    lastJarInfo = entry.getValue();
                    return true;
                }
            }
            return true;
        }

        // jar包数量大于1个,从Map取值时使用当前JarEntry的第一层目录名称
        int index = jarEntryName.indexOf("/");
        if (index == -1) {
            System.err.println("JarEntry名称中不包含/ " + jarEntryName);
            return false;
        }

        String firstDirName = jarEntryName.substring(0, index);
        if (lastFirstDirName != null && lastFirstDirName.equals(firstDirName)) {
            // 第一层目录名未变化时,使用缓存数据
            return true;
        }
        lastFirstDirName = firstDirName;

        // 首次处理,或第一层目录名变化时,需要从Map获取
        lastJarInfo = jarInfoMap.get(firstDirName);
        if (lastJarInfo == null) {
            System.err.println("合并后的jar包中出现的名称未记录过: " + jarEntryName);
        }
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy