HHH-6476 implementing AttributeSource.getPropertyAccessorName and adding tests

This commit is contained in:
Hardy Ferentschik 2011-07-22 18:03:56 +02:00
parent 092af61f04
commit ceda40b686
10 changed files with 338 additions and 131 deletions

View File

@ -77,8 +77,6 @@ public interface AttributeBinding {
*/
public MetaAttributeContext getMetaAttributeContext();
public boolean isAlternateUniqueKey();
public boolean isLazy();

View File

@ -46,12 +46,20 @@ public class AssociationAttribute extends SimpleAttribute {
private final String referencedEntityType;
private final Set<CascadeType> cascadeTypes;
public static AssociationAttribute createAssociationAttribute(String name, Class<?> javaType, AttributeType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
return new AssociationAttribute( name, javaType, associationType, annotations );
public static AssociationAttribute createAssociationAttribute(String name,
Class<?> attributeType,
AttributeType attributeNature,
String accessType,
Map<DotName, List<AnnotationInstance>> annotations) {
return new AssociationAttribute( name, attributeType, attributeNature, accessType, annotations );
}
private AssociationAttribute(String name, Class<?> javaType, AttributeType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
super( name, javaType, annotations, false );
private AssociationAttribute(String name,
Class<?> javaType,
AttributeType associationType,
String accessType,
Map<DotName, List<AnnotationInstance>> annotations) {
super( name, javaType, accessType, annotations );
this.associationType = associationType;
this.ignoreNotFound = ignoreNotFound();
@ -82,7 +90,10 @@ public class AssociationAttribute extends SimpleAttribute {
private boolean ignoreNotFound() {
NotFoundAction action = NotFoundAction.EXCEPTION;
AnnotationInstance notFoundAnnotation = getIfExists( HibernateDotNames.NOT_FOUND );
AnnotationInstance notFoundAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.NOT_FOUND
);
if ( notFoundAnnotation != null ) {
AnnotationValue actionValue = notFoundAnnotation.value( "action" );
if ( actionValue != null ) {
@ -94,9 +105,12 @@ public class AssociationAttribute extends SimpleAttribute {
}
private String determineReferencedEntityType(AnnotationInstance associationAnnotation) {
String targetTypeName = getJavaType().getName();
String targetTypeName = getAttributeType().getName();
AnnotationInstance targetAnnotation = getIfExists( HibernateDotNames.TARGET );
AnnotationInstance targetAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.TARGET
);
if ( targetAnnotation != null ) {
targetTypeName = targetAnnotation.value().asClass().name().toString();
}

View File

@ -31,8 +31,8 @@ import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JandexHelper;
/**
* Base class for the different types of mapped attributes
@ -50,19 +50,34 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
*/
private final String name;
private final Class<?> javaType;
/**
* The java type of the attribute
*/
private final Class<?> attributeType;
/**
* The access type for this property. At the moment this is either 'field' or 'property', but Hibernate
* also allows custom named accessors (see {@link org.hibernate.property.PropertyAccessorFactory}).
*/
private final String accessType;
/**
* An optional explicit hibernate type name specified via {@link org.hibernate.annotations.Type}.
*/
private final String explicitHibernateTypeName;
/**
* Optional type parameters. See {@link #explicitHibernateTypeName}.
*/
private final Map<String, String> explicitHibernateTypeParameters;
MappedAttribute(String name, Class<?> javaType, Map<DotName, List<AnnotationInstance>> annotations) {
MappedAttribute(String name, Class<?> attributeType, String accessType, Map<DotName, List<AnnotationInstance>> annotations) {
this.annotations = annotations;
this.name = name;
this.attributeType = attributeType;
this.accessType = accessType;
this.javaType = javaType;
final AnnotationInstance typeAnnotation = getIfExists( HibernateDotNames.TYPE );
final AnnotationInstance typeAnnotation = JandexHelper.getSingleAnnotation(annotations(), HibernateDotNames.TYPE );
if ( typeAnnotation != null ) {
this.explicitHibernateTypeName = typeAnnotation.value( "type" ).asString();
this.explicitHibernateTypeParameters = extractTypeParameters( typeAnnotation );
@ -74,7 +89,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
}
private Map<String, String> extractTypeParameters(AnnotationInstance typeAnnotation) {
HashMap<String,String> typeParameters = new HashMap<String, String>();
HashMap<String, String> typeParameters = new HashMap<String, String>();
AnnotationValue parameterAnnotationValue = typeAnnotation.value( "parameters" );
if ( parameterAnnotationValue != null ) {
AnnotationInstance[] parameterAnnotations = parameterAnnotationValue.asNestedArray();
@ -92,8 +107,12 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return name;
}
public final Class<?> getJavaType() {
return javaType;
public final Class<?> getAttributeType() {
return attributeType;
}
public String getAccessType() {
return accessType;
}
public String getExplicitHibernateTypeName() {
@ -104,27 +123,6 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return explicitHibernateTypeParameters;
}
/**
* Returns the annotation with the specified name or {@code null}
*
* @param annotationDotName The annotation to retrieve/check
*
* @return Returns the annotation with the specified name or {@code null}. Note, since these are the
* annotations defined on a single attribute there can never be more than one.
*/
public final AnnotationInstance getIfExists(DotName annotationDotName) {
if ( annotations.containsKey( annotationDotName ) ) {
List<AnnotationInstance> instanceList = annotations.get( annotationDotName );
if ( instanceList.size() > 1 ) {
throw new AssertionFailure( "There cannot be more than one @" + annotationDotName.toString() + " annotation per mapped attribute" );
}
return instanceList.get( 0 );
}
else {
return null;
}
}
Map<DotName, List<AnnotationInstance>> annotations() {
return annotations;
}

View File

@ -73,6 +73,9 @@ public class SimpleAttribute extends MappedAttribute {
*/
private boolean isOptional = true;
/**
* Are this properties generated and when
*/
private PropertyGeneration propertyGeneration;
private boolean isInsertable = true;
private boolean isUpdatable = true;
@ -86,23 +89,12 @@ public class SimpleAttribute extends MappedAttribute {
private final String customReadFragment;
private final String checkCondition;
public static SimpleAttribute createSimpleAttribute(String name, Class<?> type, Map<DotName, List<AnnotationInstance>> annotations) {
return new SimpleAttribute( name, type, annotations, false );
public static SimpleAttribute createSimpleAttribute(String name, Class<?> attributeType, Map<DotName, List<AnnotationInstance>> annotations, String accessType) {
return new SimpleAttribute( name, attributeType, accessType, annotations );
}
public static SimpleAttribute createSimpleAttribute(SimpleAttribute simpleAttribute, ColumnValues columnValues) {
SimpleAttribute attribute = new SimpleAttribute(
simpleAttribute.getName(),
simpleAttribute.getJavaType(),
simpleAttribute.annotations(),
false
);
attribute.columnValues = columnValues;
return attribute;
}
SimpleAttribute(String name, Class<?> type, Map<DotName, List<AnnotationInstance>> annotations, boolean isDiscriminator) {
super( name, type, annotations );
SimpleAttribute(String name, Class<?> attributeType, String accessType, Map<DotName, List<AnnotationInstance>> annotations) {
super( name, attributeType, accessType, annotations );
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
AnnotationInstance embeddedIdAnnotation = JandexHelper.getSingleAnnotation(
@ -114,13 +106,8 @@ public class SimpleAttribute extends MappedAttribute {
AnnotationInstance versionAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.VERSION );
isVersioned = versionAnnotation != null;
if ( isDiscriminator ) {
columnValues = new DiscriminatorColumnValues( annotations );
}
else {
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN );
columnValues = new ColumnValues( columnAnnotation );
}
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN );
columnValues = new ColumnValues( columnAnnotation );
if ( isId ) {
// an id must be unique and cannot be nullable
@ -193,21 +180,16 @@ public class SimpleAttribute extends MappedAttribute {
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "SimpleAttribute" );
sb.append( "{isId=" ).append( isId );
sb.append( ", isVersioned=" ).append( isVersioned );
sb.append( ", isOptimisticLockable=" ).append( isOptimisticLockable );
sb.append( ", isLazy=" ).append( isLazy );
sb.append( ", isOptional=" ).append( isOptional );
sb.append( ", propertyGeneration=" ).append( propertyGeneration );
sb.append( ", isInsertable=" ).append( isInsertable );
sb.append( ", isUpdatable=" ).append( isUpdatable );
sb.append( '}' );
sb.append( "{name=" ).append( getName() );
return sb.toString();
}
private boolean checkOptimisticLockAnnotation() {
boolean triggersVersionIncrement = true;
AnnotationInstance optimisticLockAnnotation = getIfExists( HibernateDotNames.OPTIMISTIC_LOCK );
AnnotationInstance optimisticLockAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.OPTIMISTIC_LOCK
);
if ( optimisticLockAnnotation != null ) {
boolean exclude = optimisticLockAnnotation.value( "excluded" ).asBoolean();
triggersVersionIncrement = !exclude;
@ -216,7 +198,7 @@ public class SimpleAttribute extends MappedAttribute {
}
private void checkBasicAnnotation() {
AnnotationInstance basicAnnotation = getIfExists( JPADotNames.BASIC );
AnnotationInstance basicAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.BASIC );
if ( basicAnnotation != null ) {
FetchType fetchType = FetchType.LAZY;
AnnotationValue fetchValue = basicAnnotation.value( "fetch" );
@ -234,7 +216,10 @@ public class SimpleAttribute extends MappedAttribute {
// TODO - there is more todo for updatable and insertable. Checking the @Generated annotation is only one part (HF)
private void checkGeneratedAnnotation() {
AnnotationInstance generatedAnnotation = getIfExists( HibernateDotNames.GENERATED );
AnnotationInstance generatedAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.GENERATED
);
if ( generatedAnnotation != null ) {
this.isInsertable = false;
@ -253,13 +238,19 @@ public class SimpleAttribute extends MappedAttribute {
List<AnnotationInstance> allColumnTransformerAnnotations = new ArrayList<AnnotationInstance>();
// not quite sure about the usefulness of @ColumnTransformers (HF)
AnnotationInstance columnTransformersAnnotations = getIfExists( HibernateDotNames.COLUMN_TRANSFORMERS );
AnnotationInstance columnTransformersAnnotations = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.COLUMN_TRANSFORMERS
);
if ( columnTransformersAnnotations != null ) {
AnnotationInstance[] annotationInstances = allColumnTransformerAnnotations.get( 0 ).value().asNestedArray();
allColumnTransformerAnnotations.addAll( Arrays.asList( annotationInstances ) );
}
AnnotationInstance columnTransformerAnnotation = getIfExists( HibernateDotNames.COLUMN_TRANSFORMER );
AnnotationInstance columnTransformerAnnotation = JandexHelper.getSingleAnnotation(
annotations(),
HibernateDotNames.COLUMN_TRANSFORMER
);
if ( columnTransformerAnnotation != null ) {
allColumnTransformerAnnotations.add( columnTransformerAnnotation );
}
@ -294,7 +285,7 @@ public class SimpleAttribute extends MappedAttribute {
private String parseCheckAnnotation() {
String checkCondition = null;
AnnotationInstance checkAnnotation = getIfExists( HibernateDotNames.CHECK );
AnnotationInstance checkAnnotation = JandexHelper.getSingleAnnotation( annotations(), HibernateDotNames.CHECK );
if ( checkAnnotation != null ) {
checkCondition = checkAnnotation.value( "constraints" ).toString();
}

View File

@ -45,16 +45,6 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
this.attribute = attribute;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.BASIC;
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
return new ExplicitHibernateTypeSource() {
@ -72,8 +62,7 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
@Override
public String getPropertyAccessorName() {
// todo : implememt
return null;
return attribute.getAccessType();
}
@Override
@ -106,16 +95,34 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
return attribute.getName();
}
@Override
public List<RelationalValueSource> relationalValueSources() {
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>();
valueSources.add( new ColumnSourceImpl( attribute ) );
return valueSources;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public boolean isSingular() {
return true;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.BASIC;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Collections.emptySet();
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
@ -130,13 +137,6 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
public boolean areValuesNullableByDefault() {
return true;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>();
valueSources.add( new ColumnSourceImpl( attribute ) );
return valueSources;
}
}

View File

@ -245,7 +245,7 @@ public class ConfiguredClass {
AccessType accessType = defaultAccessType;
AnnotationInstance accessAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ACCESS );
if ( accessAnnotation != null ) {
if ( accessAnnotation != null && accessAnnotation.target().getClass().equals( ClassInfo.class ) ) {
accessType = JandexHelper.getValueAsEnum( accessAnnotation, "value", AccessType.class );
}
@ -279,7 +279,7 @@ public class ConfiguredClass {
Field.setAccessible( fields, true );
for ( Field field : fields ) {
if ( isPersistentMember( transientFieldNames, explicitlyConfiguredMemberNames, field ) ) {
createMappedProperty( field, resolvedType );
createMappedAttribute( field, resolvedType, AccessType.FIELD );
}
}
}
@ -288,7 +288,7 @@ public class ConfiguredClass {
Method.setAccessible( methods, true );
for ( Method method : methods ) {
if ( isPersistentMember( transientMethodNames, explicitlyConfiguredMemberNames, method ) ) {
createMappedProperty( method, resolvedType );
createMappedAttribute( method, resolvedType, AccessType.PROPERTY );
}
}
}
@ -303,7 +303,7 @@ public class ConfiguredClass {
return false;
}
if ( explicitlyConfiguredMemberNames.contains( member.getName() ) ) {
if ( explicitlyConfiguredMemberNames.contains( ReflectionHelper.getPropertyName( member ) ) ) {
return false;
}
@ -318,11 +318,11 @@ public class ConfiguredClass {
* @return the property names of the explicitly configured attribute names in a set
*/
private Set<String> createExplicitlyConfiguredAccessProperties(ResolvedTypeWithMembers resolvedMembers) {
Set<String> explicitAccessMembers = new HashSet<String>();
Set<String> explicitAccessPropertyNames = new HashSet<String>();
List<AnnotationInstance> accessAnnotations = classInfo.annotations().get( JPADotNames.ACCESS );
if ( accessAnnotations == null ) {
return explicitAccessMembers;
return explicitAccessPropertyNames;
}
// iterate over all @Access annotations defined on the current class
@ -340,7 +340,6 @@ public class ConfiguredClass {
continue;
}
// the placement is correct, get the member
Member member;
if ( annotationTarget instanceof MethodInfo ) {
@ -356,6 +355,7 @@ public class ConfiguredClass {
);
}
member = m;
accessType = AccessType.PROPERTY;
}
else {
Field f;
@ -370,13 +370,14 @@ public class ConfiguredClass {
);
}
member = f;
accessType = AccessType.FIELD;
}
if ( ReflectionHelper.isProperty( member ) ) {
createMappedProperty( member, resolvedMembers );
explicitAccessMembers.add( member.getName() );
createMappedAttribute( member, resolvedMembers, accessType );
explicitAccessPropertyNames.add( ReflectionHelper.getPropertyName( member ) );
}
}
return explicitAccessMembers;
return explicitAccessPropertyNames;
}
private boolean isExplicitAttributeAccessAnnotationPlacedCorrectly(AnnotationTarget annotationTarget, AccessType accessType) {
@ -426,7 +427,7 @@ public class ConfiguredClass {
return true;
}
private void createMappedProperty(Member member, ResolvedTypeWithMembers resolvedType) {
private void createMappedAttribute(Member member, ResolvedTypeWithMembers resolvedType, AccessType accessType) {
final String attributeName = ReflectionHelper.getPropertyName( member );
ResolvedMember[] resolvedMembers;
if ( member instanceof Field ) {
@ -435,21 +436,26 @@ public class ConfiguredClass {
else {
resolvedMembers = resolvedType.getMemberMethods();
}
final Class<?> type = (Class<?>) findResolvedType( member.getName(), resolvedMembers );
final Class<?> attributeType = (Class<?>) findResolvedType( member.getName(), resolvedMembers );
final Map<DotName, List<AnnotationInstance>> annotations = JandexHelper.getMemberAnnotations(
classInfo, member.getName()
);
AttributeType attributeType = determineAttributeType( annotations );
switch ( attributeType ) {
AttributeType attributeNature = determineAttributeType( annotations );
String accessTypeString = accessType.toString().toLowerCase();
switch ( attributeNature ) {
case BASIC: {
SimpleAttribute attribute = SimpleAttribute.createSimpleAttribute( attributeName, type, annotations );
SimpleAttribute attribute = SimpleAttribute.createSimpleAttribute(
attributeName, attributeType, annotations, accessTypeString
);
if ( attribute.isId() ) {
idAttributeMap.put( attributeName, attribute );
} else if (attribute.isVersioned()) {
}
else if ( attribute.isVersioned() ) {
// todo - error handling in case there are multiple version attributes
versionAttribute = attribute;
} else {
}
else {
simpleAttributeMap.put( attributeName, attribute );
}
break;
@ -458,12 +464,12 @@ public class ConfiguredClass {
case EMBEDDED_ID:
case EMBEDDED: {
resolveEmbeddable( attributeName, type );
resolveEmbeddable( attributeName, attributeType );
}
// TODO handle the different association types
default: {
AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute(
attributeName, type, attributeType, annotations
attributeName, attributeType, attributeNature, accessTypeString, annotations
);
associationAttributeMap.put( attributeName, attribute );
}

View File

@ -32,7 +32,7 @@ public interface AttributeSource {
/**
* Obtain the attribute name.
*
* @return The attribute name. {@code nulls} are NOT allowed!
* @return The attribute name. {@code null} ais NOT allowed!
*/
public String getName();
@ -53,5 +53,4 @@ public interface AttributeSource {
* @return The meta-attribute sources.
*/
public Iterable<MetaAttributeSource> metaAttributes();
}

View File

@ -32,6 +32,7 @@ import java.util.List;
*/
public interface RelationalValueSourceContainer {
public boolean areValuesIncludedInInsertByDefault();
public boolean areValuesIncludedInUpdateByDefault();
public boolean areValuesNullableByDefault();

View File

@ -0,0 +1,153 @@
/*
* 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.entity;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.junit.Test;
import org.hibernate.AnnotationException;
import org.hibernate.metamodel.binding.EntityBinding;
import static junit.framework.Assert.assertEquals;
/**
* Tests for different types of attribute access
*
* @author Hardy Ferentschik
*/
public class AccessBindingTests extends BaseAnnotationBindingTestCase {
@Entity
class FieldAccess {
@Id
private int id;
}
@Test
@Resources(annotatedClasses = { FieldAccess.class })
public void testDefaultFieldAccess() {
EntityBinding binding = getEntityBinding( FieldAccess.class );
assertEquals( "Wrong access type", "field", binding.getAttributeBinding( "id" ).getPropertyAccessorName() );
}
@Entity
class PropertyAccess {
private int id;
@Id
public int getId() {
return id;
}
}
@Test
@Resources(annotatedClasses = { PropertyAccess.class })
public void testDefaultPropertyAccess() {
EntityBinding binding = getEntityBinding( PropertyAccess.class );
assertEquals( "Wrong access type", "property", binding.getAttributeBinding( "id" ).getPropertyAccessorName() );
}
@Entity
class NoAccess {
private int id;
public int getId() {
return id;
}
}
@Test(expected = AnnotationException.class)
@Resources(annotatedClasses = { NoAccess.class })
public void testNoAccess() {
// actual error happens when the binding gets created
}
@Entity
class MixedAccess {
@Id
private int id;
private String name;
@Access(AccessType.PROPERTY)
public String getName() {
return name;
}
}
@Test
@Resources(annotatedClasses = { MixedAccess.class })
public void testMixedAccess() {
EntityBinding binding = getEntityBinding( MixedAccess.class );
assertEquals( "Wrong access type", "field", binding.getAttributeBinding( "id" ).getPropertyAccessorName() );
assertEquals(
"Wrong access type",
"property",
binding.getAttributeBinding( "name" ).getPropertyAccessorName()
);
}
@Entity
class Base {
@Id
int id;
}
@Entity
@Access(AccessType.PROPERTY)
class ClassConfiguredAccess extends Base {
private String name;
public String getName() {
return name;
}
}
@Test
@Resources(annotatedClasses = { ClassConfiguredAccess.class, Base.class })
public void testExplicitClassConfiguredAccess() {
EntityBinding binding = getEntityBinding( Base.class );
assertEquals(
"Wrong access type",
"field",
binding.getAttributeBinding( "id" ).getPropertyAccessorName()
);
binding = getEntityBinding( ClassConfiguredAccess.class );
assertEquals(
"Wrong access type",
"property",
binding.getAttributeBinding( "name" ).getPropertyAccessorName()
);
}
}

View File

@ -25,6 +25,7 @@ package org.hibernate.metamodel.source.annotations.entity;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
@ -45,21 +46,8 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
@Rule
public MethodRule buildMetaData = new MethodRule() {
@Override
public Statement apply(Statement statement, FrameworkMethod frameworkMethod, Object o) {
sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
Resources resourcesAnnotation = frameworkMethod.getAnnotation( Resources.class );
if ( resourcesAnnotation != null ) {
sources.getMetadataBuilder().with( resourcesAnnotation.cacheMode() );
for ( Class<?> annotatedClass : resourcesAnnotation.annotatedClasses() ) {
sources.addAnnotatedClass( annotatedClass );
}
if ( !resourcesAnnotation.ormXmlPath().isEmpty() ) {
sources.addResource( resourcesAnnotation.ormXmlPath() );
}
}
meta = (MetadataImpl) sources.buildMetadata();
return statement;
public Statement apply(final Statement statement, FrameworkMethod frameworkMethod, Object o) {
return new KeepSetupFailureStatement( statement, frameworkMethod );
}
};
@ -76,6 +64,65 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
public EntityBinding getRootEntityBinding(Class<?> clazz) {
return meta.getRootEntityBinding( clazz.getName() );
}
class KeepSetupFailureStatement extends Statement {
private final Statement origStatement;
private final FrameworkMethod origFrameworkMethod;
private Throwable setupError;
private boolean expectedException;
KeepSetupFailureStatement(Statement statement, FrameworkMethod frameworkMethod) {
this.origStatement = statement;
this.origFrameworkMethod = frameworkMethod;
}
@Override
public void evaluate() throws Throwable {
try {
createBindings();
origStatement.evaluate();
if ( setupError != null ) {
throw setupError;
}
}
catch ( Throwable t ) {
if ( setupError == null ) {
throw t;
}
else {
if ( !expectedException ) {
throw setupError;
}
}
}
}
private void createBindings() {
try {
sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
Resources resourcesAnnotation = origFrameworkMethod.getAnnotation( Resources.class );
if ( resourcesAnnotation != null ) {
sources.getMetadataBuilder().with( resourcesAnnotation.cacheMode() );
for ( Class<?> annotatedClass : resourcesAnnotation.annotatedClasses() ) {
sources.addAnnotatedClass( annotatedClass );
}
if ( !resourcesAnnotation.ormXmlPath().isEmpty() ) {
sources.addResource( resourcesAnnotation.ormXmlPath() );
}
}
meta = (MetadataImpl) sources.buildMetadata();
}
catch ( final Throwable t ) {
setupError = t;
Test testAnnotation = origFrameworkMethod.getAnnotation( Test.class );
Class<?> expected = testAnnotation.expected();
if ( t.getClass().equals( expected ) ) {
expectedException = true;
}
}
}
}
}