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

live.document.mavenplugin.method.SpecificEntitiesAndTablesOfMethodFinder Maven / Gradle / Ivy

package live.document.mavenplugin.method;

import live.document.generator.BaseMethodMindMapGenerator;
import live.document.generator.model.CallNode;
import live.document.mavenplugin.common.CallNodeVisibleFunc;
import live.document.mavenplugin.common.Constants;
import live.document.plsqlscanner.PlSqlExplained;
import live.document.scanner.CallGraph;
import live.document.scanner.DbObjectTypeEnum;
import live.document.scanner.DbOperationTypeEnum;
import live.document.scanner.MethodObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

class SpecificEntitiesAndTablesOfMethodFinder {
    private final BaseMethodMindMapGenerator generator;
    private final CallNodeVisibleFunc visibleFunc;
    private Set entitySet = new HashSet<>();
    private Set tableSet = new HashSet<>();
    private MethodMindMap4CallTree mindmap4CallTree;
    private CallGraph callGraph;
    private PlSqlExplained plSqlExplained;

    public SpecificEntitiesAndTablesOfMethodFinder(String[] entities, String[] tables, String[] ignorePatterns, String[] parentNodeIgnorePatterns) {
        visibleFunc = new CallNodeVisibleFunc(entities, tables, ignorePatterns, parentNodeIgnorePatterns);

        if (entities != null) {
            entitySet.addAll(Arrays.asList(entities));
        }

        if (tables != null) {
            tableSet.addAll(Arrays.asList(tables));
        }

        this.mindmap4CallTree = new MethodMindMap4CallTree();
        mindmap4CallTree.setHasEntityWriteOperation(node -> isNodeHasEntityWriteOperation(node));
        mindmap4CallTree.setGetEntityOperations(node -> getSpecificEntityOperations(node));

        generator = new BaseMethodMindMapGenerator(mindmap4CallTree);
    }

    private List getSpecificEntityOperations(CallNode node) {
        List allEntityOperations = getSpecificEntityOperations(node, true, new HashSet<>());
        List results = getDistinctEntityAndOperation(allEntityOperations);

        return results;
    }

    private List getSpecificEntityOperations(CallNode node, boolean isRoot, Set scannedNodes) {
        if (scannedNodes.contains(node)) {
            return new ArrayList<>();
        }
        scannedNodes.add(node);

        if (node.isLink() && node.getLinkedNode() != null) {
            return getSpecificEntityOperations(node.getLinkedNode(), isRoot, scannedNodes);
        }


        List results = new ArrayList<>();
        MethodObject methodObject = node.getMethodObject();
        boolean isEntity = isEntityClass(methodObject);

        if (isEntity && isRoot) {
            return results;
        }

        if (isEntity) {
            if (isSpecifiedEntityClass(node.getMethodObject())) {
                results.add(getClassNameWithOperation(node));
            }
            return results;
        }

        if (node.getDbOperation() != null && node.getDbOperation().getObjectType() == DbObjectTypeEnum.TABLE) {
            if (isSpecifiedDbObject(node.getDbOperation().getName())) {
                results.add(node.getDbOperation().toString());
            }
        }

        for (CallNode child : node.getChildren()) {
            List allEntityOperations = getSpecificEntityOperations(child, false, scannedNodes);
            results.addAll(allEntityOperations);
        }

        return results;
    }

    List getDistinctEntityAndOperation(List allEntityOperations) {
        Map> map = new HashMap<>();
        for (String allEntityOperation : allEntityOperations) {
            int endIndex = allEntityOperation.indexOf(",");
            if (endIndex > 0) {
                //for class
                String entityName = allEntityOperation.substring(0, endIndex).trim();
                String operation = allEntityOperation.substring(endIndex + 1).trim();

                Set set = map.get(entityName);
                if (set == null) {
                    set = new HashSet<>();
                    map.put(entityName, set);
                }
                addAlphabetToSet(set, operation.toUpperCase());
            } else {
                //for db table
                int spaceIndex = allEntityOperation.indexOf(" ");
                String tableName = allEntityOperation.substring(0, spaceIndex);
                String tableOperation = allEntityOperation
                        .substring(spaceIndex + 1)
                        .replace("[", "")
                        .replace("]", "");

                Set set = map.get(tableName);
                if (set == null) {
                    set = new HashSet<>();
                    map.put(tableName, set);
                }
                addAlphabetToSet(set, tableOperation.toUpperCase());
            }
        }

        List results = map.entrySet()
                .stream()
                .map(i -> "[" + i.getKey() + ", " + i.getValue().stream().sorted().collect(Collectors.joining()) + "]")
                .sorted()
                .collect(Collectors.toList());
        results.sort(String::compareTo);

        return results;
    }

