Hibernate SVN: r17061 - in jpamodelgen/trunk: test/src/main/java/model and 1 other directories.
by hibernate-commits@lists.jboss.org
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;
+ }
}
}
14 years, 10 months
Hibernate SVN: r17060 - in jpamodelgen/trunk: test/src/main/java/model and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-07-09 12:31:10 -0400 (Thu, 09 Jul 2009)
New Revision: 17060
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
jpamodelgen/trunk/test/src/main/java/model/Product.java
jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
Log:
exclude transient fields and static
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:14:51 UTC (rev 17059)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-09 16:31:10 UTC (rev 17060)
@@ -11,6 +11,7 @@
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.Modifier;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.PrimitiveType;
@@ -272,10 +273,13 @@
}
@Override
- public MetaAttribute visitPrimitive(PrimitiveType t, Element p) {
+ public MetaAttribute visitPrimitive(PrimitiveType t, Element element) {
//FIXME consider XML
- if ( p.getAnnotation( Transient.class ) == null ) {
- return new MetaSingleAttribute( parent, p, TypeUtils.toTypeString( t ) );
+ if ( element.getAnnotation( Transient.class ) == null
+ && !element.getModifiers().contains( Modifier.TRANSIENT )
+ && !element.getModifiers().contains( Modifier.STATIC )
+ ) {
+ return new MetaSingleAttribute( parent, element, TypeUtils.toTypeString( t ) );
}
else {
return null;
@@ -286,7 +290,10 @@
@Override
public MetaAttribute visitDeclared(DeclaredType t, Element element) {
//FIXME consider XML
- if ( element.getAnnotation( Transient.class ) == null ) {
+ if ( element.getAnnotation( Transient.class ) == null
+ && ! element.getModifiers().contains( Modifier.TRANSIENT )
+ && !element.getModifiers().contains( Modifier.STATIC )
+ ) {
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/Product.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Product.java 2009-07-09 16:14:51 UTC (rev 17059)
+++ jpamodelgen/trunk/test/src/main/java/model/Product.java 2009-07-09 16:31:10 UTC (rev 17060)
@@ -10,6 +10,9 @@
@Entity
public class Product {
+
+ transient String nonPersistent;
+ static String nonPersistent2;
@Id
long id;
Modified: jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 16:14:51 UTC (rev 17059)
+++ jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 16:31:10 UTC (rev 17060)
@@ -12,7 +12,14 @@
*/
@Test
public class AccessTypeTest {
+
@Test
+ public void testExcludeTransientFieldAndStatic() throws Exception{
+ absenceOfField( "model.Product_", "nonPersistent" );
+ absenceOfField( "model.Product_", "nonPersistent2" );
+ }
+
+ @Test
public void testDefaultAccessTypeOnEntity() throws Exception{
absenceOfField( "model.User_", "nonPersistent" );
}
14 years, 10 months
Hibernate SVN: r17059 - in jpamodelgen/trunk: test/src/main/java/model and 1 other directories.
by hibernate-commits@lists.jboss.org
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) {}
}
14 years, 10 months
Hibernate SVN: r17058 - in jpamodelgen/trunk: test/src/main/resources/META-INF and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-07-09 07:55:33 -0400 (Thu, 09 Jul 2009)
New Revision: 17058
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java
jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml
Log:
added onetoone mapping
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java 2009-07-09 11:45:57 UTC (rev 17057)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java 2009-07-09 11:55:33 UTC (rev 17058)
@@ -40,6 +40,7 @@
import org.hibernate.jpa.metamodel.xml.jaxb.ManyToOne;
import org.hibernate.jpa.metamodel.xml.jaxb.MappedSuperclass;
import org.hibernate.jpa.metamodel.xml.jaxb.OneToMany;
+import org.hibernate.jpa.metamodel.xml.jaxb.OneToOne;
/**
* @author Hardy Ferentschik
@@ -106,6 +107,11 @@
members.add( attribute );
}
+ for ( OneToOne oneToOne : attributes.getOneToOne() ) {
+ attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), getType( oneToOne.getName() ) );
+ members.add( attribute );
+ }
+
XmlMetaCollection metaCollection;
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
String[] types = getCollectionType( oneToMany.getName() );
@@ -222,6 +228,11 @@
members.add( attribute );
}
+ for ( OneToOne oneToOne : attributes.getOneToOne() ) {
+ attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), getType( oneToOne.getName() ) );
+ members.add( attribute );
+ }
+
XmlMetaCollection metaCollection;
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
String[] types = getCollectionType( oneToMany.getName() );
Modified: jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml
===================================================================
--- jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml 2009-07-09 11:45:57 UTC (rev 17057)
+++ jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml 2009-07-09 11:55:33 UTC (rev 17058)
@@ -10,7 +10,7 @@
<!-- default package -->
<mapped-superclass class="Building" access="FIELD" metadata-complete="true"> <!--means ignore annotations-->
<attributes>
- <many-to-one name="address" fetch="LAZY"/>
+ <one-to-one name="address" fetch="LAZY"/>
</attributes>
</mapped-superclass>
</entity-mappings>
14 years, 10 months
Hibernate SVN: r17057 - in jpamodelgen/trunk: test/src/main/java/model and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-07-09 07:45:57 -0400 (Thu, 09 Jul 2009)
New Revision: 17057
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
jpamodelgen/trunk/test/src/main/java/model/Area.java
jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
Log:
Add support for default access type for mapped superclass objects
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 09:53:56 UTC (rev 17056)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-09 11:45:57 UTC (rev 17057)
@@ -111,9 +111,21 @@
//pe.getMessager().printMessage(Kind.WARNING, "Not a valid JPA property", mymember);
}
}
+ }
+ //process superclasses
+ for(TypeElement superclass = TypeUtils.getSuperclass(element) ;
+ superclass != null ;
+ superclass = TypeUtils.getSuperclass( superclass ) ) {
+ if ( superclass.getAnnotation( Entity.class ) != null ) {
+ break; //will be handled or has been handled already
+ }
+ else if ( superclass.getAnnotation( MappedSuperclass.class ) != null ) {
+ context.processElement( superclass, defaultAccessTypeForHierarchy );
+ }
}
+
if ( members.size() == 0 ) {
pe.getMessager().printMessage( Kind.WARNING, "No properties found on " + element, element );
}
Modified: jpamodelgen/trunk/test/src/main/java/model/Area.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Area.java 2009-07-09 09:53:56 UTC (rev 17056)
+++ jpamodelgen/trunk/test/src/main/java/model/Area.java 2009-07-09 11:45:57 UTC (rev 17057)
@@ -11,6 +11,11 @@
private int width;
private int height;
+ //should not be persistent
+ public int getVolume() {
+ return length*width*height;
+ }
+
public int getLength() {
return length;
}
Modified: jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 09:53:56 UTC (rev 17056)
+++ jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-09 11:45:57 UTC (rev 17057)
@@ -27,7 +27,12 @@
absenceOfField( "model.Detail_", "nonPersistent " );
}
+ @Test
+ public void testDefaultAccessTypeForMappedSuperclass() throws Exception{
+ absenceOfField( "model.Detail_", "volume" );
+ }
+
private void absenceOfField(String className, String fieldName) throws ClassNotFoundException {
Class<?> user_ = Class.forName( className );
try {
14 years, 10 months
Hibernate SVN: r17056 - in jpamodelgen/trunk: generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-07-09 05:53:56 -0400 (Thu, 09 Jul 2009)
New Revision: 17056
Added:
jpamodelgen/trunk/test/src/main/java/model/xmlmapped/Building.java
jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java
jpamodelgen/trunk/test/src/main/resources/META-INF/address.xml
jpamodelgen/trunk/test/src/main/resources/META-INF/persistence.xml
jpamodelgen/trunk/test/src/test/java/tests/XmlMappingTest.java
Log:
added xml mapped superclasses
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java 2009-07-08 23:25:41 UTC (rev 17055)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java 2009-07-09 09:53:56 UTC (rev 17056)
@@ -3,17 +3,10 @@
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import javax.annotation.Generated;
import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.FilerException;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
@@ -24,9 +17,6 @@
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.DeclaredType;
import javax.persistence.Embeddable;
import javax.persistence.MappedSuperclass;
import javax.tools.Diagnostic;
@@ -66,7 +56,7 @@
public void init(ProcessingEnvironment env) {
super.init( env );
- context = new Context(env);
+ context = new Context( env );
processingEnv.getMessager().printMessage( Diagnostic.Kind.NOTE, "Init Processor " + this );
}
@@ -164,6 +154,7 @@
parseEntities( mappings );
parseEmbeddable( mappings );
+ parseMappedSuperClass( mappings );
}
private void parseEntities(EntityMappings mappings) {
@@ -173,7 +164,7 @@
String fullyQualifiedClassName = packageName + "." + entity.getClazz();
Elements utils = processingEnv.getElementUtils();
XmlMetaEntity metaEntity = new XmlMetaEntity(
- entity, packageName, utils.getTypeElement( fullyQualifiedClassName ), context
+ entity, packageName, utils.getTypeElement( fullyQualifiedClassName )
);
if ( context.getMetaEntitiesToProcess().containsKey( fullyQualifiedClassName ) ) {
@@ -206,6 +197,26 @@
}
}
+ private void parseMappedSuperClass(EntityMappings mappings) {
+ String packageName = mappings.getPackage();
+ Collection<org.hibernate.jpa.metamodel.xml.jaxb.MappedSuperclass> mappedSuperClasses = mappings.getMappedSuperclass();
+ for ( org.hibernate.jpa.metamodel.xml.jaxb.MappedSuperclass mappedSuperClass : mappedSuperClasses ) {
+ String fullyQualifiedClassName = packageName + "." + mappedSuperClass.getClazz();
+ Elements utils = processingEnv.getElementUtils();
+ XmlMetaEntity metaEntity = new XmlMetaEntity(
+ mappedSuperClass, packageName, utils.getTypeElement( fullyQualifiedClassName )
+ );
+
+ if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
+ processingEnv.getMessager().printMessage(
+ Diagnostic.Kind.WARNING,
+ fullyQualifiedClassName + " was already processed once. Skipping second occurance."
+ );
+ }
+ context.getMetaSuperclassAndEmbeddableToProcess().put( fullyQualifiedClassName, metaEntity );
+ }
+ }
+
private void handleRootElementAnnotationMirrors(final Element element) {
List<? extends AnnotationMirror> annotationMirrors = element
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java 2009-07-08 23:25:41 UTC (rev 17055)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java 2009-07-09 09:53:56 UTC (rev 17056)
@@ -26,20 +26,20 @@
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
+import org.hibernate.jpa.metamodel.ap.IMetaAttribute;
import org.hibernate.jpa.metamodel.ap.IMetaEntity;
-import org.hibernate.jpa.metamodel.ap.IMetaAttribute;
import org.hibernate.jpa.metamodel.ap.ImportContext;
import org.hibernate.jpa.metamodel.ap.ImportContextImpl;
-import org.hibernate.jpa.metamodel.ap.Context;
import org.hibernate.jpa.metamodel.xml.jaxb.Attributes;
import org.hibernate.jpa.metamodel.xml.jaxb.Basic;
import org.hibernate.jpa.metamodel.xml.jaxb.ElementCollection;
+import org.hibernate.jpa.metamodel.xml.jaxb.Embeddable;
+import org.hibernate.jpa.metamodel.xml.jaxb.EmbeddableAttributes;
import org.hibernate.jpa.metamodel.xml.jaxb.Entity;
import org.hibernate.jpa.metamodel.xml.jaxb.Id;
import org.hibernate.jpa.metamodel.xml.jaxb.ManyToOne;
+import org.hibernate.jpa.metamodel.xml.jaxb.MappedSuperclass;
import org.hibernate.jpa.metamodel.xml.jaxb.OneToMany;
-import org.hibernate.jpa.metamodel.xml.jaxb.Embeddable;
-import org.hibernate.jpa.metamodel.xml.jaxb.EmbeddableAttributes;
/**
* @author Hardy Ferentschik
@@ -64,10 +64,8 @@
final private List<IMetaAttribute> members = new ArrayList<IMetaAttribute>();
private TypeElement element;
- private Context context;
- public XmlMetaEntity(Entity ormEntity, String packageName, TypeElement element, Context context) {
- this.context = context;
+ public XmlMetaEntity(Entity ormEntity, String packageName, TypeElement element) {
this.clazzName = ormEntity.getClazz();
this.packageName = packageName;
importContext = new ImportContextImpl( getPackageName() );
@@ -77,28 +75,17 @@
XmlMetaSingleAttribute attribute = new XmlMetaSingleAttribute( this, id.getName(), getType( id.getName() ) );
members.add( attribute );
- for ( Basic basic : attributes.getBasic() ) {
- attribute = new XmlMetaSingleAttribute( this, basic.getName(), getType( basic.getName() ) );
- members.add( attribute );
- }
+ parseAttributes( attributes );
+ }
- for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
- attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), getType( manyToOne.getName() ) );
- members.add( attribute );
- }
+ public XmlMetaEntity(MappedSuperclass mappedSuperclass, String packageName, TypeElement element) {
+ this.clazzName = mappedSuperclass.getClazz();
+ this.packageName = packageName;
+ importContext = new ImportContextImpl( getPackageName() );
+ this.element = element;
+ Attributes attributes = mappedSuperclass.getAttributes();
- XmlMetaCollection metaCollection;
- for ( OneToMany oneToMany : attributes.getOneToMany() ) {
- String[] types = getCollectionType( oneToMany.getName() );
- metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
- members.add( metaCollection );
- }
-
- for ( ElementCollection collection : attributes.getElementCollection() ) {
- String[] types = getCollectionType( collection.getName() );
- metaCollection = new XmlMetaCollection( this, collection.getName(), types[0], types[1] );
- members.add( metaCollection );
- }
+ parseAttributes( attributes );
}
public XmlMetaEntity(Embeddable embeddable, String packageName, TypeElement element) {
@@ -222,4 +209,30 @@
sb.append( '}' );
return sb.toString();
}
+
+ private void parseAttributes(Attributes attributes) {
+ XmlMetaSingleAttribute attribute;
+ for ( Basic basic : attributes.getBasic() ) {
+ attribute = new XmlMetaSingleAttribute( this, basic.getName(), getType( basic.getName() ) );
+ members.add( attribute );
+ }
+
+ for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
+ attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), getType( manyToOne.getName() ) );
+ members.add( attribute );
+ }
+
+ XmlMetaCollection metaCollection;
+ for ( OneToMany oneToMany : attributes.getOneToMany() ) {
+ String[] types = getCollectionType( oneToMany.getName() );
+ metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
+ members.add( metaCollection );
+ }
+
+ for ( ElementCollection collection : attributes.getElementCollection() ) {
+ String[] types = getCollectionType( collection.getName() );
+ metaCollection = new XmlMetaCollection( this, collection.getName(), types[0], types[1] );
+ members.add( metaCollection );
+ }
+ }
}
Copied: jpamodelgen/trunk/test/src/main/java/model/xmlmapped/Building.java (from rev 17055, jpamodelgen/trunk/test/src/main/java/model/Building.java)
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/xmlmapped/Building.java (rev 0)
+++ jpamodelgen/trunk/test/src/main/java/model/xmlmapped/Building.java 2009-07-09 09:53:56 UTC (rev 17056)
@@ -0,0 +1,19 @@
+package model.xmlmapped;
+
+import model.Address;
+import model.Area;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Building extends Area {
+ private Address address;
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+}
\ No newline at end of file
Modified: jpamodelgen/trunk/test/src/main/resources/META-INF/address.xml
===================================================================
--- jpamodelgen/trunk/test/src/main/resources/META-INF/address.xml 2009-07-08 23:25:41 UTC (rev 17055)
+++ jpamodelgen/trunk/test/src/main/resources/META-INF/address.xml 2009-07-09 09:53:56 UTC (rev 17056)
@@ -16,13 +16,3 @@
</embeddable>
</entity-mappings>
-
- <!--
-public class Order {
- long id;
- Set<Item> items;
- boolean filled;
- Date date;
- List<String> notes;
- Shop shop;
-} -->
\ No newline at end of file
Copied: jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml (from rev 17055, jpamodelgen/trunk/test/src/main/resources/META-INF/address.xml)
===================================================================
--- jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml (rev 0)
+++ jpamodelgen/trunk/test/src/main/resources/META-INF/building.xml 2009-07-09 09:53:56 UTC (rev 17056)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
+ version="2.0"
+ >
+ <!-- careful old JPA1 schema -->
+ <package>model.xmlmapped</package>
+ <!-- default package -->
+ <mapped-superclass class="Building" access="FIELD" metadata-complete="true"> <!--means ignore annotations-->
+ <attributes>
+ <many-to-one name="address" fetch="LAZY"/>
+ </attributes>
+ </mapped-superclass>
+</entity-mappings>
+
Modified: jpamodelgen/trunk/test/src/main/resources/META-INF/persistence.xml
===================================================================
--- jpamodelgen/trunk/test/src/main/resources/META-INF/persistence.xml 2009-07-08 23:25:41 UTC (rev 17055)
+++ jpamodelgen/trunk/test/src/main/resources/META-INF/persistence.xml 2009-07-09 09:53:56 UTC (rev 17056)
@@ -6,5 +6,6 @@
<description>Test persistence unit</description>
<mapping-file>/META-INF/order.xml</mapping-file>
<mapping-file>/META-INF/address.xml</mapping-file>
+ <mapping-file>/META-INF/building.xml</mapping-file>
</persistence-unit>
</persistence>
Modified: jpamodelgen/trunk/test/src/test/java/tests/XmlMappingTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/XmlMappingTest.java 2009-07-08 23:25:41 UTC (rev 17055)
+++ jpamodelgen/trunk/test/src/test/java/tests/XmlMappingTest.java 2009-07-09 09:53:56 UTC (rev 17056)
@@ -6,10 +6,16 @@
/**
* @author Hardy Ferentschik
*/
-@Test
public class XmlMappingTest {
@Test
- public void testDefaultAccessType() throws Exception {
+ public void testXmlConfiguredEmbeddedClassGenerated() throws Exception {
assertNotNull( Class.forName( "model.xmlmapped.Address_" ) );
}
+
+ @Test
+ public void testXmlConfiguredMappedSuperclassGenerated() throws Exception {
+ Class<?> building = Class.forName( "model.xmlmapped.Building_" );
+ assertNotNull( building );
+ assertNotNull( building.getField( "address" ));
+ }
}
\ No newline at end of file
14 years, 10 months
Hibernate SVN: r17055 - in jpamodelgen/trunk: generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-07-08 19:25:41 -0400 (Wed, 08 Jul 2009)
New Revision: 17055
Added:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/ClassWriter.java
jpamodelgen/trunk/test/src/main/java/model/Detail.java
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
jpamodelgen/trunk/test/src/main/java/model/Item.java
jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
Log:
Add support for default access type for embeddable objects
Added: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/ClassWriter.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/ClassWriter.java (rev 0)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/ClassWriter.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -0,0 +1,123 @@
+package org.hibernate.jpa.metamodel.ap;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.FilerException;
+import javax.annotation.Generated;
+import javax.tools.FileObject;
+import javax.tools.Diagnostic;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ClassWriter {
+
+ public static void writeFile(IMetaEntity entity, ProcessingEnvironment processingEnv, Context context) {
+ try {
+ String metaModelPackage = entity.getPackageName();
+
+ StringBuffer body = generateBody( entity, context );
+
+ FileObject fo = processingEnv.getFiler().createSourceFile(
+ metaModelPackage + "." + entity.getSimpleName() + "_"
+ );
+ OutputStream os = fo.openOutputStream();
+ PrintWriter pw = new PrintWriter( os );
+
+ pw.println( "package " + metaModelPackage + ";" );
+
+ pw.println();
+
+ pw.println( entity.generateImports() );
+
+ pw.println( body );
+
+ pw.flush();
+ pw.close();
+
+ }
+ catch ( FilerException filerEx ) {
+ processingEnv.getMessager().printMessage(
+ Diagnostic.Kind.ERROR,
+ "Problem with Processing Environment Filer: "
+ + filerEx.getMessage()
+ );
+ }
+ catch ( IOException ioEx ) {
+ processingEnv.getMessager().printMessage(
+ Diagnostic.Kind.ERROR,
+ "Problem opening file to write MetaModel for " + entity.getSimpleName()
+ + ioEx.getMessage()
+ );
+ }
+ }
+
+ /**
+ * Generate everything after import statements.
+ *
+ * @param entity The meta entity for which to write the body
+ *
+ * @return body content
+ */
+ private static StringBuffer generateBody(IMetaEntity entity, Context context) {
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = null;
+ try {
+
+ pw = new PrintWriter( sw );
+
+ pw.println( "@" + entity.importType( Generated.class.getName() ) + "(\"JPA MetaModel for " + entity.getQualifiedName() + "\")" );
+
+ pw.println( "@" + entity.importType( "javax.persistence.metamodel.StaticMetamodel" ) + "(" + entity.getSimpleName() + ".class)" );
+
+
+
+ printClassDeclaration( entity, pw, context );
+
+ pw.println();
+
+ List<IMetaAttribute> members = entity.getMembers();
+
+ for ( IMetaAttribute metaMember : members ) {
+ pw.println( " " + metaMember.getDeclarationString() );
+ }
+ pw.println();
+ pw.println( "}" );
+ return sw.getBuffer();
+ }
+ finally {
+ if ( pw != null ) {
+ pw.close();
+ }
+ }
+ }
+
+ private static void printClassDeclaration(IMetaEntity entity, PrintWriter pw, Context context) {
+ pw.print( "public abstract class " + entity.getSimpleName() + "_" );
+
+ final TypeMirror superClass = entity.getTypeElement().getSuperclass();
+ //superclass of Object is of NoType which returns some other kind
+ String superclassDeclaration = "";
+ if (superClass.getKind() == TypeKind.DECLARED ) {
+ //F..king Ch...t Have those people used their horrible APIs even once?
+ final Element superClassElement = ( ( DeclaredType ) superClass ).asElement();
+ String superClassName = ( ( TypeElement ) superClassElement ).getQualifiedName().toString();
+ if ( context.getMetaEntitiesToProcess().containsKey( superClassName )
+ || context.getMetaSuperclassAndEmbeddableToProcess().containsKey( superClassName ) ) {
+ pw.print( " extends " + superClassName + "_" );
+ }
+ }
+
+ pw.println( " {" );
+ }
+}
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java 2009-07-08 18:11:20 UTC (rev 17054)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -2,16 +2,38 @@
import java.util.Map;
import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
import javax.lang.model.element.TypeElement;
import javax.persistence.AccessType;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.tools.Diagnostic;
+import org.hibernate.jpa.metamodel.ap.annotation.MetaEntity;
+
/**
* @author Emmanuel Bernard
*/
public class Context {
//used to cache access types
private Map<TypeElement, AccessType> accessTypes = new HashMap<TypeElement,AccessType>();
+ private Set<String> elementsAlreadyProcessed = new HashSet<String>();
+ private ProcessingEnvironment pe;
+ private final Map<String, IMetaEntity> metaEntitiesToProcess = new HashMap<String, IMetaEntity>();
+ private final Map<String, IMetaEntity> metaSuperclassAndEmbeddableToProcess = new HashMap<String, IMetaEntity>();
+ public Context(ProcessingEnvironment pe) {
+ this.pe = pe;
+ }
+
+ public Map<String, IMetaEntity> getMetaEntitiesToProcess() {
+ return metaEntitiesToProcess;
+ }
+
+ public Map<String, IMetaEntity> getMetaSuperclassAndEmbeddableToProcess() {
+ return metaSuperclassAndEmbeddableToProcess;
+ }
+
public void addAccessType(TypeElement element, AccessType accessType) {
accessTypes.put( element, accessType );
}
@@ -19,4 +41,20 @@
public Map<TypeElement, AccessType> getAccessTypes() {
return accessTypes;
}
+
+ public Set<String> getElementsAlreadyProcessed() {
+ return elementsAlreadyProcessed;
+ }
+
+ //only process Embeddable or Superclass
+ //does not work for Entity (risk of circularity)
+ public void processElement(TypeElement element, AccessType defaultAccessTypeForHierarchy) {
+ if ( elementsAlreadyProcessed.contains( element.getQualifiedName().toString() ) ) {
+ pe.getMessager().printMessage( Diagnostic.Kind.WARNING, "Element already processed (ignoring): " + element );
+ return;
+ }
+
+ ClassWriter.writeFile( new MetaEntity( pe, element, this, defaultAccessTypeForHierarchy ), pe, this );
+ elementsAlreadyProcessed.add( element.getQualifiedName().toString() );
+ }
}
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java 2009-07-08 18:11:20 UTC (rev 17054)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -57,18 +57,16 @@
private static final String PATH_SEPARATOR = "/";
private static final String PERSISTENCE_XML = "/META-INF/persistence.xml";
private static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.TRUE;
-
- private final Map<String, IMetaEntity> metaEntities = new HashMap<String, IMetaEntity>();
- private boolean xmlProcessed = false;
private static final String ENTITY_ANN = javax.persistence.Entity.class.getName();
private static final String MAPPED_SUPERCLASS_ANN = MappedSuperclass.class.getName();
private static final String EMBEDDABLE_ANN = Embeddable.class.getName();
- private Context context = new Context();
+ private boolean xmlProcessed = false;
+ private Context context;
-
public void init(ProcessingEnvironment env) {
super.init( env );
+ context = new Context(env);
processingEnv.getMessager().printMessage( Diagnostic.Kind.NOTE, "Init Processor " + this );
}
@@ -107,11 +105,22 @@
}
private void createMetaModelClasses() {
- for ( IMetaEntity entity : metaEntities.values() ) {
+ for ( IMetaEntity entity : context.getMetaEntitiesToProcess().values() ) {
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Writing meta model for " + entity );
- writeFile( entity );
+ ClassWriter.writeFile( entity, processingEnv, context );
}
+
+ //process left over, in most cases is empty
+ for ( String className : context.getElementsAlreadyProcessed() ) {
+ context.getMetaSuperclassAndEmbeddableToProcess().remove( className );
+ }
+
+ for ( IMetaEntity entity : context.getMetaSuperclassAndEmbeddableToProcess().values() ) {
+ processingEnv.getMessager()
+ .printMessage( Diagnostic.Kind.NOTE, "Writing meta model for " + entity );
+ ClassWriter.writeFile( entity, processingEnv, context );
+ }
}
private boolean hostJPAAnnotations(Set<? extends TypeElement> annotations) {
@@ -167,13 +176,13 @@
entity, packageName, utils.getTypeElement( fullyQualifiedClassName ), context
);
- if ( metaEntities.containsKey( fullyQualifiedClassName ) ) {
+ if ( context.getMetaEntitiesToProcess().containsKey( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " was already processed once. Skipping second occurance."
);
}
- metaEntities.put( fullyQualifiedClassName, metaEntity );
+ context.getMetaEntitiesToProcess().put( fullyQualifiedClassName, metaEntity );
}
}
@@ -187,13 +196,13 @@
embeddable, packageName, utils.getTypeElement( fullyQualifiedClassName )
);
- if ( metaEntities.containsKey( fullyQualifiedClassName ) ) {
+ if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " was already processed once. Skipping second occurance."
);
}
- metaEntities.put( fullyQualifiedClassName, metaEntity );
+ context.getMetaSuperclassAndEmbeddableToProcess().put( fullyQualifiedClassName, metaEntity );
}
}
@@ -205,118 +214,23 @@
for ( AnnotationMirror mirror : annotationMirrors ) {
final String annotationType = mirror.getAnnotationType().toString();
- if ( element.getKind() == ElementKind.CLASS &&
- ( annotationType.equals( ENTITY_ANN )
- || annotationType.equals( MAPPED_SUPERCLASS_ANN )
- || annotationType.equals( EMBEDDABLE_ANN )
- ) ) {
- MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element, context );
+ if ( element.getKind() == ElementKind.CLASS ) {
+ if ( annotationType.equals( ENTITY_ANN ) ) {
+ MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element, context );
+ // TODO instead of just adding the entity we have to do some merging.
+ context.getMetaEntitiesToProcess().put( metaEntity.getQualifiedName(), metaEntity );
+ }
+ else if ( annotationType.equals( MAPPED_SUPERCLASS_ANN )
+ || annotationType.equals( EMBEDDABLE_ANN ) ) {
+ MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element, context );
- // TODO instead of just adding the entity we have to do some merging.
- metaEntities.put( metaEntity.getQualifiedName(), metaEntity );
+ // TODO instead of just adding the entity we have to do some merging.
+ context.getMetaSuperclassAndEmbeddableToProcess().put( metaEntity.getQualifiedName(), metaEntity );
+ }
}
}
}
- private void writeFile(IMetaEntity entity) {
- try {
- String metaModelPackage = entity.getPackageName();
-
- StringBuffer body = generateBody( entity );
-
- FileObject fo = processingEnv.getFiler().createSourceFile(
- metaModelPackage + "." + entity.getSimpleName() + "_"
- );
- OutputStream os = fo.openOutputStream();
- PrintWriter pw = new PrintWriter( os );
-
- pw.println( "package " + metaModelPackage + ";" );
-
- pw.println();
-
- pw.println( entity.generateImports() );
-
- pw.println( body );
-
- pw.flush();
- pw.close();
-
- }
- catch ( FilerException filerEx ) {
- processingEnv.getMessager().printMessage(
- Diagnostic.Kind.ERROR,
- "Problem with Processing Environment Filer: "
- + filerEx.getMessage()
- );
- }
- catch ( IOException ioEx ) {
- processingEnv.getMessager().printMessage(
- Diagnostic.Kind.ERROR,
- "Problem opening file to write MetaModel for " + entity.getSimpleName()
- + ioEx.getMessage()
- );
- }
- }
-
- /**
- * Generate everything after import statements.
- *
- * @param entity The meta entity for which to write the body
- *
- * @return body content
- */
- private StringBuffer generateBody(IMetaEntity entity) {
-
- StringWriter sw = new StringWriter();
- PrintWriter pw = null;
- try {
-
- pw = new PrintWriter( sw );
-
- pw.println( "@" + entity.importType( Generated.class.getName() ) + "(\"JPA MetaModel for " + entity.getQualifiedName() + "\")" );
-
- pw.println( "@" + entity.importType( "javax.persistence.metamodel.StaticMetamodel" ) + "(" + entity.getSimpleName() + ".class)" );
-
-
-
- printClassDeclaration( entity, pw );
-
- pw.println();
-
- List<IMetaAttribute> members = entity.getMembers();
-
- for ( IMetaAttribute metaMember : members ) {
- pw.println( " " + metaMember.getDeclarationString() );
- }
- pw.println();
- pw.println( "}" );
- return sw.getBuffer();
- }
- finally {
- if ( pw != null ) {
- pw.close();
- }
- }
- }
-
- private void printClassDeclaration(IMetaEntity entity, PrintWriter pw) {
- pw.print( "public abstract class " + entity.getSimpleName() + "_" );
-
- final TypeMirror superClass = entity.getTypeElement().getSuperclass();
- //superclass of Object is of NoType which returns some other kind
- String superclassDeclaration = "";
- if (superClass.getKind() == TypeKind.DECLARED ) {
- //F..king Ch...t Have those people used their horrible APIs even once?
- final Element superClassElement = ( ( DeclaredType ) superClass ).asElement();
- String superClassName = ( ( TypeElement ) superClassElement ).getQualifiedName().toString();
- if ( metaEntities.containsKey( superClassName ) ) {
- pw.print( " extends " + superClassName + "_" );
- }
- }
-
- pw.println( " {" );
- }
-
private InputStream getInputStreamForResource(String resource) {
String pkg = getPackage( resource );
String name = getRelativeName( resource );
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-08 18:11:20 UTC (rev 17054)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -23,6 +23,8 @@
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
+import javax.persistence.Embedded;
+import javax.persistence.Embeddable;
import javax.tools.Diagnostic.Kind;
import javax.tools.Diagnostic;
@@ -40,6 +42,7 @@
final ImportContext importContext;
private Context context;
+ private AccessType defaultAccessTypeForHierarchy;
public MetaEntity(ProcessingEnvironment pe, TypeElement element, Context context) {
this.element = element;
@@ -48,6 +51,11 @@
this.context = context;
}
+ public MetaEntity(ProcessingEnvironment pe, TypeElement element, Context context, AccessType accessType) {
+ this(pe, element, context);
+ this.defaultAccessTypeForHierarchy = accessType;
+ }
+
public String getSimpleName() {
return element.getSimpleName().toString();
}
@@ -113,8 +121,17 @@
}
private boolean useFields() {
+ //default strategy has more power than local discovery
+ if ( this.defaultAccessTypeForHierarchy != null ) {
+ return defaultAccessTypeForHierarchy == AccessType.FIELD;
+ }
+
+ //get local strategy
AccessType accessType = getAccessTypeForClass( element );
- if (accessType != null) return accessType == AccessType.FIELD;
+ if (accessType != null) {
+ this.defaultAccessTypeForHierarchy = accessType;
+ return accessType == AccessType.FIELD;
+ }
//we dont' know
//if an enity go up
@@ -127,18 +144,25 @@
if ( superClass.getAnnotation( Entity.class ) != null ) {
//FIXME make it work for XML
accessType = getAccessTypeForClass(superClass);
- if ( accessType != null ) return accessType == AccessType.FIELD;
+ if ( accessType != null ) {
+ this.defaultAccessTypeForHierarchy = accessType;
+ return accessType == AccessType.FIELD;
+ }
}
else if ( superClass.getAnnotation( MappedSuperclass.class ) != null ) {
accessType = getAccessTypeForClass(superClass);
- if ( accessType != null ) return accessType == AccessType.FIELD;
+ if ( accessType != null ) {
+ this.defaultAccessTypeForHierarchy = accessType;
+ return accessType == AccessType.FIELD;
+ }
}
}
}
while ( superClass != null );
//this is a subclass so caching is OK
+ this.defaultAccessTypeForHierarchy = accessType;
context.addAccessType( this.element, AccessType.PROPERTY );
- return false;
+ return false; //default to getter
}
private AccessType getAccessTypeForClass(TypeElement searchedElement) {
@@ -175,7 +199,6 @@
}
}
}
- pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "No access type found: " + searchedElement );
return null;
}
@@ -223,21 +246,28 @@
@Override
- public MetaAttribute visitDeclared(DeclaredType t, Element p) {
+ public MetaAttribute visitDeclared(DeclaredType t, Element element) {
//FIXME consider XML
- if ( p.getAnnotation( Transient.class ) == null ) {
- TypeElement e = ( TypeElement ) pe.getTypeUtils().asElement( t );
- String collection = COLLECTIONS.get( e.getQualifiedName().toString() ); // WARNING: .toString() is necessary here since Name equals does not compare to String
+ if ( element.getAnnotation( Transient.class ) == null ) {
+ 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
if ( collection != null ) {
if ( collection.equals( "javax.persistence.metamodel.MapAttribute" ) ) {
- return new MetaMap( parent, p, collection, getKeyType( t ), getElementType( t ) );
+ return new MetaMap( parent, element, collection, getKeyType( t ), getElementType( t ) );
}
else {
- return new MetaCollection( parent, p, collection, getElementType( t ) );
+ return new MetaCollection( parent, element, collection, getElementType( t ) );
}
}
else {
- return new MetaSingleAttribute( parent, p, e.getQualifiedName().toString() );
+ //FIXME Consider XML
+ if ( element.getAnnotation( Embedded.class ) != null
+ || returnedElement.getAnnotation( Embeddable.class ) != null ) {
+ this.parent.context.processElement( returnedElement,
+ this.parent.defaultAccessTypeForHierarchy );
+ }
+ return new MetaSingleAttribute( parent, element, returnedElement.getQualifiedName().toString() );
}
}
else {
Added: jpamodelgen/trunk/test/src/main/java/model/Detail.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Detail.java (rev 0)
+++ jpamodelgen/trunk/test/src/main/java/model/Detail.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -0,0 +1,38 @@
+package model;
+
+import javax.persistence.Embeddable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Embeddable
+public class Detail {
+ Integer length;
+ Integer width;
+ Integer height;
+ Integer nonPersistent;
+
+ public Integer getLength() {
+ return length;
+ }
+
+ public void setLength(Integer length) {
+ this.length = length;
+ }
+
+ public Integer getWidth() {
+ return width;
+ }
+
+ public void setWidth(Integer width) {
+ this.width = width;
+ }
+
+ public Integer getHeight() {
+ return height;
+ }
+
+ public void setHeight(Integer height) {
+ this.height = height;
+ }
+}
Modified: jpamodelgen/trunk/test/src/main/java/model/Item.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Item.java 2009-07-08 18:11:20 UTC (rev 17054)
+++ jpamodelgen/trunk/test/src/main/java/model/Item.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -19,6 +19,8 @@
Order _order;
+ Detail detail;
+
@Id
public long getId() {
return _id;
@@ -58,6 +60,12 @@
public Map<String, Order> getNamedOrders() {
return null;
}
-
-
+
+ public Detail getDetail() {
+ return detail;
+ }
+
+ public void setDetail(Detail detail) {
+ this.detail = detail;
+ }
}
Modified: jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-08 18:11:20 UTC (rev 17054)
+++ jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-08 23:25:41 UTC (rev 17055)
@@ -22,7 +22,12 @@
absenceOfField( "model.Customer_", "nonPersistent" );
}
+ @Test
+ public void testDefaultAccessTypeForEmbeddable() throws Exception{
+ absenceOfField( "model.Detail_", "nonPersistent " );
+ }
+
private void absenceOfField(String className, String fieldName) throws ClassNotFoundException {
Class<?> user_ = Class.forName( className );
try {
14 years, 10 months
Hibernate SVN: r17054 - jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-07-08 14:11:20 -0400 (Wed, 08 Jul 2009)
New Revision: 17054
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java
Log:
Support for access type for entity and sub entity
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-08 18:10:15 UTC (rev 17053)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-08 18:11:20 UTC (rev 17054)
@@ -212,6 +212,7 @@
@Override
public MetaAttribute visitPrimitive(PrimitiveType t, Element p) {
+ //FIXME consider XML
if ( p.getAnnotation( Transient.class ) == null ) {
return new MetaSingleAttribute( parent, p, TypeUtils.toTypeString( t ) );
}
@@ -223,6 +224,7 @@
@Override
public MetaAttribute visitDeclared(DeclaredType t, Element p) {
+ //FIXME consider XML
if ( p.getAnnotation( Transient.class ) == null ) {
TypeElement e = ( TypeElement ) pe.getTypeUtils().asElement( t );
String collection = COLLECTIONS.get( e.getQualifiedName().toString() ); // WARNING: .toString() is necessary here since Name equals does not compare to String
14 years, 10 months
Hibernate SVN: r17053 - in jpamodelgen/trunk: generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-07-08 14:10:15 -0400 (Wed, 08 Jul 2009)
New Revision: 17053
Added:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java
Modified:
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java
jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/TypeUtils.java
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/xml/XmlMetaEntity.java
jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
Log:
Support for access type for entity and sub entity
Added: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java (rev 0)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/Context.java 2009-07-08 18:10:15 UTC (rev 17053)
@@ -0,0 +1,22 @@
+package org.hibernate.jpa.metamodel.ap;
+
+import java.util.Map;
+import java.util.HashMap;
+import javax.lang.model.element.TypeElement;
+import javax.persistence.AccessType;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Context {
+ //used to cache access types
+ private Map<TypeElement, AccessType> accessTypes = new HashMap<TypeElement,AccessType>();
+
+ public void addAccessType(TypeElement element, AccessType accessType) {
+ accessTypes.put( element, accessType );
+ }
+
+ public Map<TypeElement, AccessType> getAccessTypes() {
+ return accessTypes;
+ }
+}
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java 2009-07-08 18:08:11 UTC (rev 17052)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/JPAMetaModelEntityProcessor.java 2009-07-08 18:10:15 UTC (rev 17053)
@@ -64,7 +64,9 @@
private static final String MAPPED_SUPERCLASS_ANN = MappedSuperclass.class.getName();
private static final String EMBEDDABLE_ANN = Embeddable.class.getName();
+ private Context context = new Context();
+
public void init(ProcessingEnvironment env) {
super.init( env );
processingEnv.getMessager().printMessage( Diagnostic.Kind.NOTE, "Init Processor " + this );
@@ -162,7 +164,7 @@
String fullyQualifiedClassName = packageName + "." + entity.getClazz();
Elements utils = processingEnv.getElementUtils();
XmlMetaEntity metaEntity = new XmlMetaEntity(
- entity, packageName, utils.getTypeElement( fullyQualifiedClassName )
+ entity, packageName, utils.getTypeElement( fullyQualifiedClassName ), context
);
if ( metaEntities.containsKey( fullyQualifiedClassName ) ) {
@@ -208,7 +210,7 @@
|| annotationType.equals( MAPPED_SUPERCLASS_ANN )
|| annotationType.equals( EMBEDDABLE_ANN )
) ) {
- MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element );
+ MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element, context );
// TODO instead of just adding the entity we have to do some merging.
metaEntities.put( metaEntity.getQualifiedName(), metaEntity );
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/TypeUtils.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/TypeUtils.java 2009-07-08 18:08:11 UTC (rev 17052)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/TypeUtils.java 2009-07-08 18:10:15 UTC (rev 17053)
@@ -4,6 +4,10 @@
import java.util.Map;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.Element;
public class TypeUtils {
@@ -30,4 +34,18 @@
return type.toString();
}
+
+ static public TypeElement getSuperclass(TypeElement element) {
+ final TypeMirror superClass = element.getSuperclass();
+ //superclass of Object is of NoType which returns some other kind
+ String superclassDeclaration = "";
+ if (superClass.getKind() == TypeKind.DECLARED ) {
+ //F..king Ch...t Have those people used their horrible APIs even once?
+ final Element superClassElement = ( ( DeclaredType ) superClass ).asElement();
+ return ( TypeElement ) superClassElement;
+ }
+ else {
+ return null;
+ }
+ }
}
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-08 18:08:11 UTC (rev 17052)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation/MetaEntity.java 2009-07-08 18:10:15 UTC (rev 17053)
@@ -19,13 +19,19 @@
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.persistence.EmbeddedId;
import javax.persistence.Id;
+import javax.persistence.AccessType;
+import javax.persistence.Entity;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
import javax.tools.Diagnostic.Kind;
+import javax.tools.Diagnostic;
import org.hibernate.jpa.metamodel.ap.IMetaEntity;
import org.hibernate.jpa.metamodel.ap.IMetaAttribute;
import org.hibernate.jpa.metamodel.ap.ImportContext;
import org.hibernate.jpa.metamodel.ap.ImportContextImpl;
import org.hibernate.jpa.metamodel.ap.TypeUtils;
+import org.hibernate.jpa.metamodel.ap.Context;
public class MetaEntity implements IMetaEntity {
@@ -33,11 +39,13 @@
final protected ProcessingEnvironment pe;
final ImportContext importContext;
+ private Context context;
- public MetaEntity(ProcessingEnvironment pe, TypeElement element) {
+ public MetaEntity(ProcessingEnvironment pe, TypeElement element, Context context) {
this.element = element;
this.pe = pe;
importContext = new ImportContextImpl( getPackageName() );
+ this.context = context;
}
public String getSimpleName() {
@@ -66,7 +74,7 @@
List<? extends Element> myMembers = ElementFilter.fieldsIn( element.getEnclosedElements() );
pe.getMessager()
- .printMessage( Kind.NOTE, "Scanning " + myMembers.size() + " field s for " + element.toString() );
+ .printMessage( Kind.NOTE, "Scanning " + myMembers.size() + " fields for " + element.toString() );
for ( Element mymember : myMembers ) {
@@ -75,15 +83,12 @@
members.add( result );
}
else {
- pe.getMessager()
- .printMessage( Kind.WARNING, "Could not find valid info for JPA property", mymember );
+ //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()
@@ -107,29 +112,71 @@
return members;
}
+ private boolean useFields() {
+ AccessType accessType = getAccessTypeForClass( element );
+ if (accessType != null) return accessType == AccessType.FIELD;
- //TODO: Find more efficient way to identify wether we should use fields or properties
- private boolean useFields() {
- List<? extends Element> myMembers = element.getEnclosedElements();
- for ( Element element : myMembers ) {
+ //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
+ TypeElement superClass = element;
+ do {
+ superClass = TypeUtils.getSuperclass( superClass );
+ if (superClass != null) {
+ if ( superClass.getAnnotation( Entity.class ) != null ) {
+ //FIXME make it work for XML
+ accessType = getAccessTypeForClass(superClass);
+ if ( accessType != null ) return accessType == AccessType.FIELD;
+ }
+ else if ( superClass.getAnnotation( MappedSuperclass.class ) != null ) {
+ accessType = getAccessTypeForClass(superClass);
+ if ( accessType != null ) return accessType == AccessType.FIELD;
+ }
+ }
+ }
+ while ( superClass != null );
+ //this is a subclass so caching is OK
+ context.addAccessType( this.element, AccessType.PROPERTY );
+ return false;
+ }
+
+ private AccessType getAccessTypeForClass(TypeElement searchedElement) {
+ pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "check class" + searchedElement );
+ final AccessType accessType = context.getAccessTypes().get( searchedElement );
+ if ( accessType != null ) {
+ pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "Found in cache" + searchedElement + ":" + accessType );
+ return accessType;
+ }
+
+ List<? extends Element> myMembers = searchedElement.getEnclosedElements();
+ for ( Element subElement : myMembers ) {
List<? extends AnnotationMirror> entityAnnotations =
- pe.getElementUtils().getAllAnnotationMirrors( element );
+ pe.getElementUtils().getAllAnnotationMirrors( subElement );
for ( Object entityAnnotation : entityAnnotations ) {
AnnotationMirror annotationMirror = ( AnnotationMirror ) entityAnnotation;
final String annotationType = annotationMirror.getAnnotationType().toString();
- if ( annotationType.equals( Id.class.getName() ) ||
- annotationType.equals( EmbeddedId.class.getName() ) ) {
- if ( element.getKind() == ElementKind.FIELD ) {
- return true;
+ 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;
}
+ else {
+ context.addAccessType( searchedElement, AccessType.PROPERTY );
+ pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " + searchedElement + ":" + accessType );
+ return AccessType.PROPERTY;
+ }
}
}
}
-
- return false;
+ pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "No access type found: " + searchedElement );
+ return null;
}
@Override
@@ -165,25 +212,34 @@
@Override
public MetaAttribute visitPrimitive(PrimitiveType t, Element p) {
- return new MetaSingleAttribute( parent, p, TypeUtils.toTypeString( t ) );
+ if ( p.getAnnotation( Transient.class ) == null ) {
+ return new MetaSingleAttribute( parent, p, TypeUtils.toTypeString( t ) );
+ }
+ else {
+ return null;
+ }
}
@Override
public MetaAttribute visitDeclared(DeclaredType t, Element p) {
- TypeElement e = ( TypeElement ) pe.getTypeUtils().asElement( t );
-
- String collection = COLLECTIONS.get( e.getQualifiedName().toString() ); // WARNING: .toString() is necessary here since Name equals does not compare to String
- if ( collection != null ) {
- if ( collection.equals( "javax.persistence.metamodel.MapAttribute" ) ) {
- return new MetaMap( parent, p, collection, getKeyType( t ), getElementType( t ) );
+ if ( p.getAnnotation( Transient.class ) == null ) {
+ TypeElement e = ( TypeElement ) pe.getTypeUtils().asElement( t );
+ String collection = COLLECTIONS.get( e.getQualifiedName().toString() ); // WARNING: .toString() is necessary here since Name equals does not compare to String
+ if ( collection != null ) {
+ if ( collection.equals( "javax.persistence.metamodel.MapAttribute" ) ) {
+ return new MetaMap( parent, p, collection, getKeyType( t ), getElementType( t ) );
+ }
+ else {
+ return new MetaCollection( parent, p, collection, getElementType( t ) );
+ }
}
else {
- return new MetaCollection( parent, p, collection, getElementType( t ) );
+ return new MetaSingleAttribute( parent, p, e.getQualifiedName().toString() );
}
}
else {
- return new MetaSingleAttribute( parent, p, e.getQualifiedName().toString() );
+ return null;
}
}
Modified: jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java
===================================================================
--- jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java 2009-07-08 18:08:11 UTC (rev 17052)
+++ jpamodelgen/trunk/generator/src/main/java/org/hibernate/jpa/metamodel/ap/xml/XmlMetaEntity.java 2009-07-08 18:10:15 UTC (rev 17053)
@@ -30,6 +30,7 @@
import org.hibernate.jpa.metamodel.ap.IMetaAttribute;
import org.hibernate.jpa.metamodel.ap.ImportContext;
import org.hibernate.jpa.metamodel.ap.ImportContextImpl;
+import org.hibernate.jpa.metamodel.ap.Context;
import org.hibernate.jpa.metamodel.xml.jaxb.Attributes;
import org.hibernate.jpa.metamodel.xml.jaxb.Basic;
import org.hibernate.jpa.metamodel.xml.jaxb.ElementCollection;
@@ -63,8 +64,10 @@
final private List<IMetaAttribute> members = new ArrayList<IMetaAttribute>();
private TypeElement element;
+ private Context context;
- public XmlMetaEntity(Entity ormEntity, String packageName, TypeElement element) {
+ public XmlMetaEntity(Entity ormEntity, String packageName, TypeElement element, Context context) {
+ this.context = context;
this.clazzName = ormEntity.getClazz();
this.packageName = packageName;
importContext = new ImportContextImpl( getPackageName() );
Modified: jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java
===================================================================
--- jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-08 18:08:11 UTC (rev 17052)
+++ jpamodelgen/trunk/test/src/test/java/tests/AccessTypeTest.java 2009-07-08 18:10:15 UTC (rev 17053)
@@ -13,13 +13,23 @@
@Test
public class AccessTypeTest {
@Test
- public void testDefaultAccessType() throws Exception{
- Class<?> user_ = Class.forName( "model.User_" );
+ public void testDefaultAccessTypeOnEntity() throws Exception{
+ absenceOfField( "model.User_", "nonPersistent" );
+ }
+
+ @Test
+ public void testDefaultAccessTypeForSubclassOfEntity() throws Exception{
+ absenceOfField( "model.Customer_", "nonPersistent" );
+ }
+
+
+ private void absenceOfField(String className, String fieldName) throws ClassNotFoundException {
+ Class<?> user_ = Class.forName( className );
try {
- final Field nonPersistentField = user_.getField( "nonPersistent" );
+
+ final Field nonPersistentField = user_.getField( fieldName );
Assert.fail( "field should not be persistent" );
}
catch (NoSuchFieldException e) {}
-
}
}
14 years, 10 months
Hibernate SVN: r17052 - jpamodelgen/trunk/test/src/main/java/model.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-07-08 14:08:11 -0400 (Wed, 08 Jul 2009)
New Revision: 17052
Modified:
jpamodelgen/trunk/test/src/main/java/model/Customer.java
Log:
Support for access type for entity and sub entity
Modified: jpamodelgen/trunk/test/src/main/java/model/Customer.java
===================================================================
--- jpamodelgen/trunk/test/src/main/java/model/Customer.java 2009-07-08 15:00:18 UTC (rev 17051)
+++ jpamodelgen/trunk/test/src/main/java/model/Customer.java 2009-07-08 18:08:11 UTC (rev 17052)
@@ -10,6 +10,7 @@
@Entity
public class Customer extends User {
private Set<Order> orders;
+ private String nonPersistent;
public Set<Order> getOrders() {
return orders;
14 years, 10 months