HHH-6109 Starting the implementation of a replacement for InheritanceState. The determined mapped classes need to be pre-processed
in order to detmerine inheritance features, default access types, etc
This commit is contained in:
parent
42502e696b
commit
297c703449
|
@ -30,20 +30,22 @@ manifest.mainAttributes(
|
|||
'Main-Class': 'org.hibernate.Version'
|
||||
)
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
// resources inherently exclude sources
|
||||
resources {
|
||||
setSrcDirs( ['src/test/java','src/test/resources'] )
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.main {
|
||||
originalJavaSrcDirs = java.srcDirs
|
||||
jaxbTargetDir = file( "${buildDir}/generated-src/jaxb" )
|
||||
java.srcDir jaxbTargetDir
|
||||
}
|
||||
|
||||
// resources inherently exclude sources
|
||||
sourceSets.test.resources {
|
||||
setSrcDirs( ['src/test/java','src/test/resources'] )
|
||||
}
|
||||
|
||||
ideaModule {
|
||||
sourceDirs.add( file( '$buildDir/generated-src/antlr/main' ) )
|
||||
}
|
||||
|
||||
|
||||
task jaxb << {
|
||||
jaxbTargetDir = file( "${buildDir}/generated-src/jaxb" )
|
||||
jaxbTargetDir.mkdirs()
|
||||
|
|
|
@ -21,14 +21,10 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// $Id$
|
||||
|
||||
package org.hibernate.cfg;
|
||||
|
||||
|
||||
/**
|
||||
* Enum defining deifferent access strategies for accessing entity values.
|
||||
* Enum defining different access strategies for accessing entity values.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
|
|
|
@ -24,18 +24,14 @@
|
|||
package org.hibernate.metamodel.source.annotations;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.util.Set;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -48,10 +44,6 @@ import org.hibernate.metamodel.source.Metadata;
|
|||
* @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;
|
||||
|
||||
|
@ -61,33 +53,30 @@ public class AnnotationBinder {
|
|||
|
||||
public void bindMappedClasses(Index annotationIndex) {
|
||||
// need to order our annotated entities into an order we can process
|
||||
EntityHierarchyBuilder builder = new EntityHierarchyBuilder();
|
||||
List<EntityHierarchy> hierarchies = builder.createEntityHierarchies( annotationIndex );
|
||||
ConfiguredClassHierarchyBuilder builder = new ConfiguredClassHierarchyBuilder();
|
||||
Set<ConfiguredClassHierarchy> hierarchies = builder.createEntityHierarchies( annotationIndex );
|
||||
|
||||
// now we process each hierarchy one at the time
|
||||
for ( EntityHierarchy hierarchy : hierarchies ) {
|
||||
Iterator<Entity> iter = hierarchy.iterator();
|
||||
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
|
||||
Iterator<ConfiguredClass> iter = hierarchy.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
Entity entity = iter.next();
|
||||
ConfiguredClass entity = iter.next();
|
||||
bindEntity( entity );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void bindEntity(Entity entity) {
|
||||
public void bindEntity(ConfiguredClass 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()
|
||||
);
|
||||
}
|
||||
AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation( classInfo, ConfiguredClass.ENTITY );
|
||||
AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation(
|
||||
classInfo, ConfiguredClass.MAPPED_SUPER_CLASS
|
||||
);
|
||||
AnnotationInstance hibernateEntityAnnotation = JandexHelper.getSingleAnnotation(
|
||||
classInfo, ConfiguredClass.HIBERNATE_ENTITY
|
||||
);
|
||||
|
||||
|
||||
// //TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc)
|
||||
|
@ -307,30 +296,6 @@ public class AnnotationBinder {
|
|||
// 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<AnnotationInstance> 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 javax.persistence.Entity;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
|
||||
/**
|
||||
* Represents an entity, mapped superclass or component configured via annotations/xml.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ConfiguredClass {
|
||||
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 final ClassInfo classInfo;
|
||||
private final ConfiguredClassHierarchy hierarchy;
|
||||
|
||||
public ConfiguredClass(ClassInfo info, ConfiguredClassHierarchy hierarchy) {
|
||||
this.classInfo = info;
|
||||
this.hierarchy = hierarchy;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
//@Entity and @MappedSuperclass on the same class leads to a NPE down the road
|
||||
AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation( classInfo, ENTITY );
|
||||
AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( classInfo, MAPPED_SUPER_CLASS );
|
||||
AnnotationInstance hibernateEntityAnnotation = JandexHelper.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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ClassInfo getClassInfo() {
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "ConfiguredClass" );
|
||||
sb.append( "{classInfo=" ).append( classInfo );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -23,16 +23,47 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.source.annotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
|
||||
import org.hibernate.cfg.AccessType;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class EntityHierarchy implements Iterable<Entity> {
|
||||
@Override
|
||||
public Iterator<Entity> iterator() {
|
||||
public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
||||
private final AccessType defaultAccessType;
|
||||
private final List<ConfiguredClass> configuredClasses;
|
||||
|
||||
ConfiguredClassHierarchy(List<ClassInfo> classes) {
|
||||
configuredClasses = new ArrayList<ConfiguredClass>();
|
||||
for ( ClassInfo info : classes ) {
|
||||
configuredClasses.add( new ConfiguredClass( info, this ) );
|
||||
}
|
||||
defaultAccessType = determineDefaultAccessType();
|
||||
}
|
||||
|
||||
private AccessType determineDefaultAccessType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ConfiguredClass> iterator() {
|
||||
return configuredClasses.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "ConfiguredClassHierarchy" );
|
||||
sb.append( "{defaultAccessType=" ).append( defaultAccessType );
|
||||
sb.append( ", configuredClasses=" ).append( configuredClasses );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.Index;
|
||||
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
|
||||
/**
|
||||
* Given a annotation index build a list of class hierarchies.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ConfiguredClassHierarchyBuilder {
|
||||
|
||||
public Set<ConfiguredClassHierarchy> createEntityHierarchies(Index index) {
|
||||
Map<ClassInfo, List<ClassInfo>> processedClassInfos = new HashMap<ClassInfo, List<ClassInfo>>();
|
||||
|
||||
for ( ClassInfo info : index.getKnownClasses() ) {
|
||||
if ( processedClassInfos.containsKey( info ) ) {
|
||||
continue;
|
||||
}
|
||||
List<ClassInfo> configuredClassList = new ArrayList<ClassInfo>();
|
||||
ClassInfo tmpClassInfo = info;
|
||||
Class<?> clazz = classForName( tmpClassInfo );
|
||||
while ( clazz != null && !clazz.equals( Object.class ) ) {
|
||||
tmpClassInfo = index.getClassByName( DotName.createSimple( clazz.getName() ) );
|
||||
clazz = clazz.getSuperclass();
|
||||
if ( tmpClassInfo == null ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( existsHierarchyWithClassInfoAsLeaf( processedClassInfos, tmpClassInfo ) ) {
|
||||
List<ClassInfo> classInfoList = processedClassInfos.get( tmpClassInfo );
|
||||
for ( ClassInfo tmpInfo : configuredClassList ) {
|
||||
classInfoList.add( tmpInfo );
|
||||
processedClassInfos.put( tmpInfo, classInfoList );
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
configuredClassList.add( 0, tmpClassInfo );
|
||||
processedClassInfos.put( tmpClassInfo, configuredClassList );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Set<ConfiguredClassHierarchy> hierarchies = new HashSet<ConfiguredClassHierarchy>();
|
||||
List<List<ClassInfo>> processedList = new ArrayList<List<ClassInfo>>();
|
||||
for ( List<ClassInfo> classInfoList : processedClassInfos.values() ) {
|
||||
if ( !processedList.contains( classInfoList ) ) {
|
||||
hierarchies.add( new ConfiguredClassHierarchy( classInfoList ) );
|
||||
processedList.add( classInfoList );
|
||||
}
|
||||
}
|
||||
|
||||
return hierarchies;
|
||||
}
|
||||
|
||||
private boolean existsHierarchyWithClassInfoAsLeaf(Map<ClassInfo, List<ClassInfo>> processedClassInfos, ClassInfo tmpClassInfo) {
|
||||
if ( !processedClassInfos.containsKey( tmpClassInfo ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ClassInfo> classInfoList = processedClassInfos.get( tmpClassInfo );
|
||||
return classInfoList.get( classInfoList.size() - 1 ).equals( tmpClassInfo );
|
||||
}
|
||||
|
||||
private Class<?> classForName(ClassInfo info) {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = ReflectHelper.classForName( info.toString() );
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
// todo what to do here!?i
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
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<EntityHierarchy> createEntityHierarchies(Index index) {
|
||||
List<EntityHierarchy> hierarchies = new ArrayList<EntityHierarchy>();
|
||||
|
||||
|
||||
return hierarchies;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package org.hibernate.metamodel.source.annotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class JandexHelper {
|
||||
private JandexHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 org.hibernate.AssertionFailure in case there is
|
||||
*/
|
||||
static public AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName)
|
||||
throws AssertionFailure {
|
||||
List<AnnotationInstance> 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,7 +4,6 @@ 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;
|
||||
|
@ -18,6 +17,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.metamodel.source.xml.EntityMappings;
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,8 @@ import org.hibernate.metamodel.source.xml.EntityMappings;
|
|||
*/
|
||||
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";
|
||||
private static final String ORM1_MAPPING_XSD = "org/hibernate/ejb/orm_1_0.xsd";
|
||||
private static final String ORM2_MAPPING_XSD = "org/hibernate/ejb/orm_2_0.xsd";
|
||||
|
||||
/**
|
||||
* Parses the given xml configuration files and returns a updated annotation index
|
||||
|
@ -40,12 +41,26 @@ public class OrmXmlParser {
|
|||
|
||||
Set<InputStream> mappingStreams = new HashSet<InputStream>();
|
||||
for ( String fileName : mappingFileNames ) {
|
||||
mappingStreams.add( getInputStreamForPath( fileName ) );
|
||||
}
|
||||
|
||||
for ( InputStream in : mappingStreams ) {
|
||||
EntityMappings entityMappings = getEntityMappings( in );
|
||||
// ...
|
||||
Schema schema = getMappingSchema( ORM2_MAPPING_XSD );
|
||||
InputStream in = getInputStreamForPath( fileName );
|
||||
EntityMappings entityMappings;
|
||||
try {
|
||||
entityMappings = unmarshallXml( in, schema );
|
||||
}
|
||||
catch ( JAXBException orm2Exception ) {
|
||||
// if we cannot parse against orm_2_0.xsd we try orm_1_0.xsd for backwards compatibility
|
||||
try {
|
||||
schema = getMappingSchema( ORM1_MAPPING_XSD );
|
||||
in = getInputStreamForPath( fileName );
|
||||
entityMappings = unmarshallXml( in, schema );
|
||||
}
|
||||
catch ( JAXBException orm1Exception ) {
|
||||
throw new AnnotationException( "Unable to parse xml configuration.", orm1Exception );
|
||||
}
|
||||
}
|
||||
|
||||
// ..
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -62,35 +77,27 @@ public class OrmXmlParser {
|
|||
return inputStream;
|
||||
}
|
||||
|
||||
private EntityMappings getEntityMappings(InputStream in) {
|
||||
private EntityMappings unmarshallXml(InputStream in, Schema schema) throws JAXBException {
|
||||
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<EntityMappings> 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 );
|
||||
}
|
||||
JAXBContext jc = JAXBContext.newInstance( EntityMappings.class );
|
||||
Unmarshaller unmarshaller = jc.createUnmarshaller();
|
||||
unmarshaller.setSchema( schema );
|
||||
StreamSource stream = new StreamSource( in );
|
||||
JAXBElement<EntityMappings> root = unmarshaller.unmarshal( stream, EntityMappings.class );
|
||||
entityMappings = root.getValue();
|
||||
return entityMappings;
|
||||
}
|
||||
|
||||
private Schema getMappingSchema() {
|
||||
private Schema getMappingSchema(String schemaVersion) {
|
||||
ClassLoader loader = OrmXmlParser.class.getClassLoader();
|
||||
URL schemaUrl = loader.getResource( ORM_MAPPING_XSD );
|
||||
URL schemaUrl = loader.getResource( schemaVersion );
|
||||
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() );
|
||||
log.debug( "Unable to create schema for {}: {}", ORM2_MAPPING_XSD, e.getMessage() );
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ import static org.junit.Assert.fail;
|
|||
*/
|
||||
public class BasicAnnotationBindingTests extends AbstractBasicBindingTests {
|
||||
|
||||
//@FailureExpected(jiraKey = "HHH-5672", message = "Work in progress")
|
||||
@FailureExpected(jiraKey = "HHH-5672", message = "Work in progress")
|
||||
@Test
|
||||
public void testSimpleEntityMapping() {
|
||||
super.testSimpleEntityMapping();
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
package org.hibernate.metamodel.source.annotations;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.Index;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase {
|
||||
|
||||
@Test
|
||||
public void testSingleEntity() {
|
||||
Index index = indexForClass( Foo.class );
|
||||
ConfiguredClassHierarchyBuilder builder = new ConfiguredClassHierarchyBuilder();
|
||||
Set<ConfiguredClassHierarchy> hierarchies = builder.createEntityHierarchies( index );
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
ClassInfo info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( Foo.class.getName() ), info.name() );
|
||||
assertFalse( iter.hasNext() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleInheritance() {
|
||||
Index index = indexForClass( B.class, A.class );
|
||||
ConfiguredClassHierarchyBuilder builder = new ConfiguredClassHierarchyBuilder();
|
||||
Set<ConfiguredClassHierarchy> hierarchies = builder.createEntityHierarchies( index );
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
ClassInfo info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() );
|
||||
info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() );
|
||||
assertFalse( iter.hasNext() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleHierarchies() {
|
||||
Index index = indexForClass( B.class, A.class, Foo.class );
|
||||
ConfiguredClassHierarchyBuilder builder = new ConfiguredClassHierarchyBuilder();
|
||||
Set<ConfiguredClassHierarchy> hierarchies = builder.createEntityHierarchies( index );
|
||||
assertEquals( "There should be only one hierarchy", 2, hierarchies.size() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMappedSuperClass() {
|
||||
Index index = indexForClass( MappedSubClass.class, MappedSuperClass.class, UnmappedSubClass.class );
|
||||
ConfiguredClassHierarchyBuilder builder = new ConfiguredClassHierarchyBuilder();
|
||||
Set<ConfiguredClassHierarchy> hierarchies = builder.createEntityHierarchies( index );
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
ClassInfo info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( MappedSuperClass.class.getName() ), info.name() );
|
||||
info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( UnmappedSubClass.class.getName() ), info.name() );
|
||||
assertFalse( iter.hasNext() );
|
||||
info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( MappedSubClass.class.getName() ), info.name() );
|
||||
assertFalse( iter.hasNext() );
|
||||
}
|
||||
|
||||
@Test(expected = AnnotationException.class)
|
||||
public void testEntityAndMappedSuperClassAnnotations() {
|
||||
Index index = indexForClass( EntityAndMappedSuperClass.class );
|
||||
ConfiguredClassHierarchyBuilder builder = new ConfiguredClassHierarchyBuilder();
|
||||
builder.createEntityHierarchies( index );
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class Foo {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class A {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class B extends A {
|
||||
private String name;
|
||||
}
|
||||
|
||||
@MappedSuperclass
|
||||
public class MappedSuperClass {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
}
|
||||
|
||||
public class UnmappedSubClass extends MappedSuperClass {
|
||||
private String unmappedProperty;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public class MappedSubClass extends UnmappedSubClass {
|
||||
private String mappedProperty;
|
||||
}
|
||||
|
||||
@Entity
|
||||
@MappedSuperclass
|
||||
public class EntityAndMappedSuperClass {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -17,7 +17,14 @@ public class OrmXmlParserTests extends BaseUnitTestCase {
|
|||
Set<String> xmlFiles = new HashSet<String>();
|
||||
xmlFiles.add( "org/hibernate/metamodel/source/annotations/orm.xml" );
|
||||
parser.parseAndUpdateIndex( xmlFiles, null );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrmXmlWithOldSchema() {
|
||||
OrmXmlParser parser = new OrmXmlParser();
|
||||
Set<String> xmlFiles = new HashSet<String>();
|
||||
xmlFiles.add( "org/hibernate/metamodel/source/annotations/orm2.xml" );
|
||||
parser.parseAndUpdateIndex( xmlFiles, null );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package org.hibernate.metamodel.source.annotations;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
@Entity
|
||||
public class Star {
|
||||
private int id;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
|
||||
version="1.0"
|
||||
>
|
||||
<!-- use orm_1_0 on purpose to test backward compatibility -->
|
||||
<package>org.hibernate.metamodel.source.annotations</package>
|
||||
<entity class="Star" access="FIELD" metadata-complete="false">
|
||||
<attributes>
|
||||
<id name="id">
|
||||
<column name="STAR_ID"/>
|
||||
</id>
|
||||
</attributes>
|
||||
</entity>
|
||||
</entity-mappings>
|
Loading…
Reference in New Issue