package io.datakernel.cube;
import io.datakernel.async.CompletionCallback;
import io.datakernel.codegen.ClassBuilder;
import io.datakernel.codegen.DefiningClassLoader;
import io.datakernel.codegen.Expression;
import io.datakernel.codegen.ExpressionSequence;
import io.datakernel.cube.attributes.AttributeResolver;
import io.datakernel.util.WithValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static io.datakernel.codegen.Expressions.*;
class Utils {
private Utils() {
}
public static Class<?> createResultClass(Collection<String> attributes, Collection<String> measures,
Cube cube, DefiningClassLoader classLoader) {
ClassBuilder<Object> builder = ClassBuilder.create(classLoader, Object.class);
for (String attribute : attributes) {
builder = builder.withField(attribute.replace('.', '$'), cube.getAttributeInternalType(attribute));
}
for (String measure : measures) {
builder = builder.withField(measure, cube.getMeasureInternalType(measure));
}
return builder.build();
}
static boolean startsWith(List<String> list, List<String> prefix) {
if (prefix.size() >= list.size())
return false;
for (int i = 0; i < prefix.size(); ++i) {
if (!list.get(i).equals(prefix.get(i)))
return false;
}
return true;
}
@SuppressWarnings("unchecked")
public static <R> void resolveAttributes(final List<R> results, final AttributeResolver attributeResolver,
final List<String> recordDimensions, final List<String> recordAttributes,
final Class<R> recordClass, DefiningClassLoader classLoader,
CompletionCallback callback) {
final AttributeResolver.KeyFunction keyFunction = ClassBuilder.create(classLoader, AttributeResolver.KeyFunction.class)
.withMethod("extractKey", new WithValue<Expression>() {
@Override
public Expression get() {
ExpressionSequence extractKey = ExpressionSequence.create();
Expression key = let(newArray(Object.class, value(recordDimensions.size())));
for (int i = 0; i < recordDimensions.size(); i++) {
String dimension = recordDimensions.get(i);
extractKey.add(setArrayItem(key, value(i),
cast(field(cast(arg(0), recordClass), dimension), Object.class)));
}
return extractKey.add(key);
}
}.get())
.buildClassAndCreateNewInstance();
final ArrayList<String> resolverAttributes = newArrayList(attributeResolver.getAttributeTypes().keySet());
final AttributeResolver.AttributesFunction attributesFunction = ClassBuilder.create(classLoader, AttributeResolver.AttributesFunction.class)
.withMethod("applyAttributes", new WithValue<Expression>() {
@Override
public Expression get() {
ExpressionSequence applyAttributes = ExpressionSequence.create();
for (String attribute : recordAttributes) {
String attributeName = attribute.substring(attribute.indexOf('.') + 1);
int resolverAttributeIndex = resolverAttributes.indexOf(attributeName);
applyAttributes.add(set(
field(cast(arg(0), recordClass), attribute.replace('.', '$')),
getArrayItem(arg(1), value(resolverAttributeIndex))));
}
return applyAttributes;
}
}.get())
.buildClassAndCreateNewInstance();
attributeResolver.resolveAttributes((List) results, keyFunction, attributesFunction, callback);
}
}