[hibernate-commits] Hibernate SVN: r18773 - in jpamodelgen/trunk/src: main/java/org/hibernate/jpamodelgen/annotation and 5 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed Feb 10 21:43:52 EST 2010
Author: hardy.ferentschik
Date: 2010-02-10 21:43:51 -0500 (Wed, 10 Feb 2010)
New Revision: 18773
Added:
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationEmbeddable.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/Constants.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEmbeddable.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaMappedSuperClass.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Coordinates.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Location.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/ZeroCoordinates.java
jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/mixedmode/coordinates.xml
Modified:
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/Context.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaAttribute.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEntity.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlParser.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/MixedConfigurationTest.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java
Log:
METAGEN-9 Added support for Embeddable
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/Context.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/Context.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/Context.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -26,6 +26,7 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
import javax.persistence.AccessType;
import javax.tools.Diagnostic;
@@ -87,6 +88,14 @@
return pe;
}
+ public Elements getElementUtils() {
+ return pe.getElementUtils();
+ }
+
+ public Types getTypeUtils() {
+ return pe.getTypeUtils();
+ }
+
public String getPersistenceXmlLocation() {
return persistenceXmlLocation;
}
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -18,6 +18,7 @@
package org.hibernate.jpamodelgen;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
@@ -30,13 +31,22 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleTypeVisitor6;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.tools.Diagnostic;
+import org.hibernate.jpamodelgen.annotation.AnnotationEmbeddable;
import org.hibernate.jpamodelgen.annotation.AnnotationMetaEntity;
import org.hibernate.jpamodelgen.model.MetaEntity;
+import org.hibernate.jpamodelgen.util.Constants;
+import org.hibernate.jpamodelgen.util.StringUtil;
import org.hibernate.jpamodelgen.util.TypeUtils;
import org.hibernate.jpamodelgen.xml.XmlParser;
@@ -86,15 +96,10 @@
if ( !xmlProcessed ) {
XmlParser parser = new XmlParser( context );
- parser.parsePersistenceXml();
+ parser.parseXml();
xmlProcessed = true;
}
- if ( !hostJPAAnnotations( annotations ) ) {
- context.logMessage( Diagnostic.Kind.OTHER, "Current processing round does not contain entities" );
- return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
- }
-
if ( context.isPersistenceUnitCompletelyXmlConfigured() ) {
context.logMessage(
Diagnostic.Kind.OTHER,
@@ -105,8 +110,8 @@
Set<? extends Element> elements = roundEnvironment.getRootElements();
for ( Element element : elements ) {
- if ( TypeUtils.containsAnnotation( element, Entity.class, MappedSuperclass.class, Embeddable.class ) ) {
- context.logMessage( Diagnostic.Kind.OTHER, "Processing " + element.toString() );
+ if ( isJPAEntity( element ) ) {
+ context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class " + element.toString() );
handleRootElementAnnotationMirrors( element );
}
}
@@ -116,59 +121,162 @@
private void createMetaModelClasses() {
for ( MetaEntity entity : context.getMetaEntities() ) {
- context.logMessage( Diagnostic.Kind.OTHER, "Writing meta model for " + entity );
+ context.logMessage( Diagnostic.Kind.OTHER, "Writing meta model for entity " + entity );
ClassWriter.writeFile( entity, context );
}
- for ( MetaEntity entity : context.getMetaSuperclassOrEmbeddable() ) {
- context.logMessage( Diagnostic.Kind.OTHER, "Writing meta model for " + entity );
- ClassWriter.writeFile( entity, context );
+ Collection<MetaEntity> toProcessEntities = context.getMetaSuperclassOrEmbeddable();
+ while ( !toProcessEntities.isEmpty() ) {
+ Set<MetaEntity> processedEntities = new HashSet<MetaEntity>();
+ for ( MetaEntity entity : toProcessEntities ) {
+ if ( containedInEntity( toProcessEntities, entity ) ) {
+ continue;
+ }
+ context.logMessage(
+ Diagnostic.Kind.OTHER, "Writing meta model for embeddable/mapped superclass" + entity
+ );
+ ClassWriter.writeFile( entity, context );
+ processedEntities.add( entity );
+ }
+ toProcessEntities.removeAll( processedEntities );
}
}
- private boolean hostJPAAnnotations(Collection<? extends TypeElement> annotations) {
- for ( TypeElement type : annotations ) {
- if ( TypeUtils.isTypeElementOfType( type, Entity.class ) ) {
- return true;
+ private boolean containedInEntity(Collection<MetaEntity> entities, MetaEntity containedEntity) {
+ ContainsAttributeTypeVisitor visitor = new ContainsAttributeTypeVisitor(
+ containedEntity.getTypeElement(), context
+ );
+ for ( MetaEntity entity : entities ) {
+ if ( entity.equals( containedEntity ) ) {
+ continue;
}
- else if ( TypeUtils.isTypeElementOfType( type, Embeddable.class ) ) {
- return true;
+ for ( Element subElement : ElementFilter.fieldsIn( entity.getTypeElement().getEnclosedElements() ) ) {
+ TypeMirror mirror = subElement.asType();
+ if ( !TypeKind.DECLARED.equals( mirror.getKind() ) ) {
+ continue;
+ }
+ boolean contains = mirror.accept( visitor, subElement );
+ if ( contains ) {
+ return true;
+ }
}
- else if ( TypeUtils.isTypeElementOfType( type, MappedSuperclass.class ) ) {
- return true;
+ for ( Element subElement : ElementFilter.methodsIn( entity.getTypeElement().getEnclosedElements() ) ) {
+ TypeMirror mirror = subElement.asType();
+ if ( !TypeKind.DECLARED.equals( mirror.getKind() ) ) {
+ continue;
+ }
+ boolean contains = mirror.accept( visitor, subElement );
+ if ( contains ) {
+ return true;
+ }
}
}
return false;
}
+ private boolean isJPAEntity(Element element) {
+ return TypeUtils.containsAnnotation( element, Entity.class, MappedSuperclass.class, Embeddable.class );
+ }
+
private void handleRootElementAnnotationMirrors(final Element element) {
List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
for ( AnnotationMirror mirror : annotationMirrors ) {
- if ( element.getKind() == ElementKind.CLASS ) {
- String fqn = ( ( TypeElement ) element ).getQualifiedName().toString();
- MetaEntity alreadyExistingMetaEntity = context.getMetaEntity( fqn );
- if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) {
- String msg = "Skipping processing of annotations for " + fqn + " since xml configuration is metadata complete.";
- context.logMessage( Diagnostic.Kind.OTHER, msg );
- continue;
- }
+ if ( !ElementKind.CLASS.equals( element.getKind() ) ) {
+ continue;
+ }
- AnnotationMetaEntity metaEntity = new AnnotationMetaEntity( ( TypeElement ) element, context );
- if ( alreadyExistingMetaEntity != null ) {
- metaEntity.mergeInMembers( alreadyExistingMetaEntity.getMembers() );
- }
- addMetaEntityToContext( mirror, metaEntity );
+ String fqn = ( ( TypeElement ) element ).getQualifiedName().toString();
+ MetaEntity alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, fqn );
+ if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) {
+ String msg = "Skipping processing of annotations for " + fqn + " since xml configuration is metadata complete.";
+ context.logMessage( Diagnostic.Kind.OTHER, msg );
+ continue;
}
+
+ AnnotationMetaEntity metaEntity;
+ if ( TypeUtils.containsAnnotation( element, Embeddable.class ) ) {
+ metaEntity = new AnnotationEmbeddable( ( TypeElement ) element, context );
+ }
+ else {
+ metaEntity = new AnnotationMetaEntity( ( TypeElement ) element, context );
+ }
+
+ if ( alreadyExistingMetaEntity != null ) {
+ metaEntity.mergeInMembers( alreadyExistingMetaEntity.getMembers() );
+ }
+ addMetaEntityToContext( mirror, metaEntity );
}
}
+ private MetaEntity tryGettingExistingEntityFromContext(AnnotationMirror mirror, String fqn) {
+ MetaEntity alreadyExistingMetaEntity = null;
+ if ( TypeUtils.isAnnotationMirrorOfType( mirror, Entity.class ) ) {
+ alreadyExistingMetaEntity = context.getMetaEntity( fqn );
+ }
+ else if ( TypeUtils.isAnnotationMirrorOfType( mirror, MappedSuperclass.class )
+ || TypeUtils.isAnnotationMirrorOfType( mirror, Embeddable.class ) ) {
+ alreadyExistingMetaEntity = context.getMetaSuperclassOrEmbeddable( fqn );
+ }
+ return alreadyExistingMetaEntity;
+ }
+
private void addMetaEntityToContext(AnnotationMirror mirror, AnnotationMetaEntity metaEntity) {
if ( TypeUtils.isAnnotationMirrorOfType( mirror, Entity.class ) ) {
context.addMetaEntity( metaEntity.getQualifiedName(), metaEntity );
}
- else if ( TypeUtils.isAnnotationMirrorOfType( mirror, MappedSuperclass.class )
- || TypeUtils.isAnnotationMirrorOfType( mirror, Embeddable.class ) ) {
+ else if ( TypeUtils.isAnnotationMirrorOfType( mirror, MappedSuperclass.class ) ) {
context.addMetaSuperclassOrEmbeddable( metaEntity.getQualifiedName(), metaEntity );
}
+ else if ( TypeUtils.isAnnotationMirrorOfType( mirror, Embeddable.class ) ) {
+ context.addMetaSuperclassOrEmbeddable( metaEntity.getQualifiedName(), metaEntity );
+ }
}
+
+
+ class ContainsAttributeTypeVisitor extends SimpleTypeVisitor6<Boolean, Element> {
+
+ private Context context;
+ private TypeElement type;
+
+ ContainsAttributeTypeVisitor(TypeElement elem, Context context) {
+ this.context = context;
+ this.type = elem;
+ }
+
+ @Override
+ public Boolean visitDeclared(DeclaredType declaredType, Element element) {
+ TypeElement returnedElement = ( TypeElement ) context.getTypeUtils().asElement( declaredType );
+
+ String fqNameOfReturnType = returnedElement.getQualifiedName().toString();
+ String collection = Constants.COLLECTIONS.get( fqNameOfReturnType );
+ if ( collection != null ) {
+ TypeMirror collectionElementType = TypeUtils.getCollectionElementType(
+ declaredType, fqNameOfReturnType, null, context
+ );
+ returnedElement = ( TypeElement ) context.getTypeUtils().asElement( collectionElementType );
+ }
+
+ if ( type.getQualifiedName().toString().equals( returnedElement.getQualifiedName().toString() ) ) {
+ return Boolean.TRUE;
+ }
+ else {
+ return Boolean.FALSE;
+ }
+ }
+
+ @Override
+ public Boolean visitExecutable(ExecutableType t, Element element) {
+ if ( !element.getKind().equals( ElementKind.METHOD ) ) {
+ return Boolean.FALSE;
+ }
+
+ String string = element.getSimpleName().toString();
+ if ( !StringUtil.isPropertyName( string ) ) {
+ return Boolean.FALSE;
+ }
+
+ TypeMirror returnType = t.getReturnType();
+ return returnType.accept( this, element );
+ }
+ }
}
Copied: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationEmbeddable.java (from rev 18756, jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java)
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationEmbeddable.java (rev 0)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationEmbeddable.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,69 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.annotation;
+
+import java.util.List;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+
+import org.hibernate.jpamodelgen.Context;
+import org.hibernate.jpamodelgen.model.MetaAttribute;
+
+/**
+ * @author Max Andersen
+ * @author Hardy Ferentschik
+ * @author Emmanuel Bernard
+ */
+public class AnnotationEmbeddable extends AnnotationMetaEntity {
+
+ // Embeddables needs to be lazily initialized since the access type be determined by the class which is embedding
+ // the entity. This might not be known until annotations are processed.
+ // Also note, that if two different classes with different access types embed this entity the access type of the
+ // embeddable will be the one of the last embedding entity processed. The result is not determined (that's ok
+ // according to the spec)
+ private boolean initialized;
+
+ public AnnotationEmbeddable(TypeElement element, Context context) {
+ super( element, context, true );
+ }
+
+ public List<MetaAttribute> getMembers() {
+ if ( !initialized ) {
+ context.logMessage( Diagnostic.Kind.OTHER, "Entity " + getQualifiedName() + "was lazily initialised." );
+ init();
+ initialized = true;
+ }
+ return super.getMembers();
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "AnnotationEmbeddable" );
+ sb.append( "{element=" ).append( element );
+ sb.append( ", members=" );
+ if ( initialized ) {
+ sb.append( members );
+ }
+ else {
+ sb.append( "[un-initalized]" );
+ }
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
\ No newline at end of file
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaAttribute.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaAttribute.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaAttribute.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -47,7 +47,7 @@
}
public String getPropertyName() {
- Elements elementsUtil = parent.getContext().getProcessingEnvironment().getElementUtils();
+ Elements elementsUtil = parent.getContext().getElementUtils();
if ( element.getKind() == ElementKind.FIELD ) {
return element.getSimpleName().toString();
}
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -36,7 +36,6 @@
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.persistence.AccessType;
import javax.persistence.Basic;
@@ -53,10 +52,10 @@
import org.hibernate.jpamodelgen.AccessTypeInformation;
import org.hibernate.jpamodelgen.Context;
import org.hibernate.jpamodelgen.ImportContextImpl;
-import org.hibernate.jpamodelgen.MetaModelGenerationException;
import org.hibernate.jpamodelgen.model.ImportContext;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.MetaEntity;
+import org.hibernate.jpamodelgen.util.Constants;
import org.hibernate.jpamodelgen.util.StringUtil;
import org.hibernate.jpamodelgen.util.TypeUtils;
@@ -67,54 +66,25 @@
*/
public class AnnotationMetaEntity implements MetaEntity {
- static Map<String, String> COLLECTIONS = new HashMap<String, String>();
+ protected final ImportContext importContext;
+ protected final TypeElement element;
+ protected final Map<String, MetaAttribute> members;
+ protected Context context;
- static {
- COLLECTIONS.put( "java.util.Collection", "javax.persistence.metamodel.CollectionAttribute" );
- COLLECTIONS.put( "java.util.Set", "javax.persistence.metamodel.SetAttribute" );
- COLLECTIONS.put( "java.util.List", "javax.persistence.metamodel.ListAttribute" );
- COLLECTIONS.put( "java.util.Map", "javax.persistence.metamodel.MapAttribute" );
- }
-
- static List<String> BASIC_TYPES = new ArrayList<String>();
-
- static {
- BASIC_TYPES.add( "java.lang.String" );
- BASIC_TYPES.add( "java.lang.Boolean" );
- BASIC_TYPES.add( "java.lang.Byte" );
- BASIC_TYPES.add( "java.lang.Character" );
- BASIC_TYPES.add( "java.lang.Short" );
- BASIC_TYPES.add( "java.lang.Integer" );
- BASIC_TYPES.add( "java.lang.Long" );
- BASIC_TYPES.add( "java.lang.Float" );
- BASIC_TYPES.add( "java.lang.Double" );
- BASIC_TYPES.add( "java.math.BigInteger" );
- BASIC_TYPES.add( "java.math.BigDecimal" );
- BASIC_TYPES.add( "java.util.Date" );
- BASIC_TYPES.add( "java.util.Calendar" );
- BASIC_TYPES.add( "java.sql.Date" );
- BASIC_TYPES.add( "java.sql.Time" );
- BASIC_TYPES.add( "java.sql.Timestamp" );
- }
-
- static List<String> BASIC_ARRAY_TYPES = new ArrayList<String>();
-
- static {
- BASIC_ARRAY_TYPES.add( "java.lang.Character" );
- BASIC_ARRAY_TYPES.add( "java.lang.Byte" );
- }
-
- private final TypeElement element;
- private final ImportContext importContext;
- private Context context;
- private Map<String, MetaAttribute> members;
private AccessTypeInformation entityAccessTypeInfo;
public AnnotationMetaEntity(TypeElement element, Context context) {
+ this( element, context, false );
+ }
+
+ protected AnnotationMetaEntity(TypeElement element, Context context, boolean lazilyInitialised) {
this.element = element;
this.context = context;
- importContext = new ImportContextImpl( getPackageName() );
- init();
+ this.members = new HashMap<String, MetaAttribute>();
+ this.importContext = new ImportContextImpl( getPackageName() );
+ if ( !lazilyInitialised ) {
+ init();
+ }
}
public Context getContext() {
@@ -130,8 +100,8 @@
}
public String getPackageName() {
- PackageElement packageOf = context.getProcessingEnvironment().getElementUtils().getPackageOf( element );
- return context.getProcessingEnvironment().getElementUtils().getName( packageOf.getQualifiedName() ).toString();
+ PackageElement packageOf = context.getElementUtils().getPackageOf( element );
+ return context.getElementUtils().getName( packageOf.getQualifiedName() ).toString();
}
public List<MetaAttribute> getMembers() {
@@ -149,6 +119,16 @@
}
}
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "AnnotationMetaEntity" );
+ sb.append( "{element=" ).append( element );
+ sb.append( ", members=" ).append( members );
+ sb.append( '}' );
+ return sb.toString();
+ }
+
private void addPersistentMembers(List<? extends Element> membersOfClass, AccessType membersKind) {
for ( Element memberOfClass : membersOfClass ) {
AccessType forcedAccessType = TypeUtils.determineAnnotationSpecifiedAccessType( memberOfClass );
@@ -170,18 +150,7 @@
}
}
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append( "AnnotationMetaEntity" );
- sb.append( "{element=" ).append( element );
- sb.append( ", members=" ).append( members );
- sb.append( '}' );
- return sb.toString();
- }
-
- private void init() {
- members = new HashMap<String, MetaAttribute>();
+ protected void init() {
TypeUtils.determineAccessTypeForHierarchy( element, context );
entityAccessTypeInfo = context.getAccessTypeInfo( getQualifiedName() );
@@ -248,21 +217,18 @@
@Override
public AnnotationMetaAttribute visitDeclared(DeclaredType declaredType, Element element) {
- TypeElement returnedElement = ( TypeElement ) context.getProcessingEnvironment()
- .getTypeUtils()
- .asElement( declaredType );
+ TypeElement returnedElement = ( TypeElement ) context.getTypeUtils().asElement( declaredType );
// WARNING: .toString() is necessary here since Name equals does not compare to String
String fqNameOfReturnType = returnedElement.getQualifiedName().toString();
- String collection = COLLECTIONS.get( fqNameOfReturnType );
+ String collection = Constants.COLLECTIONS.get( fqNameOfReturnType );
String targetEntity = getTargetEntity( element.getAnnotationMirrors() );
if ( collection != null ) {
if ( TypeUtils.containsAnnotation( element, ElementCollection.class ) ) {
String explicitTargetEntity = getTargetEntity( element.getAnnotationMirrors() );
- TypeMirror collectionElementType = getCollectionElementType(
- declaredType, fqNameOfReturnType, explicitTargetEntity
+ TypeMirror collectionElementType = TypeUtils.getCollectionElementType(
+ declaredType, fqNameOfReturnType, explicitTargetEntity, context
);
- final TypeElement collectionElement = ( TypeElement ) context.getProcessingEnvironment()
- .getTypeUtils()
+ final TypeElement collectionElement = ( TypeElement ) context.getTypeUtils()
.asElement( collectionElementType );
AccessTypeInformation accessTypeInfo = context.getAccessTypeInfo( collectionElement.getQualifiedName().toString() );
if ( accessTypeInfo == null ) {
@@ -281,8 +247,6 @@
else {
accessTypeInfo.setDefaultAccessType( entityAccessTypeInfo.getAccessType() );
}
- AnnotationMetaEntity metaEntity = new AnnotationMetaEntity( collectionElement, context );
- context.addMetaSuperclassOrEmbeddable( metaEntity.getQualifiedName(), metaEntity );
}
if ( collection.equals( "javax.persistence.metamodel.MapAttribute" ) ) {
return createAnnotationMetaAttributeForMap( declaredType, element, collection, targetEntity );
@@ -353,28 +317,6 @@
);
}
- private TypeMirror getCollectionElementType(DeclaredType t, String fqNameOfReturnedType, String explicitTargetEntityName) {
- TypeMirror collectionElementType;
- if ( explicitTargetEntityName != null ) {
- Elements elements = context.getProcessingEnvironment().getElementUtils();
- TypeElement element = elements.getTypeElement( explicitTargetEntityName );
- collectionElementType = element.asType();
- }
- else {
- List<? extends TypeMirror> typeArguments = t.getTypeArguments();
- if ( typeArguments.size() == 0 ) {
- throw new MetaModelGenerationException( "Unable to determine collection type for property in " + getSimpleName() );
- }
- else if ( Map.class.getCanonicalName().equals( fqNameOfReturnedType ) ) {
- collectionElementType = t.getTypeArguments().get( 1 );
- }
- else {
- collectionElementType = t.getTypeArguments().get( 0 );
- }
- }
- return collectionElementType;
- }
-
private String getElementType(DeclaredType declaredType, String targetEntity) {
if ( targetEntity != null ) {
return targetEntity;
@@ -446,8 +388,8 @@
}
/**
- * Checks whether the visited type is a basic attibute according to the JPA 2 spec
- * ( secction 2.8 Mapping Defaults for Non-Relationship Fields or Properties)
+ * Checks whether the visited type is a basic attribute according to the JPA 2 spec
+ * ( section 2.8 Mapping Defaults for Non-Relationship Fields or Properties)
*/
class BasicAttributeVisitor extends SimpleTypeVisitor6<Boolean, Element> {
@Override
@@ -458,11 +400,9 @@
@Override
public Boolean visitArray(ArrayType t, Element element) {
TypeMirror componentMirror = t.getComponentType();
- TypeElement componentElement = ( TypeElement ) context.getProcessingEnvironment()
- .getTypeUtils()
- .asElement( componentMirror );
+ TypeElement componentElement = ( TypeElement ) context.getTypeUtils().asElement( componentMirror );
- return BASIC_ARRAY_TYPES.contains( componentElement.getQualifiedName().toString() );
+ return Constants.BASIC_ARRAY_TYPES.contains( componentElement.getQualifiedName().toString() );
}
@Override
@@ -474,16 +414,14 @@
if ( ElementKind.CLASS.equals( element.getKind() ) ) {
TypeElement typeElement = ( ( TypeElement ) element );
String typeName = typeElement.getQualifiedName().toString();
- if ( BASIC_TYPES.contains( typeName ) ) {
+ if ( Constants.BASIC_TYPES.contains( typeName ) ) {
return Boolean.TRUE;
}
if ( TypeUtils.containsAnnotation( element, Embeddable.class ) ) {
return Boolean.TRUE;
}
for ( TypeMirror mirror : typeElement.getInterfaces() ) {
- TypeElement interfaceElement = ( TypeElement ) context.getProcessingEnvironment()
- .getTypeUtils()
- .asElement( mirror );
+ TypeElement interfaceElement = ( TypeElement ) context.getTypeUtils().asElement( mirror );
if ( "java.io.Serializable".equals( interfaceElement.getQualifiedName().toString() ) ) {
return Boolean.TRUE;
}
Added: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/Constants.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/Constants.java (rev 0)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/Constants.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,69 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Constants {
+ public static Map<String, String> COLLECTIONS = new HashMap<String, String>();
+
+ static {
+ COLLECTIONS.put( "java.util.Collection", "javax.persistence.metamodel.CollectionAttribute" );
+ COLLECTIONS.put( "java.util.Set", "javax.persistence.metamodel.SetAttribute" );
+ COLLECTIONS.put( "java.util.List", "javax.persistence.metamodel.ListAttribute" );
+ COLLECTIONS.put( "java.util.Map", "javax.persistence.metamodel.MapAttribute" );
+ }
+
+ public static List<String> BASIC_TYPES = new ArrayList<String>();
+
+ static {
+ BASIC_TYPES.add( "java.lang.String" );
+ BASIC_TYPES.add( "java.lang.Boolean" );
+ BASIC_TYPES.add( "java.lang.Byte" );
+ BASIC_TYPES.add( "java.lang.Character" );
+ BASIC_TYPES.add( "java.lang.Short" );
+ BASIC_TYPES.add( "java.lang.Integer" );
+ BASIC_TYPES.add( "java.lang.Long" );
+ BASIC_TYPES.add( "java.lang.Float" );
+ BASIC_TYPES.add( "java.lang.Double" );
+ BASIC_TYPES.add( "java.math.BigInteger" );
+ BASIC_TYPES.add( "java.math.BigDecimal" );
+ BASIC_TYPES.add( "java.util.Date" );
+ BASIC_TYPES.add( "java.util.Calendar" );
+ BASIC_TYPES.add( "java.sql.Date" );
+ BASIC_TYPES.add( "java.sql.Time" );
+ BASIC_TYPES.add( "java.sql.Timestamp" );
+ }
+
+ public static List<String> BASIC_ARRAY_TYPES = new ArrayList<String>();
+
+ static {
+ BASIC_ARRAY_TYPES.add( "java.lang.Character" );
+ BASIC_ARRAY_TYPES.add( "java.lang.Byte" );
+ }
+
+ private Constants(){}
+}
+
+
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -29,12 +29,17 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor6;
import javax.lang.model.util.Types;
import javax.persistence.Access;
import javax.persistence.AccessType;
+import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -43,6 +48,7 @@
import org.hibernate.jpamodelgen.AccessTypeInformation;
import org.hibernate.jpamodelgen.Context;
+import org.hibernate.jpamodelgen.MetaModelGenerationException;
/**
* Utility class.
@@ -94,7 +100,7 @@
public static String extractClosestRealTypeAsString(TypeMirror type, Context context) {
if ( type instanceof TypeVariable ) {
final TypeMirror compositeUpperBound = ( ( TypeVariable ) type ).getUpperBound();
- final Types types = context.getProcessingEnvironment().getTypeUtils();
+ final Types types = context.getTypeUtils();
final List<? extends TypeMirror> upperBounds = types.directSupertypes( compositeUpperBound );
if ( upperBounds.size() == 0 ) {
return compositeUpperBound.toString();
@@ -194,7 +200,7 @@
public static void determineAccessTypeForHierarchy(TypeElement searchedElement, Context context) {
String fqcn = searchedElement.getQualifiedName().toString();
- context.logMessage( Diagnostic.Kind.OTHER, "check class " + fqcn );
+ context.logMessage( Diagnostic.Kind.OTHER, "Determining access type for " + fqcn );
AccessTypeInformation accessTypeInfo = context.getAccessTypeInfo( fqcn );
if ( accessTypeInfo != null && accessTypeInfo.isAccessTypeResolved() ) {
@@ -213,6 +219,7 @@
);
accessTypeInfo = new AccessTypeInformation( fqcn, forcedAccessType, null );
context.addAccessTypeInformation( fqcn, accessTypeInfo );
+ updateEmbeddableAccessType( searchedElement, context, forcedAccessType );
return;
}
@@ -223,6 +230,7 @@
if ( defaultAccessType != null ) {
accessTypeInfo = new AccessTypeInformation( fqcn, null, defaultAccessType );
context.addAccessTypeInformation( fqcn, accessTypeInfo );
+ updateEmbeddableAccessType( searchedElement, context, defaultAccessType );
return;
}
@@ -235,6 +243,55 @@
context.addAccessTypeInformation( fqcn, accessTypeInfo );
}
+ public static TypeMirror getCollectionElementType(DeclaredType t, String fqNameOfReturnedType, String explicitTargetEntityName, Context context) {
+ TypeMirror collectionElementType;
+ if ( explicitTargetEntityName != null ) {
+ Elements elements = context.getElementUtils();
+ TypeElement element = elements.getTypeElement( explicitTargetEntityName );
+ collectionElementType = element.asType();
+ }
+ else {
+ List<? extends TypeMirror> typeArguments = t.getTypeArguments();
+ if ( typeArguments.size() == 0 ) {
+ throw new MetaModelGenerationException( "Unable to determine collection type" );
+ }
+ else if ( Map.class.getCanonicalName().equals( fqNameOfReturnedType ) ) {
+ collectionElementType = t.getTypeArguments().get( 1 );
+ }
+ else {
+ collectionElementType = t.getTypeArguments().get( 0 );
+ }
+ }
+ return collectionElementType;
+ }
+
+ private static void updateEmbeddableAccessType(TypeElement element, Context context, AccessType defaultAccessType) {
+ List<? extends Element> fieldsOfClass = ElementFilter.fieldsIn( element.getEnclosedElements() );
+ for ( Element field : fieldsOfClass ) {
+ updateEmbeddableAccessTypeForMember( context, defaultAccessType, field );
+ }
+
+ List<? extends Element> methodOfClass = ElementFilter.methodsIn( element.getEnclosedElements() );
+ for ( Element method : methodOfClass ) {
+ updateEmbeddableAccessTypeForMember( context, defaultAccessType, method );
+ }
+ }
+
+ private static void updateEmbeddableAccessTypeForMember(Context context, AccessType defaultAccessType, Element member) {
+ EmbeddedAttributeVisitor visitor = new EmbeddedAttributeVisitor( context );
+ String embeddedClassName = member.asType().accept( visitor, member );
+ if ( embeddedClassName != null ) {
+ AccessTypeInformation accessTypeInfo = context.getAccessTypeInfo( embeddedClassName );
+ if ( accessTypeInfo == null ) {
+ accessTypeInfo = new AccessTypeInformation( embeddedClassName, null, defaultAccessType );
+ context.addAccessTypeInformation( embeddedClassName, accessTypeInfo );
+ }
+ else {
+ accessTypeInfo.setDefaultAccessType( defaultAccessType );
+ }
+ }
+ }
+
private static AccessType getDefaultAccessForHierarchy(TypeElement element, Context context) {
AccessType defaultAccessType = null;
TypeElement superClass = element;
@@ -268,7 +325,7 @@
List<? extends Element> myMembers = searchedElement.getEnclosedElements();
for ( Element subElement : myMembers ) {
List<? extends AnnotationMirror> entityAnnotations =
- context.getProcessingEnvironment().getElementUtils().getAllAnnotationMirrors( subElement );
+ context.getElementUtils().getAllAnnotationMirrors( subElement );
for ( Object entityAnnotation : entityAnnotations ) {
AnnotationMirror annotationMirror = ( AnnotationMirror ) entityAnnotation;
if ( isIdAnnotation( annotationMirror ) ) {
@@ -322,4 +379,38 @@
return ElementKind.METHOD;
}
}
+
+ static class EmbeddedAttributeVisitor extends SimpleTypeVisitor6<String, Element> {
+
+ private Context context;
+
+ EmbeddedAttributeVisitor(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public String visitDeclared(DeclaredType declaredType, Element element) {
+ TypeElement returnedElement = ( TypeElement ) context.getTypeUtils().asElement( declaredType );
+ String fqNameOfReturnType = null;
+ if ( containsAnnotation( returnedElement, Embeddable.class ) ) {
+ fqNameOfReturnType = returnedElement.getQualifiedName().toString();
+ }
+ return fqNameOfReturnType;
+ }
+
+ @Override
+ public String visitExecutable(ExecutableType t, Element p) {
+ if ( !p.getKind().equals( ElementKind.METHOD ) ) {
+ return null;
+ }
+
+ String string = p.getSimpleName().toString();
+ if ( !StringUtil.isPropertyName( string ) ) {
+ return null;
+ }
+
+ TypeMirror returnType = t.getReturnType();
+ return returnType.accept( this, p );
+ }
+ }
}
Added: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEmbeddable.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEmbeddable.java (rev 0)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEmbeddable.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,69 @@
+// $Id: XmlMetaEntity.java 18753 2010-02-09 21:29:34Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.xml;
+
+import java.util.List;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+
+import org.hibernate.jpamodelgen.Context;
+import org.hibernate.jpamodelgen.model.MetaAttribute;
+import org.hibernate.jpamodelgen.xml.jaxb.Embeddable;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class XmlMetaEmbeddable extends XmlMetaEntity {
+ // Embeddables needs to be lazily initialized since the access type be determined by the class which is embedding
+ // the entity. This might not be known until annotations are processed.
+ // Also note, that if two different classes with different access types embed this entity the access type of the
+ // embeddable will be the one of the last embedding entity processed. The result is not determined (that's ok
+ // according to the spec)
+ private boolean initialized;
+
+ public XmlMetaEmbeddable(Embeddable embeddable, String packageName, TypeElement element, Context context) {
+ super( embeddable, packageName, element, context );
+ }
+
+ public List<MetaAttribute> getMembers() {
+ if ( !initialized ) {
+ context.logMessage( Diagnostic.Kind.OTHER, "Entity " + getQualifiedName() + "was lazily initialised." );
+ init();
+ initialized = true;
+ }
+ return members;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "XmlMetaEmbeddable" );
+ sb.append( "{accessTypeInfo=" ).append( accessTypeInfo );
+ sb.append( ", clazzName='" ).append( clazzName ).append( '\'' );
+ sb.append( ", members=" );
+ if ( initialized ) {
+ sb.append( members );
+ }
+ else {
+ sb.append( "[un-initalized]" );
+ }
+ sb.append( ", isMetaComplete=" ).append( isMetaComplete );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
\ No newline at end of file
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEntity.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEntity.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEntity.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -18,7 +18,6 @@
package org.hibernate.jpamodelgen.xml;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -67,65 +66,61 @@
COLLECTIONS.put( "java.util.Map", "javax.persistence.metamodel.MapAttribute" );
}
- private final String clazzName;
- private final String packageName;
- private final ImportContext importContext;
- private final List<MetaAttribute> members = new ArrayList<MetaAttribute>();
- private final TypeElement element;
- private final Context context;
- private final AccessTypeInformation accessTypeInfo;
+ protected final String clazzName;
+ protected final String packageName;
+ protected final ImportContext importContext;
+ protected final List<MetaAttribute> members = new ArrayList<MetaAttribute>();
+ protected final TypeElement element;
+ protected final Context context;
+ protected final boolean isMetaComplete;
- private boolean isMetaComplete;
+ private Attributes attributes;
+ private EmbeddableAttributes embeddableAttributes;
+ protected AccessTypeInformation accessTypeInfo;
public XmlMetaEntity(Entity ormEntity, String packageName, TypeElement element, Context context) {
- String className = ormEntity.getClazz();
+ this( ormEntity.getClazz(), packageName, element, context, ormEntity.isMetadataComplete() );
+ this.attributes = ormEntity.getAttributes();
+ this.embeddableAttributes = null;
+ // entities can be directly initialised
+ init();
+ }
+
+ protected XmlMetaEntity(MappedSuperclass mappedSuperclass, String packageName, TypeElement element, Context context) {
+ this( mappedSuperclass.getClazz(), packageName, element, context, mappedSuperclass.isMetadataComplete() );
+ this.attributes = mappedSuperclass.getAttributes();
+ this.embeddableAttributes = null;
+ }
+
+ protected XmlMetaEntity(Embeddable embeddable, String packageName, TypeElement element, Context context) {
+ this( embeddable.getClazz(), packageName, element, context, embeddable.isMetadataComplete() );
+ this.attributes = null;
+ this.embeddableAttributes = embeddable.getAttributes();
+ }
+
+ private XmlMetaEntity(String clazz, String packageName, TypeElement element, Context context, Boolean metaComplete) {
+ String className = clazz;
if ( StringUtil.isFullyQualified( className ) ) {
// we have to extract the package name from the fqcn. default package name gets ignored
packageName = StringUtil.packageNameFromFqcn( className );
- className = StringUtil.classNameFromFqcn( className );
+ className = StringUtil.classNameFromFqcn( clazz );
}
this.clazzName = className;
this.packageName = packageName;
this.context = context;
this.importContext = new ImportContextImpl( getPackageName() );
this.element = element;
- this.accessTypeInfo = context.getAccessTypeInfo( getQualifiedName() );
- initIsMetaComplete( ormEntity.isMetadataComplete() );
- parseAttributes( ormEntity.getAttributes() );
+ this.isMetaComplete = initIsMetaComplete( metaComplete );
}
- public XmlMetaEntity(MappedSuperclass mappedSuperclass, String packageName, TypeElement element, Context context) {
- this.clazzName = mappedSuperclass.getClazz();
- this.packageName = packageName;
- this.context = context;
- this.importContext = new ImportContextImpl( getPackageName() );
- this.element = element;
+ protected void init() {
this.accessTypeInfo = context.getAccessTypeInfo( getQualifiedName() );
- initIsMetaComplete( mappedSuperclass.isMetadataComplete() );
- parseAttributes( mappedSuperclass.getAttributes() );
- }
-
- public XmlMetaEntity(Embeddable embeddable, String packageName, TypeElement element, Context context) {
- this.clazzName = embeddable.getClazz();
- this.packageName = packageName;
- this.context = context;
- this.importContext = new ImportContextImpl( getPackageName() );
- this.element = element;
- this.accessTypeInfo = context.getAccessTypeInfo( getQualifiedName() );
- initIsMetaComplete( embeddable.isMetadataComplete() );
- parseEmbeddableAttributes( embeddable.getAttributes() );
- }
-
- private void initIsMetaComplete(Boolean metadataComplete) {
- if ( context.isPersistenceUnitCompletelyXmlConfigured() ) {
- isMetaComplete = true;
- return;
+ if ( attributes != null ) {
+ parseAttributes( attributes );
}
- if ( Boolean.TRUE.equals( metadataComplete ) ) {
- isMetaComplete = true;
- return;
+ else {
+ parseEmbeddableAttributes( embeddableAttributes );
}
- isMetaComplete = false;
}
public String getSimpleName() {
@@ -163,12 +158,28 @@
public TypeElement getTypeElement() {
return element;
}
-
+
@Override
public boolean isMetaComplete() {
return isMetaComplete;
}
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "XmlMetaEntity" );
+ sb.append( "{accessTypeInfo=" ).append( accessTypeInfo );
+ sb.append( ", clazzName='" ).append( clazzName ).append( '\'' );
+ sb.append( ", members=" ).append( members );
+ sb.append( ", isMetaComplete=" ).append( isMetaComplete );
+ sb.append( '}' );
+ return sb.toString();
+ }
+
+ private boolean initIsMetaComplete(Boolean metadataComplete) {
+ return context.isPersistenceUnitCompletelyXmlConfigured() || Boolean.TRUE.equals( metadataComplete );
+ }
+
private String[] getCollectionType(String propertyName, String explicitTargetEntity, ElementKind expectedElementKind) {
String types[] = new String[2];
for ( Element elem : element.getEnclosedElements() ) {
@@ -221,7 +232,8 @@
if ( ElementKind.METHOD.equals( elem.getKind() ) ) {
name = StringUtil.getPropertyName( name );
mirror = ( ( ExecutableElement ) elem ).getReturnType();
- } else {
+ }
+ else {
mirror = elem.asType();
}
@@ -244,6 +256,21 @@
case BOOLEAN: {
return "java.lang.Boolean";
}
+ case BYTE: {
+ return "java.lang.Byte";
+ }
+ case SHORT: {
+ return "java.lang.Short";
+ }
+ case CHAR: {
+ return "java.lang.Char";
+ }
+ case FLOAT: {
+ return "java.lang.Float";
+ }
+ case DOUBLE: {
+ return "java.lang.Double";
+ }
case DECLARED: {
return mirror.toString();
}
@@ -261,23 +288,9 @@
return null;
}
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append( "XmlMetaEntity" );
- sb.append( "{accessTypeInfo=" ).append( accessTypeInfo );
- sb.append( ", clazzName='" ).append( clazzName ).append( '\'' );
- sb.append( ", members=" ).append( members );
- sb.append( ", isMetaComplete=" ).append( isMetaComplete );
- sb.append( '}' );
- return sb.toString();
- }
-
private void parseAttributes(Attributes attributes) {
XmlMetaSingleAttribute attribute;
- if ( !attributes.getId().isEmpty() ) {
- // TODO what do we do if there are more than one id nodes?
- Id id = attributes.getId().get( 0 );
+ for ( Id id : attributes.getId() ) {
ElementKind elementKind = getElementKind( id.getAccess() );
String type = getType( id.getName(), null, elementKind );
if ( type != null ) {
Copied: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaMappedSuperClass.java (from rev 18753, jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaEntity.java)
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaMappedSuperClass.java (rev 0)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaMappedSuperClass.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,74 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.xml;
+
+import java.util.List;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+
+import org.hibernate.jpamodelgen.Context;
+import org.hibernate.jpamodelgen.MetaModelGenerationException;
+import org.hibernate.jpamodelgen.model.MetaAttribute;
+import org.hibernate.jpamodelgen.xml.jaxb.Basic;
+import org.hibernate.jpamodelgen.xml.jaxb.ElementCollection;
+import org.hibernate.jpamodelgen.xml.jaxb.EmbeddableAttributes;
+import org.hibernate.jpamodelgen.xml.jaxb.ManyToMany;
+import org.hibernate.jpamodelgen.xml.jaxb.ManyToOne;
+import org.hibernate.jpamodelgen.xml.jaxb.MappedSuperclass;
+import org.hibernate.jpamodelgen.xml.jaxb.OneToMany;
+import org.hibernate.jpamodelgen.xml.jaxb.OneToOne;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class XmlMetaMappedSuperClass extends XmlMetaEntity {
+ private boolean initialized;
+
+ public XmlMetaMappedSuperClass(MappedSuperclass mappedSuperclass, String packageName, TypeElement element, Context context) {
+ super( mappedSuperclass, packageName, element, context );
+ }
+
+ public List<MetaAttribute> getMembers() {
+ if ( !initialized ) {
+ context.logMessage( Diagnostic.Kind.OTHER, "Entity " + getQualifiedName() + "was lazily initialised." );
+ init();
+ initialized = true;
+ }
+ return members;
+ }
+
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "XmlMetaEntity" );
+ sb.append( "{accessTypeInfo=" ).append( accessTypeInfo );
+ sb.append( ", clazzName='" ).append( clazzName ).append( '\'' );
+ sb.append( ", members=" );
+ if ( initialized ) {
+ sb.append( members );
+ }
+ else {
+ sb.append( "[un-initalized]" );
+ }
+ sb.append( ", isMetaComplete=" ).append( isMetaComplete );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
\ No newline at end of file
Property changes on: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlMetaMappedSuperClass.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlParser.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlParser.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/xml/XmlParser.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -65,7 +65,7 @@
this.entityMappings = new ArrayList<EntityMappings>();
}
- public void parsePersistenceXml() {
+ public void parseXml() {
collectAllEntityMappings();
determineDefaultAccessTypeAndMetaCompleteness();
determineXmlAccessTypes();
@@ -153,11 +153,7 @@
continue;
}
- XmlMetaEntity metaEntity = new XmlMetaEntity(
- embeddable, pkg, getXmlMappedType( fqcn ),
- context
- );
-
+ XmlMetaEntity metaEntity = new XmlMetaEmbeddable( embeddable, pkg, getXmlMappedType( fqcn ), context );
if ( context.containsMetaSuperclassOrEmbeddable( fqcn ) ) {
context.logMessage(
Diagnostic.Kind.WARNING,
@@ -184,9 +180,8 @@
continue;
}
- XmlMetaEntity metaEntity = new XmlMetaEntity(
- mappedSuperClass, pkg, getXmlMappedType( fqcn ),
- context
+ XmlMetaEntity metaEntity = new XmlMetaMappedSuperClass(
+ mappedSuperClass, pkg, getXmlMappedType( fqcn ), context
);
if ( context.containsMetaSuperclassOrEmbeddable( fqcn ) ) {
@@ -297,12 +292,12 @@
}
private boolean xmlMappedTypeExists(String fullyQualifiedClassName) {
- Elements utils = context.getProcessingEnvironment().getElementUtils();
+ Elements utils = context.getElementUtils();
return utils.getTypeElement( fullyQualifiedClassName ) != null;
}
private TypeElement getXmlMappedType(String fullyQualifiedClassName) {
- Elements utils = context.getProcessingEnvironment().getElementUtils();
+ Elements utils = context.getElementUtils();
return utils.getTypeElement( fullyQualifiedClassName );
}
Added: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Coordinates.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Coordinates.java (rev 0)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Coordinates.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,31 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.test.mixedmode;
+
+import javax.persistence.Embeddable;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Embeddable
+public class Coordinates {
+ public float longitude;
+ public float latitude;
+}
+
+
Added: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Location.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Location.java (rev 0)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/Location.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,73 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.test.mixedmode;
+
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Entity
+ at Access(AccessType.FIELD)
+public class Location {
+ @Id
+ private long id;
+ private String description;
+ // implicitly embedded
+ private Coordinates coordinates;
+ @Embedded
+ private ZeroCoordinates zeroCoordinates;
+
+ public Coordinates getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(Coordinates coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public ZeroCoordinates getZeroCoordinates() {
+ return zeroCoordinates;
+ }
+
+ public void setZeroCoordinates(ZeroCoordinates zeroCoordinates) {
+ this.zeroCoordinates = zeroCoordinates;
+ }
+}
+
+
Modified: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/MixedConfigurationTest.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/MixedConfigurationTest.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/MixedConfigurationTest.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -27,6 +27,7 @@
import org.hibernate.jpamodelgen.test.util.TestUtil;
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertAbsenceOfFieldInMetamodelFor;
+import static org.hibernate.jpamodelgen.test.util.TestUtil.assertAttributeTypeInMetaModelFor;
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMetamodelClassGeneratedFor;
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertPresenceOfFieldInMetamodelFor;
@@ -38,30 +39,60 @@
public void testDefaultAccessTypeApplied() {
assertMetamodelClassGeneratedFor( Vehicle.class );
assertMetamodelClassGeneratedFor( Car.class );
- assertAbsenceOfFieldInMetamodelFor( Car.class, "horsePower" );
+
+ assertAbsenceOfFieldInMetamodelFor(
+ Car.class, "horsePower", "'horsePower' should not appear in metamodel since it does have no field."
+ );
}
@Test
public void testExplicitXmlConfiguredAccessTypeApplied() {
assertMetamodelClassGeneratedFor( Vehicle.class );
assertMetamodelClassGeneratedFor( Truck.class );
+
assertPresenceOfFieldInMetamodelFor(
Truck.class, "horsePower", "Property 'horsePower' has explicit access type and should be in metamodel"
);
+ assertAttributeTypeInMetaModelFor( Truck.class, "horsePower", Integer.class, "Wrong meta model type" );
}
@Test
public void testMixedConfiguration() {
assertMetamodelClassGeneratedFor( RentalCar.class );
assertMetamodelClassGeneratedFor( RentalCompany.class );
+
assertPresenceOfFieldInMetamodelFor(
RentalCar.class, "company", "Property 'company' should be included due to xml configuration"
);
+ assertAttributeTypeInMetaModelFor( RentalCar.class, "company", RentalCompany.class, "Wrong meta model type" );
+
assertPresenceOfFieldInMetamodelFor(
RentalCar.class, "insurance", "Property 'insurance' should be included since it is an embeddable"
);
+ assertAttributeTypeInMetaModelFor( RentalCar.class, "insurance", Insurance.class, "Wrong meta model type" );
}
+ @Test
+ public void testAccessTypeForXmlConfiguredEmbeddables() {
+ assertMetamodelClassGeneratedFor( Coordinates.class );
+ assertPresenceOfFieldInMetamodelFor(
+ Coordinates.class, "longitude", "field exists and should be in metamodel"
+ );
+ assertPresenceOfFieldInMetamodelFor( Coordinates.class, "latitude", "field exists and should be in metamodel" );
+
+ assertMetamodelClassGeneratedFor( ZeroCoordinates.class );
+ assertAbsenceOfFieldInMetamodelFor(
+ ZeroCoordinates.class,
+ "longitude",
+ "Field access should be used, but ZeroCoordinates does not define fields"
+ );
+ assertAbsenceOfFieldInMetamodelFor(
+ ZeroCoordinates.class,
+ "latitude",
+ "Field access should be used, but ZeroCoordinates does not define fields"
+ );
+ }
+
@Override
protected String getPackageNameOfTestSources() {
return MixedConfigurationTest.class.getPackage().getName();
@@ -74,6 +105,7 @@
ormFiles.add( dir + "/car.xml" );
ormFiles.add( dir + "/rentalcar.xml" );
ormFiles.add( dir + "/truck.xml" );
+ ormFiles.add( dir + "/coordinates.xml" );
return ormFiles;
}
}
\ No newline at end of file
Added: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/ZeroCoordinates.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/ZeroCoordinates.java (rev 0)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/mixedmode/ZeroCoordinates.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,41 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.test.mixedmode;
+
+import javax.persistence.Embeddable;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Embeddable
+public class ZeroCoordinates {
+ public float getLatitude() {
+ return 0f;
+ }
+
+ public void setLatitude(float latitude) {
+ }
+
+ public float getLongitude() {
+ return 0f;
+ }
+
+ public void setLongitude(float longitude) {
+ }
+}
\ No newline at end of file
Modified: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java 2010-02-11 02:42:15 UTC (rev 18772)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java 2010-02-11 02:43:51 UTC (rev 18773)
@@ -114,14 +114,18 @@
public static void assertAttributeTypeInMetaModelFor(Class<?> clazz, String fieldName, Class<?> expectedType, String errorString) {
Field field = getFieldFromMetamodelFor( clazz, fieldName );
- assertNotNull( field, "Field " + fieldName + " should exist." );
+ assertNotNull( field, "Cannot find field '" + fieldName + "' in " + clazz.getName() );
ParameterizedType type = ( ParameterizedType ) field.getGenericType();
Type actualType = type.getActualTypeArguments()[1];
if ( expectedType.isArray() ) {
expectedType = expectedType.getComponentType();
actualType = ( ( GenericArrayType ) actualType ).getGenericComponentType();
}
- assertEquals( actualType, expectedType, errorString );
+ assertEquals(
+ actualType,
+ expectedType,
+ "Types do not match: " + errorString
+ );
}
public static void assertMapAttributesInMetaModelFor(Class<?> clazz, String fieldName, Class<?> expectedMapKey, Class<?> expectedMapValue, String errorString) {
@@ -180,13 +184,13 @@
private static class MetaModelFilenameFilter implements FileFilter {
@Override
- public boolean accept(File pathname) {
- if ( pathname.isDirectory() ) {
+ public boolean accept(File pathName) {
+ if ( pathName.isDirectory() ) {
return true;
}
else {
- return pathname.getAbsolutePath().endsWith( "_.java" )
- || pathname.getAbsolutePath().endsWith( "_.class" );
+ return pathName.getAbsolutePath().endsWith( "_.java" )
+ || pathName.getAbsolutePath().endsWith( "_.class" );
}
}
}
Copied: jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/mixedmode/coordinates.xml (from rev 18734, jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/mixedmode/car.xml)
===================================================================
--- jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/mixedmode/coordinates.xml (rev 0)
+++ jpamodelgen/trunk/src/test/resources/org/hibernate/jpamodelgen/test/mixedmode/coordinates.xml 2010-02-11 02:43:51 UTC (rev 18773)
@@ -0,0 +1,22 @@
+<?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"
+ >
+ <!-- no implicit or explicit access configured here -->
+ <embeddable class="org.hibernate.jpamodelgen.test.mixedmode.Coordinates">
+ <attributes>
+ <basic name="longitude"/>
+ <basic name="latitude"/>
+ </attributes>
+ </embeddable>
+ <embeddable class="org.hibernate.jpamodelgen.test.mixedmode.ZeroCoordinates">
+ <attributes>
+ <basic name="longitude"/>
+ <basic name="latitude"/>
+ </attributes>
+ </embeddable>
+</entity-mappings>
+
More information about the hibernate-commits
mailing list