This commit is contained in:
Timo Westkämper 2009-05-28 14:09:54 +00:00
parent 2e92db39d5
commit 970e530d08
6 changed files with 344 additions and 45 deletions

View File

@ -1,4 +1,7 @@
/*
*
*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
@ -18,41 +21,41 @@ import org.apache.commons.lang.StringUtils;
* @author tiwe
* @version $Id$
*/
public class Type implements Comparable<Type> {
public class ClassModel implements Comparable<ClassModel> {
private Set<Field> booleanFields = new TreeSet<Field>();
private Set<FieldModel> booleanFields = new TreeSet<FieldModel>();
private Set<Field> comparableFields = new TreeSet<Field>();
private Set<FieldModel> comparableFields = new TreeSet<FieldModel>();
private Set<Constructor> constructors = new HashSet<Constructor>();
private Set<ConstructorModel> constructors = new HashSet<ConstructorModel>();
private Set<Field> entityCollections = new TreeSet<Field>();
private Set<FieldModel> entityCollections = new TreeSet<FieldModel>();
private Set<Field> entityFields = new TreeSet<Field>();
private Set<FieldModel> entityFields = new TreeSet<FieldModel>();
private Set<Field> entityLists = new TreeSet<Field>();
private Set<FieldModel> entityLists = new TreeSet<FieldModel>();
private Set<Field> entityMaps = new TreeSet<Field>();
private Set<FieldModel> entityMaps = new TreeSet<FieldModel>();
private Set<Field> numericFields = new TreeSet<Field>();
private Set<FieldModel> numericFields = new TreeSet<FieldModel>();
private Set<Field> simpleCollections = new TreeSet<Field>();
private Set<FieldModel> simpleCollections = new TreeSet<FieldModel>();
private Set<Field> simpleFields = new TreeSet<Field>();
private Set<FieldModel> simpleFields = new TreeSet<FieldModel>();
private Set<Field> simpleLists = new TreeSet<Field>();
private Set<FieldModel> simpleLists = new TreeSet<FieldModel>();
private Set<Field> simpleMaps = new TreeSet<Field>();
private Set<FieldModel> simpleMaps = new TreeSet<FieldModel>();
private String simpleName, uncapSimpleName, name, packageName;
private int escapeSuffix = 1;
private Set<Field> stringFields = new TreeSet<Field>();
private Set<FieldModel> stringFields = new TreeSet<FieldModel>();
private String superType;
public Type(String superType, String packageName, String name,
public ClassModel(String superType, String packageName, String name,
String simpleName) {
this.superType = superType;
this.packageName = packageName;
@ -61,11 +64,11 @@ public class Type implements Comparable<Type> {
this.uncapSimpleName = StringUtils.uncapitalize(simpleName);
}
public void addConstructor(Constructor co) {
public void addConstructor(ConstructorModel co) {
constructors.add(co);
}
public void addField(Field fieldDecl) {
public void addField(FieldModel fieldDecl) {
validateField(fieldDecl);
switch (fieldDecl.getFieldType()) {
case BOOLEAN:
@ -107,47 +110,46 @@ public class Type implements Comparable<Type> {
}
}
private Field validateField(Field field) {
private FieldModel validateField(FieldModel field) {
if (field.getName().equals(this.uncapSimpleName)) {
uncapSimpleName = StringUtils.uncapitalize(simpleName)
+ (escapeSuffix++);
uncapSimpleName = StringUtils.uncapitalize(simpleName)+ (escapeSuffix++);
}
return field;
}
public int compareTo(Type o) {
public int compareTo(ClassModel o) {
return simpleName.compareTo(o.simpleName);
}
public boolean equals(Object o) {
return o instanceof Type && simpleName.equals(((Type) o).simpleName);
return o instanceof ClassModel && simpleName.equals(((ClassModel) o).simpleName);
}
public Collection<Field> getBooleanFields() {
public Collection<FieldModel> getBooleanFields() {
return booleanFields;
}
public Collection<Field> getComparableFields() {
public Collection<FieldModel> getComparableFields() {
return comparableFields;
}
public Collection<Constructor> getConstructors() {
public Collection<ConstructorModel> getConstructors() {
return constructors;
}
public Collection<Field> getEntityCollections() {
public Collection<FieldModel> getEntityCollections() {
return entityCollections;
}
public Collection<Field> getEntityFields() {
public Collection<FieldModel> getEntityFields() {
return entityFields;
}
public Collection<Field> getEntityLists() {
public Collection<FieldModel> getEntityLists() {
return entityLists;
}
public Collection<Field> getEntityMaps() {
public Collection<FieldModel> getEntityMaps() {
return entityMaps;
}
@ -155,7 +157,7 @@ public class Type implements Comparable<Type> {
return name;
}
public Collection<Field> getNumericFields() {
public Collection<FieldModel> getNumericFields() {
return numericFields;
}
@ -163,19 +165,19 @@ public class Type implements Comparable<Type> {
return packageName;
}
public Collection<Field> getSimpleCollections() {
public Collection<FieldModel> getSimpleCollections() {
return simpleCollections;
}
public Collection<Field> getSimpleFields() {
public Collection<FieldModel> getSimpleFields() {
return simpleFields;
}
public Collection<Field> getSimpleLists() {
public Collection<FieldModel> getSimpleLists() {
return simpleLists;
}
public Collection<Field> getSimpleMaps() {
public Collection<FieldModel> getSimpleMaps() {
return simpleMaps;
}
@ -187,7 +189,7 @@ public class Type implements Comparable<Type> {
return uncapSimpleName;
}
public Collection<Field> getStringFields() {
public Collection<FieldModel> getStringFields() {
return stringFields;
}
@ -199,7 +201,7 @@ public class Type implements Comparable<Type> {
return name.hashCode();
}
public void include(Type decl) {
public void include(ClassModel decl) {
addAll(booleanFields, decl.booleanFields);
addAll(entityCollections, decl.entityCollections);
addAll(entityFields, decl.entityFields);
@ -214,8 +216,8 @@ public class Type implements Comparable<Type> {
addAll(stringFields, decl.stringFields);
}
private void addAll(Set<Field> target, Set<Field> source) {
for (Field field : source) {
private void addAll(Set<FieldModel> target, Set<FieldModel> source) {
for (FieldModel field : source) {
target.add(validateField(field));
}
}

View File

@ -0,0 +1,250 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.codegen;
import java.lang.reflect.Type;
import java.util.Locale;
import org.apache.commons.lang.ClassUtils;
import com.mysema.query.annotations.Literal;
import com.mysema.query.util.TypeUtil;
/**
*
* @author tiwe
*
*/
public class ClassModelFactory {
private FieldType fieldType;
private String simpleName, fullName, packageName = "", keyTypeName;
public ClassModelFactory(Class<?> cl) {
this(cl, cl);
}
public static ClassModel createType(Class<?> clazz) {
ClassModel type = new ClassModel(clazz.getSuperclass().getName(), clazz
.getPackage().getName(), clazz.getName(), clazz.getSimpleName());
for (java.lang.reflect.Field f : clazz.getDeclaredFields()) {
ClassModelFactory typeHelper = new ClassModelFactory(f.getType(), f.getGenericType());
FieldModel field = new FieldModel(
f.getName(),
typeHelper.getKeyTypeName(), typeHelper.getPackageName(),
typeHelper.getFullName(), typeHelper.getSimpleName(),
typeHelper.getFieldType());
type.addField(field);
}
return type;
}
public ClassModelFactory(Class<?> cl, java.lang.reflect.Type genericType) {
if (cl == null) {
throw new IllegalArgumentException("cl was null");
} else if (cl.isArray()) {
visitArrayType(cl);
} else if (cl.isEnum()) {
visitEnumType(cl);
} else if (cl.isPrimitive()) {
visitPrimitiveType(cl);
} else if (cl.isInterface()) {
visitInterfaceType(cl, genericType);
} else {
visitClassType(cl);
}
if (fullName == null) {
fullName = cl.getName();
}
setDefaults();
}
public FieldType getFieldType() {
return fieldType;
}
public String getFullName() {
return fullName;
}
public String getKeyTypeName() {
return keyTypeName;
}
public String getPackageName() {
return packageName;
}
public String getSimpleName() {
return simpleName;
}
public String getValueTypeName() {
return fullName;
}
private void handleCollectionInterface(Class<?> type, Type genericType) {
ClassModelFactory valueInfo = new ClassModelFactory(TypeUtil.getTypeParameter(genericType, 0));
handleCollection(valueInfo);
}
private void handleCollection(ClassModelFactory valueInfo) {
fullName = valueInfo.getFullName();
packageName = valueInfo.getPackageName();
if (valueInfo.fieldType == FieldType.ENTITY) {
fieldType = FieldType.ENTITYCOLLECTION;
} else {
fieldType = FieldType.SIMPLECOLLECTION;
}
}
private void handleList(ClassModelFactory valueInfo) {
fullName = valueInfo.getFullName();
packageName = valueInfo.getPackageName();
if (valueInfo.fieldType == FieldType.ENTITY) {
fieldType = FieldType.ENTITYLIST;
} else {
fieldType = FieldType.SIMPLELIST;
}
}
private void handleListInterface(Class<?> type, Type genericType) {
ClassModelFactory valueInfo = new ClassModelFactory(TypeUtil.getTypeParameter(genericType, 0));
handleList(valueInfo);
}
private void handleMapInterface(Class<?> type, Type genericType) {
ClassModelFactory keyInfo = new ClassModelFactory(TypeUtil.getTypeParameter(genericType, 0));
ClassModelFactory valueInfo = new ClassModelFactory(TypeUtil.getTypeParameter(genericType, 1));
handleMapInterface(keyInfo, valueInfo);
}
private void handleMapInterface(ClassModelFactory keyInfo, ClassModelFactory valueInfo) {
keyTypeName = keyInfo.getFullName();
fullName = valueInfo.getFullName();
packageName = valueInfo.getPackageName();
if (valueInfo.fieldType == FieldType.ENTITY) {
fieldType = FieldType.ENTITYMAP;
} else {
fieldType = FieldType.SIMPLEMAP;
}
}
private void setDefaults() {
if (fieldType == null) {
fieldType = FieldType.ENTITY;
}
if (simpleName == null) {
simpleName = fullName.substring(fullName.lastIndexOf('.') + 1);
}
}
public String toString() {
return fullName;
}
private void visitArrayComponentType(ClassModelFactory valueInfo) {
fullName = valueInfo.getFullName();
packageName = valueInfo.getPackageName();
if (valueInfo.fieldType == FieldType.ENTITY) {
fieldType = FieldType.ENTITYCOLLECTION;
} else {
fieldType = FieldType.SIMPLECOLLECTION;
}
}
public void visitArrayType(Class<?> clazz) {
ClassModelFactory valueInfo = new ClassModelFactory(clazz.getComponentType());
visitArrayComponentType(valueInfo);
}
public void visitClassType(Class<?> type) {
fullName = type.getName();
packageName = type.getPackage().getName();
if (type.equals(String.class)) {
fieldType = FieldType.STRING;
} else if (type.equals(Boolean.class)) {
fieldType = FieldType.BOOLEAN;
} else if (type.equals(Locale.class) || type.equals(Class.class)
|| type.equals(Object.class)) {
fieldType = FieldType.SIMPLE;
} else if (isNumericSupported(fullName)
&& Number.class.isAssignableFrom(type)) {
fieldType = FieldType.NUMERIC;
} else if (type.getAnnotation(Literal.class) != null) {
if (Comparable.class.isAssignableFrom(type)) {
fieldType = FieldType.COMPARABLE;
} else {
fieldType = FieldType.SIMPLE;
}
} else if (isComparableSupported(fullName)
&& Comparable.class.isAssignableFrom(type)) {
fieldType = FieldType.COMPARABLE;
} else if (asSimpleType(fullName)) {
fieldType = FieldType.SIMPLE;
}
}
private boolean isNumericSupported(String fullName) {
return isComparableSupported(fullName);
}
private boolean isComparableSupported(String fullName) {
return fullName.startsWith("java.") || fullName.startsWith("javax.")
|| fullName.startsWith("org.joda.time");
}
private boolean asSimpleType(String fullName) {
return false;
}
public void visitEnumType(Class<?> type) {
fieldType = FieldType.SIMPLE;
}
public void visitInterfaceType(Class<?> type, Type genericType) {
if (java.util.Map.class.isAssignableFrom(type)) {
handleMapInterface(type, genericType);
} else if (java.util.List.class.isAssignableFrom(type)) {
handleListInterface(type, genericType);
} else if (java.util.Collection.class.isAssignableFrom(type)) {
handleCollectionInterface(type, genericType);
}
}
public void visitPrimitiveType(Class<?> cl) {
visitPrimitiveWrapperType(ClassUtils.primitiveToWrapper(cl));
}
private void visitPrimitiveWrapperType(Class<?> cl) {
if (cl.equals(Boolean.class)) {
fieldType = FieldType.BOOLEAN;
} else if (Number.class.isAssignableFrom(cl)) {
fieldType = FieldType.NUMERIC;
} else if (Comparable.class.isAssignableFrom(cl)) {
fieldType = FieldType.COMPARABLE;
} else {
fieldType = FieldType.SIMPLE;
}
fullName = cl.getName();
simpleName = cl.getSimpleName();
}
}

View File

@ -13,10 +13,10 @@ import java.util.Collection;
* @author tiwe
* @version $Id$
*/
public class Constructor {
public class ConstructorModel {
private final Collection<Parameter> parameters;
public Constructor(Collection<Parameter> params) {
public ConstructorModel(Collection<Parameter> params) {
parameters = params;
}

View File

@ -11,7 +11,7 @@ package com.mysema.query.codegen;
* @author tiwe
* @version $Id$
*/
public class Field implements Comparable<Field> {
public class FieldModel implements Comparable<FieldModel> {
/**
* The Enum Type.
@ -37,7 +37,7 @@ public class Field implements Comparable<Field> {
* simple type name (local)
* @param fieldType
*/
public Field(String name, String keyTypeName,
public FieldModel(String name, String keyTypeName,
String typePackage, String typeName, String simpleTypeName,
FieldType fieldType) {
this.name = name;
@ -48,12 +48,12 @@ public class Field implements Comparable<Field> {
this.fieldType = fieldType;
}
public int compareTo(Field o) {
public int compareTo(FieldModel o) {
return name.compareTo(o.name);
}
public boolean equals(Object o) {
return o instanceof Field && name.equals(((Field) o).name);
return o instanceof FieldModel && name.equals(((FieldModel) o).name);
}
public FieldType getFieldType() {

View File

@ -5,6 +5,22 @@
*/
package com.mysema.query.codegen;
/**
*
* @author tiwe
*
*/
public enum FieldType {
BOOLEAN, COMPARABLE, ENTITY, ENTITYLIST, ENTITYCOLLECTION, ENTITYMAP, NUMERIC, SIMPLE, SIMPLELIST, SIMPLECOLLECTION, SIMPLEMAP, STRING
BOOLEAN,
COMPARABLE,
ENTITY,
ENTITYLIST,
ENTITYCOLLECTION,
ENTITYMAP,
NUMERIC,
SIMPLE,
SIMPLELIST,
SIMPLECOLLECTION,
SIMPLEMAP,
STRING
}

View File

@ -0,0 +1,31 @@
package com.mysema.query.util;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
public class TypeUtil {
public static Class<?> getTypeParameter(java.lang.reflect.Type type, int index) {
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
java.lang.reflect.Type[] targs = ptype.getActualTypeArguments();
if (targs[index] instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) targs[index];
return (Class<?>) wildcardType.getUpperBounds()[0];
} else if (targs[index] instanceof TypeVariable) {
return (Class<?>) ((TypeVariable) targs[index]).getGenericDeclaration();
} else if (targs[index] instanceof ParameterizedType) {
return (Class<?>) ((ParameterizedType) targs[index]).getRawType();
} else {
try {
return (Class<?>) targs[index];
} catch (Exception e) {
e.printStackTrace();
}
}
}
return null;
}
}