Author: epbernard
Date: 2009-07-09 12:14:51 -0400 (Thu, 09 Jul 2009)
New Revision: 17059
Added:
jpamodelgen/trunk/test/src/main/java/model/Hominidae.java
jpamodelgen/trunk/test/src/main/java/model/Human.java
jpamodelgen/trunk/test/src/main/java/model/LivingBeing.java
jpamodelgen/trunk/test/src/main/java/model/Mammals.java
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
Log:
Add support for explicit @AccessType on types
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
11:55:33 UTC (rev 17058)
+++
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-09
16:14:51 UTC (rev 17059)
@@ -25,6 +25,7 @@
import javax.persistence.Transient;
import javax.persistence.Embedded;
import javax.persistence.Embeddable;
+import javax.persistence.Access;
import javax.tools.Diagnostic.Kind;
import javax.tools.Diagnostic;
@@ -42,6 +43,7 @@
final ImportContext importContext;
private Context context;
+ //used to propagate the access type of the root entity over to subclasses, superclasses
and embeddable
private AccessType defaultAccessTypeForHierarchy;
public MetaEntity(ProcessingEnvironment pe, TypeElement element, Context context) {
@@ -134,12 +136,13 @@
private boolean useFields() {
//default strategy has more power than local discovery
+ //particularly @MappedSuperclass and @Embedded have defaultAccessTypeForHierarchy
already filled
if ( this.defaultAccessTypeForHierarchy != null ) {
return defaultAccessTypeForHierarchy == AccessType.FIELD;
}
//get local strategy
- AccessType accessType = getAccessTypeForClass( element );
+ AccessType accessType = getAccessTypeForClass(element);
if (accessType != null) {
this.defaultAccessTypeForHierarchy = accessType;
return accessType == AccessType.FIELD;
@@ -147,8 +150,10 @@
//we dont' know
//if an enity go up
- //TODO if a superclass go down till you find entity
- //TODO if in the superclass case you're still unsure, go up
+ //
+ //superclasses alre always treated after their entities
+ //and their access type are discovered
+ //FIXME is it really true if only the superclass is changed
TypeElement superClass = element;
do {
superClass = TypeUtils.getSuperclass( superClass );
@@ -168,6 +173,9 @@
return accessType == AccessType.FIELD;
}
}
+ else {
+ break; //neither @Entity nor @MappedSuperclass
+ }
}
}
while ( superClass != null );
@@ -179,12 +187,26 @@
private AccessType getAccessTypeForClass(TypeElement searchedElement) {
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "check class" +
searchedElement );
- final AccessType accessType = context.getAccessTypes().get( searchedElement );
+ AccessType accessType = context.getAccessTypes().get( searchedElement );
if ( accessType != null ) {
+ this.defaultAccessTypeForHierarchy = accessType;
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "Found in cache" +
searchedElement + ":" + accessType );
return accessType;
}
+ /**
+ * when forcing access type, we can only override the defaultAccessTypeForHierarchy
+ * if we are the entity root (identified by having @Id or @EmbeddedId
+ */
+ final Access accessAnn = searchedElement.getAnnotation( Access.class );
+ AccessType forcedAccessType = accessAnn != null ? accessAnn.value() : null;
+ if ( forcedAccessType != null) {
+ pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " +
searchedElement + ":" + accessType );
+ context.addAccessType( searchedElement, forcedAccessType );
+ }
+ //continue nevertheless to check if we are root and if defaultAccessTypeForHierarchy
+ //should be overridden
+
List<? extends Element> myMembers = searchedElement.getEnclosedElements();
for ( Element subElement : myMembers ) {
List<? extends AnnotationMirror> entityAnnotations =
@@ -195,19 +217,23 @@
final String annotationType = annotationMirror.getAnnotationType().toString();
+ //FIXME consider XML
if ( annotationType.equals( Id.class.getName() )
|| annotationType.equals( EmbeddedId.class.getName() ) ) {
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "Found id on" +
searchedElement );
- if ( subElement.getKind() == ElementKind.FIELD ) {
- context.addAccessType( searchedElement, AccessType.FIELD );
- pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " +
searchedElement + ":" + accessType );
- return AccessType.FIELD;
+ final ElementKind kind = subElement.getKind();
+ if ( kind == ElementKind.FIELD || kind == ElementKind.METHOD ) {
+ accessType = kind == ElementKind.FIELD ? AccessType.FIELD : AccessType.PROPERTY;
+ this.defaultAccessTypeForHierarchy = accessType;
+ if ( forcedAccessType == null) {
+ context.addAccessType( searchedElement, accessType );
+ pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " +
searchedElement + ":" + accessType );
+ return accessType;
+ }
+ else {
+ return forcedAccessType;
+ }
}
- else {
- context.addAccessType( searchedElement, AccessType.PROPERTY );
- pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " +
searchedElement + ":" + accessType );
- return AccessType.PROPERTY;
- }
}
}
}
Added: jpamodelgen/trunk/test/src/main/java/model/Hominidae.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Hominidae.java (rev
0)
+++ jpamodelgen/trunk/test/src/main/java/model/Hominidae.java 2009-07-09 16:14:51 UTC (rev
17059)
@@ -0,0 +1,26 @@
+package model;
+
+import javax.persistence.Entity;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+(a)Access(javax.persistence.AccessType.FIELD)
+public class Hominidae extends Mammals {
+ private int intelligence;
+
+ public int getIntelligence() {
+ return intelligence;
+ }
+
+ public void setIntelligence(int intelligence) {
+ this.intelligence = intelligence;
+ }
+
+ public int getNonPersistent() {
+ return 0;
+ }
+}
Added: jpamodelgen/trunk/test/src/main/java/model/Human.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Human.java (rev 0)
+++ jpamodelgen/trunk/test/src/main/java/model/Human.java 2009-07-09 16:14:51 UTC (rev
17059)
@@ -0,0 +1,20 @@
+package model;
+
+import javax.persistence.Entity;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Human extends Hominidae {
+ private int nonPersistent;
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: jpamodelgen/trunk/test/src/main/java/model/LivingBeing.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/LivingBeing.java
(rev 0)
+++ jpamodelgen/trunk/test/src/main/java/model/LivingBeing.java 2009-07-09 16:14:51 UTC
(rev 17059)
@@ -0,0 +1,26 @@
+package model;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@MappedSuperclass
+(a)Access(javax.persistence.AccessType.FIELD)
+public class LivingBeing {
+ boolean isReallyAlive;
+
+ public boolean isReallyAlive() {
+ return isReallyAlive;
+ }
+
+ public void setReallyAlive(boolean reallyAlive) {
+ isReallyAlive = reallyAlive;
+ }
+
+ public int nonPersistent() {
+ return 0;
+ }
+}
Added: jpamodelgen/trunk/test/src/main/java/model/Mammals.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Mammals.java (rev
0)
+++ jpamodelgen/trunk/test/src/main/java/model/Mammals.java 2009-07-09 16:14:51 UTC (rev
17059)
@@ -0,0 +1,30 @@
+package model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Mammals extends LivingBeing {
+ private String id;
+ private String nbrOfMammals;
+
+ @Id
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getNbrOfMammals() {
+ return nbrOfMammals;
+ }
+
+ public void setNbrOfMammals(String nbrOfMammals) {
+ this.nbrOfMammals = nbrOfMammals;
+ }
+}
Modified: jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 11:55:33 UTC
(rev 17058)
+++ jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 16:14:51 UTC
(rev 17059)
@@ -32,13 +32,22 @@
absenceOfField( "model.Detail_", "volume" );
}
+ @Test
+ public void testExplicitAccessTypeAndDefaultFromRootEntity() throws Exception{
+ absenceOfField( "model.LivingBeing_", "nonPersistent",
"eplicit access type on mapped superclass" );
+ absenceOfField( "model.Hominidae_", "nonPersistent", "eplicit
access type on entity" );
+ absenceOfField( "model.Human_", "nonPersistent", "proper
inheritance from root entity access type" );
+ }
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 {
Class<?> user_ = Class.forName( className );
try {
final Field nonPersistentField = user_.getField( fieldName );
- Assert.fail( "field should not be persistent" );
+ Assert.fail( errorString );
}
catch (NoSuchFieldException e) {}
}