package org.quaere.dsl; import org.quaere.Queryable; import org.quaere.QueryableIterable; import org.quaere.QueryEngine; import org.quaere.Convert; import org.quaere.objects.ObjectQueryEngine; import org.quaere.expressions.Expression; import org.quaere.expressions.Identifier; import org.quaere.expressions.Statement; import org.quaere.expressions.MethodCall; import java.util.Arrays; import java.util.ArrayList; public class AggregateOperatorBuilderImpl<R> implements AggregateOperatorBuilder<R>, AggregateOperatorInClauseBuilder<R> { private final Identifier accumulationIdentifier; private final Identifier anonymousIdentifier; private Expression lambdaExpression; public AggregateOperatorBuilderImpl(Identifier accumulationIdentifier, Identifier anonymousIdentifier) { this.accumulationIdentifier = accumulationIdentifier; this.anonymousIdentifier = anonymousIdentifier; } public AggregateOperatorInClauseBuilder<R> with(String expression) { return with(LiteralExpression.parse(expression)); } public AggregateOperatorInClauseBuilder<R> with(Expression expression) { this.lambdaExpression = expression; return this; } public <T> R in(Class<R> rClass, T[] source) { return in(rClass, Arrays.asList(source)); } public <T> R in(Class<R> rClass, Iterable<T> source) { return in(rClass, new QueryableIterable<T>(source)); } public <T> R in(Class<R> rClass, Queryable<T> source) { QueryEngine queryEngine = source.createQueryEngine(); Identifier sourceIdentifier = Identifier.createUniqueIdentfier(); Statement query = new Statement( Arrays.<Expression>asList( sourceIdentifier, new MethodCall( new Identifier("aggregate"), new ArrayList<Expression>(0), anonymousIdentifier, accumulationIdentifier, lambdaExpression ) ) ); if (queryEngine instanceof ObjectQueryEngine) { ObjectQueryEngine asObjectQueryEngine = (ObjectQueryEngine) queryEngine; asObjectQueryEngine.addSource(sourceIdentifier, source); } return (R) Convert.toType(queryEngine.evaluate(query), rClass); } }