mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
small improvements to alias handling
This commit is contained in:
parent
864ea1f0dd
commit
496209e8fe
@ -39,28 +39,26 @@ public class AliasFactory {
|
||||
};
|
||||
|
||||
// cahces top level proxies (class/var as key)
|
||||
private FactoryMap<Object> proxyCache = new FactoryMap<Object>(){
|
||||
public <A> Object create(Class<A> cl, String var){
|
||||
return createProxy(cl);
|
||||
private FactoryMap<ManagedObject> proxyCache = new FactoryMap<ManagedObject>(){
|
||||
public ManagedObject create(Class<?> cl, Expr<?> path){
|
||||
return (ManagedObject) createProxy(cl, path);
|
||||
}
|
||||
};
|
||||
|
||||
public <A> A createAliasForProp(Class<A> cl, Object parent, Expr<?> path){
|
||||
A proxy = createProxy(cl);
|
||||
bindings.get().put(proxy, path);
|
||||
A proxy = createProxy(cl, path);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A> A createAliasForVar(Class<A> cl, String var){
|
||||
Expr<?> path = pathCache.get(cl,var);
|
||||
A proxy = (A) proxyCache.get(cl, var);
|
||||
bindings.get().put(proxy, path);
|
||||
A proxy = (A) proxyCache.get(cl,path);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <A> A createProxy(Class<A> cl) {
|
||||
private <A> A createProxy(Class<A> cl, Expr<?> path) {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setClassLoader(AliasFactory.class.getClassLoader());
|
||||
if (cl.isInterface()){
|
||||
@ -70,9 +68,10 @@ public class AliasFactory {
|
||||
enhancer.setInterfaces(new Class[]{ManagedObject.class});
|
||||
}
|
||||
// creates one handler per proxy
|
||||
MethodInterceptor handler = new PropertyAccessInvocationHandler(this);
|
||||
MethodInterceptor handler = new PropertyAccessInvocationHandler(path,this);
|
||||
enhancer.setCallback(handler);
|
||||
A rv = (A)enhancer.create();
|
||||
bindings.get().put(rv, path);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +36,8 @@ import com.mysema.query.grammar.types.Path.PList;
|
||||
*/
|
||||
class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
|
||||
private final Expr<?> path;
|
||||
|
||||
private final AliasFactory aliasFactory;
|
||||
|
||||
private final JavaSerializer serializer = new JavaSerializer(new JavaOps());
|
||||
@ -48,11 +50,12 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
|
||||
private final Map<String,Object> propToObj = new HashMap<String,Object>();
|
||||
|
||||
public PropertyAccessInvocationHandler(AliasFactory aliasFactory){
|
||||
public PropertyAccessInvocationHandler(Expr<?> path, AliasFactory aliasFactory){
|
||||
this.path = path;
|
||||
this.aliasFactory = aliasFactory;
|
||||
}
|
||||
|
||||
private Class<?> getFirstTypeParameter(Type type) {
|
||||
private Class<?> get1stTypeParameter(Type type) {
|
||||
if (type instanceof ParameterizedType){
|
||||
return (Class<?>)((ParameterizedType)type).getActualTypeArguments()[0];
|
||||
}else{
|
||||
@ -60,9 +63,16 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> get2ndTypeParameter(Type type) {
|
||||
if (type instanceof ParameterizedType){
|
||||
return (Class<?>)((ParameterizedType)type).getActualTypeArguments()[1];
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object intercept(Object proxy, Method method, Object[] args,
|
||||
MethodProxy methodProxy) throws Throwable {
|
||||
Expr<?> parent = aliasFactory.pathForAlias(proxy);
|
||||
MethodProxy methodProxy) throws Throwable {
|
||||
Object rv = null;
|
||||
|
||||
if (isGetter(method)){
|
||||
@ -72,11 +82,13 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
if (propToObj.containsKey(ptyName)){
|
||||
rv = propToObj.get(ptyName);
|
||||
}else{
|
||||
if (parent == null) throw new IllegalArgumentException("No path for " + proxy);
|
||||
PathMetadata<String> pm = PathMetadata.forProperty((Path<?>) parent, ptyName);
|
||||
PathMetadata<String> pm = PathMetadata.forProperty((Path<?>) path, ptyName);
|
||||
rv = newInstance(ptyClass, proxy, ptyName, pm);
|
||||
if (Collection.class.isAssignableFrom(ptyClass)){
|
||||
((ManagedObject)rv).setElementType(getFirstTypeParameter(method.getGenericReturnType()));
|
||||
((ManagedObject)rv).setElementType(get1stTypeParameter(method.getGenericReturnType()));
|
||||
}else if (Map.class.isAssignableFrom(ptyClass)){
|
||||
((ManagedObject)rv).setKeyType(get1stTypeParameter(method.getGenericReturnType()));
|
||||
((ManagedObject)rv).setValueType(get2ndTypeParameter(method.getGenericReturnType()));
|
||||
}
|
||||
}
|
||||
aliasFactory.setCurrent(propToExpr.get(ptyName));
|
||||
@ -87,17 +99,17 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
if (propToObj.containsKey(ptyName)){
|
||||
rv = propToObj.get(ptyName);
|
||||
}else{
|
||||
PathMetadata<Integer> pm = PathMetadata.forSize((PCollection<?>) parent);
|
||||
PathMetadata<Integer> pm = PathMetadata.forSize((PCollection<?>) path);
|
||||
rv = newInstance(Integer.class, proxy, ptyName, pm);
|
||||
}
|
||||
aliasFactory.setCurrent(propToExpr.get(ptyName));
|
||||
|
||||
}else if (isElementAccess(method)){
|
||||
}else if (isListElementAccess(method)){
|
||||
String ptyName = "_get" + args[0];
|
||||
if (propToObj.containsKey(ptyName)){
|
||||
rv = propToObj.get(ptyName);
|
||||
}else{
|
||||
PathMetadata<Integer> pm = PathMetadata.forListAccess((PList<?>)parent, (Integer)args[0]);
|
||||
PathMetadata<Integer> pm = PathMetadata.forListAccess((PList<?>)path, (Integer)args[0]);
|
||||
if (elementType != null){
|
||||
rv = newInstance(elementType, proxy, ptyName, pm);
|
||||
}else{
|
||||
@ -106,12 +118,15 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
}
|
||||
aliasFactory.setCurrent(propToExpr.get(ptyName));
|
||||
|
||||
}else if (isMapElementAccess(method)){
|
||||
// TODO
|
||||
|
||||
}else if (isContains(method)){
|
||||
rv = false;
|
||||
aliasFactory.setCurrent(Grammar.in(args[0], (CollectionType<Object>)parent));
|
||||
aliasFactory.setCurrent(Grammar.in(args[0], (CollectionType<Object>)path));
|
||||
|
||||
}else if (isToString(method)){
|
||||
if (toString == null) toString = serializer.handle((Expr<?>)parent).toString();
|
||||
if (toString == null) toString = serializer.handle(path).toString();
|
||||
rv = toString;
|
||||
|
||||
}else if (method.getName().equals("setElementType")){
|
||||
@ -142,11 +157,17 @@ class PropertyAccessInvocationHandler implements MethodInterceptor{
|
||||
&& method.getReturnType().equals(boolean.class);
|
||||
}
|
||||
|
||||
private boolean isElementAccess(Method method) {
|
||||
private boolean isListElementAccess(Method method) {
|
||||
return method.getName().equals("get")
|
||||
&& method.getParameterTypes().length == 1
|
||||
&& method.getParameterTypes()[0].equals(int.class);
|
||||
}
|
||||
|
||||
private boolean isMapElementAccess(Method method) {
|
||||
return method.getName().equals("get")
|
||||
&& method.getParameterTypes().length == 1
|
||||
&& method.getParameterTypes()[0].equals(Object.class);
|
||||
}
|
||||
|
||||
private boolean isGetter(Method method){
|
||||
return method.getParameterTypes().length == 0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user