alias features successfully moved to querydsl-core

alias features can now be used also from within querydsl-hql
This commit is contained in:
Timo Westkämper 2009-01-16 14:58:40 +00:00
parent a8330c173b
commit e6f3516e04
6 changed files with 55 additions and 60 deletions

View File

@ -8,15 +8,10 @@ package com.mysema.query;
import java.util.Collection;
import java.util.List;
import com.mysema.query.grammar.types.ExtTypes.ExtString;
import com.mysema.query.grammar.types.Expr.EBoolean;
import com.mysema.query.grammar.types.Expr.EComparable;
import com.mysema.query.grammar.types.Expr.ESimple;
import com.mysema.query.grammar.types.Path.PBooleanArray;
import com.mysema.query.grammar.types.Path.PComparableArray;
import com.mysema.query.grammar.types.Path.PComponentCollection;
import com.mysema.query.grammar.types.Path.PComponentList;
import com.mysema.query.grammar.types.Path.PStringArray;
import com.mysema.query.grammar.types.ExtTypes.ExtString;
import com.mysema.query.grammar.types.Path.*;
/**
* ExprFactory provides
@ -32,11 +27,11 @@ public interface ExprFactory {
<D extends Comparable<D>> EComparable<D> create(D arg);
<D> ESimple<D> create(D arg);
<D> PEntity<D> create(D arg);
<D> PComponentList<D> create(List<D> arg);
<D> PEntityList<D> create(List<D> arg);
<D> PComponentCollection<D> create(Collection<D> arg);
<D> PEntityCollection<D> create(Collection<D> arg);
<D extends Comparable<D>> PComparableArray<D> create(D[] args);

View File

@ -16,10 +16,9 @@ import org.apache.commons.collections15.map.LazyMap;
import org.apache.commons.lang.StringUtils;
import com.mysema.query.grammar.types.PathMetadata;
import com.mysema.query.grammar.types.ExtTypes.ExtString;
import com.mysema.query.grammar.types.Expr.EBoolean;
import com.mysema.query.grammar.types.Expr.EComparable;
import com.mysema.query.grammar.types.Expr.ESimple;
import com.mysema.query.grammar.types.ExtTypes.ExtString;
import com.mysema.query.grammar.types.Path.*;
/**
@ -51,24 +50,26 @@ public class SimpleExprFactory implements ExprFactory {
}
});
private final Map<Collection<?>,PComponentCollection<?>> ccToPath = new PathFactory<Collection<?>,PComponentCollection<?>>(new Transformer<Collection<?>,PComponentCollection<?>>(){
private final Map<Collection<?>,PEntityCollection<?>> ecToPath = new PathFactory<Collection<?>,PEntityCollection<?>>(new Transformer<Collection<?>,PEntityCollection<?>>(){
@SuppressWarnings("unchecked")
public PComponentCollection<?> transform(Collection<?> arg) {
public PEntityCollection<?> transform(Collection<?> arg) {
if (!arg.isEmpty()){
return new PComponentCollection(((Collection)arg).iterator().next().getClass(), md());
Class<?> cl = ((Collection)arg).iterator().next().getClass();
return new PEntityCollection(cl, cl.getSimpleName(), md());
}else{
return new PComponentCollection(null, md());
return new PEntityCollection(null, null, md());
}
}
});
private final Map<List<?>,PComponentList<?>> clToPath = new PathFactory<List<?>,PComponentList<?>>(new Transformer<List<?>,PComponentList<?>>(){
private final Map<List<?>,PEntityList<?>> elToPath = new PathFactory<List<?>,PEntityList<?>>(new Transformer<List<?>,PEntityList<?>>(){
@SuppressWarnings("unchecked")
public PComponentList<?> transform(List<?> arg) {
public PEntityList<?> transform(List<?> arg) {
if (!arg.isEmpty()){
return new PComponentList(arg.get(0).getClass(), md());
Class<?> cl = arg.get(0).getClass();
return new PEntityList(cl, cl.getSimpleName(), md());
}else{
return new PComponentList(null, md());
return new PEntityList(null, null, md());
}
}
});
@ -85,11 +86,11 @@ public class SimpleExprFactory implements ExprFactory {
return new PStringArray(md());
}
});
private final Map<Object,PSimple<?>> simToPath = new PathFactory<Object,PSimple<?>>(new Transformer<Object,PSimple<?>>(){
private final Map<Object,PEntity<?>> entityToPath = new PathFactory<Object,PEntity<?>>(new Transformer<Object,PEntity<?>>(){
@SuppressWarnings("unchecked")
public PSimple<?> transform(Object arg) {
return new PSimple(arg.getClass(), md());
public PEntity<?> transform(Object arg) {
return new PEntity(arg.getClass(), arg.getClass().getSimpleName(), md());
}
});
@ -114,8 +115,8 @@ public class SimpleExprFactory implements ExprFactory {
}
@SuppressWarnings("unchecked")
public <D> PComponentCollection<D> create(Collection<D> arg) {
return (PComponentCollection<D>) ccToPath.get(arg);
public <D> PEntityCollection<D> create(Collection<D> arg) {
return (PEntityCollection<D>) ecToPath.get(arg);
}
/* (non-Javadoc)
@ -130,8 +131,8 @@ public class SimpleExprFactory implements ExprFactory {
* @see com.mysema.query.collections.ExprFactory#create(D)
*/
@SuppressWarnings("unchecked")
public <D> ESimple<D> create(D arg){
return (ESimple<D>) simToPath.get(arg);
public <D> PEntity<D> create(D arg){
return (PEntity<D>) entityToPath.get(arg);
}
/* (non-Javadoc)
@ -143,8 +144,8 @@ public class SimpleExprFactory implements ExprFactory {
}
@SuppressWarnings("unchecked")
public <D> PComponentList<D> create(List<D> arg) {
return (PComponentList<D>) clToPath.get(arg);
public <D> PEntityList<D> create(List<D> arg) {
return (PEntityList<D>) elToPath.get(arg);
}
/* (non-Javadoc)

View File

@ -45,9 +45,9 @@ public class AliasAwareExprFactory extends SimpleExprFactory{
}
}
public <D> PComponentCollection<D> create(Collection<D> arg) {
public <D> PEntityCollection<D> create(Collection<D> arg) {
try{
return aliasFactory.hasCurrent() ? aliasFactory.<PComponentCollection<D>>getCurrent() : super.create(arg);
return aliasFactory.hasCurrent() ? aliasFactory.<PEntityCollection<D>>getCurrent() : super.create(arg);
}finally{
aliasFactory.setCurrent(null);
}
@ -62,10 +62,10 @@ public class AliasAwareExprFactory extends SimpleExprFactory{
}
@SuppressWarnings("unchecked")
public <D> ESimple<D> create(D arg){
public <D> PEntity<D> create(D arg){
try{
if (arg instanceof ManagedObject){
PSimple<D> path = (PSimple<D>) aliasFactory.pathForAlias(arg);
PEntity<D> path = (PEntity<D>) aliasFactory.pathForAlias(arg);
return path != null ? path : super.create(arg);
}else{
return super.create(arg);
@ -83,9 +83,9 @@ public class AliasAwareExprFactory extends SimpleExprFactory{
}
}
public <D> PComponentList<D> create(List<D> arg) {
public <D> PEntityList<D> create(List<D> arg) {
try{
return aliasFactory.hasCurrent() ? aliasFactory.<PComponentList<D>>getCurrent() : super.create(arg);
return aliasFactory.hasCurrent() ? aliasFactory.<PEntityList<D>>getCurrent() : super.create(arg);
}finally{
aliasFactory.setCurrent(null);
}

View File

@ -11,7 +11,7 @@ import net.sf.cglib.proxy.MethodInterceptor;
import com.mysema.query.grammar.types.Expr;
import com.mysema.query.grammar.types.Path;
import com.mysema.query.grammar.types.PathMetadata;
import com.mysema.query.grammar.types.Path.PSimple;
import com.mysema.query.grammar.types.Path.PEntity;
import com.mysema.query.util.FactoryMap;
/**
@ -32,9 +32,9 @@ public class AliasFactory {
private final ThreadLocal<Expr<?>> current = new ThreadLocal<Expr<?>>();
// caches top level paths (class/var as key)
private FactoryMap<PSimple<?>> pathCache = new FactoryMap<PSimple<?>>(){
public <A> PSimple<A> create(Class<A> cl, String var){
return new Path.PSimple<A>(cl, PathMetadata.forVariable(var));
private FactoryMap<PEntity<?>> pathCache = new FactoryMap<PEntity<?>>(){
public <A> PEntity<A> create(Class<A> cl, String var){
return new Path.PEntity<A>(cl, cl.getSimpleName(), PathMetadata.forVariable(var));
}
};

View File

@ -76,18 +76,13 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
if (isGetter(method)){
String ptyName = propertyNameForGetter(method);
Class<?> ptyClass = method.getReturnType();
Type genericType = method.getGenericReturnType();
if (propToObj.containsKey(ptyName)){
rv = propToObj.get(ptyName);
}else{
PathMetadata<String> pm = PathMetadata.forProperty((Path<?>) path, ptyName);
rv = newInstance(ptyClass, proxy, ptyName, pm);
if (Collection.class.isAssignableFrom(ptyClass)){
((ManagedObject)rv).setElementType(get1stTypeParameter(method.getGenericReturnType()));
}else if (Map.class.isAssignableFrom(ptyClass)){
((ManagedObject)rv).setKeyType(get1stTypeParameter(method.getGenericReturnType()));
((ManagedObject)rv).setValueType(get2ndTypeParameter(method.getGenericReturnType()));
}
rv = newInstance(ptyClass, genericType, proxy, ptyName, pm);
}
aliasFactory.setCurrent(propToExpr.get(ptyName));
@ -98,7 +93,7 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
rv = propToObj.get(ptyName);
}else{
PathMetadata<Integer> pm = PathMetadata.forSize((PCollection<?>) path);
rv = newInstance(Integer.class, proxy, ptyName, pm);
rv = newInstance(Integer.class, Integer.class, proxy, ptyName, pm);
}
aliasFactory.setCurrent(propToExpr.get(ptyName));
@ -109,9 +104,9 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
}else{
PathMetadata<Integer> pm = PathMetadata.forListAccess((PList<?>)path, (Integer)args[0]);
if (elementType != null){
rv = newInstance(elementType, proxy, ptyName, pm);
rv = newInstance(elementType, elementType, proxy, ptyName, pm);
}else{
rv = newInstance(method.getReturnType(), proxy, ptyName, pm);
rv = newInstance(method.getReturnType(), method.getGenericReturnType(), proxy, ptyName, pm);
}
}
aliasFactory.setCurrent(propToExpr.get(ptyName));
@ -181,7 +176,7 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
}
@SuppressWarnings("unchecked")
private <T> T newInstance(Class<T> type, Object parent, String prop, PathMetadata<?> pm) {
private <T> T newInstance(Class<T> type, Type genericType, Object parent, String prop, PathMetadata<?> pm) {
Expr<?> path;
T rv;
@ -230,19 +225,24 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
// Collection API types
} else if (List.class.isAssignableFrom(type)) {
path = new Path.PComponentList(elementType,pm);
Class<?> _elementType = get1stTypeParameter(genericType);
path = new Path.PEntityList(_elementType, _elementType.getSimpleName(), pm);
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
} else if (Set.class.isAssignableFrom(type)) {
path = new Path.PComponentCollection(elementType,pm);
Class<?> _elementType = get1stTypeParameter(genericType);
path = new Path.PEntityCollection(_elementType, _elementType.getName(), pm);
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
} else if (Collection.class.isAssignableFrom(type)) {
path = new Path.PComponentCollection(elementType,pm);
Class<?> _elementType = get1stTypeParameter(genericType);
path = new Path.PEntityCollection(_elementType, _elementType.getSimpleName(), pm);
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
} else if (Map.class.isAssignableFrom(type)) {
path = new Path.PComponentMap(keyType,valueType,pm);
Class<?> _keyType = get1stTypeParameter(genericType);
Class<?> _valueType = get2ndTypeParameter(genericType);
path = new Path.PEntityMap(_keyType,_valueType,_valueType.getSimpleName(), pm);
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
// enums
@ -252,7 +252,7 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
rv = type.getEnumConstants()[0];
} else {
path = new Path.PSimple<T>((Class<T>)type, pm);
path = new Path.PEntity<T>((Class<T>)type, type.getSimpleName(), pm);
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
}
propToObj.put(prop, rv);

View File

@ -14,7 +14,6 @@ import com.mysema.query.alias.AliasFactory;
import com.mysema.query.grammar.types.PathMetadata;
import com.mysema.query.grammar.types.Expr.EBoolean;
import com.mysema.query.grammar.types.Expr.EComparable;
import com.mysema.query.grammar.types.Expr.ESimple;
import com.mysema.query.grammar.types.ExtTypes.ExtString;
import com.mysema.query.grammar.types.Path.*;
@ -60,15 +59,15 @@ public class GrammarWithAlias extends Grammar{
return exprFactory.create(args);
}
public static <D> PComponentCollection<D> $(Collection<D> args){
public static <D> PEntityCollection<D> $(Collection<D> args){
return exprFactory.create(args);
}
public static <D> PComponentList<D> $(List<D> args){
public static <D> PEntityList<D> $(List<D> args){
return exprFactory.create(args);
}
public static <D> ESimple<D> $(D arg){
public static <D> PEntity<D> $(D arg){
return exprFactory.create(arg);
}