HHH-6113 re-fact and more tests

This commit is contained in:
Strong Liu 2011-05-22 20:05:27 +08:00
parent 2abbe4d841
commit c62e5fccc8
20 changed files with 674 additions and 373 deletions

View File

@ -26,6 +26,8 @@ package org.hibernate.metamodel.source.annotations.xml;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
/** /**
* Pseudo JPA Annotation name to distinguish Annotations defined in <persistence-unit-metadata>
*
* @author Strong Liu * @author Strong Liu
*/ */
public interface PseudoJpaDotNames { public interface PseudoJpaDotNames {

View File

@ -33,24 +33,7 @@ import org.hibernate.metamodel.source.annotations.xml.mocker.IndexBuilder;
* @author Strong Liu * @author Strong Liu
*/ */
public interface IndexedAnnotationFilter extends JPADotNames { public interface IndexedAnnotationFilter extends JPADotNames {
DotName[] GLOBAL_ANNOTATIONS = new DotName[] { final IndexedAnnotationFilter[] ALL_FILTERS = new IndexedAnnotationFilter[] {
SEQUENCE_GENERATOR,
TABLE_GENERATOR,
NAMED_QUERIES,
NAMED_QUERY,
NAMED_NATIVE_QUERIES,
NAMED_NATIVE_QUERY,
SQL_RESULT_SET_MAPPING,
SQL_RESULT_SET_MAPPINGS
};
DotName[] SCHEMAAWARE_ANNOTATIONS = new DotName[] {
TABLE, JOIN_TABLE, COLLECTION_TABLE, SECONDARY_TABLE, SECONDARY_TABLES
, TABLE_GENERATOR, SEQUENCE_GENERATOR
};
DotName[] ASSOCIATION_ANNOTATIONS = new DotName[] {
ONE_TO_MANY, ONE_TO_ONE, MANY_TO_ONE, MANY_TO_MANY
};
IndexedAnnotationFilter[] filters = new IndexedAnnotationFilter[] {
ExclusiveAnnotationFilter.INSTANCE, ExclusiveAnnotationFilter.INSTANCE,
NameAnnotationFilter.INSTANCE, NameTargetAnnotationFilter.INSTANCE NameAnnotationFilter.INSTANCE, NameTargetAnnotationFilter.INSTANCE
}; };

View File

@ -55,11 +55,16 @@ abstract class AbstractEntityObjectMocker extends AnnotationMocker {
private boolean isPreProcessCalled = false; private boolean isPreProcessCalled = false;
/**
* Pre-process Entity Objects to find the default {@link javax.persistence.Access} for later attributes processing.
*/
final void preProcess() { final void preProcess() {
applyDefaults(); applyDefaults();
classInfo = indexBuilder.createClassInfo( getClassName() ); classInfo = indexBuilder.createClassInfo( getClassName() );
DotName classDotName = classInfo.name(); DotName classDotName = classInfo.name();
indexBuilder.metadataComplete( classDotName, isMetadataComplete() ); if ( isMetadataComplete() ) {
indexBuilder.metadataComplete( classDotName );
}
parserAccessType( getAccessType(), getTarget() ); parserAccessType( getAccessType(), getTarget() );
isPreProcessCalled = true; isPreProcessCalled = true;
} }

View File

@ -65,7 +65,7 @@ abstract class AnnotationMocker extends AbstractMocker {
} }
protected boolean isDefaultCascadePersist() { protected boolean isDefaultCascadePersist() {
return defaults.getCascadePersist() != null && defaults.getCascadePersist(); return defaults.isCascadePersist();
} }
//@JoinTable //@JoinTable
@ -73,7 +73,10 @@ abstract class AnnotationMocker extends AbstractMocker {
if ( joinTable == null ) { if ( joinTable == null ) {
return null; return null;
} }
MockHelper.updateSchema( new SchemaAware.JoinTableSchemaAware( joinTable ), getDefaults() ); DefaultConfigurationHelper.INSTANCE.applyDefaults(
new SchemaAware.JoinTableSchemaAware( joinTable ),
getDefaults()
);
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>(); List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", joinTable.getName(), annotationValueList ); MockHelper.stringValue( "name", joinTable.getName(), annotationValueList );
MockHelper.stringValue( "catalog", joinTable.getCatalog(), annotationValueList ); MockHelper.stringValue( "catalog", joinTable.getCatalog(), annotationValueList );
@ -380,7 +383,10 @@ abstract class AnnotationMocker extends AbstractMocker {
if ( collectionTable == null ) { if ( collectionTable == null ) {
return null; return null;
} }
MockHelper.updateSchema( new SchemaAware.CollectionTableSchemaAware( collectionTable ), getDefaults() ); DefaultConfigurationHelper.INSTANCE.applyDefaults(
new SchemaAware.CollectionTableSchemaAware( collectionTable ),
getDefaults()
);
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>(); List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", collectionTable.getName(), annotationValueList ); MockHelper.stringValue( "name", collectionTable.getName(), annotationValueList );
MockHelper.stringValue( "catalog", collectionTable.getCatalog(), annotationValueList ); MockHelper.stringValue( "catalog", collectionTable.getCatalog(), annotationValueList );
@ -478,6 +484,39 @@ abstract class AnnotationMocker extends AbstractMocker {
} }
class XMLAssociationOverrideProxy extends XMLAssociationOverride {
private AnnotationValue joinTableAnnotationValue;
private AnnotationValue joinColumnsAnnotationValue;
AnnotationValue getJoinColumnsAnnotationValue() {
return joinColumnsAnnotationValue;
}
void setJoinColumnsAnnotationValue(AnnotationValue joinColumnsAnnotationValue) {
this.joinColumnsAnnotationValue = joinColumnsAnnotationValue;
}
AnnotationValue getJoinTableAnnotationValue() {
return joinTableAnnotationValue;
}
void setJoinTableAnnotationValue(AnnotationValue joinTableAnnotationValue) {
this.joinTableAnnotationValue = joinTableAnnotationValue;
}
}
class XMLAttributeOverrideProxy extends XMLAttributeOverride {
private AnnotationValue columnAnnotationValue;
AnnotationValue getColumnAnnotationValue() {
return columnAnnotationValue;
}
void setColumnAnnotationValue(AnnotationValue columnAnnotationValue) {
this.columnAnnotationValue = columnAnnotationValue;
}
}
/** /**
* Create simple AnnotationInstance with empty annotation value. * Create simple AnnotationInstance with empty annotation value.
* AnnotationInstance's target is get from #{getTarget} * AnnotationInstance's target is get from #{getTarget}

View File

@ -30,51 +30,146 @@ import java.util.Map;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddable;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotation.xml.XMLMappedSuperclass;
import org.hibernate.metamodel.source.annotation.xml.XMLTable;
import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.annotations.xml.filter.IndexedAnnotationFilter; import org.hibernate.metamodel.source.annotations.xml.filter.IndexedAnnotationFilter;
/** /**
* @author Strong Liu * @author Strong Liu
*/ */
class DefaultConfigurationHelper { class DefaultConfigurationHelper {
static DefaultConfigurationHelper INSTANCE = new DefaultConfigurationHelper(); private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
DefaultConfigurationHelper.class.getName()
);
static final DefaultConfigurationHelper INSTANCE = new DefaultConfigurationHelper();
static final DotName[] GLOBAL_ANNOTATIONS = new DotName[] {
JPADotNames.SEQUENCE_GENERATOR,
JPADotNames.TABLE_GENERATOR,
JPADotNames.NAMED_QUERIES,
JPADotNames.NAMED_QUERY,
JPADotNames.NAMED_NATIVE_QUERIES,
JPADotNames.NAMED_NATIVE_QUERY,
JPADotNames.SQL_RESULT_SET_MAPPING,
JPADotNames.SQL_RESULT_SET_MAPPINGS
};
static final DotName[] SCHEMA_AWARE_ANNOTATIONS = new DotName[] {
JPADotNames.TABLE,
JPADotNames.JOIN_TABLE,
JPADotNames.COLLECTION_TABLE,
JPADotNames.SECONDARY_TABLE,
JPADotNames.SECONDARY_TABLES,
JPADotNames.TABLE_GENERATOR,
JPADotNames.SEQUENCE_GENERATOR
};
static final DotName[] ASSOCIATION_ANNOTATIONS = new DotName[] {
JPADotNames.ONE_TO_MANY, JPADotNames.ONE_TO_ONE, JPADotNames.MANY_TO_ONE, JPADotNames.MANY_TO_MANY
};
private DefaultConfigurationHelper() { private DefaultConfigurationHelper() {
} }
void apply(Map<DotName, List<AnnotationInstance>> annotationsMap, EntityMappingsMocker.Default defaults) { void applyDefaults(SchemaAware schemaAware, EntityMappingsMocker.Default defaults) {
if ( annotationsMap == null || annotationsMap.isEmpty() || defaults == null ) { if ( hasSchemaOrCatalogDefined( defaults ) ) {
if ( StringHelper.isEmpty( schemaAware.getSchema() ) ) {
schemaAware.setSchema( defaults.getSchema() );
}
if ( StringHelper.isEmpty( schemaAware.getCatalog() ) ) {
schemaAware.setCatalog( defaults.getCatalog() );
}
}
}
void applyDefaults(Map<DotName, List<AnnotationInstance>> annotationsMap, EntityMappingsMocker.Default defaults) {
if ( annotationsMap.isEmpty() || defaults == null ) {
return; return;
} }
if ( MockHelper.hasSchemaOrCatalogDefined( defaults ) ) { if ( hasSchemaOrCatalogDefined( defaults ) ) {
applyDefaultSchemaAndCatalog( annotationsMap, defaults );
}
if ( defaults.isCascadePersist() ) {
applyDefaultCascadePersist( annotationsMap );
}
}
for ( DotName annName : IndexedAnnotationFilter.SCHEMAAWARE_ANNOTATIONS ) { void applyDefaults(XMLMappedSuperclass mappedSuperclass, EntityMappingsMocker.Default defaults) {
if ( annName.equals( JPADotNames.TABLE ) && !annotationsMap.containsKey( JPADotNames.TABLE ) && annotationsMap applyDefaultsToEntityObject( new MappedSuperClassEntityObject( mappedSuperclass ), defaults );
.containsKey( JPADotNames.ENTITY ) ) { }
//if an entity doesn't have a @Table, we create one here
AnnotationInstance entity = annotationsMap.get( JPADotNames.ENTITY ).get( 0 );
AnnotationInstance table = AnnotationInstance.create(
JPADotNames.TABLE, entity.target(), MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY
);
List<AnnotationInstance> tableList = new ArrayList<AnnotationInstance>( 1 );
tableList.add( table );
annotationsMap.put( JPADotNames.TABLE, tableList ); void applyDefaults(XMLEmbeddable embeddable, EntityMappingsMocker.Default defaults) {
applyDefaultsToEntityObject( new EmbeddableEntityObject( embeddable ), defaults );
} }
if ( annotationsMap.containsKey( annName ) ) {
overrideScheamCatalogByDefault( annName, annotationsMap, defaults ); void applyDefaults(XMLEntity entity, EntityMappingsMocker.Default defaults) {
mockTableIfNonExist( entity, defaults );
applyDefaultsToEntityObject( new EntityEntityObject( entity ), defaults );
} }
private void applyDefaultsToEntityObject(EntityObject entityObject, EntityMappingsMocker.Default defaults) {
if ( defaults == null ) {
return;
} }
String className = MockHelper.buildSafeClassName( entityObject.getClazz(), defaults.getPackageName() );
entityObject.setClazz( className );
if ( entityObject.isMetadataComplete() == null ) {
entityObject.setMetadataComplete( defaults.isMetadataComplete() );
} }
if ( defaults.getCascadePersist() != null && defaults.getCascadePersist() ) { LOG.debugf( "Adding XML overriding information for %s", className );
for ( DotName annName : IndexedAnnotationFilter.ASSOCIATION_ANNOTATIONS ) { }
private boolean hasSchemaOrCatalogDefined(EntityMappingsMocker.Default defaults) {
return ( defaults != null ) && ( StringHelper.isNotEmpty( defaults.getSchema() ) || StringHelper.isNotEmpty(
defaults.getCatalog()
) );
}
private void applyDefaultCascadePersist(Map<DotName, List<AnnotationInstance>> annotationsMap) {
for ( DotName annName : ASSOCIATION_ANNOTATIONS ) {
if ( annotationsMap.containsKey( annName ) ) { if ( annotationsMap.containsKey( annName ) ) {
addCascadePersistIfNotExist( annName, annotationsMap ); addCascadePersistIfNotExist( annName, annotationsMap );
} }
} }
} }
private void applyDefaultSchemaAndCatalog(Map<DotName, List<AnnotationInstance>> annotationsMap, EntityMappingsMocker.Default defaults) {
for ( DotName annName : SCHEMA_AWARE_ANNOTATIONS ) {
mockTableIfNonExist( annotationsMap, annName );
if ( annotationsMap.containsKey( annName ) ) {
overrideSchemaCatalogByDefault( annName, annotationsMap, defaults );
}
}
}
private void mockTableIfNonExist(Map<DotName, List<AnnotationInstance>> annotationsMap, DotName annName) {
if ( annName == JPADotNames.TABLE && !annotationsMap.containsKey( JPADotNames.TABLE ) && annotationsMap
.containsKey( JPADotNames.ENTITY ) ) {
//if an entity doesn't have a @Table, we create one here
AnnotationInstance entity = JandexHelper.getSingleAnnotation( annotationsMap, JPADotNames.ENTITY );
AnnotationInstance table = MockHelper.create(
JPADotNames.TABLE, entity.target(), MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY
);
List<AnnotationInstance> annotationInstanceList = new ArrayList<AnnotationInstance>( 1 );
annotationInstanceList.add( table );
annotationsMap.put( JPADotNames.TABLE, annotationInstanceList );
}
}
private void mockTableIfNonExist(XMLEntity entity, EntityMappingsMocker.Default defaults) {
if ( hasSchemaOrCatalogDefined( defaults ) ) {
XMLTable table = entity.getTable();
if ( table == null ) {
table = new XMLTable();
entity.setTable( table );
}
}
} }
private void addCascadePersistIfNotExist(DotName annName, Map<DotName, List<AnnotationInstance>> indexedAnnotationMap) { private void addCascadePersistIfNotExist(DotName annName, Map<DotName, List<AnnotationInstance>> indexedAnnotationMap) {
@ -98,11 +193,12 @@ class DefaultConfigurationHelper {
for ( String type : cascadeTypes ) { for ( String type : cascadeTypes ) {
if ( "PERSIST".equals( type ) ) { if ( "PERSIST".equals( type ) ) {
hasPersistDefined = true; hasPersistDefined = true;
break; continue;
} }
} }
if ( hasPersistDefined ) { if ( hasPersistDefined ) {
break; newAnnotationInstanceList.add( annotationInstance );
continue;
} }
String[] newCascadeTypes = new String[cascadeTypes.length + 1]; String[] newCascadeTypes = new String[cascadeTypes.length + 1];
newCascadeTypes[0] = "PERSIST"; newCascadeTypes[0] = "PERSIST";
@ -116,7 +212,7 @@ class DefaultConfigurationHelper {
} }
newAnnotationValueList.add( cascadeValue ); newAnnotationValueList.add( cascadeValue );
AnnotationInstance newAnnotationInstance = AnnotationInstance.create( AnnotationInstance newAnnotationInstance = MockHelper.create(
annotationInstance.name(), annotationInstance.name(),
annotationInstance.target(), annotationInstance.target(),
MockHelper.toArray( newAnnotationValueList ) MockHelper.toArray( newAnnotationValueList )
@ -127,7 +223,7 @@ class DefaultConfigurationHelper {
} }
//@Table, @CollectionTable, @JoinTable, @SecondaryTable //@Table, @CollectionTable, @JoinTable, @SecondaryTable
private void overrideScheamCatalogByDefault(DotName annName, Map<DotName, List<AnnotationInstance>> indexedAnnotationMap, EntityMappingsMocker.Default defaults) { private void overrideSchemaCatalogByDefault(DotName annName, Map<DotName, List<AnnotationInstance>> indexedAnnotationMap, EntityMappingsMocker.Default defaults) {
List<AnnotationInstance> annotationInstanceList = indexedAnnotationMap.get( annName ); List<AnnotationInstance> annotationInstanceList = indexedAnnotationMap.get( annName );
if ( annotationInstanceList == null || annotationInstanceList.isEmpty() ) { if ( annotationInstanceList == null || annotationInstanceList.isEmpty() ) {
return; return;
@ -138,14 +234,14 @@ class DefaultConfigurationHelper {
AnnotationInstance[] secondaryTableAnnotationInstanceArray = annotationInstance.value().asNestedArray(); AnnotationInstance[] secondaryTableAnnotationInstanceArray = annotationInstance.value().asNestedArray();
AnnotationValue[] newAnnotationValueArray = new AnnotationValue[secondaryTableAnnotationInstanceArray.length]; AnnotationValue[] newAnnotationValueArray = new AnnotationValue[secondaryTableAnnotationInstanceArray.length];
for ( int i = 0; i < secondaryTableAnnotationInstanceArray.length; i++ ) { for ( int i = 0; i < secondaryTableAnnotationInstanceArray.length; i++ ) {
newAnnotationValueArray[i] = AnnotationValue.createNestedAnnotationValue( newAnnotationValueArray[i] = MockHelper.nestedAnnotationValue(
"", overrideScheamCatalogByDefault( "", overrideSchemaCatalogByDefault(
secondaryTableAnnotationInstanceArray[i], secondaryTableAnnotationInstanceArray[i],
defaults defaults
) )
); );
} }
AnnotationInstance secondaryTablesAnnotationInstance = AnnotationInstance.create( AnnotationInstance secondaryTablesAnnotationInstance = MockHelper.create(
annName, annName,
annotationInstance.target(), annotationInstance.target(),
new AnnotationValue[] { new AnnotationValue[] {
@ -155,13 +251,13 @@ class DefaultConfigurationHelper {
newAnnotationInstanceList.add( secondaryTablesAnnotationInstance ); newAnnotationInstanceList.add( secondaryTablesAnnotationInstance );
} }
else { else {
newAnnotationInstanceList.add( overrideScheamCatalogByDefault( annotationInstance, defaults ) ); newAnnotationInstanceList.add( overrideSchemaCatalogByDefault( annotationInstance, defaults ) );
} }
} }
indexedAnnotationMap.put( annName, newAnnotationInstanceList ); indexedAnnotationMap.put( annName, newAnnotationInstanceList );
} }
private AnnotationInstance overrideScheamCatalogByDefault(AnnotationInstance annotationInstance, EntityMappingsMocker.Default defaults) { private AnnotationInstance overrideSchemaCatalogByDefault(AnnotationInstance annotationInstance, EntityMappingsMocker.Default defaults) {
List<AnnotationValue> newAnnotationValueList = new ArrayList<AnnotationValue>(); List<AnnotationValue> newAnnotationValueList = new ArrayList<AnnotationValue>();
newAnnotationValueList.addAll( annotationInstance.values() ); newAnnotationValueList.addAll( annotationInstance.values() );
boolean schemaDefined = false; boolean schemaDefined = false;
@ -189,11 +285,105 @@ class DefaultConfigurationHelper {
) )
); );
} }
return AnnotationInstance.create( return MockHelper.create(
annotationInstance.name(), annotationInstance.name(),
annotationInstance.target(), annotationInstance.target(),
MockHelper.toArray( newAnnotationValueList ) MockHelper.toArray( newAnnotationValueList )
); );
}
private static interface EntityObject {
String getClazz();
void setClazz(String className);
Boolean isMetadataComplete();
void setMetadataComplete(Boolean isMetadataComplete);
}
private static class EntityEntityObject implements EntityObject {
private XMLEntity entity;
private EntityEntityObject(XMLEntity entity) {
this.entity = entity;
}
@Override
public String getClazz() {
return entity.getClazz();
}
@Override
public void setClazz(String className) {
entity.setClazz( className );
}
@Override
public Boolean isMetadataComplete() {
return entity.isMetadataComplete();
}
@Override
public void setMetadataComplete(Boolean isMetadataComplete) {
entity.setMetadataComplete( isMetadataComplete );
}
}
private static class EmbeddableEntityObject implements EntityObject {
private XMLEmbeddable entity;
private EmbeddableEntityObject(XMLEmbeddable entity) {
this.entity = entity;
}
@Override
public String getClazz() {
return entity.getClazz();
}
@Override
public void setClazz(String className) {
entity.setClazz( className );
}
@Override
public Boolean isMetadataComplete() {
return entity.isMetadataComplete();
}
@Override
public void setMetadataComplete(Boolean isMetadataComplete) {
entity.setMetadataComplete( isMetadataComplete );
}
}
private static class MappedSuperClassEntityObject implements EntityObject {
private XMLMappedSuperclass entity;
private MappedSuperClassEntityObject(XMLMappedSuperclass entity) {
this.entity = entity;
}
@Override
public String getClazz() {
return entity.getClazz();
}
@Override
public void setClazz(String className) {
entity.setClazz( className );
}
@Override
public Boolean isMetadataComplete() {
return entity.isMetadataComplete();
}
@Override
public void setMetadataComplete(Boolean isMetadataComplete) {
entity.setMetadataComplete( isMetadataComplete );
}
}
} }
}

View File

@ -73,12 +73,7 @@ class EmbeddableMocker extends AbstractEntityObjectMocker {
@Override @Override
protected void applyDefaults() { protected void applyDefaults() {
String className = MockHelper.buildSafeClassName( embeddable.getClazz(), getDefaults().getPackageName() ); DefaultConfigurationHelper.INSTANCE.applyDefaults( embeddable, getDefaults() );
embeddable.setClazz( className );
if ( embeddable.isMetadataComplete() == null ) {
embeddable.setMetadataComplete( getDefaults().getMetadataComplete() );
}
LOG.debugf( "Adding XML overriding information for %s", className );
} }
@Override @Override

View File

@ -34,7 +34,6 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType; import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddable; import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddable;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity; import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings; import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
import org.hibernate.metamodel.source.annotation.xml.XMLMappedSuperclass; import org.hibernate.metamodel.source.annotation.xml.XMLMappedSuperclass;
import org.hibernate.metamodel.source.annotation.xml.XMLPersistenceUnitDefaults; import org.hibernate.metamodel.source.annotation.xml.XMLPersistenceUnitDefaults;
@ -51,14 +50,13 @@ public class EntityMappingsMocker {
CoreMessageLogger.class, CoreMessageLogger.class,
EntityMappingsMocker.class.getName() EntityMappingsMocker.class.getName()
); );
private List<XMLEntityMappings> entityMappingsList; private final List<XMLEntityMappings> entityMappingsList;
//todo delimited-identifier /**
* Default configuration defined in Persistence Metadata Unit, one or zero per Persistence Unit.
*/
private Default globalDefaults; private Default globalDefaults;
final private IndexBuilder indexBuilder; private final IndexBuilder indexBuilder;
//todo default entity listeners private final GlobalAnnotations globalAnnotations;
//todo default access type
private XMLEntityListeners defaultEntityListeners;
final private GlobalAnnotations globalAnnotations;
public EntityMappingsMocker(List<XMLEntityMappings> entityMappingsList, Index index, ServiceRegistry serviceRegistry) { public EntityMappingsMocker(List<XMLEntityMappings> entityMappingsList, Index index, ServiceRegistry serviceRegistry) {
this.entityMappingsList = entityMappingsList; this.entityMappingsList = entityMappingsList;
@ -85,13 +83,18 @@ public class EntityMappingsMocker {
for ( XMLEntityMappings entityMappings : entityMappingsList ) { for ( XMLEntityMappings entityMappings : entityMappingsList ) {
//we have to iterate entityMappingsList first to find persistence-unit-metadata //we have to iterate entityMappingsList first to find persistence-unit-metadata
XMLPersistenceUnitMetadata pum = entityMappings.getPersistenceUnitMetadata(); XMLPersistenceUnitMetadata pum = entityMappings.getPersistenceUnitMetadata();
if ( globalDefaults != null ) {
LOG.duplicateMetadata();
return;
}
if ( pum == null ) { if ( pum == null ) {
continue; continue;
} }
if ( globalDefaults == null ) {
globalDefaults = new Default(); globalDefaults = new Default();
globalDefaults.setMetadataComplete( pum.getXmlMappingMetadataComplete() != null ); if ( pum.getXmlMappingMetadataComplete() != null ) {
indexBuilder.mappingMetadataComplete( globalDefaults ); globalDefaults.setMetadataComplete( true );
indexBuilder.mappingMetadataComplete();
}
XMLPersistenceUnitDefaults pud = pum.getPersistenceUnitDefaults(); XMLPersistenceUnitDefaults pud = pum.getPersistenceUnitDefaults();
if ( pud == null ) { if ( pud == null ) {
return; return;
@ -100,14 +103,8 @@ public class EntityMappingsMocker {
globalDefaults.setCatalog( pud.getCatalog() ); globalDefaults.setCatalog( pud.getCatalog() );
globalDefaults.setAccess( pud.getAccess() ); globalDefaults.setAccess( pud.getAccess() );
globalDefaults.setCascadePersist( pud.getCascadePersist() != null ); globalDefaults.setCascadePersist( pud.getCascadePersist() != null );
globalDefaults.setDelimitedIdentifiers( pud.getDelimitedIdentifiers() != null );
defaultEntityListeners = pud.getEntityListeners();
new PersistenceMetadataMocker( indexBuilder, pud ).process(); new PersistenceMetadataMocker( indexBuilder, pud ).process();
} }
else {
LOG.duplicateMetadata();
}
}
} }
@ -168,9 +165,8 @@ public class EntityMappingsMocker {
private String packageName; private String packageName;
private String schema; private String schema;
private String catalog; private String catalog;
private Boolean metadataComplete; private boolean metadataComplete;
private Boolean cascadePersist; private boolean cascadePersist;
private Boolean delimitedIdentifier;
public XMLAccessType getAccess() { public XMLAccessType getAccess() {
return access; return access;
@ -204,30 +200,22 @@ public class EntityMappingsMocker {
this.schema = schema; this.schema = schema;
} }
public Boolean getMetadataComplete() { public boolean isMetadataComplete() {
return metadataComplete; return metadataComplete;
} }
void setMetadataComplete(Boolean metadataComplete) { void setMetadataComplete(boolean metadataComplete) {
this.metadataComplete = metadataComplete; this.metadataComplete = metadataComplete;
} }
public Boolean getCascadePersist() { public boolean isCascadePersist() {
return cascadePersist; return cascadePersist;
} }
void setCascadePersist(Boolean cascadePersist) { void setCascadePersist(boolean cascadePersist) {
this.cascadePersist = cascadePersist; this.cascadePersist = cascadePersist;
} }
void setDelimitedIdentifiers(Boolean delimitedIdentifier) {
this.delimitedIdentifier = delimitedIdentifier;
}
public Boolean getDelimitedIdentifier() {
return delimitedIdentifier;
}
void override(Default globalDefault) { void override(Default globalDefault) {
if ( globalDefault != null ) { if ( globalDefault != null ) {
if ( globalDefault.getAccess() != null ) { if ( globalDefault.getAccess() != null ) {
@ -242,15 +230,8 @@ public class EntityMappingsMocker {
if ( globalDefault.getCatalog() != null ) { if ( globalDefault.getCatalog() != null ) {
catalog = globalDefault.getCatalog(); catalog = globalDefault.getCatalog();
} }
if ( globalDefault.getDelimitedIdentifier() != null ) { metadataComplete = globalDefault.isMetadataComplete();
delimitedIdentifier = globalDefault.getDelimitedIdentifier(); cascadePersist = globalDefault.isCascadePersist();
}
if ( globalDefault.getMetadataComplete() != null ) {
metadataComplete = globalDefault.getMetadataComplete();
}
if ( globalDefault.getCascadePersist() != null ) {
cascadePersist = globalDefault.getCascadePersist();
}
} }
} }
} }

View File

@ -114,7 +114,10 @@ class EntityMocker extends AbstractEntityObjectMocker {
if ( table == null ) { if ( table == null ) {
return null; return null;
} }
MockHelper.updateSchema( new SchemaAware.TableSchemaAware( table ), getDefaults() ); DefaultConfigurationHelper.INSTANCE.applyDefaults(
new SchemaAware.TableSchemaAware( table ),
getDefaults()
);
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>(); List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", table.getName(), annotationValueList ); MockHelper.stringValue( "name", table.getName(), annotationValueList );
MockHelper.stringValue( "catalog", table.getCatalog(), annotationValueList ); MockHelper.stringValue( "catalog", table.getCatalog(), annotationValueList );
@ -152,24 +155,7 @@ class EntityMocker extends AbstractEntityObjectMocker {
@Override @Override
protected void applyDefaults() { protected void applyDefaults() {
if ( getDefaults() == null ) { DefaultConfigurationHelper.INSTANCE.applyDefaults( entity, getDefaults() );
return;
}
if ( MockHelper.hasSchemaOrCatalogDefined( getDefaults() ) ) {
XMLTable table = entity.getTable();
if ( table == null ) {
table = new XMLTable();
entity.setTable( table );
}
MockHelper.updateSchema( new SchemaAware.TableSchemaAware( table ), getDefaults() );
}
String className = MockHelper.buildSafeClassName( entity.getClazz(), getDefaults().getPackageName() );
entity.setClazz( className );
if ( entity.isMetadataComplete() == null ) {
entity.setMetadataComplete( getDefaults().getMetadataComplete() );
}
LOG.debugf( "Adding XML overriding information for %s", className );
} }
@Override @Override
@ -282,7 +268,10 @@ class EntityMocker extends AbstractEntityObjectMocker {
if ( secondaryTable == null ) { if ( secondaryTable == null ) {
return null; return null;
} }
MockHelper.updateSchema( new SchemaAware.SecondaryTableSchemaAware( secondaryTable ), getDefaults() ); DefaultConfigurationHelper.INSTANCE.applyDefaults(
new SchemaAware.SecondaryTableSchemaAware( secondaryTable ),
getDefaults()
);
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>(); List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", secondaryTable.getName(), annotationValueList ); MockHelper.stringValue( "name", secondaryTable.getName(), annotationValueList );
MockHelper.stringValue( "catalog", secondaryTable.getCatalog(), annotationValueList ); MockHelper.stringValue( "catalog", secondaryTable.getCatalog(), annotationValueList );

View File

@ -70,20 +70,26 @@ public class IndexBuilder {
this.indexedClassInfoAnnotationsMap = new HashMap<DotName, Map<DotName, List<AnnotationInstance>>>(); this.indexedClassInfoAnnotationsMap = new HashMap<DotName, Map<DotName, List<AnnotationInstance>>>();
} }
/**
* Build new {@link Index} with mocked annotations from orm.xml.
* This method should be only called once per {@org.hibernate.metamodel.source.annotations.xml.mocker.IndexBuilder IndexBuilder} instance.
*
* @param globalDefaults Global defaults from <persistence-unit-metadata>, or null.
*
* @return Index.
*/
Index build(EntityMappingsMocker.Default globalDefaults) { Index build(EntityMappingsMocker.Default globalDefaults) {
if ( !classInfoAnnotationsMap.isEmpty() ) {
throw new AssertionFailure( "IndexBuilder.finishEntityObject must be called after processing each entity." );
}
//merge annotations that not overrided by xml into the new Index //merge annotations that not overrided by xml into the new Index
for ( ClassInfo ci : index.getKnownClasses() ) { for ( ClassInfo ci : index.getKnownClasses() ) {
DotName name = ci.name(); DotName name = ci.name();
// annotations classes NOT overrided by xml if ( indexedClassInfoAnnotationsMap.containsKey( name ) ) {
if ( !indexedClassInfoAnnotationsMap.containsKey( name ) ) { //this class has been overrided by orm.xml
continue;
}
if ( ci.annotations() != null && !ci.annotations().isEmpty() ) { if ( ci.annotations() != null && !ci.annotations().isEmpty() ) {
Map<DotName, List<AnnotationInstance>> tmp = new HashMap<DotName, List<AnnotationInstance>>( ci.annotations() ); Map<DotName, List<AnnotationInstance>> tmp = new HashMap<DotName, List<AnnotationInstance>>( ci.annotations() );
DefaultConfigurationHelper.INSTANCE.apply( tmp, globalDefaults ); DefaultConfigurationHelper.INSTANCE.applyDefaults( tmp, globalDefaults );
mergeAnnotationMap( tmp, annotations ); mergeAnnotationMap( tmp, annotations );
tmp.clear();
classes.put( name, ci ); classes.put( name, ci );
if ( ci.superName() != null ) { if ( ci.superName() != null ) {
addSubClasses( ci.superName(), ci ); addSubClasses( ci.superName(), ci );
@ -93,19 +99,15 @@ public class IndexBuilder {
} }
} }
} }
} return Index.create(
Index newIndex = Index.create(
annotations, subclasses, implementors, classes annotations, subclasses, implementors, classes
); );
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Annotations from new build Index:" );
newIndex.printAnnotations();
}
return newIndex;
} }
void mappingMetadataComplete(EntityMappingsMocker.Default globalDefaults) { /**
if ( globalDefaults != null && globalDefaults.getMetadataComplete() != null && globalDefaults.getMetadataComplete() ) { * If {@code xml-mapping-metadata-complete} is defined in PersistenceUnitMetadata, we create a new empty {@link Index} here.
*/
void mappingMetadataComplete() {
LOG.debug( LOG.debug(
"xml-mapping-metadata-complete is specified in persistence-unit-metadata, ignore JPA annotations." "xml-mapping-metadata-complete is specified in persistence-unit-metadata, ignore JPA annotations."
); );
@ -117,17 +119,15 @@ public class IndexBuilder {
); );
} }
}
/** /**
* @param name Entity Object dot name which is being process. * @param name Entity Object dot name which is being process.
* @param metadataComplete True Entity Object defined in orm.xml is supposed to override annotations.
*/ */
void metadataComplete(DotName name, boolean metadataComplete) { void metadataComplete(DotName name) {
if ( metadataComplete ) { LOG.debug(
"metadata-complete is specified in " + name + ", ignore JPA annotations."
);
getIndexedAnnotations( name ).clear(); getIndexedAnnotations( name ).clear();
} }
}
public Map<DotName, List<AnnotationInstance>> getIndexedAnnotations(DotName name) { public Map<DotName, List<AnnotationInstance>> getIndexedAnnotations(DotName name) {
Map<DotName, List<AnnotationInstance>> map = indexedClassInfoAnnotationsMap.get( name ); Map<DotName, List<AnnotationInstance>> map = indexedClassInfoAnnotationsMap.get( name );
@ -139,7 +139,7 @@ public class IndexBuilder {
else { else {
map = new HashMap<DotName, List<AnnotationInstance>>( ci.annotations() ); map = new HashMap<DotName, List<AnnotationInstance>>( ci.annotations() );
//here we ignore global annotations //here we ignore global annotations
for ( DotName globalAnnotationName : IndexedAnnotationFilter.GLOBAL_ANNOTATIONS ) { for ( DotName globalAnnotationName : DefaultConfigurationHelper.GLOBAL_ANNOTATIONS ) {
if ( map.containsKey( globalAnnotationName ) ) { if ( map.containsKey( globalAnnotationName ) ) {
map.put( globalAnnotationName, Collections.<AnnotationInstance>emptyList() ); map.put( globalAnnotationName, Collections.<AnnotationInstance>emptyList() );
} }
@ -163,7 +163,7 @@ public class IndexBuilder {
} }
void collectGlobalConfigurationFromIndex(GlobalAnnotations globalAnnotations) { void collectGlobalConfigurationFromIndex(GlobalAnnotations globalAnnotations) {
for ( DotName annName : IndexedAnnotationFilter.GLOBAL_ANNOTATIONS ) { for ( DotName annName : DefaultConfigurationHelper.GLOBAL_ANNOTATIONS ) {
List<AnnotationInstance> annotationInstanceList = index.getAnnotations( annName ); List<AnnotationInstance> annotationInstanceList = index.getAnnotations( annName );
if ( MockHelper.isNotEmpty( annotationInstanceList ) ) { if ( MockHelper.isNotEmpty( annotationInstanceList ) ) {
globalAnnotations.addIndexedAnnotationInstance( annotationInstanceList ); globalAnnotations.addIndexedAnnotationInstance( annotationInstanceList );
@ -174,20 +174,18 @@ public class IndexBuilder {
void finishGlobalConfigurationMocking(GlobalAnnotations globalAnnotations) { void finishGlobalConfigurationMocking(GlobalAnnotations globalAnnotations) {
annotations.putAll( globalAnnotations.getAnnotationInstanceMap() ); annotations.putAll( globalAnnotations.getAnnotationInstanceMap() );
} }
void finishEntityObject(final DotName name, final EntityMappingsMocker.Default defaults) { void finishEntityObject(final DotName name, final EntityMappingsMocker.Default defaults) {
Map<DotName, List<AnnotationInstance>> map = classInfoAnnotationsMap.get( name );
if ( map == null ) {
throw new AssertionFailure( "Calling finish entity object " + name + " before create it." );
}
// annotations classes overrided by xml // annotations classes overrided by xml
if ( indexedClassInfoAnnotationsMap.containsKey( name ) ) { if ( indexedClassInfoAnnotationsMap.containsKey( name ) ) {
Map<DotName, List<AnnotationInstance>> tmp = getIndexedAnnotations( name ); Map<DotName, List<AnnotationInstance>> tmp = getIndexedAnnotations( name );
DefaultConfigurationHelper.INSTANCE.apply( tmp, defaults ); DefaultConfigurationHelper.INSTANCE.applyDefaults( tmp, defaults );
mergeAnnotationMap( tmp, classInfoAnnotationsMap.get( name ) ); mergeAnnotationMap( tmp, map );
tmp.clear();
}
Map<DotName, List<AnnotationInstance>> map = classInfoAnnotationsMap.remove( name );
if ( map == null ) {
throw new AssertionFailure( "Calling finish entity object " + name.toString() + " before create it." );
} }
mergeAnnotationMap( map, annotations ); mergeAnnotationMap( map, annotations );
@ -198,7 +196,7 @@ public class IndexBuilder {
if ( annotationInstance == null ) { if ( annotationInstance == null ) {
return; return;
} }
for ( IndexedAnnotationFilter indexedAnnotationFilter : IndexedAnnotationFilter.filters ) { for ( IndexedAnnotationFilter indexedAnnotationFilter : IndexedAnnotationFilter.ALL_FILTERS ) {
indexedAnnotationFilter.beforePush( this, targetClassName, annotationInstance ); indexedAnnotationFilter.beforePush( this, targetClassName, annotationInstance );
} }
Map<DotName, List<AnnotationInstance>> map = classInfoAnnotationsMap.get( targetClassName ); Map<DotName, List<AnnotationInstance>> map = classInfoAnnotationsMap.get( targetClassName );
@ -224,9 +222,7 @@ public class IndexBuilder {
} }
DotName classDotName = DotName.createSimple( className ); DotName classDotName = DotName.createSimple( className );
if ( classes.containsKey( classDotName ) ) { if ( classes.containsKey( classDotName ) ) {
LOG.warnf( //classInfoAnnotationsMap.put( classDotName, new HashMap<DotName, List<AnnotationInstance>>(classes.get( classDotName ).annotations()) );
"Class %s has already been processed by IndexBuilder, ignoring this call and return previous created ClassInfo object"
);
return classes.get( classDotName ); return classes.get( classDotName );
} }
Class clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( className ); Class clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( className );

View File

@ -31,6 +31,7 @@ import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo; import org.jboss.jandex.ClassInfo;
import org.hibernate.MappingException;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListener; import org.hibernate.metamodel.source.annotation.xml.XMLEntityListener;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners; import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad; import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad;
@ -42,46 +43,46 @@ import org.hibernate.metamodel.source.annotation.xml.XMLPreRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate; import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate;
/** /**
* {@link javax.persistence.EntityListeners @EntityListeners} mocker
*
* @author Strong Liu * @author Strong Liu
*/ */
class ListenerMocker extends AbstractMocker { class ListenerMocker extends AbstractMocker {
private ClassInfo classInfo; private final ClassInfo classInfo;
ListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) { ListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) {
super( indexBuilder ); super( indexBuilder );
this.classInfo = classInfo; this.classInfo = classInfo;
} }
//@EntityListeners
AnnotationInstance parser(XMLEntityListeners entityListeners) { AnnotationInstance parser(XMLEntityListeners entityListeners) {
if ( entityListeners == null ) { if ( entityListeners.getEntityListener().isEmpty() ) {
return null; throw new MappingException( "No child element of <entity-listener> found under <entity-listeners>." );
} }
//class array value List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>( 1 );
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>(); List<String> clazzNameList = new ArrayList<String>( entityListeners.getEntityListener().size() );
List<String> clazzNameList = new ArrayList<String>();
for ( XMLEntityListener listener : entityListeners.getEntityListener() ) { for ( XMLEntityListener listener : entityListeners.getEntityListener() ) {
MockHelper.addToCollectionIfNotNull( clazzNameList, listener.getClazz() ); MockHelper.addToCollectionIfNotNull( clazzNameList, listener.getClazz() );
parser( listener ); parserEntityListener( listener );
} }
MockHelper.classArrayValue( "value", clazzNameList, annotationValueList, indexBuilder.getServiceRegistry() ); MockHelper.classArrayValue( "value", clazzNameList, annotationValueList, indexBuilder.getServiceRegistry() );
return create( ENTITY_LISTENERS, classInfo, annotationValueList ); return create( ENTITY_LISTENERS, classInfo, annotationValueList );
} }
private void parser(XMLEntityListener listener) { private void parserEntityListener(XMLEntityListener listener) {
String clazz = listener.getClazz(); String clazz = listener.getClazz();
ClassInfo tempClassInfo = indexBuilder.createClassInfo( clazz ); ClassInfo tempClassInfo = indexBuilder.createClassInfo( clazz );
ListenerMocker builder = createListenerMocker( indexBuilder, tempClassInfo ); ListenerMocker mocker = createListenerMocker( indexBuilder, tempClassInfo );
builder.parser( listener.getPostLoad() ); mocker.parser( listener.getPostLoad() );
builder.parser( listener.getPostPersist() ); mocker.parser( listener.getPostPersist() );
builder.parser( listener.getPostRemove() ); mocker.parser( listener.getPostRemove() );
builder.parser( listener.getPostUpdate() ); mocker.parser( listener.getPostUpdate() );
builder.parser( listener.getPrePersist() ); mocker.parser( listener.getPrePersist() );
builder.parser( listener.getPreRemove() ); mocker.parser( listener.getPreRemove() );
builder.parser( listener.getPreUpdate() ); mocker.parser( listener.getPreUpdate() );
indexBuilder.finishEntityObject( tempClassInfo.name(), null ); indexBuilder.finishEntityObject( tempClassInfo.name(), null );
} }
protected ListenerMocker createListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) { protected ListenerMocker createListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) {
return new ListenerMocker( indexBuilder, classInfo ); return new ListenerMocker( indexBuilder, classInfo );
} }
@ -91,7 +92,7 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( PRE_PERSIST, getTarget( callback.getMethodName() ) ); return create( PRE_PERSIST, getListenerTarget( callback.getMethodName() ) );
} }
//@PreRemove //@PreRemove
@ -99,7 +100,7 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( PRE_REMOVE, getTarget( callback.getMethodName() ) ); return create( PRE_REMOVE, getListenerTarget( callback.getMethodName() ) );
} }
//@PreUpdate //@PreUpdate
@ -107,7 +108,7 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( PRE_UPDATE, getTarget( callback.getMethodName() ) ); return create( PRE_UPDATE, getListenerTarget( callback.getMethodName() ) );
} }
//@PostPersist //@PostPersist
@ -115,7 +116,7 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( POST_PERSIST, getTarget( callback.getMethodName() ) ); return create( POST_PERSIST, getListenerTarget( callback.getMethodName() ) );
} }
//@PostUpdate //@PostUpdate
@ -123,7 +124,7 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( POST_UPDATE, getTarget( callback.getMethodName() ) ); return create( POST_UPDATE, getListenerTarget( callback.getMethodName() ) );
} }
//@PostRemove //@PostRemove
@ -131,7 +132,7 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( POST_REMOVE, getTarget( callback.getMethodName() ) ); return create( POST_REMOVE, getListenerTarget( callback.getMethodName() ) );
} }
//@PostLoad //@PostLoad
@ -139,10 +140,10 @@ class ListenerMocker extends AbstractMocker {
if ( callback == null ) { if ( callback == null ) {
return null; return null;
} }
return create( POST_LOAD, getTarget( callback.getMethodName() ) ); return create( POST_LOAD, getListenerTarget( callback.getMethodName() ) );
} }
private AnnotationTarget getTarget(String methodName) { private AnnotationTarget getListenerTarget(String methodName) {
return MockHelper.getTarget( return MockHelper.getTarget(
indexBuilder.getServiceRegistry(), classInfo, methodName, MockHelper.TargetType.METHOD indexBuilder.getServiceRegistry(), classInfo, methodName, MockHelper.TargetType.METHOD
); );

View File

@ -58,12 +58,7 @@ class MappedSuperclassMocker extends AbstractEntityObjectMocker {
@Override @Override
protected void applyDefaults() { protected void applyDefaults() {
String className = MockHelper.buildSafeClassName( mappedSuperclass.getClazz(), getDefaults().getPackageName() ); DefaultConfigurationHelper.INSTANCE.applyDefaults( mappedSuperclass, getDefaults() );
mappedSuperclass.setClazz( className );
if ( mappedSuperclass.isMetadataComplete() == null ) {
mappedSuperclass.setMetadataComplete( getDefaults().getMetadataComplete() );
}
LOG.debugf( "Adding XML overriding information for %s", className );
} }
@Override @Override

View File

@ -244,24 +244,6 @@ public class MockHelper {
} }
} }
public static boolean hasSchemaOrCatalogDefined(EntityMappingsMocker.Default defaults) {
if ( defaults == null ) {
return false;
}
return StringHelper.isNotEmpty( defaults.getSchema() ) || StringHelper.isNotEmpty( defaults.getCatalog() );
}
public static void updateSchema(SchemaAware schemaAware, EntityMappingsMocker.Default defaults) {
if ( hasSchemaOrCatalogDefined( defaults ) ) {
if ( StringHelper.isEmpty( schemaAware.getSchema() ) ) {
schemaAware.setSchema( defaults.getSchema() );
}
if ( StringHelper.isEmpty( schemaAware.getCatalog() ) ) {
schemaAware.setCatalog( defaults.getCatalog() );
}
}
}
/** /**
* @param t1 can't be null * @param t1 can't be null

View File

@ -16,38 +16,38 @@ import org.hibernate.metamodel.source.annotations.xml.PseudoJpaDotNames;
* @author Strong Liu * @author Strong Liu
*/ */
class PersistenceMetadataMocker extends AbstractMocker { class PersistenceMetadataMocker extends AbstractMocker {
private XMLPersistenceUnitDefaults persistenceUnitDefaults; private final XMLPersistenceUnitDefaults persistenceUnitDefaults;
private GlobalAnnotations globalAnnotations = new GlobalAnnotations(); private final GlobalAnnotations globalAnnotations = new GlobalAnnotations();
private static Map<DotName, DotName> nameDotNameMap = new HashMap<DotName, DotName>(); /**
* Map JPA Annotations name to Pseudo JPA Annotations name.
*/
private final static Map<DotName, DotName> nameMapper = new HashMap<DotName, DotName>();
static { static {
nameDotNameMap.put( ACCESS, PseudoJpaDotNames.DEFAULT_ACCESS ); nameMapper.put( ACCESS, PseudoJpaDotNames.DEFAULT_ACCESS );
nameDotNameMap.put( ENTITY_LISTENERS, PseudoJpaDotNames.DEFAULT_ENTITY_LISTENERS ); nameMapper.put( ENTITY_LISTENERS, PseudoJpaDotNames.DEFAULT_ENTITY_LISTENERS );
nameDotNameMap.put( POST_LOAD, PseudoJpaDotNames.DEFAULT_POST_LOAD ); nameMapper.put( POST_LOAD, PseudoJpaDotNames.DEFAULT_POST_LOAD );
nameDotNameMap.put( POST_REMOVE, PseudoJpaDotNames.DEFAULT_POST_REMOVE ); nameMapper.put( POST_REMOVE, PseudoJpaDotNames.DEFAULT_POST_REMOVE );
nameDotNameMap.put( POST_UPDATE, PseudoJpaDotNames.DEFAULT_POST_UPDATE ); nameMapper.put( POST_UPDATE, PseudoJpaDotNames.DEFAULT_POST_UPDATE );
nameDotNameMap.put( POST_PERSIST, PseudoJpaDotNames.DEFAULT_POST_PERSIST ); nameMapper.put( POST_PERSIST, PseudoJpaDotNames.DEFAULT_POST_PERSIST );
nameDotNameMap.put( PRE_REMOVE, PseudoJpaDotNames.DEFAULT_PRE_REMOVE ); nameMapper.put( PRE_REMOVE, PseudoJpaDotNames.DEFAULT_PRE_REMOVE );
nameDotNameMap.put( PRE_UPDATE, PseudoJpaDotNames.DEFAULT_PRE_UPDATE ); nameMapper.put( PRE_UPDATE, PseudoJpaDotNames.DEFAULT_PRE_UPDATE );
nameDotNameMap.put( PRE_PERSIST, PseudoJpaDotNames.DEFAULT_PRE_PERSIST ); nameMapper.put( PRE_PERSIST, PseudoJpaDotNames.DEFAULT_PRE_PERSIST );
nameDotNameMap.put( PseudoJpaDotNames.DEFAULT_DELIMITED_IDENTIFIERS, PseudoJpaDotNames.DEFAULT_DELIMITED_IDENTIFIERS ); nameMapper.put(
PseudoJpaDotNames.DEFAULT_DELIMITED_IDENTIFIERS,
PseudoJpaDotNames.DEFAULT_DELIMITED_IDENTIFIERS
);
} }
PersistenceMetadataMocker(IndexBuilder indexBuilder, XMLPersistenceUnitDefaults persistenceUnitDefaults) { PersistenceMetadataMocker(IndexBuilder indexBuilder, XMLPersistenceUnitDefaults persistenceUnitDefaults) {
super( indexBuilder ); super( indexBuilder );
this.persistenceUnitDefaults = persistenceUnitDefaults; this.persistenceUnitDefaults = persistenceUnitDefaults;
}
@Override
protected AnnotationInstance push(AnnotationInstance annotationInstance) {
if ( annotationInstance != null ) {
return globalAnnotations.push( annotationInstance.name(), annotationInstance );
}
return null;
} }
/**
* Mock global configurations defined in <persistence-unit-metadata> with pseudo JPA annotation name.
* NOTE: These mocked annotations do not have {@link AnnotationTarget target}.
*/
final void process() { final void process() {
parserAccessType( persistenceUnitDefaults.getAccess(), null ); parserAccessType( persistenceUnitDefaults.getAccess(), null );
if ( persistenceUnitDefaults.getDelimitedIdentifiers() != null ) { if ( persistenceUnitDefaults.getDelimitedIdentifiers() != null ) {
@ -59,9 +59,17 @@ class PersistenceMetadataMocker extends AbstractMocker {
indexBuilder.finishGlobalConfigurationMocking( globalAnnotations ); indexBuilder.finishGlobalConfigurationMocking( globalAnnotations );
} }
@Override
protected AnnotationInstance push(AnnotationInstance annotationInstance) {
if ( annotationInstance != null ) {
return globalAnnotations.push( annotationInstance.name(), annotationInstance );
}
return null;
}
@Override @Override
protected AnnotationInstance create(DotName name, AnnotationTarget target, AnnotationValue[] annotationValues) { protected AnnotationInstance create(DotName name, AnnotationTarget target, AnnotationValue[] annotationValues) {
DotName defaultName = nameDotNameMap.get( name ); DotName defaultName = nameMapper.get( name );
if ( defaultName == null ) { if ( defaultName == null ) {
return null; return null;
} }
@ -69,7 +77,7 @@ class PersistenceMetadataMocker extends AbstractMocker {
} }
class DefaultListenerMocker extends ListenerMocker { private class DefaultListenerMocker extends ListenerMocker {
DefaultListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) { DefaultListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) {
super( indexBuilder, classInfo ); super( indexBuilder, classInfo );
} }
@ -89,6 +97,4 @@ class PersistenceMetadataMocker extends AbstractMocker {
return new DefaultListenerMocker( indexBuilder, classInfo ); return new DefaultListenerMocker( indexBuilder, classInfo );
} }
} }
} }

View File

@ -1,53 +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.xml.mocker;
import org.jboss.jandex.AnnotationValue;
import org.hibernate.metamodel.source.annotation.xml.XMLAssociationOverride;
/**
* @author Strong Liu
*/
class XMLAssociationOverrideProxy extends XMLAssociationOverride {
private AnnotationValue joinTableAnnotationValue;
private AnnotationValue joinColumnsAnnotationValue;
AnnotationValue getJoinColumnsAnnotationValue() {
return joinColumnsAnnotationValue;
}
void setJoinColumnsAnnotationValue(AnnotationValue joinColumnsAnnotationValue) {
this.joinColumnsAnnotationValue = joinColumnsAnnotationValue;
}
AnnotationValue getJoinTableAnnotationValue() {
return joinTableAnnotationValue;
}
void setJoinTableAnnotationValue(AnnotationValue joinTableAnnotationValue) {
this.joinTableAnnotationValue = joinTableAnnotationValue;
}
}

View File

@ -1,43 +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.xml.mocker;
import org.jboss.jandex.AnnotationValue;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributeOverride;
/**
* @author Strong Liu
*/
class XMLAttributeOverrideProxy extends XMLAttributeOverride {
private AnnotationValue columnAnnotationValue;
AnnotationValue getColumnAnnotationValue() {
return columnAnnotationValue;
}
void setColumnAnnotationValue(AnnotationValue columnAnnotationValue) {
this.columnAnnotationValue = columnAnnotationValue;
}
}

View File

@ -122,15 +122,18 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
} }
Index index = indexer.complete(); Index index = indexer.complete();
// process the xml configuration
final OrmXmlParser ormParser = new OrmXmlParser( this );
List<JaxbRoot<XMLEntityMappings>> mappings = new ArrayList<JaxbRoot<XMLEntityMappings>>(); List<JaxbRoot<XMLEntityMappings>> mappings = new ArrayList<JaxbRoot<XMLEntityMappings>>();
for ( JaxbRoot<?> root : metadataSources.getJaxbRootList() ) { for ( JaxbRoot<?> root : metadataSources.getJaxbRootList() ) {
if ( root.getRoot() instanceof XMLEntityMappings ) { if ( root.getRoot() instanceof XMLEntityMappings ) {
mappings.add( (JaxbRoot<XMLEntityMappings>) root ); mappings.add( (JaxbRoot<XMLEntityMappings>) root );
} }
} }
if ( !mappings.isEmpty() ) {
// process the xml configuration
final OrmXmlParser ormParser = new OrmXmlParser( this );
index = ormParser.parseAndUpdateIndex( mappings, index ); index = ormParser.parseAndUpdateIndex( mappings, index );
}
// create the annotation binder and pass it the final annotation index // create the annotation binder and pass it the final annotation index
final AnnotationBinder annotationBinder = new AnnotationBinder( this, index ); final AnnotationBinder annotationBinder = new AnnotationBinder( this, index );

View File

@ -147,7 +147,9 @@ public abstract class AbstractMockerTest {
} }
} }
} }
protected void assertHasAnnotation(Index index, DotName annName) {
assertHasAnnotation( index, null, annName, 1 );
}
protected void assertHasAnnotation(Index index, DotName className, DotName annName) { protected void assertHasAnnotation(Index index, DotName className, DotName annName) {
assertHasAnnotation( index, className, annName, 1 ); assertHasAnnotation( index, className, annName, 1 );
} }

View File

@ -0,0 +1,200 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SecondaryTable;
import javax.persistence.SecondaryTables;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.junit.Test;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author Strong Liu
*/
public class DefaultConfigurationHelperTest extends AbstractMockerTest {
@Test
public void applyNullDefaultToEntity() {
XMLEntity entity = new XMLEntity();
entity.setClazz( "Entity" );
DefaultConfigurationHelper.INSTANCE.applyDefaults( entity, null );
assertNull( entity.getTable() );
assertEquals( "Entity", entity.getClazz() );
}
@Test
public void applyDefaultToEntity() {
EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default();
defaults.setPackageName( "org.test" );
defaults.setSchema( "schema" );
defaults.setMetadataComplete( true );
XMLEntity entity = new XMLEntity();
entity.setClazz( "Entity" );
DefaultConfigurationHelper.INSTANCE.applyDefaults( entity, defaults );
assertNotNull( entity.getTable() );
assertNull( entity.getTable().getSchema() );
assertNull( entity.getTable().getCatalog() );
assertTrue( entity.isMetadataComplete() );
assertEquals( "org.test.Entity", entity.getClazz() );
DefaultConfigurationHelper.INSTANCE
.applyDefaults( new SchemaAware.TableSchemaAware( entity.getTable() ), defaults );
assertEquals( "schema", entity.getTable().getSchema() );
assertNull( entity.getTable().getCatalog() );
}
@Test
public void testDefaultCascadePersist() {
EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default();
defaults.setCascadePersist( true );
Index index = getIndex();
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
annotations.putAll( index.getClassByName( DotName.createSimple( Parent.class.getName() ) ).annotations() );
assertEquals( 4, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.ENTITY ).size() );
assertEquals( 1, annotations.get( JPADotNames.ID ).size() );
assertEquals( 1, annotations.get( JPADotNames.ONE_TO_MANY ).size() );
assertEquals( 1, annotations.get( JPADotNames.MANY_TO_ONE ).size() );
DefaultConfigurationHelper.INSTANCE.applyDefaults( annotations, defaults );
assertEquals( 4, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.ENTITY ).size() );
assertEquals( 1, annotations.get( JPADotNames.ID ).size() );
assertEquals( 1, annotations.get( JPADotNames.ONE_TO_MANY ).size() );
assertEquals( 1, annotations.get( JPADotNames.MANY_TO_ONE ).size() );
AnnotationInstance oneToMany = annotations.get( JPADotNames.ONE_TO_MANY ).get( 0 );
String[] cascadeTypes = oneToMany.value( "cascade" ).asEnumArray();
assertArrayEquals( new String[] { "ALL", "DETACH", "PERSIST" }, cascadeTypes );
AnnotationInstance manyToOne = annotations.get( JPADotNames.MANY_TO_ONE ).get( 0 );
cascadeTypes = manyToOne.value( "cascade" ).asEnumArray();
assertArrayEquals( new String[] { "PERSIST" }, cascadeTypes );
annotations.clear();
annotations.putAll( index.getClassByName( DotName.createSimple( Child.class.getName() ) ).annotations() );
assertEquals( 3, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.ENTITY ).size() );
assertEquals( 1, annotations.get( JPADotNames.ID ).size() );
assertEquals( 1, annotations.get( JPADotNames.MANY_TO_ONE ).size() );
DefaultConfigurationHelper.INSTANCE.applyDefaults( annotations, defaults );
assertEquals( 3, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.ENTITY ).size() );
assertEquals( 1, annotations.get( JPADotNames.ID ).size() );
assertEquals( 1, annotations.get( JPADotNames.MANY_TO_ONE ).size() );
manyToOne = annotations.get( JPADotNames.MANY_TO_ONE ).get( 0 );
cascadeTypes = manyToOne.value( "cascade" ).asEnumArray();
assertArrayEquals( new String[] { "PERSIST", "ALL", "DETACH" }, cascadeTypes );
}
@Test
public void testDefaultSchemaToAnnotationInstance() {
EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default();
defaults.setSchema( "hib_schema" );
defaults.setCatalog( "hib_catalog" );
Index index = getIndex();
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
annotations.putAll( index.getClassByName( DotName.createSimple( Parent.class.getName() ) ).annotations() );
assertEquals( 4, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.ENTITY ).size() );
assertEquals( 1, annotations.get( JPADotNames.ID ).size() );
assertEquals( 1, annotations.get( JPADotNames.ONE_TO_MANY ).size() );
assertEquals( 1, annotations.get( JPADotNames.MANY_TO_ONE ).size() );
DefaultConfigurationHelper.INSTANCE.applyDefaults( annotations, defaults );
assertEquals( 5, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.ENTITY ).size() );
assertEquals( 1, annotations.get( JPADotNames.ID ).size() );
assertEquals( 1, annotations.get( JPADotNames.ONE_TO_MANY ).size() );
assertEquals( 1, annotations.get( JPADotNames.MANY_TO_ONE ).size() );
assertEquals( 1, annotations.get( JPADotNames.TABLE ).size() );
AnnotationInstance table = annotations.get( JPADotNames.TABLE ).get( 0 );
assertEquals( "hib_schema", table.value( "schema" ).asString() );
assertEquals( "hib_catalog", table.value( "catalog" ).asString() );
annotations.clear();
annotations.putAll( index.getClassByName( DotName.createSimple( Name.class.getName() ) ).annotations() );
DefaultConfigurationHelper.INSTANCE.applyDefaults( annotations, defaults );
assertEquals( 1, annotations.size() );
assertEquals( 1, annotations.get( JPADotNames.SECONDARY_TABLES ).size() );
AnnotationInstance[] secondaryTables = annotations.get( JPADotNames.SECONDARY_TABLES )
.get( 0 )
.value()
.asNestedArray();
assertEquals( 2, secondaryTables.length );
AnnotationInstance secondaryTable = secondaryTables[0];
String name = secondaryTable.value( "name" ).asString();
if ( name.equals( "sec1" ) ) {
assertSt1( secondaryTable );
assertSt2( secondaryTables[1] );
}
else {
assertSt1( secondaryTables[1] );
assertSt2( secondaryTable );
}
}
private void assertSt1(AnnotationInstance secondaryTable) {
assertEquals( "hib_schema", secondaryTable.value( "schema" ).asString() );
assertEquals( "sec1_catalog", secondaryTable.value( "catalog" ).asString() );
}
private void assertSt2(AnnotationInstance secondaryTable) {
assertEquals( "sec2_schema", secondaryTable.value( "schema" ).asString() );
assertEquals( "hib_catalog", secondaryTable.value( "catalog" ).asString() );
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Parent.class, Child.class, Name.class };
}
@SecondaryTables( {
@SecondaryTable(name = "sec1", catalog = "sec1_catalog"),
@SecondaryTable(name = "sec2", schema = "sec2_schema")
})
class Name {
}
@Entity
class Parent {
@Id
long id;
@OneToMany(cascade = { CascadeType.ALL, CascadeType.DETACH, CascadeType.PERSIST })
Set<Child> children = new HashSet<Child>();
@ManyToOne
Parent parent;
}
@Entity
class Child {
@Id
long id;
@ManyToOne(cascade = { CascadeType.ALL, CascadeType.DETACH })
Parent parent;
}
}

