package org.araqne.logdb.cep.query;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.araqne.logdb.QueryContext;
import org.araqne.logdb.QueryParseException;
import org.araqne.logdb.Row;
import org.araqne.logdb.cep.EventContext;
import org.araqne.logdb.cep.EventContextService;
import org.araqne.logdb.cep.EventContextStorage;
import org.araqne.logdb.cep.EventKey;
import org.araqne.logdb.query.expr.Expression;
public class EvtCtxGetFunction implements Expression {
private Expression topicExpr;
private Expression keyExpr;
private Expression fieldExpr;
private final String field;
private Expression hostExpr;
// 1: counter, 2: created, 3: expire_at, 4: host, 5: timeout_at, 6: rows
private int fieldType;
private EventContextStorage storage;
// evtctxget("topic", "key", "counter")
// evtctxget("topic", "key", "counter", "host")
public EvtCtxGetFunction(QueryContext ctx, List<Expression> exprs, EventContextService eventContextService) {
this.storage = eventContextService.getDefaultStorage();
if (exprs.size() != 3 && exprs.size() != 4)
throw new QueryParseException("invalid-evtctxget-arguments", -1, "argument-count-mismatch");
this.topicExpr = exprs.get(0);
this.keyExpr = exprs.get(1);
this.fieldExpr = exprs.get(2);
if (exprs.size() == 4)
this.hostExpr = exprs.get(3);
try {
this.field = fieldExpr.eval(null).toString();
if (field.equals("counter")) {
fieldType = 1;
} else if (field.equals("created")) {
fieldType = 2;
} else if (field.equals("expire")) {
fieldType = 3;
} else if (field.equals("timeout")) {
fieldType = 4;
} else if (field.equals("rows")) {
fieldType = 5;
}
} catch (Throwable t) {
throw new QueryParseException("invalid-evtctxget-field", -1);
}
if (fieldType == 0)
throw new QueryParseException("unsupported-evtctx-field", -1);
}
@Override
public Object eval(Row row) {
EventContext ctx = EvtCtxGetFunction.findContext(storage, topicExpr, keyExpr, hostExpr, row);
if (ctx == null)
return null;
switch (fieldType) {
case 1:
return ctx.getCounter().get();
case 2:
return new Date(ctx.getCreated());
case 3:
if (ctx.getExpireTime() == 0)
return null;
return new Date(ctx.getExpireTime());
case 4:
if (ctx.getTimeoutTime() == 0)
return null;
return new Date(ctx.getTimeoutTime());
case 5:
ArrayList<Object> l = new ArrayList<Object>(ctx.getRows().size());
for (Row r : ctx.getRows()) {
l.add(Row.clone(r.map()));
}
return l;
}
return null;
}
@Override
public String toString() {
return "evtctxget(" + topicExpr + ", " + keyExpr + ", " + fieldExpr + ")";
}
public static EventContext findContext(EventContextStorage storage, Expression topicExpr, Expression keyExpr,
Expression hostExpr, Row row) {
Object arg1 = topicExpr.eval(row);
Object arg2 = keyExpr.eval(row);
if (arg1 == null || arg2 == null)
return null;
String topic = arg1.toString();
String key = arg2.toString();
String host = null;
if (hostExpr != null) {
Object arg3 = hostExpr.eval(row);
if (arg3 != null)
host = arg3.toString();
}
return storage.getContext(new EventKey(topic, key, host));
}
}