From af7df11b6915527e0566ff96f7dc5b1e16c8d237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Fri, 30 Jan 2009 11:46:38 +0000 Subject: [PATCH] added Projection for inline projections --- .../main/java/com/mysema/query/QueryBase.java | 4 +- .../mysema/query/grammar/types/ExtTypes.java | 3 - .../query/grammar/types/Projection.java | 74 +++++++++++++++++++ .../mysema/query/grammar/types/SubQuery.java | 3 + .../mysema/query/grammar/types/Visitor.java | 2 + .../query/grammar/types/VisitorAdapter.java | 6 +- 6 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 querydsl-core/src/main/java/com/mysema/query/grammar/types/Projection.java diff --git a/querydsl-core/src/main/java/com/mysema/query/QueryBase.java b/querydsl-core/src/main/java/com/mysema/query/QueryBase.java index 4fc4ef867..317eed94b 100644 --- a/querydsl-core/src/main/java/com/mysema/query/QueryBase.java +++ b/querydsl-core/src/main/java/com/mysema/query/QueryBase.java @@ -38,13 +38,15 @@ public class QueryBase> implements Quer where.clear(); } + private A self = (A)this; + private final Metadata metadata = new Metadata(); public A from(Expr.EEntity... o) { for (EEntity expr : o){ joins.add(new JoinExpression(JoinType.DEFAULT,expr)); } - return (A) this; + return self; } public A groupBy(Expr... o) { diff --git a/querydsl-core/src/main/java/com/mysema/query/grammar/types/ExtTypes.java b/querydsl-core/src/main/java/com/mysema/query/grammar/types/ExtTypes.java index 1d1d139cc..060a1df83 100644 --- a/querydsl-core/src/main/java/com/mysema/query/grammar/types/ExtTypes.java +++ b/querydsl-core/src/main/java/com/mysema/query/grammar/types/ExtTypes.java @@ -5,10 +5,7 @@ */ package com.mysema.query.grammar.types; -import com.mysema.query.Query; -import com.mysema.query.QueryBase; import com.mysema.query.grammar.Grammar; -import com.mysema.query.grammar.OrderSpecifier; /** diff --git a/querydsl-core/src/main/java/com/mysema/query/grammar/types/Projection.java b/querydsl-core/src/main/java/com/mysema/query/grammar/types/Projection.java new file mode 100644 index 000000000..d986a264a --- /dev/null +++ b/querydsl-core/src/main/java/com/mysema/query/grammar/types/Projection.java @@ -0,0 +1,74 @@ +package com.mysema.query.grammar.types; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; + +/** + * Projection provides + * + * @author tiwe + * @version $Id$ + */ +public class Projection extends Path.PEntity{ + + private String entityName; + + private static Method _numberMethod, _comparableMethod; + + static{ + try { + _numberMethod = PEntity.class.getDeclaredMethod("_number", String.class, Class.class); + _comparableMethod = PEntity.class.getDeclaredMethod("_comparable", String.class, Class.class); + _numberMethod.setAccessible(true); + _comparableMethod.setAccessible(true); + } catch (Exception e) { + String error = "Caught " + e.getClass().getName(); + throw new RuntimeException(error, e); + } + } + + public Projection(String entityName) { + super(Object.class, entityName, PathMetadata.forVariable(entityName)); + Class cl = getClass(); + try{ + while (!cl.equals(Projection.class)){ + for (Field field : cl.getDeclaredFields()){ + if (Expr.class.isAssignableFrom(field.getType()) && field.getGenericType() instanceof ParameterizedType){ + field.setAccessible(true); + handleField(field); + } + } + cl = cl.getSuperclass(); + } + }catch(Exception e){ + String error = "Caught " + e.getClass().getName(); + throw new RuntimeException(error, e); + } + this.entityName = entityName; + } + + private void handleField(Field field) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + ParameterizedType type = (ParameterizedType) field.getGenericType(); + Class exprType = (Class) type.getActualTypeArguments()[0]; + Expr fieldVal; + if (Boolean.class.isAssignableFrom(exprType)){ + fieldVal = _boolean(field.getName()); + }else if (Number.class.isAssignableFrom(exprType)){ + fieldVal = (Expr) _numberMethod.invoke(this, field.getName(), exprType); + }else if (String.class.isAssignableFrom(exprType)){ + fieldVal = _string(field.getName()); + }else if (Comparable.class.isAssignableFrom(exprType)){ + fieldVal = (Expr) _comparableMethod.invoke(this, field.getName(), exprType); + }else{ + fieldVal = _simple(field.getName(), exprType); + } + field.set(this, fieldVal); + } + + public String getName(){ + return entityName; + } + +} diff --git a/querydsl-core/src/main/java/com/mysema/query/grammar/types/SubQuery.java b/querydsl-core/src/main/java/com/mysema/query/grammar/types/SubQuery.java index 92829ca7b..2712c6c5d 100644 --- a/querydsl-core/src/main/java/com/mysema/query/grammar/types/SubQuery.java +++ b/querydsl-core/src/main/java/com/mysema/query/grammar/types/SubQuery.java @@ -41,6 +41,9 @@ public class SubQuery extends Expr implements Query>, Co public SubQuery select(Expr... o) {query.s(o); return this;} public SubQuery where(EBoolean... o) {query.where(o); return this;} public SubQuery with(EBoolean o) {query.with(o); return this;} + // TODO : add some validation that the given Projection is valid for this subquery + public Alias.ASimple as(Projection to) { return new Alias.ASimple(this, to.getName()); } + public Alias.ASimple as(String to) { return new Alias.ASimple(this, to); } private static class QueryWithPublicSelect extends QueryBase>{ public void s(Expr... expr){ diff --git a/querydsl-core/src/main/java/com/mysema/query/grammar/types/Visitor.java b/querydsl-core/src/main/java/com/mysema/query/grammar/types/Visitor.java index f5f7c9dd5..9a3e223e5 100644 --- a/querydsl-core/src/main/java/com/mysema/query/grammar/types/Visitor.java +++ b/querydsl-core/src/main/java/com/mysema/query/grammar/types/Visitor.java @@ -121,4 +121,6 @@ public abstract class Visitor> { protected abstract void visit(Path expr); + protected abstract void visit(Projection expr); + } diff --git a/querydsl-core/src/main/java/com/mysema/query/grammar/types/VisitorAdapter.java b/querydsl-core/src/main/java/com/mysema/query/grammar/types/VisitorAdapter.java index 044a26b5f..df6bf5a6b 100644 --- a/querydsl-core/src/main/java/com/mysema/query/grammar/types/VisitorAdapter.java +++ b/querydsl-core/src/main/java/com/mysema/query/grammar/types/VisitorAdapter.java @@ -90,7 +90,7 @@ public abstract class VisitorAdapter> extends Visito @Override protected void visit(PComponentMap expr) { visit((PMap) expr); - } + } @Override protected void visit(PEntity expr) { visit((Path) expr); @@ -123,4 +123,8 @@ public abstract class VisitorAdapter> extends Visito protected void visit(PStringArray expr) { visit((PArray) expr); } + @Override + protected void visit(Projection expr){ + visit((PEntity)expr); + } }