METAGEN-15 use the first upper bound when the type to be exported is a generic.
This commit is contained in:
parent
33d734f33a
commit
d4dac16e32
|
@ -62,7 +62,7 @@ public class ClassWriter {
|
||||||
}
|
}
|
||||||
catch ( FilerException filerEx ) {
|
catch ( FilerException filerEx ) {
|
||||||
context.logMessage(
|
context.logMessage(
|
||||||
Diagnostic.Kind.ERROR, "Problem with Processing Environment Filer: " + filerEx.getMessage()
|
Diagnostic.Kind.WARNING, "Problem with Processing Environment Filer: " + filerEx.getMessage()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( IOException ioEx ) {
|
catch ( IOException ioEx ) {
|
||||||
|
|
|
@ -110,6 +110,7 @@ public class Context {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClassWriter.writeFile( new AnnotationMetaEntity( element, this, defaultAccessTypeForHierarchy ), this );
|
ClassWriter.writeFile( new AnnotationMetaEntity( element, this, defaultAccessTypeForHierarchy ), this );
|
||||||
|
TypeUtils.extractClosestRealTypeAsString( element.asType(), this );
|
||||||
elementsAlreadyProcessed.add( element.getQualifiedName().toString() );
|
elementsAlreadyProcessed.add( element.getQualifiedName().toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
||||||
entity, packageName, getXmlMappedType( fullyQualifiedClassName )
|
entity, packageName, getXmlMappedType( fullyQualifiedClassName ),
|
||||||
|
context
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( context.getMetaEntitiesToProcess().containsKey( fullyQualifiedClassName ) ) {
|
if ( context.getMetaEntitiesToProcess().containsKey( fullyQualifiedClassName ) ) {
|
||||||
|
@ -264,7 +265,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
||||||
embeddable, packageName, getXmlMappedType( fullyQualifiedClassName )
|
embeddable, packageName, getXmlMappedType( fullyQualifiedClassName ),
|
||||||
|
context
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
|
if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
|
||||||
|
@ -292,7 +294,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
||||||
mappedSuperClass, packageName, getXmlMappedType( fullyQualifiedClassName )
|
mappedSuperClass, packageName, getXmlMappedType( fullyQualifiedClassName ),
|
||||||
|
context
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
|
if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
|
||||||
|
|
|
@ -21,11 +21,11 @@ package org.hibernate.jpamodelgen;
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public interface MetaAttribute {
|
public interface MetaAttribute {
|
||||||
String getDeclarationString();
|
String getDeclarationString();
|
||||||
|
|
||||||
String getMetaType();
|
String getMetaType();
|
||||||
|
|
||||||
String getPropertyName();
|
String getPropertyName();
|
||||||
|
|
||||||
String getTypeDeclaration();
|
String getTypeDeclaration();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.hibernate.jpamodelgen;
|
package org.hibernate.jpamodelgen;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
@ -25,6 +26,8 @@ import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.DeclaredType;
|
import javax.lang.model.type.DeclaredType;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.lang.model.type.TypeVariable;
|
||||||
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class.
|
* Utility class.
|
||||||
|
@ -72,4 +75,24 @@ public class TypeUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 List<? extends TypeMirror> upperBounds = types.directSupertypes( compositeUpperBound );
|
||||||
|
if (upperBounds.size() == 0) {
|
||||||
|
return compositeUpperBound.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//take the first one
|
||||||
|
return extractClosestRealTypeAsString( upperBounds.get( 0 ), context );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return type.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,15 +435,18 @@ public class AnnotationMetaEntity implements MetaEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKeyType(DeclaredType t) {
|
private String getKeyType(DeclaredType t) {
|
||||||
return t.getTypeArguments().get( 0 ).toString();
|
return TypeUtils.extractClosestRealTypeAsString( t.getTypeArguments().get( 0 ), context );
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getElementType(DeclaredType declaredType) {
|
private String getElementType(DeclaredType declaredType) {
|
||||||
if ( declaredType.getTypeArguments().size() == 1 ) {
|
if ( declaredType.getTypeArguments().size() == 1 ) {
|
||||||
return declaredType.getTypeArguments().get( 0 ).toString();
|
final TypeMirror type = declaredType.getTypeArguments().get( 0 );
|
||||||
|
return TypeUtils.extractClosestRealTypeAsString( type, context );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return declaredType.getTypeArguments().get( 1 ).toString();
|
return TypeUtils.extractClosestRealTypeAsString( declaredType.getTypeArguments().get( 1 ), context );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,12 @@ import javax.lang.model.element.Name;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.type.DeclaredType;
|
import javax.lang.model.type.DeclaredType;
|
||||||
|
|
||||||
|
import org.hibernate.jpamodelgen.Context;
|
||||||
import org.hibernate.jpamodelgen.MetaAttribute;
|
import org.hibernate.jpamodelgen.MetaAttribute;
|
||||||
import org.hibernate.jpamodelgen.ImportContextImpl;
|
import org.hibernate.jpamodelgen.ImportContextImpl;
|
||||||
import org.hibernate.jpamodelgen.MetaEntity;
|
import org.hibernate.jpamodelgen.MetaEntity;
|
||||||
import org.hibernate.jpamodelgen.ImportContext;
|
import org.hibernate.jpamodelgen.ImportContext;
|
||||||
|
import org.hibernate.jpamodelgen.TypeUtils;
|
||||||
import org.hibernate.jpamodelgen.xml.jaxb.Attributes;
|
import org.hibernate.jpamodelgen.xml.jaxb.Attributes;
|
||||||
import org.hibernate.jpamodelgen.xml.jaxb.Basic;
|
import org.hibernate.jpamodelgen.xml.jaxb.Basic;
|
||||||
import org.hibernate.jpamodelgen.xml.jaxb.ElementCollection;
|
import org.hibernate.jpamodelgen.xml.jaxb.ElementCollection;
|
||||||
|
@ -65,31 +67,35 @@ public class XmlMetaEntity implements MetaEntity {
|
||||||
final private List<MetaAttribute> members = new ArrayList<MetaAttribute>();
|
final private List<MetaAttribute> members = new ArrayList<MetaAttribute>();
|
||||||
|
|
||||||
private TypeElement element;
|
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.clazzName = ormEntity.getClazz();
|
this.clazzName = ormEntity.getClazz();
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
importContext = new ImportContextImpl( getPackageName() );
|
this.context = context;
|
||||||
|
this.importContext = new ImportContextImpl( getPackageName() );
|
||||||
this.element = element;
|
this.element = element;
|
||||||
Attributes attributes = ormEntity.getAttributes();
|
Attributes attributes = ormEntity.getAttributes();
|
||||||
|
|
||||||
parseAttributes( attributes );
|
parseAttributes( attributes );
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlMetaEntity(MappedSuperclass mappedSuperclass, String packageName, TypeElement element) {
|
public XmlMetaEntity(MappedSuperclass mappedSuperclass, String packageName, TypeElement element, Context context) {
|
||||||
this.clazzName = mappedSuperclass.getClazz();
|
this.clazzName = mappedSuperclass.getClazz();
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
importContext = new ImportContextImpl( getPackageName() );
|
this.context = context;
|
||||||
|
this.importContext = new ImportContextImpl( getPackageName() );
|
||||||
this.element = element;
|
this.element = element;
|
||||||
Attributes attributes = mappedSuperclass.getAttributes();
|
Attributes attributes = mappedSuperclass.getAttributes();
|
||||||
|
|
||||||
parseAttributes( attributes );
|
parseAttributes( attributes );
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlMetaEntity(Embeddable embeddable, String packageName, TypeElement element) {
|
public XmlMetaEntity(Embeddable embeddable, String packageName, TypeElement element, Context context) {
|
||||||
this.clazzName = embeddable.getClazz();
|
this.clazzName = embeddable.getClazz();
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
importContext = new ImportContextImpl( getPackageName() );
|
this.context = context;
|
||||||
|
this.importContext = new ImportContextImpl( getPackageName() );
|
||||||
this.element = element;
|
this.element = element;
|
||||||
EmbeddableAttributes attributes = embeddable.getAttributes();
|
EmbeddableAttributes attributes = embeddable.getAttributes();
|
||||||
|
|
||||||
|
@ -164,7 +170,7 @@ public class XmlMetaEntity implements MetaEntity {
|
||||||
for ( Element elem : element.getEnclosedElements() ) {
|
for ( Element elem : element.getEnclosedElements() ) {
|
||||||
if ( elem.getSimpleName().toString().equals( propertyName ) ) {
|
if ( elem.getSimpleName().toString().equals( propertyName ) ) {
|
||||||
DeclaredType type = ( ( DeclaredType ) elem.asType() );
|
DeclaredType type = ( ( DeclaredType ) elem.asType() );
|
||||||
types[0] = type.getTypeArguments().get( 0 ).toString();
|
types[0] = TypeUtils.extractClosestRealTypeAsString(type.getTypeArguments().get( 0 ), context);
|
||||||
types[1] = COLLECTIONS.get( type.asElement().toString() );
|
types[1] = COLLECTIONS.get( type.asElement().toString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.hibernate.jpamodelgen.test.generics;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name="ejb_child")
|
||||||
|
public class Child {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
// $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.test.generics;
|
||||||
|
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import org.hibernate.jpamodelgen.test.elementcollection.House;
|
||||||
|
import org.hibernate.jpamodelgen.test.util.CompilationTest;
|
||||||
|
|
||||||
|
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertClassGenerated;
|
||||||
|
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertNoGeneratedSourceFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
*/
|
||||||
|
public class GenericsTest extends CompilationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerics() {
|
||||||
|
assertClassGenerated( Parent.class.getName() + "_" );
|
||||||
|
assertClassGenerated( Child.class.getName() + "_" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestPackage() {
|
||||||
|
return Parent.class.getPackage().getName();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package org.hibernate.jpamodelgen.test.generics;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name="ejb_parent")
|
||||||
|
public class Parent {
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Relatives<T> {
|
||||||
|
private Set<T> siblings;
|
||||||
|
|
||||||
|
@OneToMany
|
||||||
|
@JoinColumn(name="siblings_fk")
|
||||||
|
public Set<T> getSiblings() {
|
||||||
|
return siblings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSiblings(Set<T> siblings) {
|
||||||
|
this.siblings = siblings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
private Set<Child> children;
|
||||||
|
private Relatives<Child> siblings;
|
||||||
|
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OneToMany
|
||||||
|
@JoinColumn(name="parent_fk", nullable = false)
|
||||||
|
public Set<Child> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildren(Set<Child> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
public Relatives<Child> getSiblings() {
|
||||||
|
return siblings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSiblings(Relatives<Child> siblings) {
|
||||||
|
this.siblings = siblings;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue