/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.event.bean;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.epl.core.EngineImportException;
import com.espertech.esper.epl.core.EngineImportService;
import com.espertech.esper.epl.expression.core.ExprEvaluator;
import com.espertech.esper.epl.expression.core.ExprEvaluatorContext;
import com.espertech.esper.epl.expression.core.ExprValidationException;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastConstructor;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
public class InstanceManufacturerUtil {
public static Pair<FastConstructor, ExprEvaluator[]> getManufacturer(Class targetClass, EngineImportService engineImportService, ExprEvaluator[] exprEvaluators, Object[] expressionReturnTypes)
throws ExprValidationException {
Class[] ctorTypes = new Class[expressionReturnTypes.length];
ExprEvaluator[] evaluators = new ExprEvaluator[exprEvaluators.length];
for (int i = 0; i < expressionReturnTypes.length; i++) {
Object columnType = expressionReturnTypes[i];
if (columnType instanceof Class || columnType == null) {
ctorTypes[i] = (Class) expressionReturnTypes[i];
evaluators[i] = exprEvaluators[i];
continue;
}
if (columnType instanceof EventType) {
EventType columnEventType = (EventType) columnType;
final Class returnType = columnEventType.getUnderlyingType();
final ExprEvaluator inner = exprEvaluators[i];
evaluators[i] = new ExprEvaluator() {
public Object evaluate(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) {
EventBean theEvent = (EventBean) inner.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (theEvent != null) {
return theEvent.getUnderlying();
}
return null;
}
public Class getType() {
return returnType;
}
};
ctorTypes[i] = returnType;
continue;
}
// handle case where the select-clause contains an fragment array
if (columnType instanceof EventType[]) {
EventType columnEventType = ((EventType[]) columnType)[0];
final Class componentReturnType = columnEventType.getUnderlyingType();
final ExprEvaluator inner = exprEvaluators[i];
evaluators[i] = new ExprEvaluator() {
public Object evaluate(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) {
Object result = inner.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (!(result instanceof EventBean[])) {
return null;
}
EventBean[] events = (EventBean[]) result;
Object values = Array.newInstance(componentReturnType, events.length);
for (int i = 0; i < events.length; i++) {
Array.set(values, i, events[i].getUnderlying());
}
return values;
}
public Class getType() {
return componentReturnType;
}
};
continue;
}
String message = "Invalid assignment of expression " + i + " returning type '" + columnType +
"', column and parameter types mismatch";
throw new ExprValidationException(message);
}
try {
Constructor ctor = engineImportService.resolveCtor(targetClass, ctorTypes);
FastClass fastClass = FastClass.create(engineImportService.getFastClassClassLoader(targetClass), targetClass);
return new Pair<FastConstructor, ExprEvaluator[]>(fastClass.getConstructor(ctor), evaluators);
} catch (EngineImportException ex) {
throw new ExprValidationException("Failed to find a suitable constructor for class '" + targetClass.getName() + "': " + ex.getMessage(), ex);
}
}
}