METAGEN-20 support raw collections and honor targetEntity
This commit is contained in:
parent
d4dac16e32
commit
b78ebb332c
|
@ -79,8 +79,7 @@ public class TypeUtils {
|
|||
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.getProcessingEnvironment().getTypeUtils();
|
||||
final List<? extends TypeMirror> upperBounds = types.directSupertypes( compositeUpperBound );
|
||||
if (upperBounds.size() == 0) {
|
||||
return compositeUpperBound.toString();
|
||||
|
@ -89,7 +88,6 @@ public class TypeUtils {
|
|||
//take the first one
|
||||
return extractClosestRealTypeAsString( upperBounds.get( 0 ), context );
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
return type.toString();
|
||||
|
|
|
@ -22,8 +22,10 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
|
@ -43,7 +45,11 @@ import javax.persistence.Embedded;
|
|||
import javax.persistence.EmbeddedId;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Transient;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
|
@ -348,8 +354,11 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
String fqElementName = returnedElement.getQualifiedName()
|
||||
.toString(); // WARNING: .toString() is necessary here since Name equals does not compare to String
|
||||
String collection = COLLECTIONS.get( fqElementName );
|
||||
final List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors();
|
||||
String targetEntity = getTargetEntity( annotations );
|
||||
if ( collection != null ) {
|
||||
if ( element.getAnnotation( ElementCollection.class ) != null ) {
|
||||
if ( containsAnnotation( annotations, ElementCollection.class ) ) {
|
||||
//FIXME I don't understand why this code is different between Elementcollection and a regular collection but it needs to take targetClass into account
|
||||
TypeMirror collectionElementType = getCollectionElementType( t, fqElementName );
|
||||
final TypeElement collectionElement = ( TypeElement ) context.getProcessingEnvironment()
|
||||
.getTypeUtils()
|
||||
|
@ -361,11 +370,12 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
}
|
||||
if ( collection.equals( "javax.persistence.metamodel.MapAttribute" ) ) {
|
||||
return new AnnotationMetaMap(
|
||||
parent, element, collection, getKeyType( t ), getElementType( t )
|
||||
//FIXME support targetEntity for map's key @MapKeyClass
|
||||
parent, element, collection, getKeyType( t ), getElementType( t, targetEntity )
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new AnnotationMetaCollection( parent, element, collection, getElementType( t ) );
|
||||
return new AnnotationMetaCollection( parent, element, collection, getElementType( t, targetEntity ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -414,6 +424,63 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean containsAnnotation(List<? extends AnnotationMirror> annotations, Class<?> annotation) {
|
||||
String annString = annotation.getName();
|
||||
for ( AnnotationMirror mirror : annotations ) {
|
||||
if ( annString.equals( mirror.getAnnotationType().toString() ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns targetEntity or null if no targetEntity is here or if equals to void
|
||||
*/
|
||||
private String getTargetEntity(List<? extends AnnotationMirror> annotations) {
|
||||
final String elementCollection = ElementCollection.class.getName();
|
||||
|
||||
for ( AnnotationMirror mirror : annotations ) {
|
||||
final String annotation = mirror.getAnnotationType().toString();
|
||||
if ( elementCollection.equals( annotation ) ) {
|
||||
final String targetEntity = getTargetEntity( mirror );
|
||||
if (targetEntity != null) return targetEntity;
|
||||
}
|
||||
else if ( OneToMany.class.getName().equals( annotation ) ) {
|
||||
final String targetEntity = getTargetEntity( mirror );
|
||||
if (targetEntity != null) return targetEntity;
|
||||
}
|
||||
else if ( ManyToMany.class.getName().equals( annotation ) ) {
|
||||
final String targetEntity = getTargetEntity( mirror );
|
||||
if (targetEntity != null) return targetEntity;
|
||||
}
|
||||
else if ( ManyToOne.class.getName().equals( annotation ) ) {
|
||||
final String targetEntity = getTargetEntity( mirror );
|
||||
if (targetEntity != null) return targetEntity;
|
||||
}
|
||||
else if ( OneToOne.class.getName().equals( annotation ) ) {
|
||||
final String targetEntity = getTargetEntity( mirror );
|
||||
if (targetEntity != null) return targetEntity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getTargetEntity(AnnotationMirror mirror) {
|
||||
String targetEntity = null;
|
||||
final Map<? extends ExecutableElement, ? extends AnnotationValue> attributes = mirror.getElementValues();
|
||||
for ( Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : attributes.entrySet() ) {
|
||||
final String simpleName = entry.getKey().getSimpleName().toString();
|
||||
if ( "targetEntity".equals( simpleName ) ) {
|
||||
targetEntity = entry.getValue().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
targetEntity = ( "void.class".equals( targetEntity ) ) ? null : targetEntity;
|
||||
return targetEntity != null && targetEntity.endsWith( ".class" ) ?
|
||||
targetEntity.substring( 0, targetEntity.length() - 6 ) : null;
|
||||
}
|
||||
|
||||
public String generateImports() {
|
||||
return importContext.generateImports();
|
||||
}
|
||||
|
@ -438,13 +505,23 @@ public class AnnotationMetaEntity implements MetaEntity {
|
|||
return TypeUtils.extractClosestRealTypeAsString( t.getTypeArguments().get( 0 ), context );
|
||||
}
|
||||
|
||||
private String getElementType(DeclaredType declaredType) {
|
||||
if ( declaredType.getTypeArguments().size() == 1 ) {
|
||||
final TypeMirror type = declaredType.getTypeArguments().get( 0 );
|
||||
private String getElementType(DeclaredType declaredType, String targetEntity) {
|
||||
if (targetEntity != null) return targetEntity;
|
||||
final List<? extends TypeMirror> mirrors = declaredType.getTypeArguments();
|
||||
if ( mirrors.size() == 1 ) {
|
||||
final TypeMirror type = mirrors.get( 0 );
|
||||
return TypeUtils.extractClosestRealTypeAsString( type, context );
|
||||
}
|
||||
else if ( mirrors.size() == 2 ) {
|
||||
return TypeUtils.extractClosestRealTypeAsString( mirrors.get( 1 ), context );
|
||||
}
|
||||
else {
|
||||
return TypeUtils.extractClosestRealTypeAsString( declaredType.getTypeArguments().get( 1 ), context );
|
||||
//for 0 or many
|
||||
//0 is expected, many is not
|
||||
if ( mirrors.size() > 2) {
|
||||
context.logMessage( Diagnostic.Kind.WARNING, "Unable to find the closest solid type" + declaredType );
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class Parent {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@OneToMany
|
||||
@OneToMany(targetEntity = void.class)
|
||||
@JoinColumn(name="parent_fk", nullable = false)
|
||||
public Set<Child> getChildren() {
|
||||
return children;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package org.hibernate.jpamodelgen.test.rawTypes;
|
||||
|
||||
import java.util.Collection;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class A implements java.io.Serializable {
|
||||
|
||||
@Id
|
||||
protected String id;
|
||||
|
||||
@Basic
|
||||
protected String name;
|
||||
|
||||
@Basic
|
||||
protected int value;
|
||||
|
||||
|
||||
public A() {
|
||||
}
|
||||
|
||||
@ManyToMany(targetEntity = B.class, cascade = CascadeType.ALL)
|
||||
@JoinTable(name = "tbl_A_B",
|
||||
joinColumns =
|
||||
@JoinColumn(
|
||||
name = "A_FK", referencedColumnName = "ID"),
|
||||
inverseJoinColumns =
|
||||
@JoinColumn(
|
||||
name = "B_FK", referencedColumnName = "ID")
|
||||
)
|
||||
protected Collection bCol = new java.util.ArrayList();
|
||||
|
||||
|
||||
public Collection getBCol() {
|
||||
return bCol;
|
||||
}
|
||||
|
||||
public void setBCol(Collection bCol) {
|
||||
this.bCol = bCol;
|
||||
}
|
||||
|
||||
public String getAId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setAName(String aName) {
|
||||
this.name = aName;
|
||||
}
|
||||
|
||||
|
||||
public int getAValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package org.hibernate.jpamodelgen.test.rawTypes;
|
||||
|
||||
import java.util.Collection;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class B implements java.io.Serializable {
|
||||
|
||||
@Id
|
||||
protected String id;
|
||||
|
||||
@Basic
|
||||
protected String name;
|
||||
|
||||
@Basic
|
||||
protected int value;
|
||||
|
||||
|
||||
@ManyToMany(targetEntity = A.class, mappedBy = "bCol", cascade = CascadeType.ALL)
|
||||
protected Collection aCol = new java.util.ArrayList();
|
||||
|
||||
|
||||
public B() {
|
||||
}
|
||||
|
||||
|
||||
public Collection getACol() {
|
||||
return aCol;
|
||||
}
|
||||
|
||||
public void setACol(Collection aCol) {
|
||||
this.aCol = aCol;
|
||||
}
|
||||
|
||||
public String getBId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getBName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getBValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// $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.rawTypes;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.hibernate.jpamodelgen.test.util.CompilationTest;
|
||||
|
||||
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertClassGenerated;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class RawTypesTest extends CompilationTest {
|
||||
|
||||
@Test
|
||||
public void testGenerics() {
|
||||
assertClassGenerated( A.class.getName() + "_" );
|
||||
assertClassGenerated( B.class.getName() + "_" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestPackage() {
|
||||
return A.class.getPackage().getName();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue