This commit is contained in:
Timo Westkämper 2009-05-28 11:19:15 +00:00
parent aa2fe22330
commit 08726d3af3
31 changed files with 2074 additions and 0 deletions

87
querydsl-apt-jdk5/pom.xml Normal file
View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-root</artifactId>
<version>0.3.10-SNAPSHOT</version>
</parent>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<name>Querydsl - APT support</name>
<description>source code generation for querydsl</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.12</version>
<!-- license : BSD-style license -->
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
<!-- license : Apache License 2.0 -->
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/assembly/one-jar.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>default-tools.jar</id>
<activation>
<property>
<name>java.vendor</name>
<value>Sun Microsystems Inc.</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.4.2</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,27 @@
<assembly>
<id>one-jar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory />
<unpack>true</unpack>
</dependencySet>
</dependencySets>
<!--
<files>
<file>
<source>src/assembly/plugin.xml</source>
<outputDirectory />
</file>
</files>
-->
<fileSets>
<fileSet>
<directory>target/classes</directory>
<outputDirectory />
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin
id="com.mysema.querydsl-apt"
name="Querydsl APT Plug-in"
version="1.0.0"
provider-name="Mysema.com">
<runtime>
<library name="querydsl-apt.jar"/>
</runtime>
<requires>
<import plugin="org.eclipse.core.runtime"/>
<import plugin="org.eclipse.jdt.apt.core"/>
</requires>
<extension point="org.eclipse.jdt.apt.core.annotationProcessorFactory">
<factories enableDefault="true">
<factory class="com.mysema.query.apt.APTFactory">
</factory>
</factories>
</extension>
</plugin>

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import static com.mysema.query.apt.Constants.*;
import static com.mysema.query.apt.APTUtils.getString;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import com.mysema.query.apt.general.QuerydslProcessor;
import com.mysema.query.apt.jdo.JDOProcessor;
import com.mysema.query.apt.jpa.JPAProcessor;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
/**
* APTFactory is the main APT factory for Querydsl code generation
*
* @author tiwe
* @version $Id$
*/
public class APTFactory implements AnnotationProcessorFactory {
private static final Collection<String> supportedAnnotations = Arrays
.asList(QD_ENTITY, QD_DTO, JDO_ENTITY, JPA_ENTITY, JPA_SUPERCLASS,
JPA_EMBEDDABLE);
private static final Collection<String> supportedOptions = Collections
.emptySet();
public Collection<String> supportedAnnotationTypes() {
return supportedAnnotations;
}
public Collection<String> supportedOptions() {
return supportedOptions;
}
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
String profile = getString(env.getOptions(), "profile", "jpa");
if ("jpa".equals(profile)) {
return new JPAProcessor(env);
} else if ("jdo".equals(profile)) {
return new JDOProcessor(env);
} else if ("querydsl".equals(profile)) {
return new QuerydslProcessor(env);
} else {
throw new IllegalArgumentException("Unknown profile " + profile);
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import java.io.*;
import java.util.Map;
import org.apache.commons.io.FileUtils;
/**
* APUtils provides utilities for APT code generation in Querydsl
*
* @author tiwe
* @version $Id$
*/
public class APTUtils {
public static Writer writerFor(File file) {
if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
System.err.println("Folder " + file.getParent()
+ " could not be created");
}
try {
return new OutputStreamWriter(new FileOutputStream(file));
} catch (FileNotFoundException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public static String getFileContent(Map<String, String> options,
String key, String defaultValue) throws IOException {
String path = getString(options, key, null);
if (path != null) {
return FileUtils.readFileToString(new File(path), "UTF-8");
} else {
return "";
}
}
public static String getString(Map<String, String> options, String key,
String defaultValue) {
String prefix = "-A" + key + "=";
for (Map.Entry<String, String> entry : options.entrySet()) {
if (entry.getKey().startsWith(prefix)) {
return entry.getKey().substring(prefix.length());
} else if (entry.getKey().equals(key)) {
return entry.getValue();
}
}
return defaultValue;
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import com.mysema.query.annotations.DTO;
import com.mysema.query.annotations.Entity;
/**
* Constants provides constants for use in Querydsl APT
*
* @author tiwe
* @version $Id$
*/
public final class Constants {
private Constants() {
}
public static final String QD_ENTITY = Entity.class.getName();
public static final String QD_DTO = DTO.class.getName();
// JDO
public static final String JDO_ENTITY = "javax.jdo.annotations.PersistenceCapable";
// JPA
public static final String JPA_SUPERCLASS = "javax.persistence.MappedSuperclass";
public static final String JPA_ENTITY = "javax.persistence.Entity";
public static final String JPA_EMBEDDABLE = "javax.persistence.Embeddable";
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateException;
/**
* FreeMarkerSerializer provides FreeMarker based serialization of querydsl
* types to Java sources
*
* @author tiwe
* @version $Id$
*/
public class FreeMarkerSerializer {
private static final Configuration cfg;
static {
cfg = new Configuration();
cfg.setClassForTemplateLoading(FreeMarkerSerializer.class, "/");
cfg.setObjectWrapper(new DefaultObjectWrapper());
}
private final String templateLocation;
public FreeMarkerSerializer(String template) {
if (template == null)
throw new IllegalArgumentException("template was null");
templateLocation = template;
}
public void serialize(Map<String, Object> model, Writer writer)
throws IOException, TemplateException {
cfg.getTemplate(templateLocation).process(model, writer);
writer.flush();
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import com.mysema.query.apt.model.Constructor;
import com.mysema.query.apt.model.Parameter;
import com.mysema.query.apt.model.Type;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.ConstructorDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
import com.sun.mirror.util.SimpleDeclarationVisitor;
/**
* DTOVisitor is a visitor for DTO types.
*
* @author tiwe
* @version $Id$
*/
public class DefaultDTOVisitor extends SimpleDeclarationVisitor {
final Set<Type> types = new TreeSet<Type>();
private Type last;
@Override
public void visitClassDeclaration(ClassDeclaration d) {
String simpleName = d.getSimpleName();
String name = d.getQualifiedName();
String packageName = d.getPackage().getQualifiedName();
String superType = d.getSuperclass().getDeclaration()
.getQualifiedName();
last = new Type(superType, packageName, name, simpleName);
types.add(last);
}
@Override
public void visitConstructorDeclaration(ConstructorDeclaration d) {
List<Parameter> parameters = new ArrayList<Parameter>(d.getParameters()
.size());
for (ParameterDeclaration pa : d.getParameters()) {
String name = pa.getSimpleName();
String typeName = new TypeHelper(pa.getType()).getFullName();
parameters.add(new Parameter(name, typeName));
}
last.addConstructor(new Constructor(parameters));
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.mysema.query.apt.model.Field;
import com.mysema.query.apt.model.FieldType;
import com.mysema.query.apt.model.Type;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.InterfaceDeclaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.Modifier;
import com.sun.mirror.util.SimpleDeclarationVisitor;
/**
* DefaultEntityVisitor is a visitor for entity and embeddable types.
*
* @author tiwe
* @version $Id$
*/
public class DefaultEntityVisitor extends SimpleDeclarationVisitor {
private Type last;
public final Map<String, Type> types = new HashMap<String, Type>();
private void addField(String originalName, TypeHelper typeInfo) {
String name = FieldHelper.javaSafe(originalName);
String realName = FieldHelper.realName(originalName);
String keyTypeName = typeInfo.getKeyTypeName();
String typeName = typeInfo.getFullName();
String typePackage = typeInfo.getPackageName();
String simpleTypeName = typeInfo.getSimpleName();
FieldType fieldType = typeInfo.getFieldType();
last.addField(new Field(name, realName, keyTypeName, typePackage,
typeName, simpleTypeName, fieldType));
}
@Override
public void visitClassDeclaration(ClassDeclaration d) {
String simpleName = d.getSimpleName();
String name = d.getQualifiedName();
String packageName = d.getPackage().getQualifiedName();
String superType = d.getSuperclass().getDeclaration()
.getQualifiedName();
last = new Type(superType, packageName, name, simpleName);
types.put(d.getQualifiedName(), last);
}
@Override
public void visitFieldDeclaration(FieldDeclaration d) {
if (!d.getModifiers().contains(Modifier.STATIC)
&& !d.getModifiers().contains(Modifier.TRANSIENT)) {
addField(d.getSimpleName(), new TypeHelper(d.getType()));
}
}
@Override
public void visitInterfaceDeclaration(InterfaceDeclaration d) {
String simpleName = d.getSimpleName();
String name = d.getQualifiedName();
String packageName = d.getPackage().getQualifiedName();
String superType = null;
if (!d.getSuperinterfaces().isEmpty()) {
superType = d.getSuperinterfaces().iterator().next()
.getDeclaration().getQualifiedName();
}
last = new Type(superType, packageName, name, simpleName);
types.put(d.getQualifiedName(), last);
}
@Override
public void visitMethodDeclaration(MethodDeclaration d) {
if (!d.getModifiers().contains(Modifier.STATIC)) {
if (d.getParameters().isEmpty()) {
if (d.getSimpleName().startsWith("get")) {
String name = StringUtils.uncapitalize(d.getSimpleName()
.substring(3));
addField(name, new TypeHelper(d.getReturnType()));
} else if (d.getSimpleName().startsWith("is")) {
String name = StringUtils.uncapitalize(d.getSimpleName()
.substring(2));
addField(name, new TypeHelper(d.getReturnType()));
}
}
}
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
/**
* FieldHelper provides convenience methods for field name escaping
*
* @author tiwe
* @version $Id$
*/
public class FieldHelper {
public static String javaSafe(String name) {
// TODO : improve this
if (name.equals("private")) {
return "prvate";
} else if (name.equals("public")) {
return "pblic";
} else {
return name;
}
}
public static String realName(String name) {
// TODO : improve this
if (name.equals("prvate")) {
return "private";
} else if (name.equals("pblic")) {
return "public";
} else {
return name;
}
}
}

View File

@ -0,0 +1,190 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import static com.mysema.query.apt.APTUtils.getString;
import static com.mysema.query.apt.APTUtils.writerFor;
import static com.sun.mirror.util.DeclarationVisitors.NO_OP;
import static com.sun.mirror.util.DeclarationVisitors.getDeclarationScanner;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.mysema.query.apt.FreeMarkerSerializer;
import com.mysema.query.apt.model.Type;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.Declaration;
/**
* GeneralProcessor is the main processor for APT code generation.
*
* @author tiwe
* @version $Id$
*/
public abstract class GeneralProcessor implements AnnotationProcessor {
public static final FreeMarkerSerializer DOMAIN_OUTER_TMPL = new FreeMarkerSerializer(
"/domain-as-outer-classes.ftl"),
EMBEDDABLE_OUTER_TMPL = new FreeMarkerSerializer(
"/embeddable-as-outer-classes.ftl"),
DTO_OUTER_TMPL = new FreeMarkerSerializer(
"/dto-as-outer-classes.ftl");
protected final String namePrefix, targetFolder;
protected final AnnotationProcessorEnvironment env;
protected final String superClassAnnotation, domainAnnotation,
dtoAnnotation;
public GeneralProcessor(AnnotationProcessorEnvironment env,
String superClassAnnotation, String domainAnnotation,
String dtoAnnotation) {
this.env = env;
this.targetFolder = env.getOptions().get("-s");
this.namePrefix = getString(env.getOptions(), "namePrefix", "Q");
this.superClassAnnotation = superClassAnnotation;
this.domainAnnotation = domainAnnotation;
this.dtoAnnotation = dtoAnnotation;
}
private void addSupertypeFields(Type typeDecl,
Map<String, Type> entityTypes, Map<String, Type> mappedSupertypes) {
String stype = typeDecl.getSupertypeName();
Class<?> superClass = safeClassForName(stype);
if (entityTypes.containsKey(stype)
|| mappedSupertypes.containsKey(stype)) {
while (true) {
Type sdecl;
if (entityTypes.containsKey(stype)) {
sdecl = entityTypes.get(stype);
} else if (mappedSupertypes.containsKey(stype)) {
sdecl = mappedSupertypes.get(stype);
} else {
return;
}
typeDecl.include(sdecl);
stype = sdecl.getSupertypeName();
}
} else if (superClass != null && !superClass.equals(Object.class)) {
// TODO : recursively up ?
Type type = TypeFactory.createType(superClass);
// include fields of supertype
typeDecl.include(type);
}
}
private Class<?> safeClassForName(String stype) {
try {
return stype != null ? Class.forName(stype) : null;
} catch (ClassNotFoundException e) {
return null;
}
}
protected DefaultEntityVisitor createEntityVisitor() {
return new DefaultEntityVisitor();
}
protected DefaultDTOVisitor createDTOVisitor() {
return new DefaultDTOVisitor();
}
private void createDomainClasses() {
DefaultEntityVisitor superclassVisitor = createEntityVisitor();
// mapped superclass
AnnotationTypeDeclaration a;
Map<String, Type> mappedSupertypes;
if (superClassAnnotation != null) {
a = (AnnotationTypeDeclaration) env
.getTypeDeclaration(superClassAnnotation);
for (Declaration typeDecl : env.getDeclarationsAnnotatedWith(a)) {
typeDecl
.accept(getDeclarationScanner(superclassVisitor, NO_OP));
}
mappedSupertypes = superclassVisitor.types;
} else {
mappedSupertypes = new HashMap<String, Type>();
}
// domain types
DefaultEntityVisitor entityVisitor = createEntityVisitor();
a = (AnnotationTypeDeclaration) env
.getTypeDeclaration(domainAnnotation);
for (Declaration typeDecl : env.getDeclarationsAnnotatedWith(a)) {
typeDecl.accept(getDeclarationScanner(entityVisitor, NO_OP));
}
Map<String, Type> entityTypes = entityVisitor.types;
for (Type typeDecl : entityTypes.values()) {
addSupertypeFields(typeDecl, entityTypes, mappedSupertypes);
}
if (entityTypes.isEmpty()) {
env.getMessager().printNotice(
"No class generation for domain types");
} else {
serializeAsOuterClasses(entityTypes.values(), DOMAIN_OUTER_TMPL);
}
}
private void createDTOClasses() {
AnnotationTypeDeclaration a = (AnnotationTypeDeclaration) env
.getTypeDeclaration(dtoAnnotation);
DefaultDTOVisitor dtoVisitor = createDTOVisitor();
for (Declaration typeDecl : env.getDeclarationsAnnotatedWith(a)) {
typeDecl.accept(getDeclarationScanner(dtoVisitor, NO_OP));
}
if (dtoVisitor.types.isEmpty()) {
env.getMessager().printNotice("No class generation for DTO types");
} else {
serializeAsOuterClasses(dtoVisitor.types, DTO_OUTER_TMPL);
}
}
public void process() {
if (domainAnnotation != null) {
createDomainClasses();
}
if (dtoAnnotation != null) {
createDTOClasses();
}
}
protected void serializeAsOuterClasses(Collection<Type> entityTypes,
FreeMarkerSerializer serializer) {
// populate model
Map<String, Object> model = new HashMap<String, Object>();
model.put("pre", namePrefix);
for (Type type : entityTypes) {
String packageName = type.getPackageName();
model.put("package", packageName);
model.put("type", type);
model.put("classSimpleName", type.getSimpleName());
// serialize it
try {
String path = packageName.replace('.', '/') + "/" + namePrefix
+ type.getSimpleName() + ".java";
serializer.serialize(model, writerFor(new File(targetFolder,
path)));
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import static com.mysema.query.apt.Constants.*;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.MethodDeclaration;
/**
* QureydslProcessor provides Querydsl annotation handling support
*
* @author tiwe
* @version $Id$
*/
public class QuerydslProcessor extends GeneralProcessor {
public QuerydslProcessor(AnnotationProcessorEnvironment env) {
super(env, null, QD_ENTITY, QD_DTO);
}
@Override
protected DefaultEntityVisitor createEntityVisitor() {
return new DefaultEntityVisitor() {
@Override
public void visitMethodDeclaration(MethodDeclaration d) {
// skip property handling
}
};
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import com.mysema.query.apt.model.Field;
import com.mysema.query.apt.model.Type;
/**
* TypeFactory provides
*
* @author tiwe
* @version $Id$
*/
public class TypeFactory {
public static Type createType(Class<?> clazz) {
Type type = new Type(clazz.getSuperclass().getName(), clazz
.getPackage().getName(), clazz.getName(), clazz.getSimpleName());
for (java.lang.reflect.Field f : clazz.getDeclaredFields()) {
TypeHelper typeHelper = new TypeHelper(f.getType(), f
.getGenericType());
Field field = new Field(
FieldHelper.javaSafe(f.getName()), // name
FieldHelper.realName(f.getName()), // realName
typeHelper.getKeyTypeName(), typeHelper.getPackageName(),
typeHelper.getFullName(), typeHelper.getSimpleName(),
typeHelper.getFieldType());
type.addField(field);
}
return type;
}
// TODO : move this to common place
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;
}
}

View File

@ -0,0 +1,400 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.Locale;
import org.apache.commons.lang.ClassUtils;
import com.mysema.query.annotations.Literal;
import com.mysema.query.apt.model.FieldType;
import com.sun.mirror.type.*;
import com.sun.mirror.util.SimpleTypeVisitor;
/**
* TypeInfo is a helper type for determing types of fields and methods
*
* @author tiwe
* @version $Id$
*/
// TODO : clean this up
public class TypeHelper extends SimpleTypeVisitor {
private FieldType fieldType;
private String simpleName, fullName, packageName = "", keyTypeName;
public TypeHelper(Class<?> cl) {
this(cl, cl);
}
public TypeHelper(Class<?> cl, 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 TypeHelper(TypeMirror type) {
type.accept(this);
if (fullName == null) {
fullName = type.toString();
}
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) {
TypeHelper valueInfo = new TypeHelper(TypeFactory.getTypeParameter(
genericType, 0));
handleCollection(valueInfo);
}
private void handleCollectionInterface(Iterator<TypeMirror> i) {
TypeHelper valueInfo = new TypeHelper(i.next());
handleCollection(valueInfo);
}
private void handleCollection(TypeHelper valueInfo) {
fullName = valueInfo.getFullName();
packageName = valueInfo.getPackageName();
if (valueInfo.fieldType == FieldType.ENTITY) {
fieldType = FieldType.ENTITYCOLLECTION;
} else {
fieldType = FieldType.SIMPLECOLLECTION;
}
}
private void handleList(Iterator<TypeMirror> i) {
TypeHelper valueInfo = new TypeHelper(i.next());
handleList(valueInfo);
}
private void handleList(TypeHelper 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) {
TypeHelper valueInfo = new TypeHelper(TypeFactory.getTypeParameter(
genericType, 0));
handleList(valueInfo);
}
private void handleMapInterface(Class<?> type, Type genericType) {
TypeHelper keyInfo = new TypeHelper(TypeFactory.getTypeParameter(
genericType, 0));
TypeHelper valueInfo = new TypeHelper(TypeFactory.getTypeParameter(
genericType, 1));
handleMapInterface(keyInfo, valueInfo);
}
private void handleMapInterface(Iterator<TypeMirror> i) {
TypeHelper keyInfo = new TypeHelper(i.next());
TypeHelper valueInfo = new TypeHelper(i.next());
handleMapInterface(keyInfo, valueInfo);
}
private void handleMapInterface(TypeHelper keyInfo, TypeHelper 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;
}
@Override
public void visitAnnotationType(AnnotationType arg0) {
//
}
private void visitArrayComponentType(TypeHelper valueInfo) {
fullName = valueInfo.getFullName();
packageName = valueInfo.getPackageName();
if (valueInfo.fieldType == FieldType.ENTITY) {
fieldType = FieldType.ENTITYCOLLECTION;
} else {
fieldType = FieldType.SIMPLECOLLECTION;
}
}
@Override
public void visitArrayType(ArrayType arg0) {
TypeHelper valueInfo = new TypeHelper(arg0.getComponentType());
visitArrayComponentType(valueInfo);
}
public void visitArrayType(Class<?> clazz) {
TypeHelper valueInfo = new TypeHelper(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;
}
}
@Override
public void visitClassType(ClassType arg0) {
try {
fullName = arg0.getDeclaration().getQualifiedName();
packageName = arg0.getDeclaration().getPackage().getQualifiedName();
if (fullName.equals(String.class.getName())) {
fieldType = FieldType.STRING;
} else if (fullName.equals(Boolean.class.getName())) {
fieldType = FieldType.BOOLEAN;
} else if (fullName.equals(Locale.class.getName())
|| fullName.equals(Class.class.getName())
|| fullName.equals(Object.class.getName())) {
fieldType = FieldType.SIMPLE;
} else if (isNumericSupported(fullName)
&& Number.class.isAssignableFrom(Class.forName(fullName))) {
fieldType = FieldType.NUMERIC;
} else if (arg0.getDeclaration().getAnnotation(Literal.class) != null) {
if (Comparable.class.isAssignableFrom(Class.forName(fullName))) {
fieldType = FieldType.COMPARABLE;
} else {
fieldType = FieldType.SIMPLE;
}
} else if (isComparableSupported(fullName)
&& Comparable.class.isAssignableFrom(Class
.forName(fullName))) {
fieldType = FieldType.COMPARABLE;
} else if (asSimpleType(fullName)) {
fieldType = FieldType.SIMPLE;
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
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;
}
@Override
public void visitEnumType(EnumType arg0) {
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);
}
}
@Override
public void visitInterfaceType(InterfaceType arg0) {
Iterator<TypeMirror> i = arg0.getActualTypeArguments().iterator();
String typeName = arg0.getDeclaration().getQualifiedName();
if (typeName.equals(java.util.Map.class.getName())) {
handleMapInterface(i);
} else if (typeName.equals(java.util.Collection.class.getName())
|| typeName.equals(java.util.Set.class.getName())
|| typeName.equals(java.util.SortedSet.class.getName())) {
handleCollectionInterface(i);
} else if (typeName.equals(java.util.List.class.getName())) {
handleList(i);
}
}
public void visitPrimitiveType(Class<?> cl) {
visitPrimitiveWrapperType(ClassUtils.primitiveToWrapper(cl));
}
@Override
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;
}
visitPrimitiveWrapperType(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();
}
@Override
public void visitTypeVariable(TypeVariable arg0) {
if (!arg0.getDeclaration().getBounds().isEmpty()) {
TypeHelper lb = new TypeHelper(arg0.getDeclaration().getBounds()
.iterator().next());
fullName = lb.getFullName();
packageName = lb.getPackageName();
simpleName = lb.getSimpleName();
fieldType = lb.getFieldType();
}
}
@Override
public void visitWildcardType(WildcardType arg0) {
if (!arg0.getUpperBounds().isEmpty()) {
TypeHelper lb = new TypeHelper(arg0.getUpperBounds().iterator()
.next());
fullName = lb.getFullName();
packageName = lb.getPackageName();
simpleName = lb.getSimpleName();
fieldType = lb.getFieldType();
}
}
}

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
/**
* APT implementation classes
*/
package com.mysema.query.apt.general;

View File

@ -0,0 +1,25 @@
package com.mysema.query.apt.jdo;
import static com.mysema.query.apt.Constants.*;
import com.mysema.query.apt.general.DefaultEntityVisitor;
import com.mysema.query.apt.general.GeneralProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.MethodDeclaration;
public class JDOProcessor extends GeneralProcessor {
public JDOProcessor(AnnotationProcessorEnvironment env) {
super(env, JDO_ENTITY, JDO_ENTITY, QD_DTO);
}
@Override
protected DefaultEntityVisitor createEntityVisitor() {
return new DefaultEntityVisitor() {
@Override
public void visitMethodDeclaration(MethodDeclaration d) {
// skip property handling
}
};
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.jpa;
import static com.mysema.query.apt.Constants.*;
import static com.sun.mirror.util.DeclarationVisitors.NO_OP;
import static com.sun.mirror.util.DeclarationVisitors.getDeclarationScanner;
import java.util.Map;
import com.mysema.query.apt.general.DefaultEntityVisitor;
import com.mysema.query.apt.general.GeneralProcessor;
import com.mysema.query.apt.model.Type;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.Declaration;
import com.sun.mirror.declaration.MethodDeclaration;
/**
* JpaProcessor provides JPA annotation handling support
*
* @author tiwe
* @version $Id$
*/
public class JPAProcessor extends GeneralProcessor {
public JPAProcessor(AnnotationProcessorEnvironment env) {
super(env, JPA_SUPERCLASS, JPA_ENTITY, QD_DTO);
}
private void createEmbeddableClasses() {
DefaultEntityVisitor entityVisitor = new DefaultEntityVisitor();
AnnotationTypeDeclaration a = (AnnotationTypeDeclaration) env
.getTypeDeclaration(JPA_EMBEDDABLE);
for (Declaration typeDecl : env.getDeclarationsAnnotatedWith(a)) {
typeDecl.accept(getDeclarationScanner(entityVisitor, NO_OP));
}
Map<String, Type> entityTypes = entityVisitor.types;
if (entityTypes.isEmpty()) {
env.getMessager().printNotice(
"No class generation for embeddable types");
} else {
serializeAsOuterClasses(entityTypes.values(), EMBEDDABLE_OUTER_TMPL);
}
}
// TODO : add switch for field / getter handling
@Override
protected DefaultEntityVisitor createEntityVisitor() {
return new DefaultEntityVisitor() {
@Override
public void visitMethodDeclaration(MethodDeclaration d) {
// skip property handling
}
};
}
public void process() {
super.process();
createEmbeddableClasses();
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.model;
import java.util.Collection;
/**
* Constructor represents a constructor for a DTO query type.
*
* @author tiwe
* @version $Id$
*/
public class Constructor {
private final Collection<Parameter> parameters;
public Constructor(Collection<Parameter> params) {
parameters = params;
}
public Collection<Parameter> getParameters() {
return parameters;
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.model;
/**
* Field represents a field / property in a query domain type.
*
* @author tiwe
* @version $Id$
*/
public class Field implements Comparable<Field> {
/**
* The Enum Type.
*/
private final FieldType fieldType;
private String name, realName, keyTypeName, typeName, typePackage,
simpleTypeName;
/**
* Construct a new Field instance
*
* @param name
* normalized field name
* @param realName
* real fieldName
* @param keyTypeName
* key type name for Map types
* @param typePackage
* @param typeName
* full type name (with package)
* @param simpleTypeName
* simple type name (local)
* @param fieldType
*/
public Field(String name, String realName, String keyTypeName,
String typePackage, String typeName, String simpleTypeName,
FieldType fieldType) {
this.name = name;
this.realName = realName;
this.keyTypeName = keyTypeName;
this.typePackage = typePackage;
this.typeName = typeName;
this.simpleTypeName = simpleTypeName;
this.fieldType = fieldType;
}
public int compareTo(Field o) {
return name.compareTo(o.name);
}
public boolean equals(Object o) {
return o instanceof Field && name.equals(((Field) o).name);
}
public FieldType getFieldType() {
return fieldType;
}
/**
* Returns the type name of key element for Map fields
*
* @return
*/
public String getKeyTypeName() {
return keyTypeName;
}
public String getName() {
return name;
}
public String getRealName() {
return realName;
}
/**
* Returns the simple name of the field type
*
* @return
*/
public String getSimpleTypeName() {
return simpleTypeName;
}
/**
* Returns the full name of the field type
*
* @return
*/
public String getTypeName() {
return typeName;
}
public String getTypePackage() {
return typePackage;
}
public int hashCode() {
return name.hashCode();
}
public String toString() {
return typeName + " " + name;
}
}

View File

@ -0,0 +1,10 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.model;
public enum FieldType {
BOOLEAN, COMPARABLE, ENTITY, ENTITYLIST, ENTITYCOLLECTION, ENTITYMAP, NUMERIC, SIMPLE, SIMPLELIST, SIMPLECOLLECTION, SIMPLEMAP, STRING
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.model;
/**
* Parameter represents a parameter in a Constructor
*
* @author tiwe
* @version $Id$
*/
public class Parameter implements Comparable<Parameter> {
private final String name, typeName;
public Parameter(String name, String typeName) {
this.name = name;
this.typeName = typeName;
}
public int compareTo(Parameter o) {
return name.compareTo(o.name);
}
public boolean equals(Object o) {
return o instanceof Parameter && name.equals(((Parameter) o).name);
}
public String getName() {
return name;
}
public String getTypeName() {
return typeName;
}
public int hashCode() {
return name.hashCode();
}
}

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.model;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.lang.StringUtils;
/**
* Type represents a query domain type.
*
* @author tiwe
* @version $Id$
*/
public class Type implements Comparable<Type> {
private Set<Field> booleanFields = new TreeSet<Field>();
private Set<Field> comparableFields = new TreeSet<Field>();
private Set<Constructor> constructors = new HashSet<Constructor>();
private Set<Field> entityCollections = new TreeSet<Field>();
private Set<Field> entityFields = new TreeSet<Field>();
private Set<Field> entityLists = new TreeSet<Field>();
private Set<Field> entityMaps = new TreeSet<Field>();
private Set<Field> numericFields = new TreeSet<Field>();
private Set<Field> simpleCollections = new TreeSet<Field>();
private Set<Field> simpleFields = new TreeSet<Field>();
private Set<Field> simpleLists = new TreeSet<Field>();
private Set<Field> simpleMaps = new TreeSet<Field>();
private String simpleName, uncapSimpleName, name, packageName;
private int escapeSuffix = 1;
private Set<Field> stringFields = new TreeSet<Field>();
private String superType;
public Type(String superType, String packageName, String name,
String simpleName) {
this.superType = superType;
this.packageName = packageName;
this.name = name;
this.simpleName = simpleName;
this.uncapSimpleName = StringUtils.uncapitalize(simpleName);
}
public void addConstructor(Constructor co) {
constructors.add(co);
}
public void addField(Field fieldDecl) {
validateField(fieldDecl);
switch (fieldDecl.getFieldType()) {
case BOOLEAN:
booleanFields.add(fieldDecl);
break;
case STRING:
stringFields.add(fieldDecl);
break;
case SIMPLE:
simpleFields.add(fieldDecl);
break;
case COMPARABLE:
comparableFields.add(fieldDecl);
break;
case NUMERIC:
numericFields.add(fieldDecl);
break;
case ENTITY:
entityFields.add(fieldDecl);
break;
case ENTITYCOLLECTION:
entityCollections.add(fieldDecl);
break;
case SIMPLECOLLECTION:
simpleCollections.add(fieldDecl);
break;
case ENTITYLIST:
entityLists.add(fieldDecl);
break;
case SIMPLELIST:
simpleLists.add(fieldDecl);
break;
case ENTITYMAP:
entityMaps.add(fieldDecl);
break;
case SIMPLEMAP:
simpleMaps.add(fieldDecl);
break;
}
}
private Field validateField(Field field) {
if (field.getName().equals(this.uncapSimpleName)) {
uncapSimpleName = StringUtils.uncapitalize(simpleName)
+ (escapeSuffix++);
}
return field;
}
public int compareTo(Type o) {
return simpleName.compareTo(o.simpleName);
}
public boolean equals(Object o) {
return o instanceof Type && simpleName.equals(((Type) o).simpleName);
}
public Collection<Field> getBooleanFields() {
return booleanFields;
}
public Collection<Field> getComparableFields() {
return comparableFields;
}
public Collection<Constructor> getConstructors() {
return constructors;
}
public Collection<Field> getEntityCollections() {
return entityCollections;
}
public Collection<Field> getEntityFields() {
return entityFields;
}
public Collection<Field> getEntityLists() {
return entityLists;
}
public Collection<Field> getEntityMaps() {
return entityMaps;
}
public String getName() {
return name;
}
public Collection<Field> getNumericFields() {
return numericFields;
}
public String getPackageName() {
return packageName;
}
public Collection<Field> getSimpleCollections() {
return simpleCollections;
}
public Collection<Field> getSimpleFields() {
return simpleFields;
}
public Collection<Field> getSimpleLists() {
return simpleLists;
}
public Collection<Field> getSimpleMaps() {
return simpleMaps;
}
public String getSimpleName() {
return simpleName;
}
public String getUncapSimpleName() {
return uncapSimpleName;
}
public Collection<Field> getStringFields() {
return stringFields;
}
public String getSupertypeName() {
return superType;
}
public int hashCode() {
return name.hashCode();
}
public void include(Type decl) {
addAll(booleanFields, decl.booleanFields);
addAll(entityCollections, decl.entityCollections);
addAll(entityFields, decl.entityFields);
addAll(entityLists, decl.entityLists);
addAll(entityMaps, decl.entityMaps);
addAll(comparableFields, decl.comparableFields);
addAll(numericFields, decl.numericFields);
addAll(simpleCollections, decl.simpleCollections);
addAll(simpleFields, decl.simpleFields);
addAll(simpleLists, decl.simpleLists);
addAll(simpleMaps, decl.simpleMaps);
addAll(stringFields, decl.stringFields);
}
private void addAll(Set<Field> target, Set<Field> source) {
for (Field field : source) {
target.add(validateField(field));
}
}
}

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
/**
* APTFactory and related classes
*/
package com.mysema.query.apt;

View File

@ -0,0 +1 @@
com.mysema.query.apt.APTFactory

View File

@ -0,0 +1,12 @@
<#import "/macros.ftl" as cl>
package ${package};
import com.mysema.query.types.path.*;
/**
* ${pre}${classSimpleName} is a Querydsl query type for ${classSimpleName}
*
*/
public class ${pre}${classSimpleName} extends PEntity<${type.name}>{
<@cl.classContent decl=type embeddable=false/>
}

View File

@ -0,0 +1,16 @@
<#import "/macros.ftl" as cl>
package ${package};
import com.mysema.query.types.expr.*;
/**
* ${pre}${classSimpleName} is a Querydsl DTO type
*
*/
public class ${pre}${classSimpleName} extends EConstructor<${type.name}>{
<#list type.constructors as co>
public ${pre}${type.simpleName}(<#list co.parameters as pa>Expr<${pa.typeName}> ${pa.name}<#if pa_has_next>,</#if></#list>){
super(${type.name}.class<#list co.parameters as pa>,${pa.name}</#list>);
}
</#list>
}

View File

@ -0,0 +1,12 @@
<#import "/macros.ftl" as cl>
package ${package};
import com.mysema.query.types.path.*;
/**
* ${pre}${classSimpleName} is a Querydsl embeddable type
*
*/
public class ${pre}${classSimpleName} extends PEntity<${type.name}>{
<@cl.classContent decl=type embeddable=true/>
}

View File

@ -0,0 +1,141 @@
<#assign reserved = ["isnull", "isnotnull", "getType", "getMetadata", "toString", "hashCode", "getClass", "notify", "notifyAll", "wait"]>
<#macro classContent decl embeddable>
<#if !embeddable>
public static final ${pre}${decl.simpleName} ${decl.uncapSimpleName} = new ${pre}${decl.simpleName}("${decl.uncapSimpleName}");
</#if>
<#list decl.stringFields as field>
<@stringField field=field/>
</#list>
<#list decl.booleanFields as field>
<@booleanField field=field/>
</#list>
<#list decl.simpleFields as field>
<@simpleField field=field/>
</#list>
<#list decl.comparableFields as field>
<@comparableField field=field/>
</#list>
<#list decl.numericFields as field>
<@numericField field=field/>
</#list>
<#list decl.simpleMaps as field>
<@simpleMap field=field/>
</#list>
<#list decl.simpleCollections as field>
<@simpleCollection field=field/>
</#list>
<#list decl.simpleLists as field>
<@simpleList field=field/>
</#list>
<#list decl.entityMaps as field>
<@entityMap field=field/>
</#list>
<#list decl.entityCollections as field>
<@entityCollection field=field/>
</#list>
<#list decl.entityLists as field>
<@entityList field=field/>
</#list>
<#list decl.entityFields as field>
<@entityField field=field/>
</#list>
<#-- constructors -->
<#if !embeddable>
public ${pre}${decl.simpleName}(java.lang.String path) {
this(${decl.name}.class, path);
}
public ${pre}${decl.simpleName}(Class<? extends ${decl.name}> cl, java.lang.String path) {
super(cl, "${decl.simpleName}", path);
<#list decl.entityFields as field>
<#if !reserved?seq_contains(field.name)>
_${field.name}();
</#if>
</#list>
}
</#if>
public ${pre}${decl.simpleName}(PathMetadata<?> metadata) {
super(${decl.name}.class, "${decl.simpleName}", metadata);
}
</#macro>
<#macro booleanField field>
public final PBoolean ${field.name} = _boolean("${field.realName}");
</#macro>
<#macro comparableField field>
public final PComparable<${field.typeName}> ${field.name} = _comparable("${field.realName}",${field.typeName}.class);
</#macro>
<#macro entityCollection field>
public final PEntityCollection<${field.typeName}> ${field.name} = _entitycol("${field.realName}",${field.typeName}.class, "${field.simpleTypeName}");
</#macro>
<#macro entityField field>
public ${field.typePackage}.${pre}${field.simpleTypeName} ${field.name};
<#if !reserved?seq_contains(field.name)>
public ${field.typePackage}.${pre}${field.simpleTypeName} _${field.name}() {
if (${field.name} == null) ${field.name} = new ${field.typePackage}.${pre}${field.simpleTypeName}(PathMetadata.forProperty(this,"${field.realName}"));
return ${field.name};
}
</#if>
</#macro>
<#macro entityList field>
public final PEntityList<${field.typeName}> ${field.name} = _entitylist("${field.realName}",${field.typeName}.class,"${field.simpleTypeName}");
public ${field.typePackage}.${pre}${field.simpleTypeName} ${field.name}(int index) {
return new ${field.typePackage}.${pre}${field.simpleTypeName}(PathMetadata.forListAccess(${field.name},index));
}
public ${field.typePackage}.${pre}${field.simpleTypeName} ${field.name}(com.mysema.query.types.expr.Expr<Integer> index) {
return new ${field.typePackage}.${pre}${field.simpleTypeName}(PathMetadata.forListAccess(${field.name},index));
}
</#macro>
<#macro entityMap field>
public final PEntityMap<${field.keyTypeName},${field.typeName}> ${field.name} = _entitymap("${field.realName}",${field.keyTypeName}.class,${field.typeName}.class,"${field.simpleTypeName}");
public ${field.typePackage}.${pre}${field.simpleTypeName} ${field.name}(${field.keyTypeName} key) {
return new ${field.typePackage}.${pre}${field.simpleTypeName}(PathMetadata.forMapAccess(${field.name},key));
}
public ${field.typePackage}.${pre}${field.simpleTypeName} ${field.name}(com.mysema.query.types.expr.Expr<${field.keyTypeName}> key) {
return new ${field.typePackage}.${pre}${field.simpleTypeName}(PathMetadata.forMapAccess(${field.name},key));
}
</#macro>
<#macro numericField field>
public final PNumber<${field.typeName}> ${field.name} = _number("${field.realName}",${field.typeName}.class);
</#macro>
<#macro simpleField field>
public final PSimple<${field.typeName}> ${field.name} = _simple("${field.realName}",${field.typeName}.class);
</#macro>
<#macro simpleMap field>
public final PComponentMap<${field.keyTypeName},${field.typeName}> ${field.name} = _simplemap("${field.realName}",${field.keyTypeName}.class,${field.typeName}.class);
public PSimple<${field.typeName}> ${field.name}(${field.keyTypeName} key) {
return new PSimple<${field.typeName}>(${field.typeName}.class,PathMetadata.forMapAccess(${field.name},key));
}
public PSimple<${field.typeName}> ${field.name}(com.mysema.query.types.expr.Expr<${field.keyTypeName}> key) {
return new PSimple<${field.typeName}>(${field.typeName}.class,PathMetadata.forMapAccess(${field.name},key));
}
</#macro>
<#macro simpleCollection field>
public final PComponentCollection<${field.typeName}> ${field.name} = _simplecol("${field.realName}",${field.typeName}.class);
</#macro>
<#macro simpleList field>
public final PComponentList<${field.typeName}> ${field.name} = _simplelist("${field.realName}",${field.typeName}.class);
public PSimple<${field.typeName}> ${field.name}(int index) {
return new PSimple<${field.typeName}>(${field.typeName}.class,PathMetadata.forListAccess(${field.name},index));
}
public PSimple<${field.typeName}> ${field.name}(com.mysema.query.types.expr.Expr<Integer> index) {
return new PSimple<${field.typeName}>(${field.typeName}.class,PathMetadata.forListAccess(${field.name},index));
}
</#macro>
<#macro stringField field>
public final PString ${field.name} = _string("${field.realName}");
</#macro>

View File

@ -0,0 +1,16 @@
<project name="querydsl-apt">
<bannerLeft>
<src>/images/logos/header_mysema_logo.png</src>
<href>http://source.mysema.com</href>
</bannerLeft>
<bannerRight>
<name>${project.name}</name>
<href>/index.html</href>
</bannerRight>
<body>
<menu ref="parent"/>
<menu ref="reports"/>
</body>
</project>

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.mysema.query.apt.model.Constructor;
import com.mysema.query.apt.model.Field;
import com.mysema.query.apt.model.FieldType;
import com.mysema.query.apt.model.Parameter;
import com.mysema.query.apt.model.Type;
/**
* HibernateProcessorTest provides.
*
* @author tiwe
* @version $Id$
*/
public class GeneralProcessorTest {
private Type type;
private Writer writer = new StringWriter();
private Map<String, Object> model = new HashMap<String, Object>();
public GeneralProcessorTest() {
type = new Type("com.mysema.query.DomainSuperClass",
"com.mysema.query", "com.mysema.query.DomainClass",
"DomainClass");
Field field = new Field("field", "field", null, "java.lang",
"java.lang.String", "String", FieldType.STRING);
type.addField(field);
Parameter param = new Parameter("name", "java.lang.String");
type.addConstructor(new Constructor(Collections.singleton(param)));
}
@Test
public void testDomainTypesAsOuterClasses() throws Exception {
model.put("type", type);
model.put("pre", "");
model.put("include", "");
model.put("package", "com.mysema.query");
model.put("classSimpleName", "Test");
// as outer classes
GeneralProcessor.DOMAIN_OUTER_TMPL.serialize(model, writer);
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.apt.general;
import static org.junit.Assert.assertEquals;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import com.mysema.query.apt.model.Field;
import com.mysema.query.apt.model.Type;
/**
* TypeHelperTest provides
*
* @author tiwe
* @version $Id$
*/
public class TypeHelperTest {
@Test
public void test() {
Type type = TypeFactory.createType(TestType.class);
assertEquals(1, type.getEntityMaps().size());
assertEquals(1, type.getSimpleMaps().size());
assertEquals(2, type.getEntityCollections().size());
assertEquals(2, type.getSimpleCollections().size());
assertEquals(1, type.getEntityLists().size());
assertEquals(1, type.getSimpleLists().size());
assertEquals(1, type.getEntityFields().size());
assertEquals(1, type.getStringFields().size());
assertEquals(2, type.getNumericFields().size());
assertEquals(3, type.getSimpleFields().size());
}
public static class TestType {
// entity map
public Map<String, TestType> map1;
// simple map
public Map<String, String> map2;
// entity col
public Collection<TestType> col1;
public Set<TestType> set1;
// simple col
public Collection<Object> col2;
public Set<Object> set2;
// entity list
public List<TestType> list1;
// simple list
public List<Object> list2;
// entity
public TestType ref;
// string
public String str;
// numeric
public int intField;
public Integer intField2;
// simple
public Class<?> cl;
public Object o;
public Locale l;
}
}