diff --git a/build.gradle b/build.gradle index 0646f16e94..1ca25ec6da 100644 --- a/build.gradle +++ b/build.gradle @@ -46,6 +46,7 @@ libraries = [ // Annotations commons_annotations: 'org.hibernate:hibernate-commons-annotations:3.2.0.Final', + jandex: 'org.jboss:jandex:1.0.0.Beta6', // Jakarta commons-collections todo : get rid of commons-collections dependency commons_collections: @@ -53,6 +54,7 @@ libraries = [ // Dom4J dom4j: 'dom4j:dom4j:1.6.1@jar', + jaxb: 'com.sun.xml.bind:jaxb-xjc:2.1.6', // h2 h2: 'com.h2database:h2:1.2.145', @@ -114,11 +116,14 @@ subprojects { subProject -> deployerJars { description = 'Jars needed for doing deployment to JBoss Nexus repo' } + jaxb { + description = 'Dependencies for running ant xjc (jaxb class generation)' + } } // appropriately inject the common dependencies into each sub-project dependencies { - compile( libraries.logging ) + compile( libraries.logging ) testCompile( libraries.junit ) testRuntime( libraries.slf4j_api ) testRuntime( libraries.slf4j_log4j12 ) @@ -127,8 +132,9 @@ subprojects { subProject -> testRuntime( libraries.jcl ) testRuntime( libraries.javassist ) testRuntime( libraries.h2 ) - jbossLoggingTool( libraries.logging_tools ) + jbossLoggingTool( libraries.logging_tools ) hibernateJpaModelGenTool( libraries.jpa_modelgen ) + jaxb( libraries.jaxb ) deployerJars "org.apache.maven.wagon:wagon-http:1.0-beta-6" } diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index 61a6fc4143..87d9888069 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -9,6 +9,7 @@ dependencies { transitive = false } compile( libraries.commons_annotations ) + compile( libraries.jandex ) compile( libraries.jpa ) compile( libraries.javassist ) antlr( libraries.antlr ) @@ -43,3 +44,16 @@ ideaModule { } +task jaxb << { + jaxbTargetDir = file( "${buildDir}/generated-src/jaxb" ) + jaxbTargetDir.mkdirs() + + ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.jaxb.asPath) + ant.jaxbTargetDir = jaxbTargetDir + ant.xjc(destdir: '${jaxbTargetDir}', package: 'org.hibernate.metamodel.source.xml') { + schema(dir: 'src/main/resources/org/hibernate/ejb', includes: 'orm_2_0.xsd') + } +} +compileJava.dependsOn jaxb + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java index 57cefd3e8d..b9d0d449af 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java @@ -28,7 +28,7 @@ import org.hibernate.internal.CoreMessageLogger; import org.jboss.logging.Logger; /** - * TODO : javadoc + * Binds the entity identifier. * * @author Steve Ebersole */ @@ -42,7 +42,8 @@ public class EntityIdentifier { /** * Create an identifier - * @param entityBinding + * + * @param entityBinding the entity binding for which this instance is the id */ public EntityIdentifier(EntityBinding entityBinding) { this.entityBinding = entityBinding; @@ -54,7 +55,8 @@ public class EntityIdentifier { public void setValueBinding(AttributeBinding attributeBinding) { if ( this.attributeBinding != null ) { - // todo : error? or just log? for now just log + // todo : error? or just log? For now throw exception and see what happens. Easier to see whether this + // method gets called multiple times LOG.entityIdentifierValueBindingExists( entityBinding.getEntity().getName() ); } this.attributeBinding = attributeBinding; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java index 6a9b819a86..e4d9ad74b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java @@ -29,23 +29,21 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.hibernate.DuplicateMappingException; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.annotations.common.reflection.MetadataProvider; -import org.hibernate.annotations.common.reflection.MetadataProviderInjector; -import org.hibernate.annotations.common.reflection.ReflectionManager; -import org.hibernate.annotations.common.reflection.java.JavaReflectionManager; import org.hibernate.cfg.EJB3NamingStrategy; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider; import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.MetadataSource; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.relational.Database; +import org.hibernate.metamodel.source.annotations.AnnotationBinder; import org.hibernate.metamodel.source.hbm.HibernateXmlBinder; -import org.jboss.logging.Logger; /** * TODO : javadoc @@ -53,19 +51,36 @@ import org.jboss.logging.Logger; * @author Steve Ebersole */ public class Metadata implements Serializable { + private static final Logger log = LoggerFactory.getLogger( Metadata.class ); - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, Metadata.class.getName()); + private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, Metadata.class.getName()); + private final AnnotationBinder annotationBinder; + private final HibernateXmlBinder hibernateXmlBinder; + private final ExtendsQueue extendsQueue; + private final MetadataSourceQueue metadataSourceQueue; + private final Database database = new Database(); - private final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this ); - private final ExtendsQueue extendsQueue = new ExtendsQueue( this ); - private final MetadataSourceQueue metadataSourceQueue = new MetadataSourceQueue( this ); + private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE; + private Map entityBindingMap = new HashMap(); + private Map collectionBindingMap = new HashMap(); + private Map fetchProfiles = new HashMap(); + private Map imports; - private transient ReflectionManager reflectionManager = createReflectionManager(); + public Metadata() { + annotationBinder = new AnnotationBinder( this ); + hibernateXmlBinder = new HibernateXmlBinder( this ); + extendsQueue = new ExtendsQueue( this ); + metadataSourceQueue = new MetadataSourceQueue( this ); + } public HibernateXmlBinder getHibernateXmlBinder() { return hibernateXmlBinder; } + public AnnotationBinder getAnnotationBinder() { + return annotationBinder; + } + public ExtendsQueue getExtendsQueue() { return extendsQueue; } @@ -74,32 +89,10 @@ public class Metadata implements Serializable { return metadataSourceQueue; } - public ReflectionManager getReflectionManager() { - return reflectionManager; - } - - public void setReflectionManager(ReflectionManager reflectionManager) { - this.reflectionManager = reflectionManager; - } - - private ReflectionManager createReflectionManager() { - return createReflectionManager( new JPAMetadataProvider() ); - } - - private ReflectionManager createReflectionManager(MetadataProvider metadataProvider) { - ReflectionManager reflectionManager = new JavaReflectionManager(); - ( (MetadataProviderInjector) reflectionManager ).setMetadataProvider( metadataProvider ); - return reflectionManager; - } - - private final Database database = new Database(); - public Database getDatabase() { return database; } - private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE; - public NamingStrategy getNamingStrategy() { return namingStrategy; } @@ -108,8 +101,6 @@ public class Metadata implements Serializable { this.namingStrategy = namingStrategy; } - private Map entityBindingMap = new HashMap(); - public EntityBinding getEntityBinding(String entityName) { return entityBindingMap.get( entityName ); } @@ -126,8 +117,6 @@ public class Metadata implements Serializable { entityBindingMap.put( entityName, entityBinding ); } - private Map collectionBindingMap = new HashMap(); - public PluralAttributeBinding getCollection(String collectionRole) { return collectionBindingMap.get( collectionRole ); } @@ -146,21 +135,17 @@ public class Metadata implements Serializable { collectionBindingMap.put( collectionRole, pluralAttributeBinding ); } - private Map imports; - public void addImport(String importName, String entityName) { if ( imports == null ) { imports = new HashMap(); } - LOG.tracef( "Import: %s -> %s", importName, entityName ); + log.trace( "Import: " + importName + " -> " + entityName ); String old = imports.put( importName, entityName ); if ( old != null ) { - LOG.debugf( "import name [%s] overrode previous [%s]", importName, old ); + log.debug( "import name [{}] overrode previous [{}]", importName, old ); } } - private Map fetchProfiles = new HashMap(); - public Iterable getFetchProfiles() { return fetchProfiles.values(); } @@ -175,16 +160,10 @@ public class Metadata implements Serializable { } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { - //we need reflectionManager before reading the other components (MetadataSourceQueue in particular) - final MetadataProvider metadataProvider = (MetadataProvider) ois.readObject(); - this.reflectionManager = createReflectionManager( metadataProvider ); ois.defaultReadObject(); } private void writeObject(java.io.ObjectOutputStream out) throws IOException { - //We write MetadataProvider first as we need reflectionManager before reading the other components - final MetadataProvider metadataProvider = ( ( MetadataProviderInjector ) reflectionManager ).getMetadataProvider(); - out.writeObject( metadataProvider ); out.defaultWriteObject(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java index ae389e426c..3c1b7b9c94 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java @@ -34,20 +34,20 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import javax.persistence.Entity; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.InvalidMappingException; import org.hibernate.MappingException; -import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.cfg.MetadataSourceType; import org.hibernate.internal.util.collections.JoinedIterator; import org.hibernate.internal.util.xml.XmlDocument; -import org.jboss.logging.Logger; + /** * TODO : javadoc @@ -55,19 +55,14 @@ import org.jboss.logging.Logger; * @author Steve Ebersole */ public class MetadataSourceQueue implements Serializable { - + private static final Logger log = LoggerFactory.getLogger( MetadataSourceQueue.class ); private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataSourceQueue.class.getName()); - private final Metadata metadata; private LinkedHashMap> hbmMetadataToEntityNamesMap = new LinkedHashMap>(); private Map hbmMetadataByEntityNameXRef = new HashMap(); - - //XClass are not serializable by default - private transient List annotatedClasses = new ArrayList(); - //only used during the secondPhaseCompile pass, hence does not need to be serialized - private transient Map annotatedClassesByEntityNameMap = new HashMap(); + private transient List annotatedClasses = new ArrayList(); public MetadataSourceQueue(Metadata metadata) { this.metadata = metadata; @@ -75,24 +70,10 @@ public class MetadataSourceQueue implements Serializable { private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); - annotatedClassesByEntityNameMap = new HashMap(); - - //build back annotatedClasses - @SuppressWarnings("unchecked") - List serializableAnnotatedClasses = (List) ois.readObject(); - annotatedClasses = new ArrayList( serializableAnnotatedClasses.size() ); - for ( Class clazz : serializableAnnotatedClasses ) { - annotatedClasses.add( metadata.getReflectionManager().toXClass( clazz ) ); - } } private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.defaultWriteObject(); - List serializableAnnotatedClasses = new ArrayList( annotatedClasses.size() ); - for ( XClass xClass : annotatedClasses ) { - serializableAnnotatedClasses.add( metadata.getReflectionManager().toClass( xClass ) ); - } - out.writeObject( serializableAnnotatedClasses ); } public void add(XmlDocument metadataXml) { @@ -143,28 +124,11 @@ public class MetadataSourceQueue implements Serializable { return unqualifiedName; } - public void add(XClass annotatedClass) { + public void add(Class annotatedClass) { annotatedClasses.add( annotatedClass ); } - protected void syncAnnotatedClasses() { - final Iterator itr = annotatedClasses.iterator(); - while ( itr.hasNext() ) { - final XClass annotatedClass = itr.next(); - if ( annotatedClass.isAnnotationPresent( Entity.class ) ) { - annotatedClassesByEntityNameMap.put( annotatedClass.getName(), annotatedClass ); - continue; - } - - if ( !annotatedClass.isAnnotationPresent( javax.persistence.MappedSuperclass.class ) ) { - itr.remove(); - } - } - } - protected void processMetadata(List order) { - syncAnnotatedClasses(); - for ( MetadataSourceType type : order ) { if ( MetadataSourceType.HBM.equals( type ) ) { processHbmXmlQueue(); @@ -176,7 +140,7 @@ public class MetadataSourceQueue implements Serializable { } private void processHbmXmlQueue() { - LOG.debug( "Processing hbm.xml files" ); + log.debug( "Processing hbm.xml files" ); for ( Map.Entry> entry : hbmMetadataToEntityNamesMap.entrySet() ) { // Unfortunately we have to create a Mappings instance for each iteration here processHbmXml( entry.getKey(), entry.getValue() ); @@ -196,83 +160,14 @@ public class MetadataSourceQueue implements Serializable { me ); } - - for ( String entityName : entityNames ) { - if ( annotatedClassesByEntityNameMap.containsKey( entityName ) ) { - annotatedClasses.remove( annotatedClassesByEntityNameMap.get( entityName ) ); - annotatedClassesByEntityNameMap.remove( entityName ); - } - } } private void processAnnotatedClassesQueue() { - LOG.debug( "Process annotated classes" ); - //bind classes in the correct order calculating some inheritance state - List orderedClasses = orderAndFillHierarchy( annotatedClasses ); -// Map inheritanceStatePerClass = AnnotationBinder.buildInheritanceStates( -// orderedClasses, mappings -// ); - - - for ( XClass clazz : orderedClasses ) { -// todo : replace this with similar non-static code. -// AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, mappings ); - - final String entityName = clazz.getName(); - if ( hbmMetadataByEntityNameXRef.containsKey( entityName ) ) { - hbmMetadataToEntityNamesMap.remove( hbmMetadataByEntityNameXRef.get( entityName ) ); - hbmMetadataByEntityNameXRef.remove( entityName ); - } - } + log.debug( "Process annotated classes" ); annotatedClasses.clear(); - annotatedClassesByEntityNameMap.clear(); - } - - private List orderAndFillHierarchy(List original) { - List copy = new ArrayList( original ); - insertMappedSuperclasses( original, copy ); - - // order the hierarchy - List workingCopy = new ArrayList( copy ); - List newList = new ArrayList( copy.size() ); - while ( workingCopy.size() > 0 ) { - XClass clazz = workingCopy.get( 0 ); - orderHierarchy( workingCopy, newList, copy, clazz ); - } - return newList; - } - - private void insertMappedSuperclasses(List original, List copy) { - for ( XClass clazz : original ) { - XClass superClass = clazz.getSuperclass(); - while ( superClass != null - && !metadata.getReflectionManager().equals( superClass, Object.class ) - && !copy.contains( superClass ) ) { - if ( superClass.isAnnotationPresent( Entity.class ) - || superClass.isAnnotationPresent( javax.persistence.MappedSuperclass.class ) ) { - copy.add( superClass ); - } - superClass = superClass.getSuperclass(); - } - } - } - - private void orderHierarchy(List copy, List newList, List original, XClass clazz) { - if ( clazz == null || metadata.getReflectionManager().equals( clazz, Object.class ) ) { - return; - } - //process superclass first - orderHierarchy( copy, newList, original, clazz.getSuperclass() ); - if ( original.contains( clazz ) ) { - if ( !newList.contains( clazz ) ) { - newList.add( clazz ); - } - copy.remove( clazz ); - } } public boolean isEmpty() { return hbmMetadataToEntityNamesMap.isEmpty() && annotatedClasses.isEmpty(); } - } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java new file mode 100644 index 0000000000..28017a5ad2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java @@ -0,0 +1,336 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, 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.metamodel.source.annotations; + +import java.util.Iterator; +import java.util.List; +import javax.persistence.MappedSuperclass; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Index; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.hibernate.AnnotationException; +import org.hibernate.AssertionFailure; +import org.hibernate.metamodel.source.Metadata; + +/** + * Main class responsible to creating and binding the Hibernate meta-model from annotations. + * This binder only has to deal with annotation index. XML configuration is already processed and pseudo annotations + * are added to the annotation index. + * + * @author Hardy Ferentschik + * @todo On top of the index we probably needs to pass some sort of XMLContext for global configuration data + * @todo The annotation index should really be passed at construction time + */ +public class AnnotationBinder { + public static final DotName ENTITY = DotName.createSimple( Entity.class.getName() ); + public static final DotName HIBERNATE_ENTITY = DotName.createSimple( org.hibernate.annotations.Entity.class.getName() ); + public static final DotName MAPPED_SUPER_CLASS = DotName.createSimple( MappedSuperclass.class.getName() ); + + private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class ); + private final Metadata metadata; + + public AnnotationBinder(Metadata metadata) { + this.metadata = metadata; + } + + public void bindMappedClasses(Index annotationIndex) { + // need to order our annotated entities into an order we can process + EntityHierarchyBuilder builder = new EntityHierarchyBuilder(); + List hierarchies = builder.createEntityHierarchies( annotationIndex ); + + // now we process each hierarchy one at the time + for ( EntityHierarchy hierarchy : hierarchies ) { + Iterator iter = hierarchy.iterator(); + while ( iter.hasNext() ) { + Entity entity = iter.next(); + bindEntity( entity ); + } + } + } + + public void bindEntity(Entity entity) { + ClassInfo classInfo = entity.getClassInfo(); + + //@Entity and @MappedSuperclass on the same class leads to a NPE down the road + AnnotationInstance jpaEntityAnnotation = getSingleAnnotation( classInfo, ENTITY ); + AnnotationInstance mappedSuperClassAnnotation = getSingleAnnotation( classInfo, MAPPED_SUPER_CLASS ); + AnnotationInstance hibernateEntityAnnotation = getSingleAnnotation( classInfo, HIBERNATE_ENTITY ); + + if ( jpaEntityAnnotation != null && mappedSuperClassAnnotation != null ) { + throw new AnnotationException( + "An entity cannot be annotated with both @Entity and @MappedSuperclass: " + + classInfo.name().toString() + ); + } + + +// //TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc) +// InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess ); +// AnnotatedClassType classType = mappings.getClassType( clazzToProcess ); +// +// //Queries declared in MappedSuperclass should be usable in Subclasses +// if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) { +// bindQueries( clazzToProcess, mappings ); +// bindTypeDefs( clazzToProcess, mappings ); +// bindFilterDefs( clazzToProcess, mappings ); +// } +// +// if ( !isEntityClassType( clazzToProcess, classType ) ) { +// return; +// } +// + log.info( "Binding entity from annotated class: {}", classInfo.name() ); +// +// PersistentClass superEntity = getSuperEntity( +// clazzToProcess, inheritanceStatePerClass, mappings, inheritanceState +// ); +// +// PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity ); + + + EntityBinder entityBinder = new EntityBinder( + metadata, classInfo, jpaEntityAnnotation, hibernateEntityAnnotation + ); +// entityBinder.setInheritanceState( inheritanceState ); +// +// bindQueries( clazzToProcess, mappings ); +// bindFilterDefs( clazzToProcess, mappings ); +// bindTypeDefs( clazzToProcess, mappings ); +// bindFetchProfiles( clazzToProcess, mappings ); +// BinderHelper.bindAnyMetaDefs( clazzToProcess, mappings ); +// +// String schema = ""; +// String table = ""; //might be no @Table annotation on the annotated class +// String catalog = ""; +// List uniqueConstraints = new ArrayList(); +// if ( clazzToProcess.isAnnotationPresent( javax.persistence.Table.class ) ) { +// javax.persistence.Table tabAnn = clazzToProcess.getAnnotation( javax.persistence.Table.class ); +// table = tabAnn.name(); +// schema = tabAnn.schema(); +// catalog = tabAnn.catalog(); +// uniqueConstraints = TableBinder.buildUniqueConstraintHolders( tabAnn.uniqueConstraints() ); +// } +// +// Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns( +// clazzToProcess, mappings, inheritanceState, superEntity +// ); +// Ejb3DiscriminatorColumn discriminatorColumn = null; +// if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) { +// discriminatorColumn = processDiscriminatorProperties( +// clazzToProcess, mappings, inheritanceState, entityBinder +// ); +// } +// +// entityBinder.setProxy( clazzToProcess.getAnnotation( Proxy.class ) ); +// entityBinder.setBatchSize( clazzToProcess.getAnnotation( BatchSize.class ) ); +// entityBinder.setWhere( clazzToProcess.getAnnotation( Where.class ) ); +// entityBinder.setCache( determineCacheSettings( clazzToProcess, mappings ) ); +// +// //Filters are not allowed on subclasses +// if ( !inheritanceState.hasParents() ) { +// bindFilters( clazzToProcess, entityBinder, mappings ); +// } +// +// entityBinder.bindEntity(); +// +// if ( inheritanceState.hasTable() ) { +// Check checkAnn = clazzToProcess.getAnnotation( Check.class ); +// String constraints = checkAnn == null ? +// null : +// checkAnn.constraints(); +// entityBinder.bindTable( +// schema, catalog, table, uniqueConstraints, +// constraints, inheritanceState.hasDenormalizedTable() ? +// superEntity.getTable() : +// null +// ); +// } +// else { +// if ( clazzToProcess.isAnnotationPresent( Table.class ) ) { +// log.warn( +// "Illegal use of @Table in a subclass of a SINGLE_TABLE hierarchy: " + clazzToProcess +// .getName() +// ); +// } +// } +// +// PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder( +// clazzToProcess, +// persistentClass, +// entityBinder, mappings, inheritanceStatePerClass +// ); +// +// javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation( +// javax.persistence.SecondaryTable.class +// ); +// javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation( +// javax.persistence.SecondaryTables.class +// ); +// entityBinder.firstLevelSecondaryTablesBinding( secTabAnn, secTabsAnn ); +// +// OnDelete onDeleteAnn = clazzToProcess.getAnnotation( OnDelete.class ); +// boolean onDeleteAppropriate = false; +// if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) && inheritanceState.hasParents() ) { +// onDeleteAppropriate = true; +// final JoinedSubclass jsc = ( JoinedSubclass ) persistentClass; +// if ( persistentClass.getEntityPersisterClass() == null ) { +// persistentClass.getRootClass().setEntityPersisterClass( JoinedSubclassEntityPersister.class ); +// } +// SimpleValue key = new DependantValue( mappings, jsc.getTable(), jsc.getIdentifier() ); +// jsc.setKey( key ); +// ForeignKey fk = clazzToProcess.getAnnotation( ForeignKey.class ); +// if ( fk != null && !BinderHelper.isEmptyAnnotationValue( fk.name() ) ) { +// key.setForeignKeyName( fk.name() ); +// } +// if ( onDeleteAnn != null ) { +// key.setCascadeDeleteEnabled( OnDeleteAction.CASCADE.equals( onDeleteAnn.action() ) ); +// } +// else { +// key.setCascadeDeleteEnabled( false ); +// } +// //we are never in a second pass at that stage, so queue it +// SecondPass sp = new JoinedSubclassFkSecondPass( jsc, inheritanceJoinedColumns, key, mappings ); +// mappings.addSecondPass( sp ); +// mappings.addSecondPass( new CreateKeySecondPass( jsc ) ); +// +// } +// else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) { +// if ( inheritanceState.hasParents() ) { +// if ( persistentClass.getEntityPersisterClass() == null ) { +// persistentClass.getRootClass().setEntityPersisterClass( SingleTableEntityPersister.class ); +// } +// } +// else { +// if ( inheritanceState.hasSiblings() || !discriminatorColumn.isImplicit() ) { +// //need a discriminator column +// bindDiscriminatorToPersistentClass( +// (RootClass) persistentClass, +// discriminatorColumn, +// entityBinder.getSecondaryTables(), +// propertyHolder, +// mappings +// ); +// entityBinder.bindDiscriminatorValue();//bind it again since the type might have changed +// } +// } +// } +// else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) { +// if ( inheritanceState.hasParents() ) { +// if ( persistentClass.getEntityPersisterClass() == null ) { +// persistentClass.getRootClass().setEntityPersisterClass( UnionSubclassEntityPersister.class ); +// } +// } +// } +// if ( onDeleteAnn != null && !onDeleteAppropriate ) { +// log.warn( +// "Inapropriate use of @OnDelete on entity, annotation ignored: {}", propertyHolder.getEntityName() +// ); +// } +// +// // try to find class level generators +// HashMap classGenerators = buildLocalGenerators( clazzToProcess, mappings ); +// +// // check properties +// final InheritanceState.ElementsToProcess elementsToProcess = inheritanceState.getElementsToProcess(); +// inheritanceState.postProcess( persistentClass, entityBinder ); +// +// final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE +// && inheritanceState.hasParents(); +// Set idPropertiesIfIdClass = new HashSet(); +// boolean isIdClass = mapAsIdClass( +// inheritanceStatePerClass, +// inheritanceState, +// persistentClass, +// entityBinder, +// propertyHolder, +// elementsToProcess, +// idPropertiesIfIdClass, +// mappings +// ); +// +// if ( !isIdClass ) { +// entityBinder.setWrapIdsInEmbeddedComponents( elementsToProcess.getIdPropertyCount() > 1 ); +// } +// +// processIdPropertiesIfNotAlready( +// inheritanceStatePerClass, +// mappings, +// persistentClass, +// entityBinder, +// propertyHolder, +// classGenerators, +// elementsToProcess, +// subclassAndSingleTableStrategy, +// idPropertiesIfIdClass +// ); +// +// if ( !inheritanceState.hasParents() ) { +// final RootClass rootClass = ( RootClass ) persistentClass; +// mappings.addSecondPass( new CreateKeySecondPass( rootClass ) ); +// } +// else { +// superEntity.addSubclass( (Subclass) persistentClass ); +// } +// +// mappings.addClass( persistentClass ); +// +// //Process secondary tables and complementary definitions (ie o.h.a.Table) +// mappings.addSecondPass( new SecondaryTableSecondPass( entityBinder, propertyHolder, clazzToProcess ) ); +// +// //add process complementary Table definition (index & all) +// entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Table.class ) ); +// entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Tables.class ) ); + } + + /** + * @param classInfo the class info from which to retrieve the annotation instance + * @param annotationName the annotation to retrieve from the class info + * + * @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all + * + * @throws AssertionFailure in case there is + */ + private AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName) + throws AssertionFailure { + List annotationList = classInfo.annotations().get( annotationName ); + if ( annotationList == null ) { + return null; + } + else if ( annotationList.size() == 1 ) { + return annotationList.get( 0 ); + } + else { + throw new AssertionFailure( + "There should be only one annotation of type " + annotationName + " defined on" + classInfo.name() + ); + } + } +} + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/Entity.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/Entity.java new file mode 100644 index 0000000000..b35ca50387 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/Entity.java @@ -0,0 +1,41 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, 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.metamodel.source.annotations; + +import org.jboss.jandex.ClassInfo; + +/** + * Represents an entity or mapped superclass which needs to be mapped. + * + * @author Hardy Ferentschik + */ +public class Entity { + private ClassInfo classInfo; + + public ClassInfo getClassInfo() { + return classInfo; + } +} + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java new file mode 100644 index 0000000000..42fa1a3841 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java @@ -0,0 +1,85 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, 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.metamodel.source.annotations; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassInfo; + +import org.hibernate.AssertionFailure; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.metamodel.binding.EntityBinding; +import org.hibernate.metamodel.domain.Entity; +import org.hibernate.metamodel.source.Metadata; + +/** + * @author Hardy Ferentschik + */ +public class EntityBinder { + private final ClassInfo classToBind; + + public EntityBinder(Metadata metadata, ClassInfo classInfo, AnnotationInstance jpaEntityAnnotation, AnnotationInstance hibernateEntityAnnotation) { + this.classToBind = classInfo; + EntityBinding entityBinding = new EntityBinding(); + bindJpaAnnotation( jpaEntityAnnotation, entityBinding ); + bindHibernateAnnotation( hibernateEntityAnnotation, entityBinding ); + metadata.addEntity( entityBinding ); + } + + private void bindHibernateAnnotation(AnnotationInstance annotation, EntityBinding entityBinding) { +// if ( hibAnn != null ) { +// dynamicInsert = hibAnn.dynamicInsert(); +// dynamicUpdate = hibAnn.dynamicUpdate(); +// optimisticLockType = hibAnn.optimisticLock(); +// selectBeforeUpdate = hibAnn.selectBeforeUpdate(); +// polymorphismType = hibAnn.polymorphism(); +// explicitHibernateEntityAnnotation = true; +// //persister handled in bind +// } +// else { +// //default values when the annotation is not there +// dynamicInsert = false; +// dynamicUpdate = false; +// optimisticLockType = OptimisticLockType.VERSION; +// polymorphismType = PolymorphismType.IMPLICIT; +// selectBeforeUpdate = false; +// } + } + + private void bindJpaAnnotation(AnnotationInstance annotation, EntityBinding entityBinding) { + if ( annotation == null ) { + throw new AssertionFailure( "@Entity cannot be not null when binding an entity" ); + } + String name; + if ( annotation.value( "name" ) == null ) { + name = StringHelper.unqualify( classToBind.name().toString() ); + } + else { + name = annotation.value( "name" ).asString(); + } + entityBinding.setEntity( new Entity( name, null ) ); + } +} + + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityHierarchy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityHierarchy.java new file mode 100644 index 0000000000..ef928c27ba --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityHierarchy.java @@ -0,0 +1,38 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, 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.metamodel.source.annotations; + +import java.util.Iterator; + +/** + * @author Hardy Ferentschik + */ +public class EntityHierarchy implements Iterable { + @Override + public Iterator iterator() { + return null; + } +} + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityHierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityHierarchyBuilder.java new file mode 100644 index 0000000000..feffb255dd --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityHierarchyBuilder.java @@ -0,0 +1,22 @@ +package org.hibernate.metamodel.source.annotations; + +import java.util.ArrayList; +import java.util.List; + +import org.jboss.jandex.Index; + +/** + * Given a annotation index build a list of entity hierarchies. + * + * @author Hardy Ferentschik + */ +public class EntityHierarchyBuilder { + public List createEntityHierarchies(Index index) { + List hierarchies = new ArrayList(); + + + return hierarchies; + } +} + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java new file mode 100644 index 0000000000..b6cf51254c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java @@ -0,0 +1,99 @@ +package org.hibernate.metamodel.source.annotations; + +import java.io.InputStream; +import java.net.URL; +import java.util.HashSet; +import java.util.Set; +import javax.validation.ValidationException; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.jboss.jandex.Index; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +import org.hibernate.metamodel.source.xml.EntityMappings; + +/** + * @author Hardy Ferentschik + * @todo Need some create some XMLContext as well which can be populated w/ information which can not be expressed via annotations + */ +public class OrmXmlParser { + private static final Logger log = LoggerFactory.getLogger( OrmXmlParser.class ); + private static final String ORM_MAPPING_XSD = "org/hibernate/ejb/orm_2_0.xsd"; + + /** + * Parses the given xml configuration files and returns a updated annotation index + * + * @param mappingFileNames the file names of the xml files to parse + * @param annotationIndex the annotation index based on scanned annotations + * + * @return a new updated annotation index, enhancing and modifying the existing ones according to the jpa xml rules + */ + public Index parseAndUpdateIndex(Set mappingFileNames, Index annotationIndex) { + + Set mappingStreams = new HashSet(); + for ( String fileName : mappingFileNames ) { + mappingStreams.add( getInputStreamForPath( fileName ) ); + } + + for ( InputStream in : mappingStreams ) { + EntityMappings entityMappings = getEntityMappings( in ); + // ... + } + + return null; + } + + private InputStream getInputStreamForPath(String path) { + // try the context class loader first + InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( path ); + + // try the current class loader + if ( inputStream == null ) { + inputStream = OrmXmlParser.class.getResourceAsStream( path ); + } + return inputStream; + } + + private EntityMappings getEntityMappings(InputStream in) { + EntityMappings entityMappings; + Schema schema = getMappingSchema(); + try { + JAXBContext jc = JAXBContext.newInstance( EntityMappings.class ); + Unmarshaller unmarshaller = jc.createUnmarshaller(); + unmarshaller.setSchema( schema ); + StreamSource stream = new StreamSource( in ); + JAXBElement root = unmarshaller.unmarshal( stream, EntityMappings.class ); + entityMappings = root.getValue(); + } + catch ( JAXBException e ) { + String msg = "Error parsing mapping file."; + log.error( msg ); + throw new ValidationException( msg, e ); + } + return entityMappings; + } + + private Schema getMappingSchema() { + ClassLoader loader = OrmXmlParser.class.getClassLoader(); + URL schemaUrl = loader.getResource( ORM_MAPPING_XSD ); + SchemaFactory sf = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI ); + Schema schema = null; + try { + schema = sf.newSchema( schemaUrl ); + } + catch ( SAXException e ) { + log.debug( "Unable to create schema for {}: {}", ORM_MAPPING_XSD, e.getMessage() ); + } + return schema; + } +} + + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java index 227cfb1936..0f6db08301 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java @@ -568,22 +568,6 @@ abstract class AbstractEntityBinder { // return prop; // } - - - - - - - - - - - - - - - - protected Value processValues(Element identifierElement, TableSpecification baseTable, String propertyPath) { // first boolean (false here) indicates that by default columns are nullable // second boolean (true here) indicates that by default column names should be guessed diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java new file mode 100644 index 0000000000..455ba9a7d3 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java @@ -0,0 +1,89 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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.metamodel.binding; + +import org.junit.Test; + +import org.hibernate.metamodel.relational.Column; +import org.hibernate.testing.junit4.BaseUnitTestCase; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +/** + * Basic tests of {@code hbm.xml} and annotation binding code + * + * @author Steve Ebersole + */ +public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { + + @Test + public void testSimpleEntityMapping() { + EntityBinding entityBinding = buildSimpleEntityBinding(); + assertNotNull( entityBinding ); + assertNotNull( entityBinding.getEntityIdentifier() ); + assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() ); + assertNull( entityBinding.getVersioningValueBinding() ); + + AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); + assertNotNull( idAttributeBinding ); + assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); + assertNotNull( idAttributeBinding.getAttribute() ); + assertNotNull( idAttributeBinding.getValue() ); + assertTrue( idAttributeBinding.getValue() instanceof Column ); + + AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); + assertNotNull( nameBinding ); + assertNotNull( nameBinding.getAttribute() ); + assertNotNull( nameBinding.getValue() ); + } + + @Test + public void testSimpleVersionedEntityMapping() { + EntityBinding entityBinding = buildSimpleVersionedEntityBinding(); + assertNotNull( entityBinding ); + assertNotNull( entityBinding.getEntityIdentifier() ); + assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() ); + assertNotNull( entityBinding.getVersioningValueBinding() ); + assertNotNull( entityBinding.getVersioningValueBinding().getAttribute() ); + + AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); + assertNotNull( idAttributeBinding ); + assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); + assertNotNull( idAttributeBinding.getAttribute() ); + assertNotNull( idAttributeBinding.getValue() ); + assertTrue( idAttributeBinding.getValue() instanceof Column ); + + AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); + assertNotNull( nameBinding ); + assertNotNull( nameBinding.getAttribute() ); + assertNotNull( nameBinding.getValue() ); + } + + public abstract EntityBinding buildSimpleVersionedEntityBinding(); + + public abstract EntityBinding buildSimpleEntityBinding(); +} diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java new file mode 100644 index 0000000000..4266a49513 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java @@ -0,0 +1,88 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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.metamodel.binding; + +import java.io.IOException; +import java.io.InputStream; + +import org.jboss.jandex.Index; +import org.jboss.jandex.Indexer; +import org.junit.Test; + +import org.hibernate.metamodel.source.Metadata; +import org.hibernate.testing.FailureExpected; + +import static org.junit.Assert.fail; + +/** + * Basic tests of annotation based binding code + * + * @author Hardy Ferentschik + */ +public class BasicAnnotationBindingTests extends AbstractBasicBindingTests { + + //@FailureExpected(jiraKey = "HHH-5672", message = "Work in progress") + @Test + public void testSimpleEntityMapping() { + super.testSimpleEntityMapping(); + } + + @FailureExpected(jiraKey = "HHH-5672", message = "Work in progress") + @Test + public void testSimpleVersionedEntityMapping() { + super.testSimpleVersionedEntityMapping(); + } + + public EntityBinding buildSimpleEntityBinding() { + Index index = indexForClass( SimpleEntity.class ); + Metadata metadata = new Metadata(); + metadata.getAnnotationBinder().bindMappedClasses( index ); + + return metadata.getEntityBinding( SimpleEntity.class.getSimpleName() ); + } + + public EntityBinding buildSimpleVersionedEntityBinding() { + Index index = indexForClass( SimpleEntity.class ); + Metadata metadata = new Metadata(); + metadata.getAnnotationBinder().bindMappedClasses( index ); + + return metadata.getEntityBinding( SimpleVersionedEntity.class.getSimpleName() ); + } + + private Index indexForClass(Class... classes) { + Indexer indexer = new Indexer(); + for ( Class clazz : classes ) { + InputStream stream = getClass().getClassLoader().getResourceAsStream( + clazz.getName().replace( '.', '/' ) + ".class" + ); + try { + indexer.index( stream ); + } + catch ( IOException e ) { + fail( "Unable to index" ); + } + } + return indexer.complete(); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java index 8d0468220c..39a33d9697 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java @@ -30,75 +30,32 @@ import org.hibernate.internal.util.xml.MappingReader; import org.hibernate.internal.util.xml.Origin; import org.hibernate.internal.util.xml.XMLHelper; import org.hibernate.internal.util.xml.XmlDocument; -import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.source.Metadata; -import org.junit.Test; - -import org.hibernate.testing.junit4.BaseUnitTestCase; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - /** - * Basic tests of {@code hbm.xml} beinding code + * Basic tests of {@code hbm.xml} binding code * * @author Steve Ebersole */ -public class BasicHbmBindingTests extends BaseUnitTestCase { - @Test - public void testSuperSimpleMapping() { +public class BasicHbmBindingTests extends AbstractBasicBindingTests { + + public EntityBinding buildSimpleEntityBinding() { Metadata metadata = new Metadata(); - { - XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" ); - metadata.getHibernateXmlBinder().bindRoot( xmlDocument ); - EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() ); - assertNotNull( entityBinding ); - assertNotNull( entityBinding.getEntityIdentifier() ); - assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() ); - assertNull( entityBinding.getVersioningValueBinding() ); + XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" ); + metadata.getHibernateXmlBinder().bindRoot( xmlDocument ); + return metadata.getEntityBinding( SimpleEntity.class.getName() ); + } - AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); - assertNotNull( idAttributeBinding ); - assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); - assertNotNull( idAttributeBinding.getAttribute() ); - assertNotNull( idAttributeBinding.getValue() ); - assertTrue( idAttributeBinding.getValue() instanceof Column ); + public EntityBinding buildSimpleVersionedEntityBinding() { + Metadata metadata = new Metadata(); - AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); - assertNotNull( nameBinding ); - assertNotNull( nameBinding.getAttribute() ); - assertNotNull( nameBinding.getValue() ); - } - { - XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" ); - metadata.getHibernateXmlBinder().bindRoot( xmlDocument ); - EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() ); - assertNotNull( entityBinding ); - assertNotNull( entityBinding.getEntityIdentifier() ); - assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() ); - assertNotNull( entityBinding.getVersioningValueBinding() ); - assertNotNull( entityBinding.getVersioningValueBinding().getAttribute() ); - - AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); - assertNotNull( idAttributeBinding ); - assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); - assertNotNull( idAttributeBinding.getAttribute() ); - assertNotNull( idAttributeBinding.getValue() ); - assertTrue( idAttributeBinding.getValue() instanceof Column ); - - AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); - assertNotNull( nameBinding ); - assertNotNull( nameBinding.getAttribute() ); - assertNotNull( nameBinding.getValue() ); - } + XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" ); + metadata.getHibernateXmlBinder().bindRoot( xmlDocument ); + return metadata.getEntityBinding( SimpleVersionedEntity.class.getName() ); } private XmlDocument readResource(final String name) { - final String path = "/org/hibernate/test/id/Car.hbm.xml"; Origin origin = new Origin() { @Override public String getType() { diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntity.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntity.java index 44902ff62a..227dc31cf4 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntity.java @@ -23,10 +23,15 @@ */ package org.hibernate.metamodel.binding; +import javax.persistence.Entity; +import javax.persistence.Id; + /** * @author Steve Ebersole */ +@Entity public class SimpleEntity { + @Id private Long id; private String name; diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntitySubClass.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntitySubClass.java new file mode 100644 index 0000000000..29c6c31491 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleEntitySubClass.java @@ -0,0 +1,36 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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.metamodel.binding; + +import javax.persistence.Entity; + +/** + * @author Steve Ebersole + */ +@Entity +public class SimpleEntitySubClass extends SimpleEntity { + + public SimpleEntitySubClass() { + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java index ca0f2f5211..d4a0512b95 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java @@ -25,6 +25,8 @@ package org.hibernate.metamodel.binding; import java.sql.Types; +import org.junit.Test; + import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.relational.Column; @@ -32,9 +34,6 @@ import org.hibernate.metamodel.relational.Datatype; import org.hibernate.metamodel.relational.Schema; import org.hibernate.metamodel.relational.Size; import org.hibernate.metamodel.relational.Table; - -import org.junit.Test; - import org.hibernate.testing.junit4.BaseUnitTestCase; import static org.junit.Assert.assertSame; diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleVersionedEntity.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleVersionedEntity.java index 72d366ead5..488a0b3a4c 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleVersionedEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleVersionedEntity.java @@ -24,6 +24,8 @@ package org.hibernate.metamodel.binding; /** + * TODO : javadoc + * * @author Steve Ebersole */ public class SimpleVersionedEntity { diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/package-info.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/package-info.java new file mode 100644 index 0000000000..c4b90dd158 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/package-info.java @@ -0,0 +1,4 @@ +@GenericGenerator(name = "myGenerator", strategy = "sequence") +package org.hibernate.metamodel.binding; + +import org.hibernate.annotations.GenericGenerator; \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java new file mode 100644 index 0000000000..03ca1d6f37 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java @@ -0,0 +1,24 @@ +package org.hibernate.metamodel.source.annotations; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import org.hibernate.testing.junit4.BaseUnitTestCase; + +/** + * @author Hardy Ferentschik + */ +public class OrmXmlParserTests extends BaseUnitTestCase { + @Test + public void testSingleOrmXml() { + OrmXmlParser parser = new OrmXmlParser(); + Set xmlFiles = new HashSet(); + xmlFiles.add( "org/hibernate/metamodel/source/annotations/orm.xml" ); + parser.parseAndUpdateIndex( xmlFiles, null ); + + } +} + + diff --git a/hibernate-core/src/test/resources/org/hibernate/metamodel/source/annotations/orm.xml b/hibernate-core/src/test/resources/org/hibernate/metamodel/source/annotations/orm.xml new file mode 100644 index 0000000000..825e613de2 --- /dev/null +++ b/hibernate-core/src/test/resources/org/hibernate/metamodel/source/annotations/orm.xml @@ -0,0 +1,29 @@ + + + + org.hibernate.test.annotations.onetoone + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file