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

com.yiwowang.intellij.finding.base.util.FindApi Maven / Gradle / Ivy

The newest version!
package com.yiwowang.intellij.finding.base.util;

import com.yiwowang.intellij.finding.base.bean.ClassBean;
import com.yiwowang.intellij.finding.base.bean.MemberBean;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.*;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;


public class FindApi {
    public static final int MATCH_EQUAL = 0;
    public static final int MATCH_START = 1;
    public static final int MATCH_END = 2;
    public static final int MATCH_CONTAINS = 3;

    public static void fill(ClassBean classBean) {
        if (classBean.members != null) {
            return;
        }
        classBean.members = new ArrayList<>();
        File zipFile = new File(classBean.component.filePath);
        InputStream inputStream = ProjectFinding.findClass(zipFile, classBean.path);
        if (inputStream == null) {
            return;
        }
        JavaClass javaClass = null;
        try {
            ClassParser parser = new ClassParser(inputStream, classBean.path);
            javaClass = parser.parse();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (javaClass == null) {
            return;
        }
        Method[] methods = javaClass.getMethods();
        if (methods != null) {
            for (Method method : methods) {
                MemberBean member = new MemberBean();
                member.clazz = classBean;
                member.type = MemberBean.TYPE_METHOD;
                member.name = method.getName();
                // delete return type
                String sign = method.getSignature();
                if (sign != null) {
                    int p = sign.indexOf(")");
                    if (p > 0) {
                        member.sign = sign.substring(0, p + 1);
                    }
                }

                classBean.members.add(member);
            }
        }
        Field[] fields = javaClass.getFields();
        if (fields != null) {
            for (Field field : fields) {
                MemberBean member = new MemberBean();
                member.type = MemberBean.TYPE_FIELD;
                member.clazz = classBean;
                member.name = field.getName();
                member.sign = field.getSignature();
                classBean.members.add(member);
            }
        }
    }

    public static boolean findUsagesClass(InputStream inputStream, String currClassPath, String classPath) {
        try {
            return matchInner(inputStream, Constants.CONSTANT_Class, currClassPath, classPath, null, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean findUsagesMethod(InputStream inputStream, String currClassPath, String classPath, String
            methodName
            , String paramsType) {
        try {
            return matchInner(inputStream, Constants.CONSTANT_Methodref, currClassPath, classPath, methodName, paramsType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean findUsagesField(InputStream inputStream, String currClassPath, String classPath, String
            fieldName) {
        try {
            return matchInner(inputStream, Constants.CONSTANT_Fieldref, currClassPath, classPath, fieldName, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean findUsagesConstant(InputStream inputStream,
                                             String currClassPath,
                                             String targetClassPath, String value, int matchType, boolean ignoreCase) {
        ConstantPool cp = null;
        try {
            ClassParser classParser = new ClassParser(inputStream, currClassPath);
            JavaClass javaClass = classParser.parse();
            cp = javaClass.getConstantPool();
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (cp == null) {
            return false;
        }
        int len = cp.getLength();
        if (!StringUtils.isEmpty(targetClassPath)) {
            boolean findClass = false;
            for (int i = 0; i < len; i++) {
                Constant constant = cp.getConstant(i);
                if (constant == null) {
                    continue;
                }
                if (constant instanceof ConstantClass) {
                    ConstantClass clazz = (ConstantClass) constant;
                    String nameRef = clazz.getBytes(cp);
                    if (StringUtils.equals(targetClassPath, nameRef)) {
                        findClass = true;
                        break;
                    }
                }
            }
            if (!findClass) {
                return false;
            }
        }

        for (int i = 0; i < len; i++) {
            Constant constant = cp.getConstant(i);
            if (!(constant instanceof ConstantString)) {
                continue;
            }
            ConstantString constantString = (ConstantString) constant;
            Object constantObject = constantString.getConstantValue(cp);
            if (constantObject == null) {
                continue;
            }
            String constantValue = (String) constantObject;
            switch (matchType) {
                case MATCH_EQUAL:
                    if (ignoreCase && StringUtils.equalsIgnoreCase(constantValue, value) ||
                            StringUtils.equals(constantValue, value)) {
                        return true;
                    }
                case MATCH_START:
                    if (ignoreCase && StringUtils.startsWithIgnoreCase(constantValue, value) ||
                            StringUtils.startsWith(constantValue, value)) {
                        return true;
                    }
                case MATCH_END:
                    if (ignoreCase && StringUtils.endsWithIgnoreCase(constantValue, value) ||
                            StringUtils.endsWith(constantValue, value)) {
                        return true;
                    }
                case MATCH_CONTAINS:
                    if (ignoreCase && StringUtils.containsIgnoreCase(constantValue, value) ||
                            StringUtils.contains(constantValue, value)) {
                        return true;
                    }
            }
        }

        return false;
    }

    public static boolean findUsagesPackage(InputStream inputStream, String currClassPath,
                                            String packagePath) {
        ClassParser classParser = new ClassParser(inputStream, currClassPath);
        JavaClass javaClass = null;
        try {
            javaClass = classParser.parse();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (javaClass == null) {
            return false;
        }
        ConstantPool cp = javaClass.getConstantPool();
        if (cp == null) {
            return false;
        }
        int len = cp.getLength();
        for (int i = 0; i < len; i++) {
            Constant constant = cp.getConstant(i);
            if (constant instanceof ConstantClass) {
                ConstantClass clazz = (ConstantClass) constant;
                String nameRef = clazz.getBytes(cp);
                // TODO 看是否为路径
                if (nameRef.startsWith(packagePath)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean matchInner(InputStream inputStream,
                                      int tag, String currClassPath,
                                      String targetClassPath, String name
            , String type) throws IOException {
        String targetClassName = null;
        if (!StringUtils.isEmpty(targetClassPath)) {
            targetClassName = targetClassPath.replace("/", ".");
        }
        ClassParser classParser = new ClassParser(inputStream, currClassPath);
        JavaClass javaClass = classParser.parse();

        ConstantPool cp = javaClass.getConstantPool();
        if (cp == null) {
            return false;
        }
        int len = cp.getLength();
        for (int i = 0; i < len; i++) {
            Constant constant = cp.getConstant(i);
            if (constant == null) {
                continue;
            }
            if ((tag == Constants.CONSTANT_Fieldref || tag == Constants.CONSTANT_Methodref
                    || tag == Constants.CONSTANT_InterfaceMethodref)
                    && constant instanceof ConstantCP) {
                ConstantCP memberRef = (ConstantCP) constant;
                String className = memberRef.getClass(cp);
//                ConstantClass classIndexInfo = (ConstantClass) cp.getConstant(memberRef.getClassIndex());
//                ConstantUtf8 classNameInfo = (ConstantUtf8) cp.getConstant(memberRef.getNameIndex());
                if (!StringUtils.isEmpty(targetClassName) && !StringUtils.equals(targetClassName, className)) {
                    continue;
                }
                Constant nameAndTypeInfo = cp.getConstant(memberRef.getNameAndTypeIndex());
                if (nameAndTypeInfo instanceof ConstantNameAndType) {
                    ConstantNameAndType realNameAndTypeInfo = (ConstantNameAndType) nameAndTypeInfo;
                    String nameRef = realNameAndTypeInfo.getName(cp);
                    String signatureRef = realNameAndTypeInfo.getSignature(cp);

//                    ConstantUtf8 nameInfo = (ConstantUtf8) cp.getConstant(realNameAndTypeInfo.getNameIndex());
//                    ConstantUtf8 descInfo = (ConstantUtf8) cp.getConstant(realNameAndTypeInfo.getSignatureIndex());
//                    System.out.println("#ConstantNameAndType" + i + " tag=" + tag + " ref:" + classNameInfo.value + "," + nameInfo.value + "," + descInfo.value);
                    if (StringUtils.equals(name, nameRef)) {
                        if (StringUtils.isEmpty(type)) {
                            return true;
                        }
                        if (StringUtils.startsWith(signatureRef, type) && signatureRef.indexOf(")") == type.length() - 1) {
                            return true;
                        }
                    }
                }
            } else if (tag == Constants.CONSTANT_Class && constant instanceof ConstantClass) {
                ConstantClass clazz = (ConstantClass) constant;
                String nameRef = clazz.getBytes(cp);
                if (StringUtils.equals(targetClassPath, nameRef)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static JavaClass getJavaClass(InputStream inputStream, String classPath) {
        try {
            ClassParser classParser = new ClassParser(inputStream, classPath);
            return classParser.parse();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("error classPath " + classPath);
        }
        return null;
    }

    public static Set getRefClasses(JavaClass javaClass) {
        if (javaClass == null) {
            return null;
        }
        ConstantPool cp = javaClass.getConstantPool();
        if (cp == null) {
            return null;
        }
        Set sets = new HashSet<>();
        int len = cp.getLength();
        for (int i = 0; i < len; i++) {
            Constant constant = cp.getConstant(i);
            if (constant instanceof ConstantClass) {
                ConstantClass clazz = (ConstantClass) constant;
                String nameRef = clazz.getBytes(cp);
                sets.add(nameRef);
            }
        }
        return sets;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy