improved type derivation

This commit is contained in:
Timo Westkämper 2008-03-11 19:04:05 +00:00
parent fe816ad7a3
commit 0df7d7d559
9 changed files with 336 additions and 182 deletions

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import java.util.ArrayList;
import java.util.Collection;
import com.sun.mirror.declaration.ConstructorDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
/**
*
* ConstructorDecl provides
*
* @author tiwe
* @version $Id$
*
*/
public class ConstructorDecl {
private final Collection<ParameterDecl> parameters;
public ConstructorDecl(Collection<ParameterDecl> params) {
parameters = params;
}
public ConstructorDecl(ConstructorDeclaration co) {
parameters = new ArrayList<ParameterDecl>(co.getParameters().size());
for (ParameterDeclaration pa : co.getParameters()) {
parameters.add(new ParameterDecl(pa));
}
}
public Collection<ParameterDecl> getParameters() {
return parameters;
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import com.mysema.query.apt.util.TypeInfo;
import com.sun.mirror.declaration.FieldDeclaration;
/**
* FieldDecl provides
*
* @author tiwe
* @version $Id$
*/
public class FieldDecl implements Comparable<FieldDecl>{
private final FieldType fieldType;
private String name, keyTypeName, typeName, simpleTypeName;
public FieldDecl(FieldDeclaration field) {
TypeInfo typeInfo = new TypeInfo(field.getType());
this.name = field.getSimpleName();
this.keyTypeName = typeInfo.getKeyTypeName();
this.typeName = typeInfo.getFullName();
this.simpleTypeName = typeInfo.getSimpleName();
this.fieldType = typeInfo.getFieldType();
}
public FieldDecl(String name, String keyTypeName, String typeName,
String simpleTypeName, FieldType fieldType){
this.name = name;
this.keyTypeName = keyTypeName;
this.typeName = typeName;
this.simpleTypeName = simpleTypeName;
this.fieldType = fieldType;
}
public int compareTo(FieldDecl o) {
return name.compareTo(o.name);
}
public boolean equals(Object o){
return o instanceof FieldDecl && name.equals(((FieldDecl)o).name);
}
public FieldType getFieldType(){
return fieldType;
}
public String getKeyTypeName(){
return keyTypeName;
}
public String getName(){
return name;
}
public String getSimpleTypeName(){
return simpleTypeName;
}
public String getTypeName(){
return typeName;
}
public int hashCode(){
return name.hashCode();
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
/**
*
* FieldType provides
*
* @author tiwe
* @version $Id$
*
*/
public enum FieldType {
BOOLEAN, ENTITY, ENTITYLIST, ENTITYCOLLECTION, ENTITYMAP, SIMPLE, SIMPLELIST, SIMPLECOLLECTION, SIMPLEMAP, STRING
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import com.mysema.query.apt.util.TypeInfo;
import com.sun.mirror.declaration.ParameterDeclaration;
/**
* ParameterDecl provides
*
* @author tiwe
* @version $Id$
*/
public class ParameterDecl implements Comparable<ParameterDecl> {
private final String name, typeName;
public ParameterDecl(String name, String typeName) {
this.name = name;
this.typeName = typeName;
}
public ParameterDecl(ParameterDeclaration pa) {
name = pa.getSimpleName();
typeName = new TypeInfo(pa.getType()).getFullName();
}
public int compareTo(ParameterDecl o) {
return name.compareTo(o.name);
}
public boolean equals(Object o) {
return o instanceof ParameterDecl && name.equals(((ParameterDecl) o).name);
}
public String getName() {
return name;
}
public String getTypeName() {
return typeName;
}
public int hashCode() {
return name.hashCode();
}
}

View File

@ -10,7 +10,6 @@ import java.util.*;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.ConstructorDeclaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
/**
*
@ -21,20 +20,7 @@ import com.sun.mirror.declaration.ParameterDeclaration;
*
*/
public class TypeDecl implements Comparable<TypeDecl>{
private static Map<String,Class<?>> primitiveTypes = new HashMap<String,Class<?>>();
static {
primitiveTypes.put("byte", Byte.class);
primitiveTypes.put("short", Short.class);
primitiveTypes.put("int", Integer.class);
primitiveTypes.put("long", Long.class);
primitiveTypes.put("float", Float.class);
primitiveTypes.put("double", Double.class);
primitiveTypes.put("char", Character.class);
primitiveTypes.put("boolean", Boolean.class);
}
private final Set<FieldDecl> booleanFields = new TreeSet<FieldDecl>();
// not sorted
@ -83,7 +69,7 @@ public class TypeDecl implements Comparable<TypeDecl>{
}
public void addField(FieldDecl fieldDecl){
switch(fieldDecl.fieldType){
switch(fieldDecl.getFieldType()){
case BOOLEAN : booleanFields.add(fieldDecl); break;
case STRING : stringFields.add(fieldDecl); break;
case SIMPLE : simpleFields.add(fieldDecl); break;
@ -98,9 +84,11 @@ public class TypeDecl implements Comparable<TypeDecl>{
public int compareTo(TypeDecl o) {
return simpleName.compareTo(o.simpleName);
}
public boolean equals(Object o){
return o instanceof TypeDecl && simpleName.equals(((TypeDecl)o).simpleName);
}
public Collection<FieldDecl> getBooleanFields() {
return booleanFields;
}
@ -164,156 +152,4 @@ public class TypeDecl implements Comparable<TypeDecl>{
stringFields.addAll(decl.stringFields);
}
public static class ConstructorDecl{
private Collection<ParameterDecl> parameters = Collections.emptyList();
public ConstructorDecl(Collection<ParameterDecl> params){
parameters = params;
}
public ConstructorDecl(ConstructorDeclaration co) {
parameters = new ArrayList<ParameterDecl>(co.getParameters().size());
for (ParameterDeclaration pa : co.getParameters()){
parameters.add(new ParameterDecl(pa));
}
}
public Collection<ParameterDecl> getParameters(){
return parameters;
}
}
public static class FieldDecl implements Comparable<FieldDecl>{
private final FieldType fieldType;
private String name, keyTypeName, typeName, simpleTypeName;
public FieldDecl(String name, String keyTypeName, String typeName,
String simpleTypeName, FieldType fieldType){
this.name = name;
this.keyTypeName = keyTypeName;
this.typeName = typeName;
this.simpleTypeName = simpleTypeName;
this.fieldType = fieldType;
}
public FieldDecl(FieldDeclaration field) {
name = field.getSimpleName();
String type = field.getType().toString();
if (!primitiveTypes.containsKey(type)){
typeName = field.getType().toString();
if (typeName.contains("<")){
typeName = typeName.substring(typeName.lastIndexOf('<')+1, typeName.length()-1);
if (typeName.contains(",")){
keyTypeName = typeName.substring(0, typeName.indexOf(','));
typeName = typeName.substring(keyTypeName.length()+1);
if (forType(typeName) == FieldType.ENTITY){
fieldType = FieldType.ENTITYMAP;
}else{
fieldType = FieldType.SIMPLEMAP;
}
}else{
if (forType(typeName) == FieldType.ENTITY){
fieldType = FieldType.ENTITYCOLLECTION;
}else{
fieldType = FieldType.SIMPLECOLLECTION;
}
}
}else{
fieldType = forType(typeName);
}
simpleTypeName = typeName.substring(typeName.lastIndexOf('.')+1);
}else{
Class<?> cl = primitiveTypes.get(type);
typeName = cl.getName();
simpleTypeName = cl.getSimpleName();
fieldType = forType(cl.getName());
}
}
public int compareTo(FieldDecl o) {
return name.compareTo(o.name);
}
public boolean equals(Object o){
return o instanceof FieldDecl && name.equals(((FieldDecl)o).name);
}
private FieldType forType(String cl){
if (cl.equals(Boolean.class.getName())) return FieldType.BOOLEAN;
else if (cl.equals(String.class.getName())) return FieldType.STRING;
else if (cl.startsWith("java")) return FieldType.SIMPLE;
else return FieldType.ENTITY;
}
public FieldType getFieldType(){
return fieldType;
}
public String getName(){
return name;
}
public String getSimpleTypeName(){
return simpleTypeName;
}
public String getKeyTypeName(){
return keyTypeName;
}
public String getTypeName(){
return typeName;
}
public int hashCode(){
return name.hashCode();
}
}
public enum FieldType{
BOOLEAN,
ENTITY, ENTITYCOLLECTION, ENTITYMAP,
SIMPLE, SIMPLECOLLECTION, SIMPLEMAP,
STRING
}
public static class ParameterDecl implements Comparable<ParameterDecl>{
private final String name, typeName;
public ParameterDecl(String name, String typeName){
this.name = name;
this.typeName = typeName;
}
public ParameterDecl(ParameterDeclaration pa) {
name = pa.getSimpleName();
String type = pa.getType().toString();
if (primitiveTypes.containsKey(type)){
typeName = primitiveTypes.get(type).getSimpleName();
}else{
typeName = pa.getType().toString();
}
}
public int compareTo(ParameterDecl o) {
return name.compareTo(o.name);
}
public boolean equals(Object o){
return o instanceof ParameterDecl && name.equals(((ParameterDecl)o).name);
}
public String getName(){
return name;
}
public String getTypeName(){
return typeName;
}
public int hashCode(){
return name.hashCode();
}
}
}

View File

@ -157,12 +157,8 @@ public class HibernateProcessor implements AnnotationProcessor {
}
public void process() {
if (!"".equals(destClass)){
createDomainClasses();
}
if (!"".equals(dtoClass)){
createDTOClasses();
}
if (!"".equals(destClass)) createDomainClasses();
if (!"".equals(dtoClass)) createDTOClasses();
}
private void serialize(File file, String template, Map<String,Object> model){

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.util;
import java.util.Iterator;
import com.mysema.query.apt.FieldType;
import com.sun.mirror.type.*;
import com.sun.mirror.util.SimpleTypeVisitor;
/**
* TypeVisitorUtil provides
*
* @author tiwe
* @version $Id$
*/
public class TypeInfo {
private FieldType fieldType;
private String simpleName, fullName, keyTypeName;
private final TypeInfoVisitor visitor = new TypeInfoVisitor();
public TypeInfo(TypeMirror type){
type.accept(visitor);
if (fieldType == null){
fieldType = FieldType.ENTITY;
}
if (fullName == null){
fullName = type.toString();
}
if (simpleName == null){
simpleName = fullName.substring(fullName.lastIndexOf('.')+1);
}
}
public FieldType getFieldType() {
return fieldType;
}
public String getFullName() {
return fullName;
}
public String getKeyTypeName() {
return keyTypeName;
}
public String getSimpleName() {
return simpleName;
}
public String getValueTypeName() {
return fullName;
}
public String toString(){
return fullName;
}
private class TypeInfoVisitor extends SimpleTypeVisitor{
public void visitAnnotationType(AnnotationType arg0) {
//
}
public void visitArrayType(ArrayType arg0) {
TypeInfo valueInfo = new TypeInfo(arg0.getComponentType());
fullName = valueInfo.getFullName();
if (valueInfo.fieldType == FieldType.ENTITY){
fieldType = FieldType.ENTITYCOLLECTION;
}else{
fieldType = FieldType.SIMPLECOLLECTION;
}
}
public void visitClassType(ClassType arg0) {
fullName = arg0.toString();
if (fullName.equals(String.class.getName())){
fieldType = FieldType.STRING;
}else if (fullName.equals(Boolean.class.getName())){
fieldType = FieldType.BOOLEAN;
}else if (fullName.startsWith("java")){
fieldType = FieldType.SIMPLE;
}
}
public void visitEnumType(EnumType arg0) {
fieldType = FieldType.SIMPLE;
}
public void visitInterfaceType(InterfaceType arg0) {
Iterator<TypeMirror> i = arg0.getActualTypeArguments().iterator();
// map
if (arg0.getActualTypeArguments().size() == 2){
TypeInfo keyInfo = new TypeInfo(i.next());
keyTypeName = keyInfo.getFullName();
TypeInfo valueInfo = new TypeInfo(i.next());
fullName = valueInfo.getFullName();
if (valueInfo.fieldType == FieldType.ENTITY){
fieldType = FieldType.ENTITYMAP;
}else{
fieldType = FieldType.SIMPLEMAP;
}
// collection
}else{
TypeInfo valueInfo = new TypeInfo(i.next());
fullName = valueInfo.getFullName();
if (valueInfo.fieldType == FieldType.ENTITY){
fieldType = FieldType.ENTITYCOLLECTION;
}else{
fieldType = FieldType.SIMPLECOLLECTION;
}
}
}
public void visitPrimitiveType(PrimitiveType arg0) {
Class<?> cl = null;
switch (arg0.getKind()){
case BOOLEAN: cl = Boolean.class; break;
case BYTE: cl = Byte.class; break;
case CHAR: cl = Character.class; break;
case DOUBLE: cl = Double.class; break;
case FLOAT: cl = Float.class; break;
case INT: cl = Integer.class; break;
case LONG: cl = Long.class; break;
case SHORT: cl = Short.class; break;
}
if (cl.equals(Boolean.class)){
fieldType = FieldType.BOOLEAN;
}else{
fieldType = FieldType.SIMPLE;
}
fullName = cl.getName();
simpleName = cl.getSimpleName();
}
}
}

View File

@ -1,4 +1,3 @@
<#assign reserved = ["isnull", "isnotnull", "getType", "getMetadata", "toString", "hashCode", "getClass", "notify", "notifyAll", "wait"]>
package ${package};
import static com.mysema.query.grammar.HqlGrammar.*;
@ -9,6 +8,7 @@ import static com.mysema.query.grammar.Types.*;
*
*/
public class ${classSimpleName} {
<#list dtoTypes as decl>
public static final class ${pre}${decl.simpleName} extends Constructor<${decl.name}>{
<#list decl.constructors as co>

View File

@ -8,9 +8,7 @@ import java.util.Map;
import org.junit.Test;
import com.mysema.query.apt.FreeMarkerSerializer;
import com.mysema.query.apt.TypeDecl;
import com.mysema.query.apt.TypeDecl.FieldType;
import com.mysema.query.apt.*;
import freemarker.template.TemplateException;
@ -47,11 +45,10 @@ public class HibernateProcessorTest {
private TypeDecl createTypeDecl() {
TypeDecl typeDecl = new TypeDecl("com.mysema.query.DomainSuperClass","com.mysema.query.DomainClass","DomainClass");
TypeDecl.FieldDecl field = new TypeDecl.FieldDecl("field",null,"java.lang.String","java.lang.String",FieldType.STRING);
FieldDecl field = new FieldDecl("field",null,"java.lang.String","java.lang.String",FieldType.STRING);
typeDecl.addField(field);
TypeDecl.ParameterDecl param = new TypeDecl.ParameterDecl("name","java.lang.String");
TypeDecl.ConstructorDecl constructor = new TypeDecl.ConstructorDecl(Collections.singleton(param));
typeDecl.addConstructor(constructor);
ParameterDecl param = new ParameterDecl("name","java.lang.String");
typeDecl.addConstructor( new ConstructorDecl(Collections.singleton(param)));
return typeDecl;
}
}