From 496209e8fe0b21ff408d4c1cdb7d138c5fbd4ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Fri, 16 Jan 2009 09:38:18 +0000 Subject: [PATCH] small improvements to alias handling --- .../query/collections/alias/AliasFactory.java | 17 ++++--- .../PropertyAccessInvocationHandler.java | 47 ++++++++++++++----- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/alias/AliasFactory.java b/querydsl-collections/src/main/java/com/mysema/query/collections/alias/AliasFactory.java index 2afea3fe5..e584f372f 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/alias/AliasFactory.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/alias/AliasFactory.java @@ -39,28 +39,26 @@ public class AliasFactory { }; // cahces top level proxies (class/var as key) - private FactoryMap proxyCache = new FactoryMap(){ - public Object create(Class cl, String var){ - return createProxy(cl); + private FactoryMap proxyCache = new FactoryMap(){ + public ManagedObject create(Class cl, Expr path){ + return (ManagedObject) createProxy(cl, path); } }; public A createAliasForProp(Class 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 createAliasForVar(Class 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 createProxy(Class cl) { + private A createProxy(Class 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; } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/alias/PropertyAccessInvocationHandler.java b/querydsl-collections/src/main/java/com/mysema/query/collections/alias/PropertyAccessInvocationHandler.java index bda8b6063..d32c01634 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/alias/PropertyAccessInvocationHandler.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/alias/PropertyAccessInvocationHandler.java @@ -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 propToObj = new HashMap(); - 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 pm = PathMetadata.forProperty((Path) parent, ptyName); + PathMetadata 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 pm = PathMetadata.forSize((PCollection) parent); + PathMetadata 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 pm = PathMetadata.forListAccess((PList)parent, (Integer)args[0]); + PathMetadata 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)parent)); + aliasFactory.setCurrent(Grammar.in(args[0], (CollectionType)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