From 0df7d7d5599d7dda446a6d312ac4c642f7e55d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Tue, 11 Mar 2008 19:04:05 +0000 Subject: [PATCH] improved type derivation --- .../com/mysema/query/apt/ConstructorDecl.java | 40 ++++ .../java/com/mysema/query/apt/FieldDecl.java | 73 ++++++++ .../java/com/mysema/query/apt/FieldType.java | 18 ++ .../com/mysema/query/apt/ParameterDecl.java | 49 +++++ .../java/com/mysema/query/apt/TypeDecl.java | 172 +----------------- .../apt/hibernate/HibernateProcessor.java | 8 +- .../com/mysema/query/apt/util/TypeInfo.java | 145 +++++++++++++++ .../main/resources/querydsl-dto-hibernate.ftl | 2 +- .../apt/hibernate/HibernateProcessorTest.java | 11 +- 9 files changed, 336 insertions(+), 182 deletions(-) create mode 100644 querydsl-apt/src/main/java/com/mysema/query/apt/ConstructorDecl.java create mode 100644 querydsl-apt/src/main/java/com/mysema/query/apt/FieldDecl.java create mode 100644 querydsl-apt/src/main/java/com/mysema/query/apt/FieldType.java create mode 100644 querydsl-apt/src/main/java/com/mysema/query/apt/ParameterDecl.java create mode 100644 querydsl-apt/src/main/java/com/mysema/query/apt/util/TypeInfo.java diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/ConstructorDecl.java b/querydsl-apt/src/main/java/com/mysema/query/apt/ConstructorDecl.java new file mode 100644 index 000000000..e7225c546 --- /dev/null +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/ConstructorDecl.java @@ -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 parameters; + + public ConstructorDecl(Collection params) { + parameters = params; + } + + public ConstructorDecl(ConstructorDeclaration co) { + parameters = new ArrayList(co.getParameters().size()); + for (ParameterDeclaration pa : co.getParameters()) { + parameters.add(new ParameterDecl(pa)); + } + } + + public Collection getParameters() { + return parameters; + } + +} \ No newline at end of file diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/FieldDecl.java b/querydsl-apt/src/main/java/com/mysema/query/apt/FieldDecl.java new file mode 100644 index 000000000..8221d0db5 --- /dev/null +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/FieldDecl.java @@ -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{ + + 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(); + } + +} \ No newline at end of file diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/FieldType.java b/querydsl-apt/src/main/java/com/mysema/query/apt/FieldType.java new file mode 100644 index 000000000..f0a238f4a --- /dev/null +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/FieldType.java @@ -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 +} \ No newline at end of file diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/ParameterDecl.java b/querydsl-apt/src/main/java/com/mysema/query/apt/ParameterDecl.java new file mode 100644 index 000000000..d83ae16dd --- /dev/null +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/ParameterDecl.java @@ -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 { + 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(); + } +} \ No newline at end of file diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeDecl.java b/querydsl-apt/src/main/java/com/mysema/query/apt/TypeDecl.java index 5712bbd36..d116d8457 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeDecl.java +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/TypeDecl.java @@ -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{ - - private static Map> primitiveTypes = new HashMap>(); - - 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 booleanFields = new TreeSet(); // not sorted @@ -83,7 +69,7 @@ public class TypeDecl implements Comparable{ } 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{ 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 getBooleanFields() { return booleanFields; } @@ -164,156 +152,4 @@ public class TypeDecl implements Comparable{ stringFields.addAll(decl.stringFields); } - public static class ConstructorDecl{ - private Collection parameters = Collections.emptyList(); - public ConstructorDecl(Collection params){ - parameters = params; - } - public ConstructorDecl(ConstructorDeclaration co) { - parameters = new ArrayList(co.getParameters().size()); - for (ParameterDeclaration pa : co.getParameters()){ - parameters.add(new ParameterDecl(pa)); - } - } - - public Collection getParameters(){ - return parameters; - } - - } - - public static class FieldDecl implements Comparable{ - 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{ - 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(); - } - } - - - } \ No newline at end of file diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateProcessor.java index c44763f39..54786b233 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateProcessor.java +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateProcessor.java @@ -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 model){ diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/util/TypeInfo.java b/querydsl-apt/src/main/java/com/mysema/query/apt/util/TypeInfo.java new file mode 100644 index 000000000..b2e2ec25a --- /dev/null +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/util/TypeInfo.java @@ -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 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(); + + } + + } + +} diff --git a/querydsl-apt/src/main/resources/querydsl-dto-hibernate.ftl b/querydsl-apt/src/main/resources/querydsl-dto-hibernate.ftl index 3936f67c8..bfcb8df2a 100644 --- a/querydsl-apt/src/main/resources/querydsl-dto-hibernate.ftl +++ b/querydsl-apt/src/main/resources/querydsl-dto-hibernate.ftl @@ -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> diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/hibernate/HibernateProcessorTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/hibernate/HibernateProcessorTest.java index cd1ed19ba..60eab831e 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/hibernate/HibernateProcessorTest.java +++ b/querydsl-apt/src/test/java/com/mysema/query/apt/hibernate/HibernateProcessorTest.java @@ -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; } }