Author: epbernard
Date: 2009-07-10 03:12:22 -0400 (Fri, 10 Jul 2009)
New Revision: 17061
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
jpamodelgen/trunk/test/src/main/java/model/Customer.java
jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
Log:
support local overriding of member access type
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
===================================================================
---
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-09
16:31:10 UTC (rev 17060)
+++
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-10
07:12:22 UTC (rev 17061)
@@ -77,45 +77,14 @@
}
public List<IMetaAttribute> getMembers() {
+ List<IMetaAttribute> membersFound = new ArrayList<IMetaAttribute>();
+ final AccessType elementAccessType = getAccessTypeForElement();
+ List<? extends Element> fieldsOfClass = ElementFilter.fieldsIn(
element.getEnclosedElements() );
+ addPersistentMembers( membersFound, elementAccessType, fieldsOfClass, AccessType.FIELD
);
- List<IMetaAttribute> members = new ArrayList<IMetaAttribute>();
+ List<? extends Element> methodsOfClass = ElementFilter.methodsIn(
element.getEnclosedElements() );
+ addPersistentMembers( membersFound, elementAccessType, methodsOfClass,
AccessType.PROPERTY );
- if ( useFields() ) {
-
- List<? extends Element> myMembers = ElementFilter.fieldsIn(
element.getEnclosedElements() );
-
- pe.getMessager()
- .printMessage( Kind.NOTE, "Scanning " + myMembers.size() + " fields
for " + element.toString() );
-
- for ( Element mymember : myMembers ) {
-
- MetaAttribute result = mymember.asType().accept( new TypeVisitor( this ), mymember
);
- if ( result != null ) {
- members.add( result );
- }
- else {
- //pe.getMessager().printMessage( Kind.WARNING, "Could not find valid info for
JPA property", mymember );
- }
- }
-
- }
- else {
- List<? extends Element> myMembers = ElementFilter.methodsIn(
element.getEnclosedElements() );
-
- pe.getMessager()
- .printMessage( Kind.NOTE, "Scanning " + myMembers.size() + " methods
for " + element.toString() );
- for ( Element mymember : myMembers ) {
-
- MetaAttribute result = mymember.asType().accept( new TypeVisitor( this ), mymember
);
- if ( result != null ) {
- members.add( result );
- }
- else {
- //pe.getMessager().printMessage(Kind.WARNING, "Not a valid JPA property",
mymember);
- }
- }
- }
-
//process superclasses
for(TypeElement superclass = TypeUtils.getSuperclass(element) ;
superclass != null ;
@@ -128,25 +97,56 @@
}
}
+ //this is valid to not have properties (ie subentities)
+// if ( membersFound.size() == 0 ) {
+// pe.getMessager().printMessage( Kind.WARNING, "No properties found on " +
element, element );
+// }
+ return membersFound;
+ }
- if ( members.size() == 0 ) {
- pe.getMessager().printMessage( Kind.WARNING, "No properties found on " +
element, element );
+ private void addPersistentMembers(
+ List<IMetaAttribute> membersFound,
+ AccessType elementAccessType,
+ List<? extends Element> membersOfClass,
+ AccessType membersKind) {
+ pe.getMessager()
+ .printMessage( Kind.NOTE, "Scanning " + membersOfClass.size() + "
" + membersKind + " for " + element.toString() );
+ AccessType explicitAccessType;
+ if (elementAccessType == membersKind) {
+ //all membersKind considered
+ explicitAccessType = null;
}
- return members;
+ else {
+ //use membersKind only if marked with @Access(membersKind)
+ explicitAccessType = membersKind;
+ }
+ for ( Element memberOfClass : membersOfClass ) {
+
+ MetaAttribute result = memberOfClass.asType().accept( new TypeVisitor( this,
explicitAccessType ),
+ memberOfClass
+ );
+ if ( result != null ) {
+ membersFound.add( result );
+ }
+//EBE not sure why?
+// else {
+// pe.getMessager().printMessage( Kind.WARNING, "Could not find valid info for
JPA property", mymember );
+// }
+ }
}
- private boolean useFields() {
+ private AccessType getAccessTypeForElement() {
//default strategy has more power than local discovery
//particularly @MappedSuperclass and @Embedded have defaultAccessTypeForHierarchy
already filled
if ( this.defaultAccessTypeForHierarchy != null ) {
- return defaultAccessTypeForHierarchy == AccessType.FIELD;
+ return defaultAccessTypeForHierarchy;
}
//get local strategy
AccessType accessType = getAccessTypeForClass(element);
if (accessType != null) {
this.defaultAccessTypeForHierarchy = accessType;
- return accessType == AccessType.FIELD;
+ return accessType;
}
//we dont' know
@@ -164,14 +164,14 @@
accessType = getAccessTypeForClass(superClass);
if ( accessType != null ) {
this.defaultAccessTypeForHierarchy = accessType;
- return accessType == AccessType.FIELD;
+ return accessType;
}
}
else if ( superClass.getAnnotation( MappedSuperclass.class ) != null ) {
accessType = getAccessTypeForClass(superClass);
if ( accessType != null ) {
this.defaultAccessTypeForHierarchy = accessType;
- return accessType == AccessType.FIELD;
+ return accessType;
}
}
else {
@@ -183,7 +183,7 @@
//this is a subclass so caching is OK
this.defaultAccessTypeForHierarchy = accessType;
context.addAccessType( this.element, AccessType.PROPERTY );
- return false; //default to getter
+ return AccessType.PROPERTY; //default to getter
}
private AccessType getAccessTypeForClass(TypeElement searchedElement) {
@@ -262,9 +262,13 @@
class TypeVisitor extends SimpleTypeVisitor6<MetaAttribute, Element> {
MetaEntity parent;
+ //if null, process all members as implicit
+ //if not null, only process members marked as @Access(explicitAccessType)
+ private AccessType explicitAccessType;
- TypeVisitor(MetaEntity parent) {
+ TypeVisitor(MetaEntity parent, AccessType explicitAccessType) {
this.parent = parent;
+ this.explicitAccessType = explicitAccessType;
}
@Override
@@ -274,11 +278,7 @@
@Override
public MetaAttribute visitPrimitive(PrimitiveType t, Element element) {
- //FIXME consider XML
- if ( element.getAnnotation( Transient.class ) == null
- && !element.getModifiers().contains( Modifier.TRANSIENT )
- && !element.getModifiers().contains( Modifier.STATIC )
- ) {
+ if ( isPersistent( element ) ) {
return new MetaSingleAttribute( parent, element, TypeUtils.toTypeString( t ) );
}
else {
@@ -286,14 +286,30 @@
}
}
+ private boolean isPersistent(Element element) {
+ //FIXME consider XML
+ boolean correctAccessType = false;
+ if (this.explicitAccessType == null) {
+ correctAccessType = true;
+ }
+ else {
+ final Access accessAnn = element.getAnnotation( Access.class );
+ if ( accessAnn != null && explicitAccessType.equals( accessAnn.value() ) ) {
+ correctAccessType = true;
+ }
+ }
+ return correctAccessType
+ && element.getAnnotation( Transient.class ) == null
+ && !element.getModifiers().contains( Modifier.TRANSIENT )
+ && !element.getModifiers().contains( Modifier.STATIC );
+ }
+
+
@Override
public MetaAttribute visitDeclared(DeclaredType t, Element element) {
//FIXME consider XML
- if ( element.getAnnotation( Transient.class ) == null
- && ! element.getModifiers().contains( Modifier.TRANSIENT )
- && !element.getModifiers().contains( Modifier.STATIC )
- ) {
+ if ( isPersistent( element ) ) {
TypeElement returnedElement = ( TypeElement ) pe.getTypeUtils().asElement( t );
String collection = COLLECTIONS.get( returnedElement.getQualifiedName().toString() );
// WARNING: .toString() is necessary here since Name equals does not compare to String
//FIXME collection of element
Modified: jpamodelgen/trunk/test/src/main/java/model/Customer.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Customer.java 2009-07-09 16:31:10 UTC (rev
17060)
+++ jpamodelgen/trunk/test/src/main/java/model/Customer.java 2009-07-10 07:12:22 UTC (rev
17061)
@@ -3,6 +3,8 @@
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
/**
* @author Emmanuel Bernard
@@ -12,6 +14,9 @@
private Set<Order> orders;
private String nonPersistent;
+ @Access(AccessType.FIELD)
+ boolean goodPayer;
+
public Set<Order> getOrders() {
return orders;
}
Modified: jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 16:31:10 UTC
(rev 17060)
+++ jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-10 07:12:22 UTC
(rev 17061)
@@ -46,16 +46,30 @@
absenceOfField( "model.Human_", "nonPersistent", "proper
inheritance from root entity access type" );
}
+ @Test
+ public void testMemberAccessType() throws Exception{
+ presenceOfField( "model.Customer_", "goodPayer", "access type
overriding" );
+ }
+
private void absenceOfField(String className, String fieldName) throws
ClassNotFoundException {
absenceOfField( className, fieldName, "field should not be persistent" );
}
private void absenceOfField(String className, String fieldName, String errorString)
throws ClassNotFoundException {
+ Assert.assertFalse( isFieldHere(className, fieldName), errorString );
+ }
+
+ private void presenceOfField(String className, String fieldName, String errorString)
throws ClassNotFoundException {
+ Assert.assertTrue( isFieldHere(className, fieldName), errorString );
+ }
+
+ private boolean isFieldHere(String className, String fieldName) throws
ClassNotFoundException {
Class<?> user_ = Class.forName( className );
try {
-
- final Field nonPersistentField = user_.getField( fieldName );
- Assert.fail( errorString );
+ final Field field = user_.getField( fieldName );
+ return true;
}
- catch (NoSuchFieldException e) {}
+ catch (NoSuchFieldException e) {
+ return false;
+ }
}
}