HHH-8934 - MetadataSources needs to index (Jandex) classes referenced in xml files

This commit is contained in:
Steve Ebersole 2014-02-05 15:40:01 -06:00
parent 7fdf40c693
commit f8020670d0
6 changed files with 473 additions and 266 deletions

View File

@ -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;
} }
} }

View File

@ -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()

View File

@ -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;
}
}

View File

@ -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 );
}
}
}

View File

@ -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();
}
}

View File

@ -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;
} }