io.github.lukehutch.fastclasspathscanner.scanner.ClassInfoUnlinked Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fast-classpath-scanner Show documentation
Show all versions of fast-classpath-scanner Show documentation
Uber-fast, ultra-lightweight Java classpath scanner. Scans the classpath by parsing the classfile binary format directly rather than by using reflection.
See https://github.com/lukehutch/fast-classpath-scanner
/*
* This file is part of FastClasspathScanner.
*
* Author: Luke Hutchison
*
* Hosted at: https://github.com/lukehutch/fast-classpath-scanner
*
* --
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Luke Hutchison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
* EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
* OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.github.lukehutch.fastclasspathscanner.scanner;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import io.github.lukehutch.fastclasspathscanner.scanner.AnnotationInfo.AnnotationParamValue;
import io.github.lukehutch.fastclasspathscanner.typesignature.ClassTypeSignature;
import io.github.lukehutch.fastclasspathscanner.utils.Join;
import io.github.lukehutch.fastclasspathscanner.utils.LogNode;
/**
* Class information that has been directly read from the binary classfile, before it is cross-linked with other
* classes. (The cross-linking is done in a separate step to avoid the complexity of dealing with race conditions.)
*/
class ClassInfoUnlinked {
String className;
private final int classModifiers;
private final boolean isInterface;
private final boolean isAnnotation;
// Superclass (can be null if no superclass, or if superclass is blacklisted)
private String superclassName;
private List implementedInterfaces;
private List classAnnotations;
private List methodAnnotations;
private List fieldAnnotations;
private Map staticFinalFieldValues;
private String fullyQualifiedContainingMethodName;
private List> classContainmentEntries;
List annotationParamDefaultValues;
private final ClasspathElement classpathElement;
List fieldInfoList;
List methodInfoList;
private String typeSignature;
ClassInfoUnlinked(final String className, final int classModifiers, final boolean isInterface,
final boolean isAnnotation, final ClasspathElement classpathElement) {
this.className = (className);
this.classModifiers = classModifiers;
this.isInterface = isInterface;
this.isAnnotation = isAnnotation;
this.classpathElement = classpathElement;
}
void addTypeSignature(final String typeSignature) {
this.typeSignature = typeSignature;
}
void addSuperclass(final String superclassName) {
this.superclassName = superclassName;
}
void addImplementedInterface(final String interfaceName) {
if (implementedInterfaces == null) {
implementedInterfaces = new ArrayList<>();
}
implementedInterfaces.add(interfaceName);
}
void addClassAnnotation(final AnnotationInfo classAnnotation) {
if (classAnnotations == null) {
classAnnotations = new ArrayList<>();
}
classAnnotations.add(classAnnotation);
}
void addMethodAnnotation(final AnnotationInfo methodAnnotation) {
if (methodAnnotations == null) {
methodAnnotations = new ArrayList<>();
}
methodAnnotations.add(methodAnnotation);
}
void addFieldAnnotation(final AnnotationInfo fieldAnnotation) {
if (fieldAnnotations == null) {
fieldAnnotations = new ArrayList<>();
}
fieldAnnotations.add(fieldAnnotation);
}
void addFieldConstantValue(final String fieldName, final Object staticFinalFieldValue) {
if (staticFinalFieldValues == null) {
staticFinalFieldValues = new HashMap<>();
}
staticFinalFieldValues.put(fieldName, staticFinalFieldValue);
}
void addFieldInfo(final FieldInfo fieldInfo) {
if (fieldInfoList == null) {
fieldInfoList = new ArrayList<>();
}
fieldInfoList.add(fieldInfo);
}
void addMethodInfo(final MethodInfo methodInfo) {
if (methodInfoList == null) {
methodInfoList = new ArrayList<>();
}
methodInfoList.add(methodInfo);
}
public void addEnclosingMethod(final String fullyQualifiedContainingMethodName) {
this.fullyQualifiedContainingMethodName = fullyQualifiedContainingMethodName;
}
public void addClassContainment(final String innerClassName, final String outerClassName) {
if (classContainmentEntries == null) {
classContainmentEntries = new ArrayList<>();
}
classContainmentEntries.add(new SimpleEntry<>(innerClassName, outerClassName));
}
public void addAnnotationParamDefaultValues(final List annotationParamDefaultValues) {
this.annotationParamDefaultValues = annotationParamDefaultValues;
}
/** Link classes. Not threadsafe, should be run in a single-threaded context. */
void link(final ScanSpec scanSpec, final Map classNameToClassInfo, final LogNode log) {
final ClassInfo classInfo = ClassInfo.addScannedClass(className, classModifiers, isInterface, isAnnotation,
scanSpec, classNameToClassInfo, classpathElement, log);
if (superclassName != null) {
classInfo.addSuperclass(superclassName, classNameToClassInfo);
}
if (implementedInterfaces != null) {
for (final String interfaceName : implementedInterfaces) {
classInfo.addImplementedInterface(interfaceName, classNameToClassInfo);
}
}
if (classAnnotations != null) {
for (final AnnotationInfo classAnnotation : classAnnotations) {
classInfo.addClassAnnotation(classAnnotation, classNameToClassInfo);
}
}
if (methodAnnotations != null) {
for (final AnnotationInfo methodAnnotation : methodAnnotations) {
classInfo.addMethodAnnotation(methodAnnotation, classNameToClassInfo);
}
}
if (fieldAnnotations != null) {
for (final AnnotationInfo fieldAnnotation : fieldAnnotations) {
classInfo.addFieldAnnotation(fieldAnnotation, classNameToClassInfo);
}
}
if (staticFinalFieldValues != null) {
for (final Entry ent : staticFinalFieldValues.entrySet()) {
classInfo.addStaticFinalFieldConstantInitializerValue(ent.getKey(), ent.getValue());
}
}
if (classContainmentEntries != null) {
ClassInfo.addClassContainment(classContainmentEntries, scanSpec, classNameToClassInfo);
}
if (annotationParamDefaultValues != null) {
classInfo.addAnnotationParamDefaultValues(annotationParamDefaultValues);
}
if (fullyQualifiedContainingMethodName != null) {
classInfo.addFullyQualifiedContainingMethodName(fullyQualifiedContainingMethodName);
}
if (fieldInfoList != null) {
classInfo.addFieldInfo(fieldInfoList, classNameToClassInfo);
}
if (methodInfoList != null) {
classInfo.addMethodInfo(methodInfoList, classNameToClassInfo);
}
if (typeSignature != null) {
classInfo.addTypeSignature(typeSignature);
}
}
void logTo(final LogNode log) {
if (log != null) {
final LogNode subLog = log.log("Found " //
+ (isAnnotation ? "annotation class" : isInterface ? "interface class" : "class") //
+ " " + className);
if (superclassName != null) {
subLog.log(
"Super" + (isInterface && !isAnnotation ? "interface" : "class") + ": " + superclassName);
}
if (implementedInterfaces != null) {
subLog.log("Interfaces: " + Join.join(", ", implementedInterfaces));
}
if (classAnnotations != null) {
subLog.log("Class annotations: " + Join.join(", ", classAnnotations));
}
if (methodAnnotations != null) {
subLog.log("Method annotations: " + Join.join(", ", methodAnnotations));
}
if (fieldAnnotations != null) {
subLog.log("Field annotations: " + Join.join(", ", fieldAnnotations));
}
if (staticFinalFieldValues != null) {
final List fieldInitializers = new ArrayList<>();
for (final Entry ent : staticFinalFieldValues.entrySet()) {
fieldInitializers.add(ent.getKey() + " = " + ent.getValue());
}
subLog.log("Static final field values: " + Join.join(", ", fieldInitializers));
}
if (typeSignature != null) {
subLog.log("Class type signature: " + ClassTypeSignature.parse(typeSignature)
.toString(classModifiers, isAnnotation, isInterface, className));
}
}
}
}