View File

@ -29,6 +29,7 @@ import org.jboss.jandex.Index;
import org.junit.Test; import org.junit.Test;
import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.xml.PseudoJpaDotNames;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -41,9 +42,23 @@ public class EntityListenerTest extends AbstractMockerTest {
Index index = getMockedIndex( "listener.xml" ); Index index = getMockedIndex( "listener.xml" );
index.printAnnotations(); index.printAnnotations();
DotName itemName = DotName.createSimple( Item.class.getName() ); DotName itemName = DotName.createSimple( Item.class.getName() );
DotName itemListenerName = DotName.createSimple( ItemListener.class.getName() );
ClassInfo itemClassInfo = index.getClassByName( itemName ); ClassInfo itemClassInfo = index.getClassByName( itemName );
assertEquals( 2, itemClassInfo.annotations().size() ); assertEquals( 3, itemClassInfo.annotations().size() );
//entity
assertHasAnnotation( index, itemName, JPADotNames.ENTITY ); assertHasAnnotation( index, itemName, JPADotNames.ENTITY );
assertHasAnnotation( index, itemName, JPADotNames.ENTITY_LISTENERS ); assertHasAnnotation( index, itemName, JPADotNames.ENTITY_LISTENERS );
assertHasAnnotation( index, itemName, JPADotNames.ACCESS );
//listener
assertHasAnnotation( index, itemListenerName, JPADotNames.PRE_PERSIST );
assertHasAnnotation( index, itemListenerName, JPADotNames.POST_PERSIST );
//assert global configurations
assertHasAnnotation( index, PseudoJpaDotNames.DEFAULT_DELIMITED_IDENTIFIERS );
assertHasAnnotation( index, PseudoJpaDotNames.DEFAULT_ACCESS );
assertHasAnnotation( index, PseudoJpaDotNames.DEFAULT_ENTITY_LISTENERS );
assertHasAnnotation( index, PseudoJpaDotNames.DEFAULT_PRE_PERSIST );
assertHasAnnotation( index, PseudoJpaDotNames.DEFAULT_POST_PERSIST );
} }
} }

View File

@ -0,0 +1,13 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import org.junit.Test;
/**
* @author Strong Liu
*/
public class IndexBuilderTest extends AbstractMockerTest {
@Test
public void test() {
IndexBuilder builder = getIndexBuilder();
}
}