    private void addAlphabetToSet(Set set, String s) {
        for (char c : s.toCharArray()) {
            set.add("" + c);
        }
    }

    private static boolean isEntityClass(MethodObject methodObject) {
        if (methodObject == null) {
            return false;
        }
        return (methodObject.getClassName().endsWith("Entity"));
    }

    private Boolean isNodeHasEntityWriteOperation(CallNode node) {
        return doCheckNodeHasEntityWriteOperation(node, new HashSet());
    }

    private Boolean doCheckNodeHasEntityWriteOperation(CallNode node, Set scannedNodes) {
        if (scannedNodes.contains(node)) {
            return false;
        }
        scannedNodes.add(node);

        if (node.isLink() && node.getLinkedNode() != null) {
            return doCheckNodeHasEntityWriteOperation(node.getLinkedNode(), scannedNodes);
        }

        if (node.getMethodObject() != null) {
            MethodObject methodObject = node.getMethodObject();
            if (isSpecifiedEntityClass(methodObject)) {
                if (isWriteOperation(methodObject)) {
                    return true;
                }
            }
        } else if (node.getDbOperation() != null) {
            if (isSpecifiedDbObject(node.getDbOperation().getName())) {
                if (node.getDbOperation().getOperationType() == DbOperationTypeEnum.READ_WRITE ||
                        node.getDbOperation().getOperationType() == DbOperationTypeEnum.WRITE) {
                    return true;
                }
            }
        }

        for (CallNode child : node.getChildren()) {
            if (doCheckNodeHasEntityWriteOperation(child, scannedNodes)) {
                return true;
            }
        }

        return false;
    }

    private boolean isWriteOperation(MethodObject methodObject) {
        for (String methodName : Constants.READONLY_METHOD_NAME) {
            if (methodObject.getMethodName().startsWith(methodName)) {
                return false;
            }
        }

        return true;
    }

    private boolean isSpecifiedDbObject(String name) {
        return tableSet.isEmpty() || tableSet.contains(name);
    }

    private boolean isSpecifiedEntityClass(MethodObject methodObject) {
        if (entitySet.isEmpty()) {
            if (tableSet.isEmpty()) {
                return methodObject.getClassName().endsWith("Entity");
            } else {
                return false;
            }
        }

        for (String entity : entitySet) {
            if (entity.indexOf(".") > 0) {
                if (methodObject.getClassName().equalsIgnoreCase(entity)) {
                    return true;
                }
            } else {
                if (methodObject.getClassName().endsWith("." + entity)) {
                    return true;
                }
            }
        }

        return false;
    }

    public MethodMindMap4CallTree getMindmap4CallTree() {
        return mindmap4CallTree;
    }

    private String getClassNameWithOperation(CallNode node) {
        String className = getSimpleClassName(node.getMethodObject().getClassName());
        return className + (isNodeHasEntityWriteOperation(node) ? ", W" : ", R");
    }

    protected String getSimpleClassName(String className) {
        int i = className.lastIndexOf(".");
        if (i > 0) {
            return className.substring(i + 1);
        }
        return className;
    }

    public void setCallGraph(CallGraph callGraph) {
        this.callGraph = callGraph;
    }

    public void setPlSqlExplained(PlSqlExplained plSqlExplained) {
        this.plSqlExplained = plSqlExplained;
        mindmap4CallTree.setPlSqlExplained(plSqlExplained);
    }

    public String generate(String className, String methodName) {
        return generator.generate(
                callGraph,
                plSqlExplained,
                className,
                methodName,
                m -> true,
                node -> visibleFunc.isVisible(node));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy