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

com.softicar.platform.common.core.java.classpath.linking.JavaClasspathLinkingValidator Maven / Gradle / Ivy

Go to download

The SoftiCAR Platform is a lightweight, Java-based library to create interactive business web applications.

There is a newer version: 50.0.0
Show newest version
package com.softicar.platform.common.core.java.classpath.linking;

import com.softicar.platform.common.core.java.classes.analyzer.AnalyzedJavaClass;
import com.softicar.platform.common.core.java.classes.analyzer.JavaClassAnalyzer;
import com.softicar.platform.common.core.java.classes.name.JavaClassName;
import com.softicar.platform.common.core.java.identifier.declaration.JavaIdentifierDeclaration;
import com.softicar.platform.common.core.java.identifier.key.JavaIdentifierKey;
import com.softicar.platform.common.core.java.method.reference.JavaMethodReference;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Validates referential integrity of the classes on the class path.
 * 

* Known limitations: *

    *
  • Only validates method references.
  • *
  • No validation of class references is done.
  • *
* * @author Oliver Richers */ public class JavaClasspathLinkingValidator { private final Map classesOnClassPath; private Predicate classFilter; private JavaClasspathLinkingValidatorResult validatorResult; public JavaClasspathLinkingValidator(Map classesOnClassPath) { this.classesOnClassPath = classesOnClassPath; this.classFilter = dummy -> true; this.validatorResult = null; } /** * Defines a filter for classes to validate. * * @param classFilter * the class filter (never null) * @return this object */ public JavaClasspathLinkingValidator setClassFilter(Predicate classFilter) { this.classFilter = classFilter; return this; } public JavaClasspathLinkingValidatorResult validate() { this.validatorResult = new JavaClasspathLinkingValidatorResult(); validateClasses(); return validatorResult; } private void validateClasses() { classesOnClassPath// .values() .stream() .filter(classFilter) .collect(Collectors.toList()) .forEach(this::validateClass); } private void validateClass(AnalyzedJavaClass javaClass) { ClassLinkingValidator linkingValidator = new ClassLinkingValidator(javaClass); javaClass// .getReferencedMethods(this::isRelevantMethodReference) .forEach(methodReference -> linkingValidator.validate(methodReference)); } private boolean isRelevantMethodReference(JavaMethodReference methodReference) { return !methodReference.getOwner().isArray(); } private class ClassLinkingValidator { private final AnalyzedJavaClass referencingClass; public ClassLinkingValidator(AnalyzedJavaClass referencingClass) { this.referencingClass = referencingClass; } public void validate(JavaMethodReference methodReference) { Optional methodDeclaration = findMethodDeclaration(methodReference.getOwner(), methodReference.getMethodKey()); if (!methodDeclaration.isPresent()) { validatorResult.addUnresolvedMethodReference(methodReference, referencingClass); } } private Optional findMethodDeclaration(JavaClassName targetClassName, JavaIdentifierKey methodKey) { return getAnalyzedJavaClass(targetClassName)// .flatMap(targetClass -> findMethodDeclaration(targetClass, methodKey)); } private Optional findMethodDeclaration(AnalyzedJavaClass targetClass, JavaIdentifierKey methodKey) { Optional methodFromClass = targetClass.findDeclaredMethod(methodKey); if (methodFromClass.isPresent()) { return methodFromClass; } Optional methodFromInterface = findMethodDeclarationInInterfaces(targetClass, methodKey); if (methodFromInterface.isPresent()) { return methodFromInterface; } Optional methodFromSuperClass = findMethodDeclarationInSuperClass(targetClass, methodKey); if (methodFromSuperClass.isPresent()) { return methodFromSuperClass; } return Optional.empty(); } private Optional findMethodDeclarationInInterfaces(AnalyzedJavaClass targetClass, JavaIdentifierKey methodKey) { for (JavaClassName interfaceClassName: targetClass.getInterfaces()) { Optional methodDeclaration = findMethodDeclaration(interfaceClassName, methodKey); if (methodDeclaration.isPresent()) { return methodDeclaration; } } return Optional.empty(); } private Optional findMethodDeclarationInSuperClass(AnalyzedJavaClass targetClass, JavaIdentifierKey methodKey) { return Optional// .ofNullable(targetClass.getSuperClass()) .flatMap(superClass -> findMethodDeclaration(superClass, methodKey)); } private Optional getAnalyzedJavaClass(JavaClassName className) { AnalyzedJavaClass javaClass = classesOnClassPath.get(className); if (javaClass != null) { return Optional.of(javaClass); } else { try { Class clazz = Class.forName(className.getName()); AnalyzedJavaClass analyzedJavaClass = new JavaClassAnalyzer(clazz).analyze(); classesOnClassPath.put(className, analyzedJavaClass); return Optional.of(analyzedJavaClass); } catch (@SuppressWarnings("unused") ClassNotFoundException exception) { validatorResult.addMissingClass(className, referencingClass); return Optional.empty(); } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy