diff --git a/querydsl-apt-jdk5/pom.xml b/querydsl-apt-jdk5/pom.xml
new file mode 100644
index 000000000..ad1228c72
--- /dev/null
+++ b/querydsl-apt-jdk5/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+
+
+ com.mysema.querydsl
+ querydsl-root
+ 0.3.10-SNAPSHOT
+
+
+ com.mysema.querydsl
+ querydsl-apt
+ Querydsl - APT support
+ source code generation for querydsl
+ jar
+
+
+
+ org.freemarker
+ freemarker
+ 2.3.12
+
+
+
+ commons-io
+ commons-io
+ 1.4
+
+
+
+ commons-lang
+ commons-lang
+ 2.4
+
+
+ com.mysema.querydsl
+ querydsl-core
+ ${project.parent.version}
+
+
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ src/assembly/one-jar.xml
+
+
+
+
+ make-assembly
+ package
+
+ attached
+
+
+
+
+
+
+
+
+
+ default-tools.jar
+
+
+ java.vendor
+ Sun Microsystems Inc.
+
+
+
+
+ com.sun
+ tools
+ 1.4.2
+ system
+ ${java.home}/../lib/tools.jar
+
+
+
+
+
+
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/assembly/one-jar.xml b/querydsl-apt-jdk5/src/assembly/one-jar.xml
new file mode 100644
index 000000000..632742931
--- /dev/null
+++ b/querydsl-apt-jdk5/src/assembly/one-jar.xml
@@ -0,0 +1,27 @@
+
+ one-jar
+
+ jar
+
+ false
+
+
+
+ true
+
+
+
+
+
+ target/classes
+
+
+
+
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/assembly/plugin.xml b/querydsl-apt-jdk5/src/assembly/plugin.xml
new file mode 100644
index 000000000..7ae891d91
--- /dev/null
+++ b/querydsl-apt-jdk5/src/assembly/plugin.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/APTFactory.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/APTFactory.java
new file mode 100644
index 000000000..42bbc2404
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/APTFactory.java
@@ -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 supportedAnnotations = Arrays
+ .asList(QD_ENTITY, QD_DTO, JDO_ENTITY, JPA_ENTITY, JPA_SUPERCLASS,
+ JPA_EMBEDDABLE);
+
+ private static final Collection supportedOptions = Collections
+ .emptySet();
+
+ public Collection supportedAnnotationTypes() {
+ return supportedAnnotations;
+ }
+
+ public Collection supportedOptions() {
+ return supportedOptions;
+ }
+
+ public AnnotationProcessor getProcessorFor(
+ Set 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);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/APTUtils.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/APTUtils.java
new file mode 100644
index 000000000..168524b93
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/APTUtils.java
@@ -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 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 options, String key,
+ String defaultValue) {
+ String prefix = "-A" + key + "=";
+ for (Map.Entry 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;
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/Constants.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/Constants.java
new file mode 100644
index 000000000..40a098a45
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/Constants.java
@@ -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";
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/FreeMarkerSerializer.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/FreeMarkerSerializer.java
new file mode 100644
index 000000000..0536f7327
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/FreeMarkerSerializer.java
@@ -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 model, Writer writer)
+ throws IOException, TemplateException {
+ cfg.getTemplate(templateLocation).process(model, writer);
+ writer.flush();
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/DefaultDTOVisitor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/DefaultDTOVisitor.java
new file mode 100644
index 000000000..901773017
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/DefaultDTOVisitor.java
@@ -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 types = new TreeSet();
+
+ 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 parameters = new ArrayList(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));
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/DefaultEntityVisitor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/DefaultEntityVisitor.java
new file mode 100644
index 000000000..0e590894b
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/DefaultEntityVisitor.java
@@ -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 types = new HashMap();
+
+ 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()));
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/FieldHelper.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/FieldHelper.java
new file mode 100644
index 000000000..e490efc76
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/FieldHelper.java
@@ -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;
+ }
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/GeneralProcessor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/GeneralProcessor.java
new file mode 100644
index 000000000..63a1d526f
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/GeneralProcessor.java
@@ -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 entityTypes, Map 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 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();
+ }
+
+ // domain types
+ DefaultEntityVisitor entityVisitor = createEntityVisitor();
+ a = (AnnotationTypeDeclaration) env
+ .getTypeDeclaration(domainAnnotation);
+ for (Declaration typeDecl : env.getDeclarationsAnnotatedWith(a)) {
+ typeDecl.accept(getDeclarationScanner(entityVisitor, NO_OP));
+ }
+ Map 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 entityTypes,
+ FreeMarkerSerializer serializer) {
+ // populate model
+ Map model = new HashMap();
+ 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);
+ }
+ }
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/QuerydslProcessor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/QuerydslProcessor.java
new file mode 100644
index 000000000..bc9430d32
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/QuerydslProcessor.java
@@ -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
+ }
+ };
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/TypeFactory.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/TypeFactory.java
new file mode 100644
index 000000000..2f9d16ad5
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/TypeFactory.java
@@ -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;
+ }
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/TypeHelper.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/TypeHelper.java
new file mode 100644
index 000000000..3c0971cff
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/TypeHelper.java
@@ -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 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 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 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 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();
+ }
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/package-info.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/package-info.java
new file mode 100644
index 000000000..09e54186e
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/general/package-info.java
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2009 Mysema Ltd.
+ * All rights reserved.
+ *
+ */
+
+/**
+ * APT implementation classes
+ */
+package com.mysema.query.apt.general;
+
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/jdo/JDOProcessor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/jdo/JDOProcessor.java
new file mode 100644
index 000000000..84103391c
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/jdo/JDOProcessor.java
@@ -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
+ }
+ };
+ }
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/jpa/JPAProcessor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/jpa/JPAProcessor.java
new file mode 100644
index 000000000..9c716c5a8
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/jpa/JPAProcessor.java
@@ -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 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();
+ }
+}
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Constructor.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Constructor.java
new file mode 100644
index 000000000..2e932c8f4
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Constructor.java
@@ -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 parameters;
+
+ public Constructor(Collection params) {
+ parameters = params;
+ }
+
+ public Collection getParameters() {
+ return parameters;
+ }
+
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Field.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Field.java
new file mode 100644
index 000000000..c9791728a
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Field.java
@@ -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 {
+
+ /**
+ * 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;
+ }
+
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/FieldType.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/FieldType.java
new file mode 100644
index 000000000..439d0fa89
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/FieldType.java
@@ -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
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Parameter.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Parameter.java
new file mode 100644
index 000000000..a3e3afb39
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Parameter.java
@@ -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 {
+ 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();
+ }
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Type.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Type.java
new file mode 100644
index 000000000..1239be366
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/model/Type.java
@@ -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 {
+
+ private Set booleanFields = new TreeSet();
+
+ private Set comparableFields = new TreeSet();
+
+ private Set constructors = new HashSet();
+
+ private Set entityCollections = new TreeSet();
+
+ private Set entityFields = new TreeSet();
+
+ private Set entityLists = new TreeSet();
+
+ private Set entityMaps = new TreeSet();
+
+ private Set numericFields = new TreeSet();
+
+ private Set simpleCollections = new TreeSet();
+
+ private Set simpleFields = new TreeSet();
+
+ private Set simpleLists = new TreeSet();
+
+ private Set simpleMaps = new TreeSet();
+
+ private String simpleName, uncapSimpleName, name, packageName;
+
+ private int escapeSuffix = 1;
+
+ private Set stringFields = new TreeSet();
+
+ 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 getBooleanFields() {
+ return booleanFields;
+ }
+
+ public Collection getComparableFields() {
+ return comparableFields;
+ }
+
+ public Collection getConstructors() {
+ return constructors;
+ }
+
+ public Collection getEntityCollections() {
+ return entityCollections;
+ }
+
+ public Collection getEntityFields() {
+ return entityFields;
+ }
+
+ public Collection getEntityLists() {
+ return entityLists;
+ }
+
+ public Collection getEntityMaps() {
+ return entityMaps;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Collection getNumericFields() {
+ return numericFields;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public Collection getSimpleCollections() {
+ return simpleCollections;
+ }
+
+ public Collection getSimpleFields() {
+ return simpleFields;
+ }
+
+ public Collection getSimpleLists() {
+ return simpleLists;
+ }
+
+ public Collection getSimpleMaps() {
+ return simpleMaps;
+ }
+
+ public String getSimpleName() {
+ return simpleName;
+ }
+
+ public String getUncapSimpleName() {
+ return uncapSimpleName;
+ }
+
+ public Collection 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 target, Set source) {
+ for (Field field : source) {
+ target.add(validateField(field));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/package-info.java b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/package-info.java
new file mode 100644
index 000000000..c1a48ac2e
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/java/com/mysema/query/apt/package-info.java
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2008 Mysema Ltd.
+ * All rights reserved.
+ *
+ */
+
+/**
+ * APTFactory and related classes
+ */
+package com.mysema.query.apt;
+
diff --git a/querydsl-apt-jdk5/src/main/resources/META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory b/querydsl-apt-jdk5/src/main/resources/META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory
new file mode 100644
index 000000000..d39d5ee7f
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/resources/META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory
@@ -0,0 +1 @@
+com.mysema.query.apt.APTFactory
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/main/resources/domain-as-outer-classes.ftl b/querydsl-apt-jdk5/src/main/resources/domain-as-outer-classes.ftl
new file mode 100644
index 000000000..a1c65f962
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/resources/domain-as-outer-classes.ftl
@@ -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/>
+}
diff --git a/querydsl-apt-jdk5/src/main/resources/dto-as-outer-classes.ftl b/querydsl-apt-jdk5/src/main/resources/dto-as-outer-classes.ftl
new file mode 100644
index 000000000..d0f869455
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/resources/dto-as-outer-classes.ftl
@@ -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>
+}
diff --git a/querydsl-apt-jdk5/src/main/resources/embeddable-as-outer-classes.ftl b/querydsl-apt-jdk5/src/main/resources/embeddable-as-outer-classes.ftl
new file mode 100644
index 000000000..2cf10be28
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/resources/embeddable-as-outer-classes.ftl
@@ -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/>
+}
diff --git a/querydsl-apt-jdk5/src/main/resources/macros.ftl b/querydsl-apt-jdk5/src/main/resources/macros.ftl
new file mode 100644
index 000000000..ca21ee73c
--- /dev/null
+++ b/querydsl-apt-jdk5/src/main/resources/macros.ftl
@@ -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 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 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>
+
+
diff --git a/querydsl-apt-jdk5/src/site/site.xml b/querydsl-apt-jdk5/src/site/site.xml
new file mode 100644
index 000000000..eb63342ce
--- /dev/null
+++ b/querydsl-apt-jdk5/src/site/site.xml
@@ -0,0 +1,16 @@
+
+
+ /images/logos/header_mysema_logo.png
+ http://source.mysema.com
+
+
+
+ ${project.name}
+ /index.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/querydsl-apt-jdk5/src/test/java/com/mysema/query/apt/general/GeneralProcessorTest.java b/querydsl-apt-jdk5/src/test/java/com/mysema/query/apt/general/GeneralProcessorTest.java
new file mode 100644
index 000000000..7a1a180f6
--- /dev/null
+++ b/querydsl-apt-jdk5/src/test/java/com/mysema/query/apt/general/GeneralProcessorTest.java
@@ -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 model = new HashMap();
+
+ 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);
+ }
+
+}
diff --git a/querydsl-apt-jdk5/src/test/java/com/mysema/query/apt/general/TypeHelperTest.java b/querydsl-apt-jdk5/src/test/java/com/mysema/query/apt/general/TypeHelperTest.java
new file mode 100644
index 000000000..d78e44912
--- /dev/null
+++ b/querydsl-apt-jdk5/src/test/java/com/mysema/query/apt/general/TypeHelperTest.java
@@ -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 map1;
+ // simple map
+ public Map map2;
+ // entity col
+ public Collection col1;
+ public Set set1;
+ // simple col
+ public Collection