package scouter.bytebuddy.description.type;
import scouter.bytebuddy.description.NamedElement;
import scouter.bytebuddy.description.annotation.AnnotationSource;
import scouter.bytebuddy.description.annotation.AnnotationList;
import scouter.bytebuddy.jar.asm.Opcodes;
/**
* A package description represents a Java package.
*/
public interface PackageDescription extends NamedElement.WithRuntimeName, AnnotationSource {
/**
* The name of a Java class representing a package description.
*/
String PACKAGE_CLASS_NAME = "package-info";
/**
* The modifiers of a Java class representing a package description.
*/
int PACKAGE_MODIFIERS = Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_SYNTHETIC;
/**
* Represents any undefined property of a type description that is instead represented as {@code null} in order
* to resemble the Java reflection API which returns {@code null} and is intuitive to many Java developers.
*/
PackageDescription UNDEFINED = null;
/**
* Checks if this package contains the provided type.
*
* @param typeDescription The type to examine.
* @return {@code true} if the given type contains the provided type.
*/
boolean contains(TypeDescription typeDescription);
/**
* An abstract base implementation of a package description.
*/
abstract class AbstractBase implements PackageDescription {
@Override
public String getInternalName() {
return getName().replace('.', '/');
}
@Override
public String getActualName() {
return getName();
}
@Override
public boolean contains(TypeDescription typeDescription) {
return this.equals(typeDescription.getPackage());
}
@Override
public int hashCode() {
return getName().hashCode();
}
@Override
public boolean equals(Object other) {
return other instanceof PackageDescription
&& getName().equals(((PackageDescription) other).getName());
}
@Override
public String toString() {
return "package " + getName();
}
}
/**
* A simple implementation of a package without annotations.
*/
class Simple extends AbstractBase {
/**
* The name of the package.
*/
private final String name;
/**
* Creates a new simple package.
*
* @param name The name of the package.
*/
public Simple(String name) {
this.name = name;
}
@Override
public AnnotationList getDeclaredAnnotations() {
return new AnnotationList.Empty();
}
@Override
public String getName() {
return name;
}
}
/**
* Represents a loaded {@link java.lang.Package} wrapped as a
* {@link PackageDescription}.
*/
class ForLoadedPackage extends AbstractBase {
/**
* The represented package.
*/
private final Package aPackage;
/**
* Creates a new loaded package representation.
*
* @param aPackage The represented package.
*/
public ForLoadedPackage(Package aPackage) {
this.aPackage = aPackage;
}
@Override
public AnnotationList getDeclaredAnnotations() {
return new AnnotationList.ForLoadedAnnotations(aPackage.getDeclaredAnnotations());
}
@Override
public String getName() {
return aPackage.getName();
}
}
}