diff --git a/querydsl-core/src/main/java/com/mysema/query/group/GroupBy.java b/querydsl-core/src/main/java/com/mysema/query/group/GroupBy.java index 7907dd14e..352c43df0 100644 --- a/querydsl-core/src/main/java/com/mysema/query/group/GroupBy.java +++ b/querydsl-core/src/main/java/com/mysema/query/group/GroupBy.java @@ -1,7 +1,6 @@ package com.mysema.query.group; import java.util.ArrayList; -import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -14,10 +13,7 @@ import com.mysema.query.Projectable; import com.mysema.query.ResultTransformer; import com.mysema.query.types.Expression; import com.mysema.query.types.Operation; -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.expr.SimpleOperation; /** * Groups results by the first expression. @@ -29,33 +25,27 @@ import com.mysema.query.types.expr.SimpleOperation; @SuppressWarnings("unchecked") public class GroupBy implements ResultTransformer> { - private static final Operator WRAPPED = new OperatorImpl("WRAPPED", Object.class); - public static GroupByBuilder groupBy(Expression key) { return new GroupByBuilder(key); } @SuppressWarnings("rawtypes") public static SimpleExpression> list(Expression expression) { - return SimpleOperation.>create((Class)List.class, WRAPPED, expression); + return new GroupExpression>((Class)List.class, new GList(expression), expression); } @SuppressWarnings("rawtypes") public static SimpleExpression> set(Expression expression) { - return SimpleOperation.>create((Class)Set.class, WRAPPED, expression); - } - - @SuppressWarnings("rawtypes") - public static SimpleExpression> collection(Expression expression) { - return SimpleOperation.>create((Class)Collection.class, WRAPPED, expression); + return new GroupExpression>((Class)Set.class, new GSet(expression), expression); } @SuppressWarnings("rawtypes") public static SimpleExpression> map(Expression key, Expression value) { - return SimpleOperation.>create((Class)Map.class, WRAPPED, key, value); + QPair qPair = new QPair(key, value); + return new GroupExpression>((Class)Map.class, new GMap(qPair), qPair); } - class GList extends AbstractGroupDefinition>{ + static class GList extends AbstractGroupDefinition>{ public GList(Expression expr) { super(expr); @@ -82,7 +72,7 @@ public class GroupBy implements ResultTransformer> { } @SuppressWarnings("hiding") - class GMap extends AbstractGroupDefinition, Map>{ + static class GMap extends AbstractGroupDefinition, Map>{ public GMap(QPair qpair) { super(qpair); @@ -109,7 +99,7 @@ public class GroupBy implements ResultTransformer> { } } - class GSet extends AbstractGroupDefinition>{ + static class GSet extends AbstractGroupDefinition>{ public GSet(Expression expr) { super(expr); @@ -135,7 +125,7 @@ public class GroupBy implements ResultTransformer> { } } - class GOne extends AbstractGroupDefinition{ + static class GOne extends AbstractGroupDefinition{ public GOne(Expression expr) { super(expr); @@ -178,21 +168,13 @@ public class GroupBy implements ResultTransformer> { projection.add(key); for (Expression expr : expressions) { - if (expr instanceof Operation && ((Operation)expr).getOperator() == WRAPPED) { - // TODO: Refactor this if-else to allow custom GroupDefinitions - Operation operation = (Operation)expr; - if (expr.getType().equals(List.class)) { - columnDefinitions.add(new GList(operation.getArg(0))); - projection.addAll(operation.getArgs()); - } else if (expr.getType().equals(Set.class)) { - columnDefinitions.add(new GSet(operation.getArg(0))); - projection.addAll(operation.getArgs()); - } else if (expr.getType().equals(Map.class)) { - QPair qPair = new QPair(operation.getArg(0), operation.getArg(1)); - maps.add(qPair); - columnDefinitions.add(new GMap(qPair)); - projection.add(qPair); - } + if (expr instanceof GroupExpression) { + GroupExpression groupExpr = (GroupExpression)expr; + columnDefinitions.add(groupExpr.getDefinition()); + projection.add(groupExpr.getDefinition().getExpression()); + if (groupExpr.getDefinition() instanceof GMap) { + maps.add((QPair) groupExpr.getDefinition().getExpression()); + } } else { columnDefinitions.add(new GOne(expr)); projection.add(expr); diff --git a/querydsl-core/src/main/java/com/mysema/query/group/GroupExpression.java b/querydsl-core/src/main/java/com/mysema/query/group/GroupExpression.java new file mode 100644 index 000000000..170adb9ef --- /dev/null +++ b/querydsl-core/src/main/java/com/mysema/query/group/GroupExpression.java @@ -0,0 +1,69 @@ +package com.mysema.query.group; + +import java.util.List; + +import com.mysema.query.types.Expression; +import com.mysema.query.types.Operation; +import com.mysema.query.types.OperationImpl; +import com.mysema.query.types.Operator; +import com.mysema.query.types.OperatorImpl; +import com.mysema.query.types.Visitor; +import com.mysema.query.types.expr.SimpleExpression; + +/** + * @author tiwe + * + * @param + */ +public class GroupExpression extends SimpleExpression implements Operation { + + private static final long serialVersionUID = -339842770639127388L; + + private static final Operator GROUP_EXPRESSION = new OperatorImpl("GROUP_EXPRESSION", Object.class); + + private final GroupDefinition definition; + + private final Operation< T> opMixin; + + @SuppressWarnings("unchecked") + public GroupExpression(Class type, GroupDefinition definition, Expression... args) { + super(type); + this.definition = definition; + this.opMixin = new OperationImpl(type, GROUP_EXPRESSION, args); + } + + @Override + public boolean equals(Object o) { + return opMixin.equals(o); + } + + @Override + public int hashCode() { + return opMixin.hashCode(); + } + + @Override + public R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + public GroupDefinition getDefinition() { + return definition; + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +}