HHH-8934 - MetadataSources needs to index (Jandex) classes referenced in xml files
This commit is contained in:
parent
7fdf40c693
commit
f8020670d0
|
@ -80,6 +80,7 @@ import org.jboss.jandex.AnnotationInstance;
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
import org.jboss.jandex.CompositeIndex;
|
import org.jboss.jandex.CompositeIndex;
|
||||||
import org.jboss.jandex.DotName;
|
import org.jboss.jandex.DotName;
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
import org.jboss.jandex.IndexView;
|
import org.jboss.jandex.IndexView;
|
||||||
import org.jboss.jandex.Indexer;
|
import org.jboss.jandex.Indexer;
|
||||||
import org.jboss.jandex.Type;
|
import org.jboss.jandex.Type;
|
||||||
|
@ -111,6 +112,7 @@ public class MetadataSources {
|
||||||
private LinkedHashSet<Class<?>> annotatedClasses = new LinkedHashSet<Class<?>>();
|
private LinkedHashSet<Class<?>> annotatedClasses = new LinkedHashSet<Class<?>>();
|
||||||
private LinkedHashSet<String> annotatedClassNames = new LinkedHashSet<String>();
|
private LinkedHashSet<String> annotatedClassNames = new LinkedHashSet<String>();
|
||||||
private LinkedHashSet<String> annotatedPackages = new LinkedHashSet<String>();
|
private LinkedHashSet<String> annotatedPackages = new LinkedHashSet<String>();
|
||||||
|
private List<Class<? extends AttributeConverter>> converterClasses;
|
||||||
|
|
||||||
private boolean hasOrmXmlJaxbRoots;
|
private boolean hasOrmXmlJaxbRoots;
|
||||||
|
|
||||||
|
@ -161,10 +163,6 @@ public class MetadataSources {
|
||||||
return serviceRegistry;
|
return serviceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasOrmXmlJaxbRoots() {
|
|
||||||
return hasOrmXmlJaxbRoots;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a builder for metadata where non-default options can be specified.
|
* Get a builder for metadata where non-default options can be specified.
|
||||||
*
|
*
|
||||||
|
@ -303,8 +301,6 @@ public class MetadataSources {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Class<? extends AttributeConverter>> converterClasses;
|
|
||||||
|
|
||||||
public MetadataSources addAttributeConverter(Class<? extends AttributeConverter> converterClass) {
|
public MetadataSources addAttributeConverter(Class<? extends AttributeConverter> converterClass) {
|
||||||
if ( converterClasses == null ) {
|
if ( converterClasses == null ) {
|
||||||
converterClasses = new ArrayList<Class<? extends AttributeConverter>>();
|
converterClasses = new ArrayList<Class<? extends AttributeConverter>>();
|
||||||
|
@ -583,304 +579,291 @@ public class MetadataSources {
|
||||||
|
|
||||||
return new EntityMappingsMocker( collectedOrmXmlMappings, jandexView, serviceRegistry ).mockNewIndex();
|
return new EntityMappingsMocker( collectedOrmXmlMappings, jandexView, serviceRegistry ).mockNewIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexView buildJandexView() {
|
public IndexView buildJandexView() {
|
||||||
return buildJandexView( false );
|
return buildJandexView( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexView buildJandexView(boolean autoIndexMemberTypes) {
|
|
||||||
// create a jandex index from the annotated classes
|
|
||||||
|
|
||||||
final Indexer indexer = new Indexer();
|
public static class JandexIndexBuilder {
|
||||||
|
private static final Logger log = Logger.getLogger( JandexIndexBuilder.class );
|
||||||
Set<String> processedClassNames = new HashSet<String>();
|
|
||||||
for ( Class<?> clazz : getAnnotatedClasses() ) {
|
private final DotName OBJECT_DOT_NAME = DotName.createSimple( Object.class.getName() );
|
||||||
indexClass( clazz, indexer, processedClassNames, autoIndexMemberTypes );
|
|
||||||
|
private final boolean autoIndexMemberTypes;
|
||||||
|
private final ClassLoaderService classLoaderService;
|
||||||
|
|
||||||
|
private final Indexer indexer = new Indexer();
|
||||||
|
private final Set<DotName> processedClassNames = new HashSet<DotName>();
|
||||||
|
|
||||||
|
private JandexIndexBuilder(boolean autoIndexMemberTypes, ServiceRegistry serviceRegistry) {
|
||||||
|
this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||||
|
this.autoIndexMemberTypes = autoIndexMemberTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( converterClasses != null ) {
|
public static IndexView process(boolean autoIndexMemberTypes, MetadataSources sources) {
|
||||||
for ( Class<? extends AttributeConverter> converterClass : converterClasses ) {
|
return new JandexIndexBuilder( autoIndexMemberTypes, sources.getServiceRegistry() ).process( sources );
|
||||||
indexClass( converterClass, indexer, processedClassNames, autoIndexMemberTypes );
|
}
|
||||||
|
|
||||||
|
private IndexView process(MetadataSources sources) {
|
||||||
|
// start off with any already-loaded Class references...
|
||||||
|
for ( Class<?> clazz : sources.getAnnotatedClasses() ) {
|
||||||
|
indexLoadedClass( clazz );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for ( String className : getAnnotatedClassNames() ) {
|
if ( sources.converterClasses != null ) {
|
||||||
indexClassName( DotName.createSimple( className ), indexer, processedClassNames, autoIndexMemberTypes );
|
for ( Class<? extends AttributeConverter> converterClass : sources.converterClasses ) {
|
||||||
}
|
indexLoadedClass( converterClass );
|
||||||
|
|
||||||
// add package-info from the configured packages
|
|
||||||
for ( String packageName : getAnnotatedPackages() ) {
|
|
||||||
indexResource( packageName.replace( '.', '/' ) + "/package-info.class", indexer );
|
|
||||||
}
|
|
||||||
|
|
||||||
// the classes referenced in any xml bindings
|
|
||||||
for ( BindResult bindResult : bindResultList ) {
|
|
||||||
if ( JaxbHibernateMapping.class.isInstance( bindResult.getRoot() ) ) {
|
|
||||||
indexHbmReferences( (JaxbHibernateMapping) bindResult.getRoot(), indexer, processedClassNames );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final JaxbEntityMappings ormXmlRoot = (JaxbEntityMappings) bindResult.getRoot();
|
|
||||||
if ( !isMappingMetadataComplete( ormXmlRoot ) ) {
|
|
||||||
indexOrmXmlReferences( ormXmlRoot, indexer, processedClassNames );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexView jandexView = indexer.complete();
|
|
||||||
Collection<AnnotationInstance> entityListenerAnnotations = jandexView.getAnnotations( JPADotNames.ENTITY_LISTENERS );
|
|
||||||
if ( entityListenerAnnotations != null ) {
|
|
||||||
Indexer entityListenerIndexer = new Indexer();
|
|
||||||
for ( AnnotationInstance entityListenerAnnotation : entityListenerAnnotations ) {
|
|
||||||
final Type[] entityListenerClassTypes = entityListenerAnnotation.value().asClassArray();
|
|
||||||
for ( Type entityListenerClassType : entityListenerClassTypes ) {
|
|
||||||
indexClassName(
|
|
||||||
entityListenerClassType.name(),
|
|
||||||
entityListenerIndexer,
|
|
||||||
processedClassNames,
|
|
||||||
autoIndexMemberTypes
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jandexView = CompositeIndex.create( jandexView, entityListenerIndexer.complete() );
|
for ( String className : sources.getAnnotatedClassNames() ) {
|
||||||
}
|
indexClassName( DotName.createSimple( className ) );
|
||||||
|
|
||||||
return wrapJandexView( jandexView );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMappingMetadataComplete(JaxbEntityMappings ormXmlRoot) {
|
|
||||||
return ormXmlRoot.getPersistenceUnitMetadata() != null
|
|
||||||
&& ormXmlRoot.getPersistenceUnitMetadata().getXmlMappingMetadataComplete() == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void indexOrmXmlReferences(JaxbEntityMappings ormXmlRoot, Indexer indexer, Set<String> processedClassNames) {
|
|
||||||
final String packageName = ormXmlRoot.getPackage();
|
|
||||||
|
|
||||||
for ( JaxbConverter jaxbConverter : ormXmlRoot.getConverter() ) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( jaxbConverter.getClazz(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( JaxbEmbeddable jaxbEmbeddable : ormXmlRoot.getEmbeddable() ) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( jaxbEmbeddable.getClazz(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( JaxbMappedSuperclass jaxbMappedSuperclass : ormXmlRoot.getMappedSuperclass() ) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( jaxbMappedSuperclass.getClazz(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( JaxbEntity jaxbEntity : ormXmlRoot.getEntity() ) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( jaxbEntity.getClazz(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DotName toDotName(String className, String packageName) {
|
|
||||||
if ( StringHelper.isNotEmpty( packageName ) ) {
|
|
||||||
if ( !className.contains( "." ) ) {
|
|
||||||
return DotName.createSimple( packageName + '.' + className );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return DotName.createSimple( className );
|
// add package-info from the configured packages
|
||||||
}
|
for ( String packageName : sources.getAnnotatedPackages() ) {
|
||||||
|
indexResource( packageName.replace( '.', '/' ) + "/package-info.class" );
|
||||||
|
}
|
||||||
|
|
||||||
private void indexHbmReferences(JaxbHibernateMapping hbmRoot, Indexer indexer, Set<String> processedClassNames) {
|
// the classes referenced in any xml bindings
|
||||||
final String packageName = hbmRoot.getPackage();
|
for ( BindResult bindResult : sources.bindResultList ) {
|
||||||
|
if ( JaxbHibernateMapping.class.isInstance( bindResult.getRoot() ) ) {
|
||||||
for ( JaxbClassElement hbmRootClass : hbmRoot.getClazz() ) {
|
indexHbmReferences( (JaxbHibernateMapping) bindResult.getRoot() );
|
||||||
if ( StringHelper.isNotEmpty( hbmRootClass.getName() ) ) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( hbmRootClass.getName(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
for ( JaxbSubclassElement hbmSubclassElement : hbmRootClass.getSubclass() ) {
|
|
||||||
processHbmSubclass( hbmSubclassElement, indexer, processedClassNames, packageName );
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
for ( JaxbJoinedSubclassElement hbmJoinedSubclass : hbmRootClass.getJoinedSubclass() ) {
|
final JaxbEntityMappings ormXmlRoot = (JaxbEntityMappings) bindResult.getRoot();
|
||||||
processHbmJoinedSubclass( hbmJoinedSubclass, indexer, processedClassNames, packageName );
|
if ( !isMappingMetadataComplete( ormXmlRoot ) ) {
|
||||||
}
|
indexOrmXmlReferences( ormXmlRoot );
|
||||||
|
}
|
||||||
for ( JaxbUnionSubclassElement hbmUnionSubclass : hbmRoot.getUnionSubclass() ) {
|
|
||||||
processHbmUnionSubclass( hbmUnionSubclass, indexer, processedClassNames, packageName );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Index jandexIndex = indexer.complete();
|
||||||
|
jandexIndex.printSubclasses();
|
||||||
|
jandexIndex.printAnnotations();
|
||||||
|
return jandexIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( JaxbSubclassElement hbmSubclassElement : hbmRoot.getSubclass() ) {
|
private void indexLoadedClass(Class loadedClass) {
|
||||||
if ( StringHelper.isNotEmpty( hbmSubclassElement.getName() ) ) {
|
if ( loadedClass == null ) {
|
||||||
processHbmSubclass( hbmSubclassElement, indexer, processedClassNames, packageName );
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for ( JaxbJoinedSubclassElement hbmJoinedSubclass : hbmRoot.getJoinedSubclass() ) {
|
final DotName classDotName = DotName.createSimple( loadedClass.getName() );
|
||||||
if ( StringHelper.isNotEmpty( hbmJoinedSubclass.getName() ) ) {
|
if ( !needsProcessing( classDotName ) ) {
|
||||||
processHbmJoinedSubclass( hbmJoinedSubclass, indexer, processedClassNames, packageName );
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for ( JaxbUnionSubclassElement hbmUnionSubclass : hbmRoot.getUnionSubclass() ) {
|
// index super type first
|
||||||
if ( StringHelper.isNotEmpty( hbmUnionSubclass.getName() ) ) {
|
indexLoadedClass( loadedClass.getSuperclass() );
|
||||||
processHbmUnionSubclass( hbmUnionSubclass, indexer, processedClassNames, packageName );
|
|
||||||
|
// index any inner classes
|
||||||
|
for ( Class innerClass : loadedClass.getDeclaredClasses() ) {
|
||||||
|
indexLoadedClass( innerClass );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processHbmSubclass(
|
// then index the class itself
|
||||||
JaxbSubclassElement hbmSubclassElement,
|
ClassInfo classInfo = indexResource( loadedClass.getName().replace( '.', '/' ) + ".class" );
|
||||||
Indexer indexer,
|
|
||||||
Set<String> processedClassNames,
|
|
||||||
String packageName) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( hbmSubclassElement.getName(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
for ( JaxbSubclassElement hbmSubclassElement2 : hbmSubclassElement.getSubclass() ) {
|
if ( !autoIndexMemberTypes ) {
|
||||||
processHbmSubclass( hbmSubclassElement2, indexer, processedClassNames, packageName );
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void processHbmJoinedSubclass(
|
for ( Class<?> fieldType : ReflectHelper.getMemberTypes( loadedClass ) ) {
|
||||||
JaxbJoinedSubclassElement hbmJoinedSubclass,
|
|
||||||
Indexer indexer,
|
|
||||||
Set<String> processedClassNames,
|
|
||||||
String packageName) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( hbmJoinedSubclass.getName(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
for ( JaxbJoinedSubclassElement hbmJoinedSubclass2 : hbmJoinedSubclass.getJoinedSubclass() ) {
|
|
||||||
processHbmJoinedSubclass( hbmJoinedSubclass2, indexer, processedClassNames, packageName );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processHbmUnionSubclass(
|
|
||||||
JaxbUnionSubclassElement hbmUnionSubclass,
|
|
||||||
Indexer indexer,
|
|
||||||
Set<String> processedClassNames,
|
|
||||||
String packageName) {
|
|
||||||
indexClassName(
|
|
||||||
toDotName( hbmUnionSubclass.getName(), packageName ),
|
|
||||||
indexer,
|
|
||||||
processedClassNames,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
for ( JaxbUnionSubclassElement hbmUnionSubclass2 : hbmUnionSubclass.getUnionSubclass() ) {
|
|
||||||
processHbmUnionSubclass( hbmUnionSubclass2, indexer, processedClassNames, packageName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DotName OBJECT_DOT_NAME = DotName.createSimple( Object.class.getName() );
|
|
||||||
|
|
||||||
private void indexClassName(DotName classDotName, Indexer indexer, Set<String> processedClassNames, boolean autoIndexMemberTypes) {
|
|
||||||
if ( classDotName == null || OBJECT_DOT_NAME.equals( classDotName ) || processedClassNames.contains( classDotName.toString() ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
processedClassNames.add( classDotName.toString() );
|
|
||||||
|
|
||||||
ClassInfo classInfo = indexResource( classDotName.toString().replace( '.', '/' ) + ".class", indexer );
|
|
||||||
if ( classInfo.superName() != null ) {
|
|
||||||
indexClassName( classInfo.superName(), indexer, processedClassNames, autoIndexMemberTypes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void indexClass(Class clazz, Indexer indexer, Set<String> processedClassNames, boolean autoIndexMemberTypes) {
|
|
||||||
if ( clazz == null || clazz == Object.class || processedClassNames.contains( clazz.getName() ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
processedClassNames.add( clazz.getName() );
|
|
||||||
|
|
||||||
ClassInfo classInfo = indexResource( clazz.getName().replace( '.', '/' ) + ".class", indexer );
|
|
||||||
|
|
||||||
// index all super classes of the specified class. Using org.hibernate.cfg.Configuration it was not
|
|
||||||
// necessary to add all annotated classes. Entities would be enough. Mapped superclasses would be
|
|
||||||
// discovered while processing the annotations. To keep this behavior we index all classes in the
|
|
||||||
// hierarchy (see also HHH-7484)
|
|
||||||
indexClass( clazz.getSuperclass(), indexer, processedClassNames, autoIndexMemberTypes );
|
|
||||||
|
|
||||||
// Similarly, index any inner class.
|
|
||||||
for ( Class innerClass : clazz.getDeclaredClasses() ) {
|
|
||||||
indexClass( innerClass, indexer, processedClassNames, autoIndexMemberTypes );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( autoIndexMemberTypes ) {
|
|
||||||
// If autoIndexMemberTypes, don't require @Embeddable
|
|
||||||
// classes to be explicitly identified.
|
|
||||||
// Automatically find them by checking the fields' types.
|
|
||||||
|
|
||||||
// this is NOT how this should be done. Lot of overhead here. Instead we should process them after
|
|
||||||
// the Index is built. See how EntityListeners are handled, as a "post process"
|
|
||||||
|
|
||||||
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
|
||||||
|
|
||||||
for ( Class<?> fieldType : ReflectHelper.getMemberTypes( clazz ) ) {
|
|
||||||
if ( !fieldType.isPrimitive() && fieldType != Object.class ) {
|
if ( !fieldType.isPrimitive() && fieldType != Object.class ) {
|
||||||
try {
|
indexLoadedClass( fieldType );
|
||||||
IndexView fieldIndex = JandexHelper.indexForClass( classLoaderService, fieldType );
|
|
||||||
if ( !fieldIndex.getAnnotations( JPADotNames.EMBEDDABLE ).isEmpty() ) {
|
|
||||||
indexClass( fieldType, indexer, processedClassNames, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check for classes within a @Target annotation.
|
// Also check for classes within a @Target annotation.
|
||||||
|
// [steve] - not so sure about this. target would name an entity, which should be
|
||||||
|
// known to us somehow
|
||||||
for ( AnnotationInstance targetAnnotation : JandexHelper.getAnnotations( classInfo, HibernateDotNames.TARGET ) ) {
|
for ( AnnotationInstance targetAnnotation : JandexHelper.getAnnotations( classInfo, HibernateDotNames.TARGET ) ) {
|
||||||
String targetClassName = targetAnnotation.value().asClass().name().toString();
|
String targetClassName = targetAnnotation.value().asClass().name().toString();
|
||||||
Class<?> targetClass = classLoaderService.classForName( targetClassName );
|
Class<?> targetClass = classLoaderService.classForName( targetClassName );
|
||||||
indexClass( targetClass, indexer, processedClassNames, true );
|
indexLoadedClass( targetClass );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean needsProcessing(DotName classDotName) {
|
||||||
|
if ( classDotName == null || OBJECT_DOT_NAME.equals( classDotName ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( processedClassNames.contains( classDotName ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
processedClassNames.add( classDotName );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassInfo indexResource(String resourceName) {
|
||||||
|
final URL resourceUrl = classLoaderService.locateResource( resourceName );
|
||||||
|
|
||||||
|
if ( resourceUrl == null ) {
|
||||||
|
throw new IllegalArgumentException( "Could not locate resource [" + resourceName + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final InputStream stream = resourceUrl.openStream();
|
||||||
|
try {
|
||||||
|
final ClassInfo classInfo = indexer.index( stream );
|
||||||
|
furtherProcess( classInfo );
|
||||||
|
return classInfo;
|
||||||
|
}
|
||||||
|
catch ( IOException e ) {
|
||||||
|
throw new HibernateException( "Unable to index from resource stream [" + resourceName + "]", e );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e ) {
|
||||||
|
log.debug( "Unable to close resource stream [" + resourceName + "] : " + e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e ) {
|
||||||
|
throw new HibernateException( "Unable to open input stream for resource [" + resourceName + "]", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void furtherProcess(ClassInfo classInfo) {
|
||||||
|
final List<AnnotationInstance> entityListenerAnnotations = classInfo.annotations().get( JPADotNames.ENTITY_LISTENERS );
|
||||||
|
if ( entityListenerAnnotations != null ) {
|
||||||
|
for ( AnnotationInstance entityListenerAnnotation : entityListenerAnnotations ) {
|
||||||
|
final Type[] entityListenerClassTypes = entityListenerAnnotation.value().asClassArray();
|
||||||
|
for ( Type entityListenerClassType : entityListenerClassTypes ) {
|
||||||
|
indexClassName( entityListenerClassType.name() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo : others?
|
||||||
|
}
|
||||||
|
|
||||||
|
private void indexClassName(DotName classDotName) {
|
||||||
|
if ( !needsProcessing( classDotName ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassInfo classInfo = indexResource( classDotName.toString().replace( '.', '/' ) + ".class" );
|
||||||
|
if ( classInfo.superName() != null ) {
|
||||||
|
indexClassName( classInfo.superName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void indexHbmReferences(JaxbHibernateMapping hbmRoot) {
|
||||||
|
final String packageName = hbmRoot.getPackage();
|
||||||
|
|
||||||
|
for ( JaxbClassElement hbmRootClass : hbmRoot.getClazz() ) {
|
||||||
|
if ( StringHelper.isNotEmpty( hbmRootClass.getName() ) ) {
|
||||||
|
indexClassName( toDotName( hbmRootClass.getName(), packageName ) );
|
||||||
|
|
||||||
|
for ( JaxbSubclassElement hbmSubclassElement : hbmRootClass.getSubclass() ) {
|
||||||
|
processHbmSubclass( hbmSubclassElement, packageName );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbJoinedSubclassElement hbmJoinedSubclass : hbmRootClass.getJoinedSubclass() ) {
|
||||||
|
processHbmJoinedSubclass( hbmJoinedSubclass, packageName );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbUnionSubclassElement hbmUnionSubclass : hbmRoot.getUnionSubclass() ) {
|
||||||
|
processHbmUnionSubclass( hbmUnionSubclass, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbSubclassElement hbmSubclassElement : hbmRoot.getSubclass() ) {
|
||||||
|
if ( StringHelper.isNotEmpty( hbmSubclassElement.getName() ) ) {
|
||||||
|
processHbmSubclass( hbmSubclassElement, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbJoinedSubclassElement hbmJoinedSubclass : hbmRoot.getJoinedSubclass() ) {
|
||||||
|
if ( StringHelper.isNotEmpty( hbmJoinedSubclass.getName() ) ) {
|
||||||
|
processHbmJoinedSubclass( hbmJoinedSubclass, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbUnionSubclassElement hbmUnionSubclass : hbmRoot.getUnionSubclass() ) {
|
||||||
|
if ( StringHelper.isNotEmpty( hbmUnionSubclass.getName() ) ) {
|
||||||
|
processHbmUnionSubclass( hbmUnionSubclass, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DotName toDotName(String className, String packageName) {
|
||||||
|
if ( StringHelper.isNotEmpty( packageName ) ) {
|
||||||
|
if ( !className.contains( "." ) ) {
|
||||||
|
return DotName.createSimple( packageName + '.' + className );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DotName.createSimple( className );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processHbmSubclass(JaxbSubclassElement hbmSubclassElement, String packageName) {
|
||||||
|
indexClassName( toDotName( hbmSubclassElement.getName(), packageName ) );
|
||||||
|
|
||||||
|
for ( JaxbSubclassElement hbmSubclassElement2 : hbmSubclassElement.getSubclass() ) {
|
||||||
|
processHbmSubclass( hbmSubclassElement2, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processHbmJoinedSubclass(JaxbJoinedSubclassElement hbmJoinedSubclass, String packageName) {
|
||||||
|
indexClassName( toDotName( hbmJoinedSubclass.getName(), packageName ) );
|
||||||
|
|
||||||
|
for ( JaxbJoinedSubclassElement hbmJoinedSubclass2 : hbmJoinedSubclass.getJoinedSubclass() ) {
|
||||||
|
processHbmJoinedSubclass( hbmJoinedSubclass2, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processHbmUnionSubclass(JaxbUnionSubclassElement hbmUnionSubclass, String packageName) {
|
||||||
|
indexClassName( toDotName( hbmUnionSubclass.getName(), packageName ) );
|
||||||
|
|
||||||
|
for ( JaxbUnionSubclassElement hbmUnionSubclass2 : hbmUnionSubclass.getUnionSubclass() ) {
|
||||||
|
processHbmUnionSubclass( hbmUnionSubclass2, packageName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMappingMetadataComplete(JaxbEntityMappings ormXmlRoot) {
|
||||||
|
return ormXmlRoot.getPersistenceUnitMetadata() != null
|
||||||
|
&& ormXmlRoot.getPersistenceUnitMetadata().getXmlMappingMetadataComplete() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void indexOrmXmlReferences(JaxbEntityMappings ormXmlRoot) {
|
||||||
|
final String packageName = ormXmlRoot.getPackage();
|
||||||
|
|
||||||
|
for ( JaxbConverter jaxbConverter : ormXmlRoot.getConverter() ) {
|
||||||
|
indexClassName( toDotName( jaxbConverter.getClazz(), packageName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbEmbeddable jaxbEmbeddable : ormXmlRoot.getEmbeddable() ) {
|
||||||
|
indexClassName( toDotName( jaxbEmbeddable.getClazz(), packageName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbMappedSuperclass jaxbMappedSuperclass : ormXmlRoot.getMappedSuperclass() ) {
|
||||||
|
indexClassName( toDotName( jaxbMappedSuperclass.getClazz(), packageName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( JaxbEntity jaxbEntity : ormXmlRoot.getEntity() ) {
|
||||||
|
indexClassName( toDotName( jaxbEntity.getClazz(), packageName ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassInfo indexResource(String resourceName, Indexer indexer) {
|
/**
|
||||||
ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
* Create a Jandex IndexView from scratch given the sources information contained here.
|
||||||
|
*
|
||||||
if ( classLoaderService.locateResource( resourceName ) != null ) {
|
* @param autoIndexMemberTypes Should the types of class members automatically be added to the built index?
|
||||||
InputStream stream = classLoaderService.locateResourceStream( resourceName );
|
*
|
||||||
try {
|
* @return
|
||||||
return indexer.index( stream );
|
*/
|
||||||
}
|
public IndexView buildJandexView(boolean autoIndexMemberTypes) {
|
||||||
catch ( IOException e ) {
|
return wrapJandexView( JandexIndexBuilder.process( autoIndexMemberTypes, this ) );
|
||||||
throw new HibernateException( "Unable to open input stream for resource " + resourceName, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ public class AssertSourcesTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
MetadataSources ann = new MetadataSources( serviceRegistry );
|
MetadataSources ann = new MetadataSources( serviceRegistry );
|
||||||
ann.addAnnotatedClass( User.class );
|
ann.addAnnotatedClass( User.class );
|
||||||
|
ann.addAnnotatedClass( User.Name.class );
|
||||||
MetadataSourceProcessor annProcessor = new AnnotationMetadataSourceProcessorImpl(
|
MetadataSourceProcessor annProcessor = new AnnotationMetadataSourceProcessorImpl(
|
||||||
buildMetadata( ann ),
|
buildMetadata( ann ),
|
||||||
ann.buildJandexView()
|
ann.buildJandexView()
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.annotations.jandex;
|
||||||
|
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class ApplicationServer {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
private Version version;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
public Version getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(Version version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.annotations.jandex;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
import org.jboss.jandex.DotName;
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
import org.jboss.jandex.IndexView;
|
||||||
|
import org.jboss.jandex.Indexer;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class BasicJandexExpectationsTest extends BaseUnitTestCase {
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
Indexer indexer = new Indexer();
|
||||||
|
add( Version.class, indexer );
|
||||||
|
add( ApplicationServer.class, indexer );
|
||||||
|
|
||||||
|
Index index = indexer.complete();
|
||||||
|
|
||||||
|
index.printSubclasses();
|
||||||
|
index.printAnnotations();
|
||||||
|
|
||||||
|
ClassInfo ci = index.getClassByName( DotName.createSimple( ApplicationServer.class.getName() ) );
|
||||||
|
List<AnnotationInstance> annotations = ci.annotations().get( DotName.createSimple( javax.persistence.Id.class.getName() ) );
|
||||||
|
assertNotNull( annotations );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndexingSameClassMultipleTimes() {
|
||||||
|
Indexer indexer = new Indexer();
|
||||||
|
add( Version.class, indexer );
|
||||||
|
add( Version.class, indexer );
|
||||||
|
add( Version.class, indexer );
|
||||||
|
add( ApplicationServer.class, indexer );
|
||||||
|
|
||||||
|
Index index = indexer.complete();
|
||||||
|
|
||||||
|
index.printSubclasses();
|
||||||
|
index.printAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassInfo add(Class theClass, Indexer indexer) {
|
||||||
|
final String theClassResourceName = '/' + theClass.getName().replace( '.', '/' ) + ".class";
|
||||||
|
|
||||||
|
InputStream stream = getClass().getResourceAsStream( theClassResourceName );
|
||||||
|
|
||||||
|
try {
|
||||||
|
return indexer.index( stream );
|
||||||
|
}
|
||||||
|
catch ( IOException e ) {
|
||||||
|
throw new HibernateException( "Unable to open input stream for resource " + theClassResourceName, e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.annotations.jandex;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Embeddable
|
||||||
|
public class Version {
|
||||||
|
private static final String DOT = ".";
|
||||||
|
private int major;
|
||||||
|
private int minor;
|
||||||
|
private int micro;
|
||||||
|
|
||||||
|
public int getMajor() {
|
||||||
|
return major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMajor(int major) {
|
||||||
|
this.major = major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinor() {
|
||||||
|
return minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinor(int minor) {
|
||||||
|
this.minor = minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMicro() {
|
||||||
|
return micro;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMicro(int micro) {
|
||||||
|
this.micro = micro;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return new StringBuffer( major ).append( DOT ).append( minor ).append( DOT ).append( micro ).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
//$Id$
|
//$Id$
|
||||||
package org.hibernate.jpa.test.pack.defaultpar_1_0;
|
package org.hibernate.jpa.test.pack.defaultpar_1_0;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
@ -31,6 +32,7 @@ public class ApplicationServer1 {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Embedded
|
||||||
public Version1 getVersion() {
|
public Version1 getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue