org.structr.javaparser.MethodVisitorAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.structr.javaparser.MethodVisitorAdapter.java

Source

/**
 * Copyright (C) 2010-2018 Structr GmbH
 *
 * This file is part of Structr <http://structr.org>.
 *
 * Structr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Structr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Structr.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.structr.javaparser;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.structr.core.app.App;
import static org.structr.javaparser.JavaParserModule.logger;
import org.structr.javaparser.entity.JavaClass;
import org.structr.javaparser.entity.Method;

public class MethodVisitorAdapter extends VoidVisitorAdapter<Object> {

    @Override
    public void visit(final MethodCallExpr methodCall, final Object arg) {

        final Map<String, Object> params = (HashMap) arg;

        final String clsName = (String) params.get("clsName");
        final JavaParserFacade facade = (JavaParserFacade) params.get("facade");
        final App app = (App) params.get("app");

        logger.info("###### " + clsName + ": " + methodCall.getName());

        try {
            ////// !!!!!!!!!!! Methoden-Aufruf kann in den meisten Fllen nicht aufgelst werden!!
            final SymbolReference<ResolvedMethodDeclaration> ref = facade.solve(methodCall);

            if (ref.isSolved()) {

                final String qualifiedSignature = ref.getCorrespondingDeclaration().getQualifiedSignature();
                //final String scopeString = scope.toString();
                final String parentNodeAsString = methodCall.getParentNode().toString();
                //logger.info("Resolved to " + qualifiedSignature + ", scope: " + scopeString + ", parent node: " + parentNodeAsString);
                logger.info("Resolved to " + qualifiedSignature + ", parent node: " + parentNodeAsString);

                final String calledMethodQualifiedName = StringUtils.replacePattern(qualifiedSignature, "\\(.*\\)",
                        "");
                final String calledMethodQualifiedClassName = StringUtils
                        .substringBeforeLast(calledMethodQualifiedName, ".");
                final String calledMethodName = StringUtils.substringAfterLast(calledMethodQualifiedName, ".");

                Method calledMethod = null;

                final JavaClass calledMethodClass = (JavaClass) app.nodeQuery(JavaClass.class)
                        .and(JavaClass.name, calledMethodQualifiedClassName).getFirst();
                if (calledMethodClass != null) {

                    logger.info(" Found called class in graph: " + calledMethodClass.getName());
                    calledMethod = (Method) app.nodeQuery(Method.class).and(Method.name, calledMethodName)
                            .and(Method.classOrInterface, calledMethodClass).getFirst();

                    if (calledMethod != null) {
                        logger.info(" Found called method in graph: "
                                + calledMethod.getProperty(Method.declaration));

                        final Optional<MethodDeclaration> callingMethod = methodCall
                                .getAncestorOfType(MethodDeclaration.class);
                        if (callingMethod.isPresent()) {

                            final String callingMethodDeclaration = callingMethod.get().getDeclarationAsString();

                            logger.info(" Calling method: " + callingMethodDeclaration);

                            final String callingMethodName = callingMethod.get().getNameAsString();
                            final Optional<TypeDeclaration> typeDecl = callingMethod.get()
                                    .getAncestorOfType(TypeDeclaration.class);

                            if (typeDecl.isPresent()) {
                                final String callingMethodClassName = typeDecl.get().getNameAsString();

                                // Find compilation unit
                                final Optional<CompilationUnit> localCU = typeDecl.get()
                                        .getAncestorOfType(CompilationUnit.class);
                                if (localCU.isPresent()) {

                                    // Does it have a package declaration?
                                    final Optional<PackageDeclaration> packageDecl = localCU.get()
                                            .getPackageDeclaration();
                                    if (packageDecl.isPresent()) {

                                        // Assemble qualified class name
                                        final String packageName = packageDecl.get().getNameAsString();
                                        final String fqcn = packageName + "." + callingMethodClassName;

                                        // Find class in graph
                                        final JavaClass callingClass = (JavaClass) app.nodeQuery(JavaClass.class)
                                                .and(JavaClass.name, fqcn).getFirst();
                                        if (callingClass != null) {

                                            final Method method = (Method) app.nodeQuery(Method.class)
                                                    .and(Method.name, callingMethodName)
                                                    .and(Method.classOrInterface, callingClass).getFirst();
                                            if (method != null) {

                                                logger.info("Found calling method in graph: " + method.getName());

                                                final List<Method> methodsCalled = method
                                                        .getProperty(Method.methodsCalled);
                                                methodsCalled.add(calledMethod);

                                                method.setProperty(Method.methodsCalled, methodsCalled);

                                                logger.info("Added " + calledMethod.getName()
                                                        + " to list of methods called in " + method.getName());
                                            }

                                        }
                                    }
                                }

                            }
                        }

                    }

                }

            }

        } catch (final Throwable t) {
            logger.info("Unable to resolve " + clsName, t);
        }
    }
}