LambdaFactory lambdaFactory = (LambdaFactory)arg;
try {
lambda = LambdaAnalysis.analyzeMethod(config.metamodel, config.alternateClassLoader, config.isObjectEqualsSafe, lambdaFactory.getLambdaMethod(), lambdaFactory.getCapturedArgs(), true);
} catch (Exception e)
{
throw new TypedValueVisitorException("Could not analyze the lambda code", e);
}
}
else if (arg instanceof MethodCallValue.VirtualMethodCallValue && ((MethodCallValue.VirtualMethodCallValue)arg).isConstructor())
{
MethodCallValue.VirtualMethodCallValue lambdaConstructor = (MethodCallValue.VirtualMethodCallValue)arg;
try {
Map<String, TypedValue> indirectParamMapping = config.findLambdaAsClassConstructorParameters(lambdaConstructor.getSignature(), lambdaConstructor.args);
lambda = LambdaAnalysis.analyzeClassAsLambda(config.metamodel, config.alternateClassLoader, config.isObjectEqualsSafe, new LambdaAnalysis.LambdaAsClassAnalysisConfig(), lambdaConstructor.getSignature().getOwnerType().getClassName(), indirectParamMapping, true);
} catch (Exception e)
{
throw new TypedValueVisitorException("Could not analyze the lambda code", e);
}
}
else
throw new TypedValueVisitorException("Expecting a lambda factory for aggregate method");
}
try {
AggregateTransform transform;
if (sig.equals(ScalaMetamodelUtil.streamSumInt)
|| sig.equals(ScalaMetamodelUtil.streamSumLong)
|| sig.equals(ScalaMetamodelUtil.streamSumDouble)
|| sig.equals(ScalaMetamodelUtil.streamSumBigDecimal)
|| sig.equals(ScalaMetamodelUtil.streamSumBigInteger))
transform = new AggregateTransform(config, AggregateTransform.AggregateType.SUM);
else if (sig.equals(ScalaMetamodelUtil.streamMax))
transform = new AggregateTransform(config, AggregateTransform.AggregateType.MAX);
else if (sig.equals(ScalaMetamodelUtil.streamMin))
transform = new AggregateTransform(config, AggregateTransform.AggregateType.MIN);
else if (sig.equals(ScalaMetamodelUtil.streamAvg))
transform = new AggregateTransform(config, AggregateTransform.AggregateType.AVG);
else if (sig.equals(ScalaMetamodelUtil.streamCount))
transform = new AggregateTransform(config, AggregateTransform.AggregateType.COUNT);
else
throw new TypedValueVisitorException("Unhandled aggregate operation");
JPQLQuery<?> aggregatedQuery = transform.apply(subQuery, lambda, argHandler);
// Return the aggregated columns that we've now calculated
if (aggregatedQuery.getClass() == SelectOnly.class)
{
SelectOnly<?> select = (SelectOnly<?>)aggregatedQuery;
return select.cols;
}
else if (aggregatedQuery.isValidSubquery() && aggregatedQuery instanceof SelectFromWhere)
{
SelectFromWhere<?> sfw = (SelectFromWhere<?>)aggregatedQuery;
ColumnExpressions<?> toReturn = new ColumnExpressions<>(sfw.cols.reader);
for (Expression col: sfw.cols.columns)
{
SelectFromWhere<?> oneColQuery = sfw.shallowCopy();
oneColQuery.cols = ColumnExpressions.singleColumn(new SimpleRowReader<>(), col);
toReturn.columns.add(SubqueryExpression.from(oneColQuery));
}
return toReturn;
}
else
{
throw new TypedValueVisitorException("Unknown subquery type");
}
} catch (QueryTransformException e)
{
throw new TypedValueVisitorException("Could not derive an aggregate function for a lambda", e);
}
}
else if (sig.equals(ScalaMetamodelUtil.streamGetOnlyValue))
{
SymbExPassDown passdown = SymbExPassDown.with(val, false);
// Check out what stream we're aggregating
SymbExToSubQuery translator = config.newSymbExToSubQuery(argHandler);
JPQLQuery<?> subQuery = val.base.visit(translator, passdown);
if (subQuery.isValidSubquery() && subQuery instanceof SelectFromWhere)
{
SelectFromWhere<?> sfw = (SelectFromWhere<?>)subQuery;
ColumnExpressions<?> toReturn = new ColumnExpressions<>(sfw.cols.reader);
for (Expression col: sfw.cols.columns)
{
SelectFromWhere<?> oneColQuery = sfw.shallowCopy();
oneColQuery.cols = ColumnExpressions.singleColumn(new SimpleRowReader<>(), col);
toReturn.columns.add(SubqueryExpression.from(oneColQuery));
}
return toReturn;
}
throw new TypedValueVisitorException("Cannot apply getOnlyValue() to the given subquery");
}
else if (sig.equals(ScalaMetamodelUtil.STRINGBUILDER_STRING))
{
List<ColumnExpressions<?>> concatenatedStrings = new ArrayList<>();
MethodCallValue.VirtualMethodCallValue baseVal = val;
while (true)
{
if (!(baseVal.base instanceof MethodCallValue.VirtualMethodCallValue))
throw new TypedValueVisitorException("Unexpected use of StringBuilder");
baseVal = (MethodCallValue.VirtualMethodCallValue)baseVal.base;
if (baseVal.getSignature().equals(ScalaMetamodelUtil.NEW_STRINGBUILDER_STRING))
{
SymbExPassDown passdown = SymbExPassDown.with(val, false);
concatenatedStrings.add(baseVal.args.get(0).visit(this, passdown));
break;
}
else if (baseVal.getSignature().equals(ScalaMetamodelUtil.NEW_STRINGBUILDER))
{
break;
}
else if (baseVal.getSignature().equals(ScalaMetamodelUtil.STRINGBUILDER_APPEND))
{
SymbExPassDown passdown = SymbExPassDown.with(val, false);
concatenatedStrings.add(baseVal.args.get(0).visit(this, passdown));
}
else
throw new TypedValueVisitorException("Unexpected use of StringBuilder");
}
if (concatenatedStrings.size() == 1)
return concatenatedStrings.get(0);
Expression head = concatenatedStrings.get(concatenatedStrings.size() - 1).getOnlyColumn();