/**************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
* http://esper.codehaus.org *
* 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.epl.expression;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventPropertyGetter;
import com.espertech.esper.client.EventType;
import com.espertech.esper.event.vaevent.VariantEvent;
import java.util.Map;
/**
* Represents the TYPEOF(a) function is an expression tree.
*/
public class ExprTypeofNode extends ExprNodeBase
{
private static final long serialVersionUID = -612634538694877204L;
private transient ExprEvaluator evaluator;
/**
* Ctor.
*/
public ExprTypeofNode()
{
}
public ExprEvaluator getExprEvaluator()
{
return evaluator;
}
public Map<String, Object> getEventType() {
return null;
}
public void validate(ExprValidationContext validationContext) throws ExprValidationException
{
if (this.getChildNodes().length != 1)
{
throw new ExprValidationException("Typeof node must have 1 child expression node supplying the expression to test");
}
if (this.getChildNodes()[0] instanceof ExprStreamUnderlyingNode) {
ExprStreamUnderlyingNode stream = (ExprStreamUnderlyingNode) getChildNodes()[0];
evaluator = new StreamEventTypeEval(stream.getStreamId());
return;
}
if (this.getChildNodes()[0] instanceof ExprIdentNode) {
ExprIdentNode ident = (ExprIdentNode) getChildNodes()[0];
int streamNum = validationContext.getStreamTypeService().getStreamNumForStreamName(ident.getFullUnresolvedName());
if (streamNum != -1) {
evaluator = new StreamEventTypeEval(streamNum);
return;
}
EventType eventType = validationContext.getStreamTypeService().getEventTypes()[ident.getStreamId()];
if (eventType.getFragmentType(ident.getResolvedPropertyName()) != null) {
evaluator = new FragmentTypeEval(ident.getStreamId(), eventType, ident.getResolvedPropertyName());
return;
}
}
evaluator = new InnerEvaluator(this.getChildNodes()[0].getExprEvaluator());
}
public boolean isConstantResult()
{
return false;
}
public Class getType()
{
return String.class;
}
/*
public Object evaluate(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext)
{
if (streamNum != -1) {
}
if (getter != null) {
getter.getFragment()
}
}
*/
public String toExpressionString()
{
StringBuilder buffer = new StringBuilder();
buffer.append("typeof(");
buffer.append(this.getChildNodes()[0].toExpressionString());
buffer.append(')');
return buffer.toString();
}
public boolean equalsNode(ExprNode node)
{
return node instanceof ExprTypeofNode;
}
public static class StreamEventTypeEval implements ExprEvaluator {
private final int streamNum;
public StreamEventTypeEval(int streamNum) {
this.streamNum = streamNum;
}
@Override
public Object evaluate(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
EventBean theEvent = eventsPerStream[streamNum];
if (theEvent == null) {
return null;
}
if (theEvent instanceof VariantEvent) {
return ((VariantEvent) theEvent).getUnderlyingEventBean().getEventType().getName();
}
return theEvent.getEventType().getName();
}
@Override
public Class getType() {
return String.class;
}
@Override
public Map<String, Object> getEventType() throws ExprValidationException {
return null;
}
}
public static class FragmentTypeEval implements ExprEvaluator {
private final int streamId;
private final EventPropertyGetter getter;
private final String fragmentType;
public FragmentTypeEval(int streamId, EventType eventType, String resolvedPropertyName) {
this.streamId = streamId;
getter = eventType.getGetter(resolvedPropertyName);
fragmentType = eventType.getFragmentType(resolvedPropertyName).getFragmentType().getName();
}
@Override
public Object evaluate(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
EventBean theEvent = eventsPerStream[streamId];
if (theEvent == null) {
return null;
}
Object fragment = getter.getFragment(theEvent);
if (fragment == null) {
return null;
}
if (fragment instanceof EventBean) {
return ((EventBean) fragment).getEventType().getName();
}
if (fragment.getClass().isArray()) {
return fragmentType + "[]";
}
return null;
}
@Override
public Class getType() {
return String.class;
}
@Override
public Map<String, Object> getEventType() throws ExprValidationException {
return null;
}
}
private static class InnerEvaluator implements ExprEvaluator {
private final ExprEvaluator evaluator;
public InnerEvaluator(ExprEvaluator evaluator) {
this.evaluator = evaluator;
}
@Override
public Map<String, Object> getEventType() throws ExprValidationException {
return null;
}
@Override
public Class getType() {
return String.class;
}
@Override
public Object evaluate(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext context) {
Object result = evaluator.evaluate(eventsPerStream, isNewData, context);
if (result == null)
{
return null;
}
return result.getClass().getSimpleName();
}
}
}