mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
updated version to 0.7.13
This commit is contained in:
parent
2969ce3ee6
commit
af6781ba1f
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
@ -6,13 +6,16 @@
|
||||
package com.mysema.query.apt;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
@ -29,6 +32,7 @@ import javax.lang.model.type.TypeVisitor;
|
||||
import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.Elements;
|
||||
|
||||
import com.mysema.query.codegen.EntityModel;
|
||||
import com.mysema.query.codegen.SimpleClassTypeModel;
|
||||
import com.mysema.query.codegen.SimpleTypeModel;
|
||||
import com.mysema.query.codegen.TypeCategory;
|
||||
@ -39,10 +43,15 @@ import com.mysema.query.codegen.TypeSuperModel;
|
||||
import com.mysema.query.util.TypeUtil;
|
||||
|
||||
/**
|
||||
* APTTypeModelFactory is a factory for APT inspection based TypeModel creation
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public class APTModelFactory implements TypeVisitor<TypeModel,Elements> {
|
||||
// TODO : simplify
|
||||
public class APTTypeModelFactory implements TypeVisitor<TypeModel,Elements> {
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
private final ProcessingEnvironment env;
|
||||
|
||||
@ -50,14 +59,18 @@ public class APTModelFactory implements TypeVisitor<TypeModel,Elements> {
|
||||
|
||||
private final TypeModel defaultValue;
|
||||
|
||||
private final Map<CharSequence,TypeModel> cache = new HashMap<CharSequence,TypeModel>();
|
||||
private final Map<List<String>,EntityModel> entityTypeCache = new HashMap<List<String>,EntityModel>();
|
||||
|
||||
private final Map<List<String>,TypeModel> cache = new HashMap<List<String>,TypeModel>();
|
||||
|
||||
private final List<Class<? extends Annotation>> entityAnnotations;
|
||||
|
||||
private final TypeElement numberType, comparableType;
|
||||
|
||||
public APTModelFactory(ProcessingEnvironment env, TypeModelFactory factory, List<Class<? extends Annotation>> annotations){
|
||||
public APTTypeModelFactory(ProcessingEnvironment env, Configuration configuration,
|
||||
TypeModelFactory factory, List<Class<? extends Annotation>> annotations){
|
||||
this.env = env;
|
||||
this.configuration = configuration;
|
||||
this.factory = factory;
|
||||
this.defaultValue = factory.create(Object.class);
|
||||
this.entityAnnotations = annotations;
|
||||
@ -65,44 +78,107 @@ public class APTModelFactory implements TypeVisitor<TypeModel,Elements> {
|
||||
this.comparableType = env.getElementUtils().getTypeElement(Comparable.class.getName());
|
||||
}
|
||||
|
||||
private String getKey(TypeMirror type, boolean deep){
|
||||
StringBuilder key = new StringBuilder(type.toString());
|
||||
private List<String> getKey(TypeMirror type, boolean deep){
|
||||
List<String> key = new ArrayList<String>();
|
||||
key.add(type.toString());
|
||||
if (type.getKind() == TypeKind.TYPEVAR){
|
||||
TypeVariable t = (TypeVariable)type;
|
||||
if (t.getUpperBound() != null){
|
||||
key.append(";").append(getKey(t.getUpperBound(), false));
|
||||
key.addAll(getKey(t.getUpperBound(), false));
|
||||
}
|
||||
if (t.getLowerBound() != null){
|
||||
key.append(";").append(getKey(t.getLowerBound(), false));
|
||||
key.addAll(getKey(t.getLowerBound(), false));
|
||||
}
|
||||
}else if (type.getKind() == TypeKind.WILDCARD){
|
||||
WildcardType t = (WildcardType)type;
|
||||
if (t.getExtendsBound() != null){
|
||||
key.append(";").append(getKey(t.getExtendsBound(), false));
|
||||
key.addAll(getKey(t.getExtendsBound(), false));
|
||||
}
|
||||
if (t.getSuperBound() != null){
|
||||
key.append(";").append(getKey(t.getSuperBound(), false));
|
||||
key.addAll(getKey(t.getSuperBound(), false));
|
||||
}
|
||||
}else if (type.getKind() == TypeKind.DECLARED){
|
||||
DeclaredType t = (DeclaredType)type;
|
||||
for (TypeMirror arg : t.getTypeArguments()){
|
||||
key.append(";").append(deep ? getKey(arg, false) : arg.toString());
|
||||
key.addAll(deep ? getKey(arg, false) : Collections.singleton(arg.toString()));
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public EntityModel createEntityModel(TypeMirror type, Elements el){
|
||||
List<String> key = getKey(type, true);
|
||||
if (entityTypeCache.containsKey(key)){
|
||||
return entityTypeCache.get(key);
|
||||
|
||||
}else{
|
||||
entityTypeCache.put(key, null);
|
||||
TypeModel value = type.accept(this, el);
|
||||
if (value != null){
|
||||
EntityModel entityModel = asEntityModel(type, el, value);
|
||||
entityTypeCache.put(key, entityModel);
|
||||
return entityModel;
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
public TypeModel create(TypeMirror type, Elements el){
|
||||
String key = getKey(type, true);
|
||||
if (cache.containsKey(key)){
|
||||
List<String> key = getKey(type, true);
|
||||
if (entityTypeCache.containsKey(key)){
|
||||
return entityTypeCache.get(key);
|
||||
|
||||
}else if (cache.containsKey(key)){
|
||||
return cache.get(key);
|
||||
|
||||
}else{
|
||||
cache.put(key, null);
|
||||
TypeModel value = type.accept(this, el);
|
||||
cache.put(key, value);
|
||||
if (value != null && value.getTypeCategory() == TypeCategory.ENTITY){
|
||||
value = asEntityModel(type, el, value);
|
||||
entityTypeCache.put(key, (EntityModel)value);
|
||||
}else{
|
||||
cache.put(key, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private EntityModel asEntityModel(TypeMirror type, Elements el, TypeModel value) {
|
||||
if (type.getKind() == TypeKind.TYPEVAR){
|
||||
TypeVariable typeVar = (TypeVariable)type;
|
||||
if (typeVar.getUpperBound() != null){
|
||||
type = typeVar.getUpperBound();
|
||||
}
|
||||
}else if (type.getKind() == TypeKind.WILDCARD){
|
||||
WildcardType wildcard = (WildcardType)type;
|
||||
if (wildcard.getExtendsBound() != null){
|
||||
type = wildcard.getExtendsBound();
|
||||
}
|
||||
}
|
||||
|
||||
Collection<String> superTypes = Collections.emptySet();
|
||||
if (type.getKind() == TypeKind.DECLARED){
|
||||
DeclaredType declaredType = (DeclaredType)type;
|
||||
TypeElement e = (TypeElement)declaredType.asElement();
|
||||
if (e.getKind() == ElementKind.CLASS){
|
||||
superTypes = Collections.singleton(create(e.getSuperclass(), el).getFullName());
|
||||
}else{
|
||||
superTypes = new ArrayList<String>(e.getInterfaces().size());
|
||||
for (TypeMirror mirror : e.getInterfaces()){
|
||||
TypeModel iface = create(mirror, el);
|
||||
if (!iface.getFullName().startsWith("java")){
|
||||
superTypes.add(iface.getFullName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
throw new IllegalArgumentException("Unsupported type kind " + type.getKind());
|
||||
}
|
||||
|
||||
return new EntityModel(configuration.getNamePrefix(), value, superTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -208,7 +284,8 @@ public class APTModelFactory implements TypeVisitor<TypeModel,Elements> {
|
||||
}
|
||||
|
||||
|
||||
private TypeModel create(TypeElement typeElement, TypeCategory category, Elements p, List<? extends TypeMirror> typeArgs) {
|
||||
private TypeModel create(TypeElement typeElement, TypeCategory category,
|
||||
Elements p, List<? extends TypeMirror> typeArgs) {
|
||||
String name = typeElement.getQualifiedName().toString();
|
||||
String simpleName = typeElement.getSimpleName().toString();
|
||||
String packageName = p.getPackageOf(typeElement).getQualifiedName().toString();
|
||||
@ -11,6 +11,8 @@ import javax.lang.model.element.VariableElement;
|
||||
import com.mysema.query.codegen.Serializer;
|
||||
|
||||
/**
|
||||
* Configuration defines the configuration options for APT based Querydsl code generation
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
@ -42,6 +44,8 @@ public interface Configuration {
|
||||
|
||||
Serializer getSupertypeSerializer();
|
||||
|
||||
Serializer getDTOSerializer();
|
||||
|
||||
Serializer getEmbeddableSerializer();
|
||||
|
||||
boolean isUseFields();
|
||||
|
||||
@ -22,9 +22,12 @@ import net.jcip.annotations.Immutable;
|
||||
import com.mysema.query.codegen.EntityModel;
|
||||
import com.mysema.query.codegen.ConstructorModel;
|
||||
import com.mysema.query.codegen.ParameterModel;
|
||||
import com.mysema.query.codegen.TypeCategory;
|
||||
import com.mysema.query.codegen.TypeModel;
|
||||
|
||||
/**
|
||||
* DTOElementVisitor is an APT visitor for DTO types
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
@ -33,11 +36,11 @@ public final class DTOElementVisitor extends SimpleElementVisitor6<EntityModel,
|
||||
|
||||
private final ProcessingEnvironment env;
|
||||
|
||||
private final APTModelFactory typeFactory;
|
||||
private final APTTypeModelFactory typeFactory;
|
||||
|
||||
private final SimpleConfiguration configuration;
|
||||
private final Configuration configuration;
|
||||
|
||||
DTOElementVisitor(ProcessingEnvironment env, SimpleConfiguration configuration, APTModelFactory typeFactory){
|
||||
DTOElementVisitor(ProcessingEnvironment env, Configuration configuration, APTTypeModelFactory typeFactory){
|
||||
this.env = env;
|
||||
this.configuration = configuration;
|
||||
this.typeFactory = typeFactory;
|
||||
@ -47,10 +50,9 @@ public final class DTOElementVisitor extends SimpleElementVisitor6<EntityModel,
|
||||
public EntityModel visitType(TypeElement e, Void p) {
|
||||
Elements elementUtils = env.getElementUtils();
|
||||
TypeModel c = typeFactory.create(e.asType(), elementUtils);
|
||||
EntityModel classModel = new EntityModel(configuration.getNamePrefix(), c);
|
||||
EntityModel classModel = new EntityModel(configuration.getNamePrefix(), c.as(TypeCategory.ENTITY));
|
||||
List<? extends Element> elements = e.getEnclosedElements();
|
||||
|
||||
// CONSTRUCTOR
|
||||
for (ExecutableElement constructor : ElementFilter.constructorsIn(elements)){
|
||||
if (configuration.isValidConstructor(constructor)){
|
||||
List<ParameterModel> parameters = new ArrayList<ParameterModel>(constructor.getParameters().size());
|
||||
|
||||
@ -6,8 +6,6 @@
|
||||
package com.mysema.query.apt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -16,11 +14,9 @@ import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.SimpleElementVisitor6;
|
||||
@ -31,14 +27,16 @@ import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.mysema.query.annotations.QueryInit;
|
||||
import com.mysema.query.annotations.QueryType;
|
||||
import com.mysema.query.codegen.EntityModel;
|
||||
import com.mysema.query.codegen.ConstructorModel;
|
||||
import com.mysema.query.codegen.EntityModel;
|
||||
import com.mysema.query.codegen.ParameterModel;
|
||||
import com.mysema.query.codegen.PropertyModel;
|
||||
import com.mysema.query.codegen.TypeCategory;
|
||||
import com.mysema.query.codegen.TypeModel;
|
||||
|
||||
/**
|
||||
* EntityElementVisitor is a an APT visitor for entity types
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
@ -47,146 +45,146 @@ public final class EntityElementVisitor extends SimpleElementVisitor6<EntityMode
|
||||
|
||||
private final ProcessingEnvironment env;
|
||||
|
||||
private final APTModelFactory typeFactory;
|
||||
private final APTTypeModelFactory typeFactory;
|
||||
|
||||
private final SimpleConfiguration configuration;
|
||||
private final Configuration configuration;
|
||||
|
||||
EntityElementVisitor(ProcessingEnvironment env, SimpleConfiguration conf, APTModelFactory typeFactory){
|
||||
EntityElementVisitor(ProcessingEnvironment env, Configuration configuration,
|
||||
APTTypeModelFactory typeFactory){
|
||||
this.env = env;
|
||||
this.configuration = conf;
|
||||
this.configuration = configuration;
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityModel visitType(TypeElement e, Void p) {
|
||||
Elements elementUtils = env.getElementUtils();
|
||||
Collection<String> superTypes;
|
||||
if (e.getKind() == ElementKind.CLASS){
|
||||
superTypes = Collections.singleton(typeFactory.create(e.getSuperclass(), elementUtils).getFullName());
|
||||
}else{
|
||||
superTypes = new ArrayList<String>(e.getInterfaces().size());
|
||||
for (TypeMirror mirror : e.getInterfaces()){
|
||||
TypeModel iface = typeFactory.create(mirror, elementUtils);
|
||||
if (!iface.getFullName().startsWith("java")){
|
||||
superTypes.add(iface.getFullName());
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeModel c = typeFactory.create(e.asType(), elementUtils);
|
||||
EntityModel classModel = new EntityModel(configuration.getNamePrefix(), c, superTypes);
|
||||
EntityModel entityModel = typeFactory.createEntityModel(e.asType(), elementUtils);
|
||||
List<? extends Element> elements = e.getEnclosedElements();
|
||||
|
||||
// CONSTRUCTORS
|
||||
VisitorConfig config = configuration.getConfig(e, elements);
|
||||
|
||||
Set<String> blockedProperties = new HashSet<String>();
|
||||
Map<String,PropertyModel> properties = new HashMap<String,PropertyModel>();
|
||||
Map<String,TypeCategory> types = new HashMap<String,TypeCategory>();
|
||||
|
||||
if (config.isVisitConstructors()){
|
||||
visitConstructors(elementUtils, entityModel, elements);
|
||||
}
|
||||
|
||||
if (config.isVisitFields()){
|
||||
visitFields(elementUtils, entityModel, elements, blockedProperties, properties, types);
|
||||
}
|
||||
|
||||
if (config.isVisitMethods()){
|
||||
visitMethods(elementUtils, entityModel, elements, blockedProperties, properties, types);
|
||||
}
|
||||
|
||||
for (Map.Entry<String,PropertyModel> entry : properties.entrySet()){
|
||||
if (!blockedProperties.contains(entry.getKey())){
|
||||
entityModel.addProperty(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return entityModel;
|
||||
}
|
||||
|
||||
private void visitConstructors(Elements elementUtils, EntityModel entityModel, List<? extends Element> elements) {
|
||||
for (ExecutableElement constructor : ElementFilter.constructorsIn(elements)){
|
||||
if (configuration.isValidConstructor(constructor)){
|
||||
List<ParameterModel> parameters = new ArrayList<ParameterModel>(constructor.getParameters().size());
|
||||
for (VariableElement var : constructor.getParameters()){
|
||||
TypeModel varType = typeFactory.create(var.asType(), elementUtils);
|
||||
parameters.add(new ParameterModel(classModel, var.getSimpleName().toString(), varType));
|
||||
parameters.add(new ParameterModel(entityModel, var.getSimpleName().toString(), varType));
|
||||
}
|
||||
classModel.addConstructor(new ConstructorModel(parameters));
|
||||
entityModel.addConstructor(new ConstructorModel(parameters));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisitorConfig config = configuration.getConfig(e, elements);
|
||||
|
||||
Set<String> blockedProperties = new HashSet<String>();
|
||||
Map<String,PropertyModel> properties = new HashMap<String,PropertyModel>();
|
||||
Map<String,TypeCategory> types = new HashMap<String,TypeCategory>();
|
||||
|
||||
// FIELDS
|
||||
|
||||
// are fields visited ?
|
||||
if (config.isVisitFields()){
|
||||
for (VariableElement field : ElementFilter.fieldsIn(elements)){
|
||||
String name = field.getSimpleName().toString();
|
||||
// is particular field visited ?
|
||||
if (configuration.isValidField(field)){
|
||||
try{
|
||||
TypeModel typeModel = typeFactory.create(field.asType(), elementUtils);
|
||||
if (field.getAnnotation(QueryType.class) != null){
|
||||
TypeCategory typeCategory = TypeCategory.get(field.getAnnotation(QueryType.class).value());
|
||||
if (typeCategory == null){
|
||||
blockedProperties.add(name);
|
||||
continue;
|
||||
}
|
||||
typeModel = typeModel.as(typeCategory);
|
||||
types.put(name, typeCategory);
|
||||
}
|
||||
String[] inits = new String[0];
|
||||
if (field.getAnnotation(QueryInit.class) != null){
|
||||
inits = field.getAnnotation(QueryInit.class).value();
|
||||
}
|
||||
properties.put(name, new PropertyModel(classModel, name, typeModel, inits));
|
||||
}catch(IllegalArgumentException ex){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Caught exception for field ");
|
||||
builder.append(c.getFullName()).append("#").append(field.getSimpleName());
|
||||
throw new RuntimeException(builder.toString(), ex);
|
||||
}
|
||||
|
||||
}else{
|
||||
blockedProperties.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// METHODS
|
||||
|
||||
// are methods visited ?
|
||||
if (config.isVisitMethods()){
|
||||
for (ExecutableElement method : ElementFilter.methodsIn(elements)){
|
||||
String name = method.getSimpleName().toString();
|
||||
if (name.startsWith("get") && method.getParameters().isEmpty()){
|
||||
name = StringUtils.uncapitalize(name.substring(3));
|
||||
}else if (name.startsWith("is") && method.getParameters().isEmpty()){
|
||||
name = StringUtils.uncapitalize(name.substring(2));
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
|
||||
// is particular method visited ?
|
||||
if (configuration.isValidGetter(method)){
|
||||
try{
|
||||
TypeModel typeModel = typeFactory.create(method.getReturnType(), elementUtils);
|
||||
if (method.getAnnotation(QueryType.class) != null){
|
||||
TypeCategory typeCategory = TypeCategory.get(method.getAnnotation(QueryType.class).value());
|
||||
if (typeCategory == null){
|
||||
blockedProperties.add(name);
|
||||
continue;
|
||||
}else if (blockedProperties.contains(name)){
|
||||
continue;
|
||||
}
|
||||
typeModel = typeModel.as(typeCategory);
|
||||
}else if (types.containsKey(name)){
|
||||
typeModel = typeModel.as(types.get(name));
|
||||
}
|
||||
String[] inits = new String[0];
|
||||
if (method.getAnnotation(QueryInit.class) != null){
|
||||
inits = method.getAnnotation(QueryInit.class).value();
|
||||
}
|
||||
properties.put(name, new PropertyModel(classModel, name, typeModel, inits));
|
||||
|
||||
}catch(IllegalArgumentException ex){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Caught exception for method ");
|
||||
builder.append(c.getFullName()).append("#").append(method.getSimpleName());
|
||||
throw new RuntimeException(builder.toString(), ex);
|
||||
}
|
||||
}else{
|
||||
blockedProperties.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String,PropertyModel> entry : properties.entrySet()){
|
||||
if (!blockedProperties.contains(entry.getKey())){
|
||||
classModel.addProperty(entry.getValue());
|
||||
private void visitMethods(Elements elementUtils, EntityModel entityModel,
|
||||
List<? extends Element> elements, Set<String> blockedProperties,
|
||||
Map<String, PropertyModel> properties,
|
||||
Map<String, TypeCategory> types) {
|
||||
for (ExecutableElement method : ElementFilter.methodsIn(elements)){
|
||||
String name = method.getSimpleName().toString();
|
||||
if (name.startsWith("get") && method.getParameters().isEmpty()){
|
||||
name = StringUtils.uncapitalize(name.substring(3));
|
||||
}else if (name.startsWith("is") && method.getParameters().isEmpty()){
|
||||
name = StringUtils.uncapitalize(name.substring(2));
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return classModel;
|
||||
|
||||
if (!configuration.isValidGetter(method)){
|
||||
blockedProperties.add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
try{
|
||||
TypeModel propertyType = typeFactory.create(method.getReturnType(), elementUtils);
|
||||
if (method.getAnnotation(QueryType.class) != null){
|
||||
TypeCategory typeCategory = TypeCategory.get(method.getAnnotation(QueryType.class).value());
|
||||
if (typeCategory == null){
|
||||
blockedProperties.add(name);
|
||||
continue;
|
||||
}else if (blockedProperties.contains(name)){
|
||||
continue;
|
||||
}
|
||||
propertyType = propertyType.as(typeCategory);
|
||||
}else if (types.containsKey(name)){
|
||||
propertyType = propertyType.as(types.get(name));
|
||||
}
|
||||
String[] inits = new String[0];
|
||||
if (method.getAnnotation(QueryInit.class) != null){
|
||||
inits = method.getAnnotation(QueryInit.class).value();
|
||||
}
|
||||
properties.put(name, new PropertyModel(entityModel, name, propertyType, inits));
|
||||
|
||||
}catch(IllegalArgumentException ex){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Caught exception for method ");
|
||||
builder.append(entityModel.getFullName()).append("#").append(method.getSimpleName());
|
||||
throw new RuntimeException(builder.toString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void visitFields(Elements elementUtils, EntityModel entityModel,
|
||||
List<? extends Element> elements, Set<String> blockedProperties,
|
||||
Map<String, PropertyModel> properties,
|
||||
Map<String, TypeCategory> types) {
|
||||
for (VariableElement field : ElementFilter.fieldsIn(elements)){
|
||||
String name = field.getSimpleName().toString();
|
||||
// is particular field visited ?
|
||||
if (!configuration.isValidField(field)){
|
||||
blockedProperties.add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
try{
|
||||
TypeModel fieldType = typeFactory.create(field.asType(), elementUtils);
|
||||
if (field.getAnnotation(QueryType.class) != null){
|
||||
TypeCategory typeCategory = TypeCategory.get(field.getAnnotation(QueryType.class).value());
|
||||
if (typeCategory == null){
|
||||
blockedProperties.add(name);
|
||||
continue;
|
||||
}
|
||||
fieldType = fieldType.as(typeCategory);
|
||||
types.put(name, typeCategory);
|
||||
}
|
||||
String[] inits = new String[0];
|
||||
if (field.getAnnotation(QueryInit.class) != null){
|
||||
inits = field.getAnnotation(QueryInit.class).value();
|
||||
}
|
||||
properties.put(name, new PropertyModel(entityModel, name, fieldType, inits));
|
||||
}catch(IllegalArgumentException ex){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Caught exception for field ");
|
||||
builder.append(entityModel.getFullName()).append("#").append(field.getSimpleName());
|
||||
throw new RuntimeException(builder.toString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ package com.mysema.query.apt;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -15,6 +15,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
@ -42,26 +43,27 @@ public class Processor {
|
||||
|
||||
private final ProcessingEnvironment env;
|
||||
|
||||
private final APTModelFactory typeFactory;
|
||||
private final APTTypeModelFactory typeFactory;
|
||||
|
||||
private final SimpleConfiguration conf;
|
||||
private final Configuration configuration;
|
||||
|
||||
private final EntityModelFactory entityModelFactory;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Processor(ProcessingEnvironment env, SimpleConfiguration configuration) {
|
||||
this.conf = configuration;
|
||||
List<Class<? extends Annotation>> anns ;
|
||||
if (conf.getEmbeddableAnn() != null){
|
||||
anns = Arrays.<Class<? extends Annotation>>asList(conf.getEntityAnn(), conf.getEmbeddableAnn());
|
||||
}else{
|
||||
anns = Arrays.<Class<? extends Annotation>>asList(conf.getEntityAnn());
|
||||
public Processor(ProcessingEnvironment env, Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
List<Class<? extends Annotation>> anns = new ArrayList<Class<? extends Annotation>>();
|
||||
anns.add(configuration.getEntityAnn());
|
||||
if (configuration.getSuperTypeAnn() != null){
|
||||
anns.add(configuration.getSuperTypeAnn());
|
||||
}
|
||||
if (configuration.getEmbeddableAnn() != null){
|
||||
anns.add(configuration.getEmbeddableAnn());
|
||||
}
|
||||
this.env = Assert.notNull(env);
|
||||
TypeModelFactory factory = new TypeModelFactory(anns);
|
||||
this.typeFactory = new APTModelFactory(env, factory, anns);
|
||||
if (conf.getSkipAnn() != null){
|
||||
this.entityModelFactory = new EntityModelFactory(factory, conf.getSkipAnn());
|
||||
this.typeFactory = new APTTypeModelFactory(env, configuration, factory, anns);
|
||||
if (configuration.getSkipAnn() != null){
|
||||
this.entityModelFactory = new EntityModelFactory(factory, configuration.getSkipAnn());
|
||||
}else{
|
||||
this.entityModelFactory = new EntityModelFactory(factory);
|
||||
}
|
||||
@ -69,30 +71,41 @@ public class Processor {
|
||||
}
|
||||
|
||||
public void process(RoundEnvironment roundEnv) {
|
||||
Map<String, EntityModel> superTypes = new HashMap<String, EntityModel>();
|
||||
EntityElementVisitor entityVisitor = new EntityElementVisitor(env, conf, typeFactory);
|
||||
|
||||
// supertypes
|
||||
if (conf.getSuperTypeAnn() != null) {
|
||||
handleSupertypes(roundEnv, superTypes, entityVisitor);
|
||||
}
|
||||
|
||||
// entities
|
||||
handleEntities(roundEnv, superTypes, entityVisitor);
|
||||
|
||||
// embeddables
|
||||
if (conf.getEmbeddableAnn() != null){
|
||||
handleEmbeddables(roundEnv, superTypes, entityVisitor);
|
||||
}
|
||||
|
||||
// projections
|
||||
DTOElementVisitor dtoVisitor = new DTOElementVisitor(env, conf, typeFactory);
|
||||
Map<String, EntityModel> actualSupertypes = new HashMap<String, EntityModel>();
|
||||
Map<String, EntityModel> allSupertypes = new HashMap<String, EntityModel>();
|
||||
Map<String, EntityModel> entityTypes = new HashMap<String, EntityModel>();
|
||||
Map<String,EntityModel> embeddables = new HashMap<String,EntityModel>();
|
||||
Map<String, EntityModel> dtos = new HashMap<String, EntityModel>();
|
||||
|
||||
EntityElementVisitor entityVisitor = new EntityElementVisitor(env, configuration, typeFactory);
|
||||
DTOElementVisitor dtoVisitor = new DTOElementVisitor(env, configuration, typeFactory);
|
||||
|
||||
// create models
|
||||
if (configuration.getSuperTypeAnn() != null) {
|
||||
handleSupertypes(roundEnv, actualSupertypes, entityVisitor);
|
||||
allSupertypes.putAll(actualSupertypes);
|
||||
}
|
||||
handleEntities(roundEnv, allSupertypes, entityTypes, entityVisitor);
|
||||
if (configuration.getEmbeddableAnn() != null){
|
||||
handleEmbeddables(roundEnv, allSupertypes, embeddables, entityVisitor);
|
||||
}
|
||||
handleDTOs(roundEnv, dtos, dtoVisitor);
|
||||
|
||||
// serialize models
|
||||
serialize(configuration.getSupertypeSerializer(), actualSupertypes);
|
||||
serialize(configuration.getEntitySerializer(), entityTypes);
|
||||
serialize(configuration.getEmbeddableSerializer(), embeddables);
|
||||
serialize(configuration.getDTOSerializer(), dtos);
|
||||
|
||||
}
|
||||
|
||||
private void handleDTOs(RoundEnvironment roundEnv,
|
||||
Map<String, EntityModel> dtos, DTOElementVisitor dtoVisitor) {
|
||||
Set<Element> visitedDTOTypes = new HashSet<Element>();
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(QueryProjection.class)) {
|
||||
Element parent = element.getEnclosingElement();
|
||||
if (parent.getAnnotation(conf.getEntityAnn()) == null
|
||||
&& parent.getAnnotation(conf.getEmbeddableAnn()) == null
|
||||
if (parent.getAnnotation(configuration.getEntityAnn()) == null
|
||||
&& parent.getAnnotation(configuration.getEmbeddableAnn()) == null
|
||||
&& !visitedDTOTypes.contains(parent)){
|
||||
EntityModel model = parent.accept(dtoVisitor, null);
|
||||
dtos.put(model.getFullName(), model);
|
||||
@ -100,18 +113,13 @@ public class Processor {
|
||||
|
||||
}
|
||||
}
|
||||
// serialize entity types
|
||||
if (!dtos.isEmpty()) {
|
||||
serialize(conf.getDTOSerializer(), dtos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleSupertypes(RoundEnvironment roundEnv,
|
||||
Map<String, EntityModel> superTypes,
|
||||
EntityElementVisitor entityVisitor) {
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(conf.getSuperTypeAnn())) {
|
||||
if (conf.getEmbeddableAnn() == null || element.getAnnotation(conf.getEmbeddableAnn()) == null){
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(configuration.getSuperTypeAnn())) {
|
||||
if (configuration.getEmbeddableAnn() == null || element.getAnnotation(configuration.getEmbeddableAnn()) == null){
|
||||
EntityModel model = element.accept(entityVisitor, null);
|
||||
superTypes.put(model.getFullName(), model);
|
||||
}
|
||||
@ -120,19 +128,13 @@ public class Processor {
|
||||
for (EntityModel superType : superTypes.values()) {
|
||||
addSupertypeFields(superType, superTypes);
|
||||
}
|
||||
// serialize supertypes
|
||||
if (!superTypes.isEmpty()){
|
||||
serialize(conf.getSupertypeSerializer(), superTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEmbeddables(RoundEnvironment roundEnv,
|
||||
Map<String, EntityModel> superTypes,
|
||||
EntityElementVisitor entityVisitor) {
|
||||
// populate entity type mappings
|
||||
Map<String, EntityModel> embeddables = new HashMap<String, EntityModel>();
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(conf.getEmbeddableAnn())) {
|
||||
Map<String, EntityModel> embeddables,
|
||||
EntityElementVisitor entityVisitor) {
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(configuration.getEmbeddableAnn())) {
|
||||
EntityModel model = element.accept(entityVisitor, null);
|
||||
embeddables.put(model.getFullName(), model);
|
||||
}
|
||||
@ -142,19 +144,16 @@ public class Processor {
|
||||
for (EntityModel embeddable : embeddables.values()) {
|
||||
addSupertypeFields(embeddable, superTypes);
|
||||
}
|
||||
// serialize entity types
|
||||
if (!embeddables.isEmpty()) {
|
||||
serialize(conf.getEmbeddableSerializer(), embeddables);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEntities(RoundEnvironment roundEnv,
|
||||
Map<String, EntityModel> superTypes,
|
||||
Map<String, EntityModel> entityTypes,
|
||||
EntityElementVisitor entityVisitor) {
|
||||
// populate entity type mappings
|
||||
Map<String, EntityModel> entityTypes = new HashMap<String, EntityModel>();
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(conf.getEntityAnn())) {
|
||||
if (conf.getEmbeddableAnn() == null || element.getAnnotation(conf.getEmbeddableAnn()) == null){
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(configuration.getEntityAnn())) {
|
||||
if (configuration.getEmbeddableAnn() == null || element.getAnnotation(configuration.getEmbeddableAnn()) == null){
|
||||
EntityModel model = element.accept(entityVisitor, null);
|
||||
entityTypes.put(model.getFullName(), model);
|
||||
}
|
||||
@ -165,10 +164,6 @@ public class Processor {
|
||||
for (EntityModel entityType : entityTypes.values()) {
|
||||
addSupertypeFields(entityType, superTypes);
|
||||
}
|
||||
// serialize entity types
|
||||
if (!entityTypes.isEmpty()) {
|
||||
serialize(conf.getEntitySerializer(), entityTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSupertypeFields(EntityModel model, Map<String, EntityModel> superTypes) {
|
||||
@ -200,10 +195,10 @@ public class Processor {
|
||||
Class<?> superClass = safeClassForName(stype);
|
||||
if (superClass != null && !superClass.equals(Object.class)) {
|
||||
// handle the supertype only, if it has the proper annotations
|
||||
if ((conf.getSuperTypeAnn() == null
|
||||
|| superClass.getAnnotation(conf.getSuperTypeAnn()) != null)
|
||||
|| superClass.getAnnotation(conf.getEntityAnn()) != null) {
|
||||
EntityModel type = entityModelFactory.create(superClass, conf.getNamePrefix());
|
||||
if ((configuration.getSuperTypeAnn() == null
|
||||
|| superClass.getAnnotation(configuration.getSuperTypeAnn()) != null)
|
||||
|| superClass.getAnnotation(configuration.getEntityAnn()) != null) {
|
||||
EntityModel type = entityModelFactory.create(superClass, configuration.getNamePrefix());
|
||||
// include fields of supertype
|
||||
model.include(type);
|
||||
}
|
||||
@ -211,6 +206,7 @@ public class Processor {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Class<?> safeClassForName(String stype) {
|
||||
try {
|
||||
return Class.forName(stype);
|
||||
@ -225,7 +221,7 @@ public class Processor {
|
||||
msg.printMessage(Kind.NOTE, type.getFullName() + " is processed");
|
||||
try {
|
||||
String packageName = type.getPackageName();
|
||||
String className = packageName + "." + conf.getNamePrefix() + type.getSimpleName();
|
||||
String className = packageName + "." + configuration.getNamePrefix() + type.getSimpleName();
|
||||
JavaFileObject fileObject = env.getFiler().createSourceFile(className);
|
||||
Writer writer = fileObject.openWriter();
|
||||
try {
|
||||
|
||||
@ -8,6 +8,7 @@ package com.mysema.query.apt;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
@ -23,6 +24,8 @@ import com.mysema.query.codegen.Serializer;
|
||||
import com.mysema.query.codegen.SupertypeSerializer;
|
||||
|
||||
/**
|
||||
* SimpleConfiguration is a simple implementation of the Configuration interface
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
@ -38,12 +41,16 @@ public class SimpleConfiguration implements Configuration {
|
||||
|
||||
private final Serializer dtoSerializer = new DTOSerializer();
|
||||
|
||||
protected final Class<? extends Annotation> entityAnn, superTypeAnn, embeddableAnn, skipAnn;
|
||||
protected final Class<? extends Annotation> entityAnn, embeddableAnn, skipAnn;
|
||||
|
||||
@Nullable
|
||||
protected final Class<? extends Annotation> superTypeAnn;
|
||||
|
||||
private boolean useFields = true, useGetters = true;
|
||||
|
||||
public SimpleConfiguration(
|
||||
Class<? extends Annotation> entityAnn,
|
||||
@Nullable
|
||||
Class<? extends Annotation> superTypeAnn,
|
||||
Class<? extends Annotation> embeddableAnn,
|
||||
Class<? extends Annotation> skipAnn) {
|
||||
@ -53,9 +60,7 @@ public class SimpleConfiguration implements Configuration {
|
||||
this.skipAnn = skipAnn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getConfig(javax.lang.model.element.TypeElement, java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public VisitorConfig getConfig(TypeElement e, List<? extends Element> elements){
|
||||
if (useFields){
|
||||
if (useGetters){
|
||||
@ -67,131 +72,95 @@ public class SimpleConfiguration implements Configuration {
|
||||
return VisitorConfig.METHODS_ONLY;
|
||||
}else{
|
||||
return VisitorConfig.NONE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#isValidConstructor(javax.lang.model.element.ExecutableElement)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isValidConstructor(ExecutableElement constructor) {
|
||||
return constructor.getModifiers().contains(Modifier.PUBLIC)
|
||||
&& constructor.getAnnotation(QueryProjection.class) != null
|
||||
&& !constructor.getParameters().isEmpty();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#isValidField(javax.lang.model.element.VariableElement)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isValidField(VariableElement field) {
|
||||
return field.getAnnotation(skipAnn) == null
|
||||
&& !field.getModifiers().contains(Modifier.TRANSIENT)
|
||||
&& !field.getModifiers().contains(Modifier.STATIC);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#isValidGetter(javax.lang.model.element.ExecutableElement)
|
||||
*/
|
||||
@Override
|
||||
public boolean isValidGetter(ExecutableElement getter){
|
||||
return getter.getAnnotation(skipAnn) == null
|
||||
&& !getter.getModifiers().contains(Modifier.STATIC);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getEntityAnn()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends Annotation> getEntityAnn() {
|
||||
return entityAnn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getSuperTypeAnn()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends Annotation> getSuperTypeAnn() {
|
||||
return superTypeAnn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getEmbeddableAnn()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends Annotation> getEmbeddableAnn() {
|
||||
return embeddableAnn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getSkipAnn()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends Annotation> getSkipAnn() {
|
||||
return skipAnn;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#setUseGetters(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void setUseGetters(boolean b) {
|
||||
this.useGetters = b;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#setUseFields(boolean)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void setUseFields(boolean b){
|
||||
this.useFields = b;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getNamePrefix()
|
||||
*/
|
||||
@Override
|
||||
public String getNamePrefix() {
|
||||
return namePrefix;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getEntitySerializer()
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Serializer getEntitySerializer() {
|
||||
return entitySerializer;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getSupertypeSerializer()
|
||||
*/
|
||||
@Override
|
||||
public Serializer getSupertypeSerializer() {
|
||||
return supertypeSerializer;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getEmbeddableSerializer()
|
||||
*/
|
||||
@Override
|
||||
public Serializer getEmbeddableSerializer() {
|
||||
return embeddableSerializer;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#isUseFields()
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseFields() {
|
||||
return useFields;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#isUseGetters()
|
||||
*/
|
||||
@Override
|
||||
public boolean isUseGetters() {
|
||||
return useGetters;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#setNamePrefix(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setNamePrefix(String namePrefix) {
|
||||
this.namePrefix = namePrefix;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.mysema.query.apt.Configuration#getDTOSerializer()
|
||||
*/
|
||||
@Override
|
||||
public Serializer getDTOSerializer() {
|
||||
return dtoSerializer;
|
||||
}
|
||||
|
||||
@ -6,26 +6,29 @@
|
||||
package com.mysema.query.apt;
|
||||
|
||||
/**
|
||||
* VisitorConfig defines the entity type specific visiting configuration
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public enum VisitorConfig {
|
||||
/**
|
||||
*
|
||||
* visit both fields and getters
|
||||
*/
|
||||
ALL(true,true),
|
||||
|
||||
/**
|
||||
*
|
||||
* visit fields only
|
||||
*/
|
||||
FIELDS_ONLY(true,false),
|
||||
|
||||
/**
|
||||
*
|
||||
* visit methods only
|
||||
*/
|
||||
METHODS_ONLY(false,true),
|
||||
|
||||
/**
|
||||
*
|
||||
* visit none
|
||||
*/
|
||||
NONE(false,false);
|
||||
|
||||
@ -43,5 +46,10 @@ public enum VisitorConfig {
|
||||
public boolean isVisitMethods(){
|
||||
return methods;
|
||||
}
|
||||
|
||||
public boolean isVisitConstructors() {
|
||||
// TODO : parametrize!
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,5 +7,10 @@
|
||||
/**
|
||||
* APT Hibernate support
|
||||
*/
|
||||
@DefaultAnnotation({ Nonnull.class })
|
||||
package com.mysema.query.apt.hibernate;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ import com.mysema.query.apt.Processor;
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class JDOAnnotationProcessor extends AbstractProcessor{
|
||||
|
||||
private Class<? extends Annotation> entity, superType, embeddable, skip;
|
||||
private Class<? extends Annotation> entity, embeddable, skip;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@ -35,11 +35,10 @@ public class JDOAnnotationProcessor extends AbstractProcessor{
|
||||
try {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName());
|
||||
entity = (Class)Class.forName("javax.jdo.annotations.PersistenceCapable");
|
||||
superType = null; // ?!?
|
||||
embeddable = (Class)Class.forName("javax.jdo.annotations.EmbeddedOnly");
|
||||
skip = (Class)Class.forName("javax.jdo.annotations.NotPersistent");
|
||||
|
||||
SimpleConfiguration configuration = new SimpleConfiguration(entity, superType, embeddable, skip);
|
||||
SimpleConfiguration configuration = new SimpleConfiguration(entity, null, embeddable, skip);
|
||||
configuration.setUseGetters(false);
|
||||
Processor processor = new Processor(processingEnv, configuration);
|
||||
processor.process(roundEnv);
|
||||
|
||||
@ -7,5 +7,10 @@
|
||||
/**
|
||||
* APT JDO support
|
||||
*/
|
||||
@DefaultAnnotation({ Nonnull.class })
|
||||
package com.mysema.query.apt.jdo;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
|
||||
|
||||
|
||||
@ -7,5 +7,10 @@
|
||||
/**
|
||||
* APT JPA support
|
||||
*/
|
||||
@DefaultAnnotation({ Nonnull.class })
|
||||
package com.mysema.query.apt.jpa;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
|
||||
|
||||
|
||||
@ -7,5 +7,10 @@
|
||||
/**
|
||||
* APTFactory and related classes
|
||||
*/
|
||||
@DefaultAnnotation({ Nonnull.class })
|
||||
package com.mysema.query.apt;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
|
||||
|
||||
|
||||
@ -7,11 +7,18 @@ import org.junit.Test;
|
||||
import com.mysema.query.annotations.QueryEntity;
|
||||
import com.mysema.query.annotations.QueryInit;
|
||||
import com.mysema.query.annotations.QuerySupertype;
|
||||
import com.mysema.query.types.path.PathInits;
|
||||
import com.mysema.query.types.path.PathMetadata;
|
||||
|
||||
public class EntityTest extends AbstractTest{
|
||||
|
||||
private static final QEntity3 entity3 = QEntity3.entity3;
|
||||
|
||||
@QueryEntity
|
||||
public static class EntityNoReferences {
|
||||
|
||||
}
|
||||
|
||||
@QueryEntity
|
||||
public static class Entity1 {
|
||||
public String entity1Field;
|
||||
@ -70,5 +77,23 @@ public class EntityTest extends AbstractTest{
|
||||
assertNotNull(QEntity4.entity4.supertypeField);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testConstructors() throws SecurityException, NoSuchMethodException{
|
||||
Class[] types = new Class[]{Class.class, String.class, PathMetadata.class, PathInits.class};
|
||||
QEntity1.class.getConstructor(types);
|
||||
QEntity2.class.getConstructor(types);
|
||||
QEntity3.class.getConstructor(types);
|
||||
QEntity4.class.getConstructor(types);
|
||||
QSupertype.class.getConstructor(types);
|
||||
QSupertype2.class.getConstructor(types);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected=NoSuchMethodException.class)
|
||||
public void testConstructors2() throws SecurityException, NoSuchMethodException{
|
||||
Class[] types = new Class[]{Class.class, String.class, PathMetadata.class, PathInits.class};
|
||||
QEntityNoReferences.class.getConstructor(types);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
@ -18,7 +18,7 @@ import org.apache.commons.lang.StringUtils;
|
||||
import com.mysema.commons.lang.Assert;
|
||||
|
||||
/**
|
||||
* BeanModel represents the model of a query domain type with properties
|
||||
* EntityModel represents a model of a query domain type with properties
|
||||
*
|
||||
* @author tiwe
|
||||
* @version $Id$
|
||||
@ -146,6 +146,5 @@ public final class EntityModel extends TypeModelAdapter implements Comparable<En
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -77,20 +77,20 @@ public class EntitySerializer implements Serializer{
|
||||
|
||||
|
||||
// 4
|
||||
if (!localName.equals(genericName)){
|
||||
builder.append(" @SuppressWarnings(\"unchecked\")\n");
|
||||
}
|
||||
builder.append(" public " + queryType + "(PathMetadata<?> metadata, PathInits inits) {\n");
|
||||
builder.append(" "+thisOrSuper+"(");
|
||||
if (!localName.equals(genericName)){
|
||||
builder.append("(Class)");
|
||||
}
|
||||
builder.append(localName + ".class, \"" + simpleName + "\", metadata");
|
||||
if (hasEntityFields){
|
||||
if (!localName.equals(genericName)){
|
||||
builder.append(" @SuppressWarnings(\"unchecked\")\n");
|
||||
}
|
||||
builder.append(" public " + queryType + "(PathMetadata<?> metadata, PathInits inits) {\n");
|
||||
builder.append(" "+thisOrSuper+"(");
|
||||
if (!localName.equals(genericName)){
|
||||
builder.append("(Class)");
|
||||
}
|
||||
builder.append(localName + ".class, \"" + simpleName + "\", metadata");
|
||||
builder.append(", inits");
|
||||
}
|
||||
builder.append(");\n");
|
||||
builder.append(" }\n\n");
|
||||
builder.append(");\n");
|
||||
builder.append(" }\n\n");
|
||||
}
|
||||
|
||||
// 5
|
||||
if (hasEntityFields){
|
||||
@ -161,12 +161,17 @@ public class EntitySerializer implements Serializer{
|
||||
for (PropertyModel field : model.getProperties()){
|
||||
if (field.getTypeCategory() == TypeCategory.ENTITY){
|
||||
builder.append(" this." + field.getEscapedName() + " = ");
|
||||
if (!field.isInherited()){
|
||||
if (!field.isInherited()){
|
||||
builder.append("inits.isInitialized(\""+field.getName()+"\") ? ");
|
||||
builder.append("new " + field.getQueryTypeName() + "(PathMetadata.forProperty(this,\"" + field.getName() + "\"), inits.getInits(\""+field.getName()+"\")) : null;\n");
|
||||
builder.append("new " + field.getQueryTypeName() + "(PathMetadata.forProperty(this,\"" + field.getName() + "\")");
|
||||
if (field.hasEntityFields()){
|
||||
builder.append(", inits.getInits(\""+field.getName()+"\")");
|
||||
}
|
||||
builder.append(") : null;\n");
|
||||
}else{
|
||||
builder.append("_super." + field.getEscapedName() +";\n");
|
||||
}
|
||||
|
||||
}else if (field.isInherited() && superModel != null && superModel.hasEntityFields()){
|
||||
builder.append(" this." + field.getEscapedName() + " = ");
|
||||
builder.append("_super." + field.getEscapedName() + ";\n");
|
||||
|
||||
@ -32,7 +32,7 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
@Nullable
|
||||
private final String queryTypeName;
|
||||
|
||||
private final TypeModel type;
|
||||
private final TypeModel propertyType;
|
||||
|
||||
private final String[] inits;
|
||||
|
||||
@ -44,20 +44,11 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
this.context = classModel;
|
||||
this.name = Assert.notNull(name);
|
||||
this.escapedName = JavaSyntaxUtils.isReserved(name) ? (name + "_") : name;
|
||||
this.type = Assert.notNull(type);
|
||||
this.typeName = type.getLocalRawName(classModel, new StringBuilder()).toString();
|
||||
if (type.getTypeCategory().isSubCategoryOf(TypeCategory.SIMPLE)){
|
||||
this.queryTypeName = null;
|
||||
}else{
|
||||
TypeModel valueType = type.getSelfOrValueType();
|
||||
if (valueType.getPackageName().equals(classModel.getPackageName())){
|
||||
this.queryTypeName = classModel.getPrefix() + valueType.getSimpleName();
|
||||
}else{
|
||||
this.queryTypeName = valueType.getPackageName() + "." + classModel.getPrefix() + valueType.getSimpleName();
|
||||
}
|
||||
}
|
||||
this.propertyType = Assert.notNull(type);
|
||||
this.typeName = type.getLocalRawName(classModel, new StringBuilder()).toString();
|
||||
this.inits = inits;
|
||||
this.inherited = inherited;
|
||||
this.queryTypeName = type.getQueryTypeName(context);
|
||||
}
|
||||
|
||||
public int compareTo(PropertyModel o) {
|
||||
@ -66,7 +57,7 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
|
||||
public PropertyModel createCopy(EntityModel model){
|
||||
boolean inherited = model.getSuperModel() != null;
|
||||
return new PropertyModel(model, name, type, inits, inherited);
|
||||
return new PropertyModel(model, name, propertyType, inits, inherited);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
@ -84,8 +75,8 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
|
||||
@Nullable
|
||||
public String getGenericParameterName(int i, boolean asArgType){
|
||||
if (i < type.getParameterCount()){
|
||||
return type.getParameter(i).getLocalGenericName(context, new StringBuilder(), asArgType).toString();
|
||||
if (i < propertyType.getParameterCount()){
|
||||
return propertyType.getParameter(i).getLocalGenericName(context, new StringBuilder(), asArgType).toString();
|
||||
|
||||
}else{
|
||||
return null;
|
||||
@ -93,7 +84,7 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
}
|
||||
|
||||
public String getGenericTypeName(){
|
||||
return type.getLocalGenericName(context, new StringBuilder(), false).toString();
|
||||
return propertyType.getLocalGenericName(context, new StringBuilder(), false).toString();
|
||||
}
|
||||
|
||||
public String[] getInits(){
|
||||
@ -110,8 +101,8 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
|
||||
@Nullable
|
||||
public String getRawParameterName(int i){
|
||||
if (i < type.getParameterCount()){
|
||||
return type.getParameter(i).getLocalRawName(context, new StringBuilder()).toString();
|
||||
if (i < propertyType.getParameterCount()){
|
||||
return propertyType.getParameter(i).getLocalRawName(context, new StringBuilder()).toString();
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
@ -122,11 +113,11 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
}
|
||||
|
||||
public String getSimpleTypeName() {
|
||||
return type.getSimpleName();
|
||||
return propertyType.getSimpleName();
|
||||
}
|
||||
|
||||
public TypeCategory getTypeCategory() {
|
||||
return type.getTypeCategory();
|
||||
return propertyType.getTypeCategory();
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
@ -134,11 +125,11 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
}
|
||||
|
||||
public String getTypePackage() {
|
||||
return type.getPackageName();
|
||||
return propertyType.getPackageName();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Arrays.asList(name, type).hashCode();
|
||||
return Arrays.asList(name, propertyType).hashCode();
|
||||
}
|
||||
|
||||
public boolean isInherited() {
|
||||
@ -146,7 +137,11 @@ public final class PropertyModel implements Comparable<PropertyModel> {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return type.getFullName() + " " + name;
|
||||
return context.getFullName() + "." + name;
|
||||
}
|
||||
|
||||
public boolean hasEntityFields() {
|
||||
return propertyType.hasEntityFields();
|
||||
}
|
||||
|
||||
}
|
||||
@ -59,12 +59,12 @@ public class SimpleClassTypeModel implements TypeModel{
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalGenericName(EntityModel context, StringBuilder builder, boolean asArgType) {
|
||||
public StringBuilder getLocalGenericName(TypeModel context, StringBuilder builder, boolean asArgType) {
|
||||
return getLocalRawName(context, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalRawName(EntityModel context, StringBuilder builder) {
|
||||
public StringBuilder getLocalRawName(TypeModel context, StringBuilder builder) {
|
||||
if (visible || context.getPackageName().equals(clazz.getPackage().getName())){
|
||||
builder.append(clazz.getName().substring(clazz.getPackage().getName().length()+1));
|
||||
}else{
|
||||
@ -141,4 +141,9 @@ public class SimpleClassTypeModel implements TypeModel{
|
||||
public boolean hasEntityFields() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryTypeName(EntityModel context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ public class SimpleTypeModel implements TypeModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalGenericName(EntityModel context, StringBuilder builder, boolean asArgType) {
|
||||
public StringBuilder getLocalGenericName(TypeModel context, StringBuilder builder, boolean asArgType) {
|
||||
builder = getLocalRawName(context, builder);
|
||||
if (parameters.length > 0){
|
||||
builder.append("<");
|
||||
@ -77,7 +77,7 @@ public class SimpleTypeModel implements TypeModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalRawName(EntityModel context, StringBuilder builder){
|
||||
public StringBuilder getLocalRawName(TypeModel context, StringBuilder builder){
|
||||
if (visible || context.getPackageName().equals(packageName)){
|
||||
builder.append(localName);
|
||||
}else{
|
||||
@ -160,5 +160,15 @@ public class SimpleTypeModel implements TypeModel {
|
||||
public boolean hasEntityFields() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryTypeName(EntityModel context){
|
||||
TypeModel valueType = getSelfOrValueType();
|
||||
if (valueType.getPackageName().equals(context.getPackageName())){
|
||||
return context.getPrefix() + valueType.getSimpleName();
|
||||
}else{
|
||||
return valueType.getPackageName() + "." + context.getPrefix() + valueType.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,7 +11,7 @@ public class TypeExtendsModel extends TypeModelAdapter{
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalGenericName(EntityModel context, StringBuilder builder, boolean asArgType) {
|
||||
public StringBuilder getLocalGenericName(TypeModel context, StringBuilder builder, boolean asArgType) {
|
||||
if (!asArgType){
|
||||
builder.append("? extends ");
|
||||
}
|
||||
|
||||
@ -14,10 +14,12 @@ import javax.annotation.Nullable;
|
||||
public interface TypeModel {
|
||||
|
||||
TypeModel as(TypeCategory category);
|
||||
|
||||
StringBuilder getLocalRawName(EntityModel context, StringBuilder builder);
|
||||
|
||||
StringBuilder getLocalGenericName(EntityModel context, StringBuilder builder, boolean asArgType);
|
||||
String getQueryTypeName(EntityModel context);
|
||||
|
||||
StringBuilder getLocalRawName(TypeModel context, StringBuilder builder);
|
||||
|
||||
StringBuilder getLocalGenericName(TypeModel context, StringBuilder builder, boolean asArgType);
|
||||
|
||||
String getFullName();
|
||||
|
||||
|
||||
@ -30,12 +30,12 @@ public class TypeModelAdapter implements TypeModel{
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalGenericName(EntityModel context, StringBuilder builder, boolean asArgType) {
|
||||
public StringBuilder getLocalGenericName(TypeModel context, StringBuilder builder, boolean asArgType) {
|
||||
return typeModel.getLocalGenericName(context, builder, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalRawName(EntityModel context, StringBuilder builder) {
|
||||
public StringBuilder getLocalRawName(TypeModel context, StringBuilder builder) {
|
||||
return typeModel.getLocalRawName(context, builder);
|
||||
}
|
||||
|
||||
@ -103,4 +103,9 @@ public class TypeModelAdapter implements TypeModel{
|
||||
public boolean hasEntityFields() {
|
||||
return typeModel.hasEntityFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryTypeName(EntityModel context) {
|
||||
return typeModel.getQueryTypeName(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public class TypeSuperModel extends TypeModelAdapter{
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLocalGenericName(EntityModel context, StringBuilder builder, boolean asArgType) {
|
||||
public StringBuilder getLocalGenericName(TypeModel context, StringBuilder builder, boolean asArgType) {
|
||||
if (!asArgType){
|
||||
builder.append("? super ");
|
||||
return superModel.getLocalGenericName(context, builder, true);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
<name>Querydsl</name>
|
||||
<description>parent project for querydsl modules</description>
|
||||
<url>http://source.mysema.com/display/querydsl</url>
|
||||
@ -121,49 +121,49 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<groups>
|
||||
<group>
|
||||
<title>Core</title>
|
||||
<packages>com.mysema.query:com.mysema.query.alias:com.mysema.query.annotations:com.mysema.query.codegen:com.mysema.query.dml:com.mysema.query.functions:com.mysema.query.serialization:com.mysema.query.support:com.mysema.query.types*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>APT</title>
|
||||
<packages>com.mysema.query.apt*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>Collections</title>
|
||||
<packages>com.mysema.query.collections*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>HQL/JPAQL</title>
|
||||
<packages>com.mysema.query.hql*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>JDOQL</title>
|
||||
<packages>com.mysema.query.jdoql*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>SQL</title>
|
||||
<packages>com.mysema.query.sql*</packages>
|
||||
</group>
|
||||
</groups>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<groups>
|
||||
<group>
|
||||
<title>Core</title>
|
||||
<packages>com.mysema.query:com.mysema.query.alias:com.mysema.query.annotations:com.mysema.query.codegen:com.mysema.query.dml:com.mysema.query.functions:com.mysema.query.serialization:com.mysema.query.support:com.mysema.query.types*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>APT</title>
|
||||
<packages>com.mysema.query.apt*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>Collections</title>
|
||||
<packages>com.mysema.query.collections*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>HQL/JPAQL</title>
|
||||
<packages>com.mysema.query.hql*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>JDOQL</title>
|
||||
<packages>com.mysema.query.jdoql*</packages>
|
||||
</group>
|
||||
<group>
|
||||
<title>SQL</title>
|
||||
<packages>com.mysema.query.sql*</packages>
|
||||
</group>
|
||||
</groups>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>maven-version-plugin</artifactId>
|
||||
<version>0.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
<configuration>
|
||||
<targetJdk>1.6</targetJdk>
|
||||
<includeTests>true</includeTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
<configuration>
|
||||
<targetJdk>1.6</targetJdk>
|
||||
<includeTests>true</includeTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-root</artifactId>
|
||||
<version>0.7.12-SNAPSHOT</version>
|
||||
<version>0.7.13</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user