METAGEN-22 Some cleanup and optimisatons prior adding new functionality

This commit is contained in:
Hardy Ferentschik 2010-02-11 21:08:01 +00:00 committed by Strong Liu
parent 6e039d710b
commit 9fb1f05259
12 changed files with 352 additions and 150 deletions

View File

@ -44,7 +44,7 @@ public class AnnotationEmbeddable extends AnnotationMetaEntity {
public List<MetaAttribute> getMembers() {
if ( !initialized ) {
context.logMessage( Diagnostic.Kind.OTHER, "Entity " + getQualifiedName() + "was lazily initialised." );
context.logMessage( Diagnostic.Kind.OTHER, "Entity " + getQualifiedName() + " was lazily initialised." );
init();
initialized = true;
}

View File

@ -306,7 +306,7 @@ public class AnnotationMetaEntity implements MetaEntity {
keyType = typeMirror.toString();
}
else {
keyType = getKeyType( declaredType );
keyType = TypeUtils.getKeyType( declaredType, context );
}
return new AnnotationMetaMap(
parent,
@ -341,14 +341,6 @@ public class AnnotationMetaEntity implements MetaEntity {
}
}
private String getKeyType(DeclaredType t) {
List<? extends TypeMirror> typeArguments = t.getTypeArguments();
if ( typeArguments.size() == 0 ) {
context.logMessage( Diagnostic.Kind.ERROR, "Entity: " + getQualifiedName() );
}
return TypeUtils.extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
}
/**
* @param annotations list of annotation mirrors.
*

View File

@ -20,7 +20,6 @@ package org.hibernate.jpamodelgen.annotation;
import javax.lang.model.element.Element;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
@ -30,13 +29,13 @@ public class AnnotationMetaMap extends AnnotationMetaCollection {
private final String keyType;
public AnnotationMetaMap(AnnotationMetaEntity parent, Element element, String collectionType,
String keyType, String elementType) {
super(parent, element, collectionType, elementType);
this.keyType = keyType;
String keyType, String elementType) {
super( parent, element, collectionType, elementType );
this.keyType = keyType;
}
public String getDeclarationString() {
return "public static volatile " + parent.importType(getMetaType()) + "<" + parent.importType(parent.getQualifiedName()) + ", " + parent.importType(keyType) + ", " + parent.importType(getTypeDeclaration()) + "> " + getPropertyName() + ";";
return "public static volatile " + parent.importType( getMetaType() ) + "<" + parent.importType( parent.getQualifiedName() ) + ", " + parent
.importType( keyType ) + ", " + parent.importType( getTypeDeclaration() ) + "> " + getPropertyName() + ";";
}
}

View File

@ -380,8 +380,15 @@ public class TypeUtils {
}
}
static class EmbeddedAttributeVisitor extends SimpleTypeVisitor6<String, Element> {
public static String getKeyType(DeclaredType t, Context context) {
List<? extends TypeMirror> typeArguments = t.getTypeArguments();
if ( typeArguments.size() == 0 ) {
context.logMessage( Diagnostic.Kind.ERROR, "Unable to determine type argument for " + t );
}
return extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
}
static class EmbeddedAttributeVisitor extends SimpleTypeVisitor6<String, Element> {
private Context context;
EmbeddedAttributeVisitor(Context context) {

View File

@ -25,33 +25,34 @@ import org.hibernate.jpamodelgen.model.MetaAttribute;
*/
public abstract class XmlMetaAttribute implements MetaAttribute {
private XmlMetaEntity parentEntity;
protected final XmlMetaEntity parentEntity;
private final String propertyName;
private final String type;
private String propertyName;
private String type;
XmlMetaAttribute(XmlMetaEntity parent, String propertyName, String type) {
this.parentEntity = parent;
this.propertyName = propertyName;
this.type = type;
}
XmlMetaAttribute(XmlMetaEntity parent, String propertyName, String type) {
this.parentEntity = parent;
this.propertyName = propertyName;
this.type = type;
}
@Override
public String getDeclarationString() {
return "public static volatile " + parentEntity.importType(getMetaType()) + "<" + parentEntity.importType(parentEntity.getQualifiedName()) + ", " + parentEntity.importType(getTypeDeclaration()) + "> " + getPropertyName() + ";";
}
public String getDeclarationString() {
return "public static volatile " + parentEntity.importType( getMetaType() )
+ "<" + parentEntity.importType( parentEntity.getQualifiedName() )
+ ", " + parentEntity.importType( getTypeDeclaration() )
+ "> " + getPropertyName() + ";";
}
public String getPropertyName() {
return propertyName;
}
public String getPropertyName() {
return propertyName;
}
public String getTypeDeclaration() {
public String getTypeDeclaration() {
return type;
}
@Override
abstract public String getMetaType();
@Override
abstract public String getMetaType();
@Override
public String toString() {

View File

@ -48,6 +48,7 @@ import org.hibernate.jpamodelgen.xml.jaxb.Entity;
import org.hibernate.jpamodelgen.xml.jaxb.Id;
import org.hibernate.jpamodelgen.xml.jaxb.ManyToMany;
import org.hibernate.jpamodelgen.xml.jaxb.ManyToOne;
import org.hibernate.jpamodelgen.xml.jaxb.MapKeyClass;
import org.hibernate.jpamodelgen.xml.jaxb.MappedSuperclass;
import org.hibernate.jpamodelgen.xml.jaxb.OneToMany;
import org.hibernate.jpamodelgen.xml.jaxb.OneToOne;
@ -182,8 +183,8 @@ public class XmlMetaEntity implements MetaEntity {
return context.isPersistenceUnitCompletelyXmlConfigured() || Boolean.TRUE.equals( metadataComplete );
}
private String[] getCollectionType(String propertyName, String explicitTargetEntity, ElementKind expectedElementKind) {
String types[] = new String[2];
private String[] getCollectionTypes(String propertyName, String explicitTargetEntity, String explicitMapKeyClass, ElementKind expectedElementKind) {
String types[] = new String[3];
for ( Element elem : element.getEnclosedElements() ) {
if ( expectedElementKind.equals( elem.getKind() ) ) {
continue;
@ -194,25 +195,45 @@ public class XmlMetaEntity implements MetaEntity {
}
DeclaredType type = ( ( DeclaredType ) elem.asType() );
List<? extends TypeMirror> typeArguments = type.getTypeArguments();
if ( typeArguments.size() == 0 && explicitTargetEntity == null ) {
throw new MetaModelGenerationException( "Unable to determine target entity type for " + clazzName + "." + propertyName + "." );
determineTargetType( type, propertyName, explicitTargetEntity, types );
determineCollectionType( type, types );
if ( types[1].equals( "javax.persistence.metamodel.MapAttribute" ) ) {
determineMapType( type, explicitMapKeyClass, types );
}
if ( explicitTargetEntity == null ) {
types[0] = TypeUtils.extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
}
else {
types[0] = explicitTargetEntity;
}
types[1] = COLLECTIONS.get( type.asElement().toString() );
return types;
}
return null;
}
private void determineMapType(DeclaredType type, String explicitMapKeyClass, String[] types) {
if ( explicitMapKeyClass != null ) {
types[2] = explicitMapKeyClass;
}
else {
types[2] = TypeUtils.getKeyType( type, context );
}
}
private void determineCollectionType(DeclaredType type, String[] types) {
types[1] = COLLECTIONS.get( type.asElement().toString() );
}
private void determineTargetType(DeclaredType type, String propertyName, String explicitTargetEntity, String[] types) {
List<? extends TypeMirror> typeArguments = type.getTypeArguments();
if ( typeArguments.size() == 0 && explicitTargetEntity == null ) {
throw new MetaModelGenerationException( "Unable to determine target entity type for " + clazzName + "." + propertyName + "." );
}
if ( explicitTargetEntity == null ) {
types[0] = TypeUtils.extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
}
else {
types[0] = explicitTargetEntity;
}
}
/**
* Returns the entity type for a property.
*
@ -302,154 +323,183 @@ public class XmlMetaEntity implements MetaEntity {
}
for ( Basic basic : attributes.getBasic() ) {
ElementKind elementKind = getElementKind( basic.getAccess() );
String type = getType( basic.getName(), null, elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, basic.getName(), type );
members.add( attribute );
}
parseBasic( basic );
}
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
ElementKind elementKind = getElementKind( manyToOne.getAccess() );
String type = getType( manyToOne.getName(), manyToOne.getTargetEntity(), elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), type );
members.add( attribute );
}
parseManyToOne( manyToOne );
}
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
ElementKind elementKind = getElementKind( oneToOne.getAccess() );
String type = getType( oneToOne.getName(), oneToOne.getTargetEntity(), elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), type );
members.add( attribute );
}
parseOneToOne( oneToOne );
}
XmlMetaCollection metaCollection;
String[] types;
for ( ManyToMany manyToMany : attributes.getManyToMany() ) {
ElementKind elementKind = getElementKind( manyToMany.getAccess() );
try {
types = getCollectionType( manyToMany.getName(), manyToMany.getTargetEntity(), elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( manyToMany.getName(), e );
if ( parseManyToMany( manyToMany ) ) {
break;
}
if ( types != null ) {
metaCollection = new XmlMetaCollection( this, manyToMany.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
ElementKind elementKind = getElementKind( oneToMany.getAccess() );
try {
types = getCollectionType( oneToMany.getName(), oneToMany.getTargetEntity(), elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( oneToMany.getName(), e );
if ( parseOneToMany( oneToMany ) ) {
break;
}
if ( types != null ) {
metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
for ( ElementCollection collection : attributes.getElementCollection() ) {
ElementKind elementKind = getElementKind( collection.getAccess() );
try {
types = getCollectionType( collection.getName(), collection.getTargetClass(), elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( collection.getName(), e );
if ( parseElementCollection( collection ) ) {
break;
}
if ( types != null ) {
metaCollection = new XmlMetaCollection( this, collection.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
}
private void parseEmbeddableAttributes(EmbeddableAttributes attributes) {
XmlMetaSingleAttribute attribute;
for ( Basic basic : attributes.getBasic() ) {
ElementKind elementKind = getElementKind( basic.getAccess() );
String type = getType( basic.getName(), null, elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, basic.getName(), type );
members.add( attribute );
}
parseBasic( basic );
}
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
ElementKind elementKind = getElementKind( manyToOne.getAccess() );
String type = getType( manyToOne.getName(), manyToOne.getTargetEntity(), elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), type );
members.add( attribute );
}
parseManyToOne( manyToOne );
}
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
ElementKind elementKind = getElementKind( oneToOne.getAccess() );
String type = getType( oneToOne.getName(), oneToOne.getTargetEntity(), elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), type );
members.add( attribute );
}
parseOneToOne( oneToOne );
}
XmlMetaCollection metaCollection;
String[] types;
for ( ManyToMany manyToMany : attributes.getManyToMany() ) {
ElementKind elementKind = getElementKind( manyToMany.getAccess() );
try {
types = getCollectionType( manyToMany.getName(), manyToMany.getTargetEntity(), elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( manyToMany.getName(), e );
if ( parseManyToMany( manyToMany ) ) {
break;
}
if ( types != null ) {
metaCollection = new XmlMetaCollection( this, manyToMany.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
ElementKind elementKind = getElementKind( oneToMany.getAccess() );
try {
types = getCollectionType( oneToMany.getName(), oneToMany.getTargetEntity(), elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( oneToMany.getName(), e );
if ( parseOneToMany( oneToMany ) ) {
break;
}
if ( types != null ) {
metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
for ( ElementCollection collection : attributes.getElementCollection() ) {
ElementKind elementKind = getElementKind( collection.getAccess() );
try {
types = getCollectionType( collection.getName(), collection.getTargetClass(), elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( collection.getName(), e );
if ( parseElementCollection( collection ) ) {
break;
}
if ( types != null ) {
}
}
private boolean parseElementCollection(ElementCollection collection) {
String[] types;
XmlMetaCollection metaCollection;
ElementKind elementKind = getElementKind( collection.getAccess() );
MapKeyClass mapKeyClass = collection.getMapKeyClass();
String explicitMapKey = null;
if ( mapKeyClass != null ) {
explicitMapKey = mapKeyClass.getClazz();
}
try {
types = getCollectionTypes(
collection.getName(), collection.getTargetClass(), explicitMapKey, elementKind
);
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( collection.getName(), e );
return true;
}
if ( types != null ) {
if ( types[2] == null ) {
metaCollection = new XmlMetaCollection( this, collection.getName(), types[0], types[1] );
members.add( metaCollection );
}
else {
metaCollection = new XmlMetaMap( this, collection.getName(), types[0], types[1], types[2] );
}
members.add( metaCollection );
}
return false;
}
private boolean parseOneToMany(OneToMany oneToMany) {
String[] types;
XmlMetaCollection metaCollection;
ElementKind elementKind = getElementKind( oneToMany.getAccess() );
MapKeyClass mapKeyClass = oneToMany.getMapKeyClass();
String explicitMapKey = null;
if ( mapKeyClass != null ) {
explicitMapKey = mapKeyClass.getClazz();
}
try {
types = getCollectionTypes( oneToMany.getName(), oneToMany.getTargetEntity(), explicitMapKey, elementKind );
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( oneToMany.getName(), e );
return true;
}
if ( types != null ) {
if ( types[2] == null ) {
metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
}
else {
metaCollection = new XmlMetaMap( this, oneToMany.getName(), types[0], types[1], types[2] );
}
members.add( metaCollection );
}
return false;
}
private boolean parseManyToMany(ManyToMany manyToMany) {
String[] types;
XmlMetaCollection metaCollection;
ElementKind elementKind = getElementKind( manyToMany.getAccess() );
MapKeyClass mapKeyClass = manyToMany.getMapKeyClass();
String explicitMapKey = null;
if ( mapKeyClass != null ) {
explicitMapKey = mapKeyClass.getClazz();
}
try {
types = getCollectionTypes(
manyToMany.getName(), manyToMany.getTargetEntity(), explicitMapKey, elementKind
);
}
catch ( MetaModelGenerationException e ) {
logMetaModelException( manyToMany.getName(), e );
return true;
}
if ( types != null ) {
if ( types[2] == null ) {
metaCollection = new XmlMetaCollection( this, manyToMany.getName(), types[0], types[1] );
}
else {
metaCollection = new XmlMetaMap( this, manyToMany.getName(), types[0], types[1], types[2] );
}
members.add( metaCollection );
}
return false;
}
private void parseOneToOne(OneToOne oneToOne) {
XmlMetaSingleAttribute attribute;
ElementKind elementKind = getElementKind( oneToOne.getAccess() );
String type = getType( oneToOne.getName(), oneToOne.getTargetEntity(), elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), type );
members.add( attribute );
}
}
private void parseManyToOne(ManyToOne manyToOne) {
XmlMetaSingleAttribute attribute;
ElementKind elementKind = getElementKind( manyToOne.getAccess() );
String type = getType( manyToOne.getName(), manyToOne.getTargetEntity(), elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), type );
members.add( attribute );
}
}
private void parseBasic(Basic basic) {
XmlMetaSingleAttribute attribute;
ElementKind elementKind = getElementKind( basic.getAccess() );
String type = getType( basic.getName(), null, elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, basic.getName(), type );
members.add( attribute );
}
}

View File

@ -0,0 +1,40 @@
// $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;
/**
* @author Hardy Ferentschik
*/
public class XmlMetaMap extends XmlMetaCollection {
private final String keyType;
public XmlMetaMap(XmlMetaEntity parent, String propertyName, String type, String collectionType, String keyType) {
super( parent, propertyName, type, collectionType );
this.keyType = keyType;
}
public String getDeclarationString() {
return "public static volatile "
+ parentEntity.importType( getMetaType() )
+ "<" + parentEntity.importType( parentEntity.getQualifiedName() )
+ ", " + parentEntity.importType( keyType ) + ", "
+ parentEntity.importType( getTypeDeclaration() )
+ "> " + getPropertyName() + ";";
}
}

View File

@ -18,6 +18,7 @@
package org.hibernate.jpamodelgen.test.elementcollection;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Hardy Ferentschik
@ -28,6 +29,7 @@ public class Cleaner {
private String name;
@Id
public int getId() {
return id;
}

View File

@ -17,9 +17,14 @@
*/
package org.hibernate.jpamodelgen.test.elementcollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.testng.annotations.Test;
import org.hibernate.jpamodelgen.test.util.CompilationTest;
import org.hibernate.jpamodelgen.test.util.TestUtil;
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMapAttributesInMetaModelFor;
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMetamodelClassGeneratedFor;
@ -55,8 +60,30 @@ public class ElementCollectionTest extends CompilationTest {
);
}
/**
* METAGEN-22
*/
@Test
public void testMapKeyClassXmlConfigured() {
assertMetamodelClassGeneratedFor( Hostel.class );
assertMapAttributesInMetaModelFor(
Hostel.class, "roomsByName", String.class, Room.class, "Wrong type in map attribute."
);
assertMapAttributesInMetaModelFor(
Hostel.class, "cleaners", Room.class, Cleaner.class, "Wrong type in map attribute."
);
}
@Override
protected String getPackageNameOfTestSources() {
return ElementCollectionTest.class.getPackage().getName();
}
@Override
protected Collection<String> getOrmFiles() {
List<String> ormFiles = new ArrayList<String>();
ormFiles.add( TestUtil.fcnToPath( ElementCollectionTest.class.getPackage().getName() ) + "/hostel.xml" );
return ormFiles;
}
}

View File

@ -0,0 +1,52 @@
// $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.elementcollection;
import java.util.Map;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.MapKeyClass;
import javax.persistence.OneToMany;
/**
* @author Hardy Ferentschik
*/
public class Hostel {
private Map roomsByName;
private Map cleaners;
@ElementCollection(targetClass = Room.class)
@MapKeyClass(String.class)
public Map getRoomsByName() {
return roomsByName;
}
public void setRoomsByName(Map roomsByName) {
this.roomsByName = roomsByName;
}
public Map getCleaners() {
return cleaners;
}
public void setCleaners(Map cleaners) {
this.cleaners = cleaners;
}
}

View File

@ -20,6 +20,8 @@ package org.hibernate.jpamodelgen.test.elementcollection;
import java.util.Map;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MapKeyClass;
import javax.persistence.OneToMany;
@ -29,10 +31,20 @@ import javax.persistence.OneToMany;
*/
@Entity
public class Hotel {
private int id;
private Map roomsByName;
private Map cleaners;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@ElementCollection(targetClass = Room.class)
@MapKeyClass(String.class)
public Map getRoomsByName() {

View File

@ -0,0 +1,20 @@
<?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"
>
<entity class="org.hibernate.jpamodelgen.test.elementcollection.Hostel">
<attributes>
<one-to-many name="cleaners" target-entity="org.hibernate.jpamodelgen.test.elementcollection.Cleaner">
<map-key-class class="org.hibernate.jpamodelgen.test.elementcollection.Room"/>
</one-to-many>
<element-collection name="roomsByName"
target-class="org.hibernate.jpamodelgen.test.elementcollection.Room">
<map-key-class class="java.lang.String"/>
</element-collection>
</attributes>
</entity>
</entity-mappings>