[hibernate-commits] Hibernate SVN: r17053 - in jpamodelgen/trunk: generator/src/main/java/org/hibernate/jpa/metamodel/ap/annotation and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Jul 8 14:10:16 EDT 2009


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) {}
-
 	}
 }




More information about the hibernate-commits mailing list