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