
org.hibernate.models.internal.jandex.JandexClassDetails Maven / Gradle / Ivy
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.models.internal.jandex;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.models.internal.ClassDetailsSupport;
import org.hibernate.models.internal.util.CollectionHelper;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MethodDetails;
import org.hibernate.models.spi.RecordComponentDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.models.spi.TypeDetails;
import org.hibernate.models.spi.TypeVariableDetails;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.RecordComponentInfo;
import org.jboss.jandex.Type;
import org.jboss.jandex.TypeVariable;
import static java.util.Collections.emptyList;
import static org.hibernate.models.internal.ModelsClassLogging.MODELS_CLASS_LOGGER;
import static org.hibernate.models.internal.jandex.JandexTypeSwitchStandard.switchType;
import static org.hibernate.models.internal.util.CollectionHelper.arrayList;
import static org.hibernate.models.internal.util.CollectionHelper.isEmpty;
/**
* @author Steve Ebersole
*/
public class JandexClassDetails extends AbstractAnnotationTarget implements ClassDetailsSupport {
private final ClassInfo classInfo;
private final ClassDetails superClass;
private TypeDetails genericSuperType;
private final List implementedInterfaces;
private List typeParameters;
private List fields;
private List methods;
private List recordComponents;
public JandexClassDetails(ClassInfo classInfo, SourceModelBuildingContext buildingContext) {
super( buildingContext );
this.classInfo = classInfo;
this.superClass = determineSuperType( classInfo, buildingContext );
this.implementedInterfaces = determineInterfaces( classInfo, buildingContext );
}
private static ClassDetails determineSuperType(
ClassInfo classInfo,
SourceModelBuildingContext buildingContext) {
if ( classInfo.superClassType() == null ) {
return null;
}
return buildingContext
.getClassDetailsRegistry()
.resolveClassDetails( classInfo.superClassType().name().toString() );
}
private TypeDetails determineGenericSuperType(ClassInfo classInfo, SourceModelBuildingContext buildingContext) {
if ( classInfo.superClassType() == null ) {
return null;
}
return switchType( classInfo.superClassType(), buildingContext );
}
private static List determineInterfaces(
ClassInfo classInfo,
SourceModelBuildingContext buildingContext) {
final List interfaceTypes = classInfo.interfaceTypes();
if ( isEmpty( interfaceTypes ) ) {
return emptyList();
}
final List result = arrayList( interfaceTypes.size() );
for ( Type interfaceType : interfaceTypes ) {
final TypeDetails switchedType = switchType(
interfaceType,
buildingContext
);
result.add( switchedType );
}
return result;
}
private List determineTypeParameters(ClassInfo classInfo, SourceModelBuildingContext buildingContext) {
final List jandexTypeVariables = classInfo.typeParameters();
if ( CollectionHelper.isEmpty( jandexTypeVariables ) ) {
return emptyList();
}
final ArrayList result = arrayList( jandexTypeVariables.size() );
for ( TypeVariable jandexTypeVariable : jandexTypeVariables ) {
result.add( (TypeVariableDetails) switchType( jandexTypeVariable, this, buildingContext ) );
}
return result;
}
@Override
protected AnnotationTarget getJandexAnnotationTarget() {
return classInfo;
}
@Override
public String getName() {
return getClassName();
}
@Override
public String getClassName() {
return classInfo.name().toString();
}
@Override
public boolean isResolved() {
return false;
}
@Override
public boolean isAbstract() {
return Modifier.isAbstract( classInfo.flags() );
}
@Override
public boolean isRecord() {
return classInfo.isRecord();
}
@Override
public ClassDetails getSuperClass() {
return superClass;
}
@Override
public TypeDetails getGenericSuperType() {
if ( genericSuperType == null && classInfo.superClassType() != null ) {
genericSuperType = determineGenericSuperType( classInfo, getBuildingContext() );
}
return genericSuperType;
}
@Override
public List getImplementedInterfaces() {
return implementedInterfaces;
}
@Override
public List getTypeParameters() {
if ( typeParameters == null ) {
this.typeParameters = determineTypeParameters( classInfo, getBuildingContext() );
}
return typeParameters;
}
@Override
public boolean isImplementor(Class> checkType) {
if ( getClassName().equals( checkType.getName() ) ) {
return true;
}
if ( superClass != null && superClass.isImplementor( checkType ) ) {
return true;
}
for ( TypeDetails intf : implementedInterfaces ) {
if ( intf.isImplementor( checkType ) ) {
return true;
}
}
return false;
}
@Override
public List getFields() {
if ( fields == null ) {
fields = resolveFields();
}
return fields;
}
private List resolveFields() {
final List fieldsInfoList = classInfo.fields();
final List result = new ArrayList<>( fieldsInfoList.size() );
for ( FieldInfo fieldInfo : fieldsInfoList ) {
result.add( new JandexFieldDetails( fieldInfo, this, getBuildingContext() ) );
}
return result;
}
@Override
public void addField(FieldDetails fieldDetails) {
getFields().add( fieldDetails );
}
@Override
public List getRecordComponents() {
if ( recordComponents == null ) {
recordComponents = resolveRecordComponents();
}
return recordComponents;
}
private List resolveRecordComponents() {
final List componentInfoList = classInfo.recordComponents();
final List result = arrayList( componentInfoList.size() );
for ( RecordComponentInfo componentInfo : componentInfoList ) {
result.add( new JandexRecordComponentDetails( componentInfo, this, getBuildingContext() ) );
}
return result;
}
@Override
public List getMethods() {
if ( methods == null ) {
methods = resolveMethods();
}
return methods;
}
private List resolveMethods() {
final List methodInfoList = classInfo.methods();
final List result = new ArrayList<>( methodInfoList.size() );
for ( MethodInfo methodInfo : methodInfoList ) {
if ( methodInfo.isConstructor() || "".equals( methodInfo.name() ) ) {
continue;
}
result.add( JandexBuilders.buildMethodDetails( methodInfo, this, getBuildingContext() ) );
}
return result;
}
@Override
public void addMethod(MethodDetails methodDetails) {
getMethods().add( methodDetails );
}
private Class> javaClass;
@Override
public Class toJavaClass() {
if ( javaClass == null ) {
if ( getClassName() == null ) {
throw new UnsupportedOperationException( "Not supported" );
}
MODELS_CLASS_LOGGER.debugf( "Loading `%s` on to classloader from Jandex ClassDetails", getClassName() );
javaClass = getBuildingContext().getClassLoading().classForName( getClassName() );
}
//noinspection unchecked
return (Class) javaClass;
}
@Override
public String toString() {
return "JandexClassDetails(" + classInfo.name().toString() + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy