package hu.bme.mit.incquery.cep.runtime.evaluation;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import hu.bme.mit.incquery.cep.metamodels.cep.AtomicEventPattern;
import hu.bme.mit.incquery.cep.metamodels.cep.ComplexEventPattern;
import hu.bme.mit.incquery.cep.metamodels.cep.ComplexOperator;
import hu.bme.mit.incquery.cep.metamodels.cep.Event;
import hu.bme.mit.incquery.cep.metamodels.cep.EventPattern;
import hu.bme.mit.incquery.cep.metamodels.cep.Timewindow;
import hu.bme.mit.incquery.cep.metamodels.internalsm.FinalState;
import hu.bme.mit.incquery.cep.metamodels.internalsm.Guard;
import hu.bme.mit.incquery.cep.metamodels.internalsm.State;
import hu.bme.mit.incquery.cep.metamodels.internalsm.StateMachine;
import hu.bme.mit.incquery.cep.metamodels.internalsm.Transition;
import hu.bme.mit.incquery.cep.metamodels.internalsm.TrapState;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
/**
*
* @author Istvan David
*
*/
public final class SMUtils {
/**
* Returns whether a {@link Transition} is enabled for a given {@link Event}
* based on its type, or not.
*
* @param transition
* @param event
* @return
*/
public static boolean isEnabled(Transition transition, Event event) {
checkArgument(transition != null);
checkArgument(event != null);
Guard guard = checkNotNull(transition.getGuard(), "The Guard must not be null.");
String guardEventType = checkNotNull(guard.getEventType().getType(),
"The Event Type of the Guard must not be null.");
String eventTypeId = checkNotNull(event.getType(), "The Event Type of the Event must not be null.");
if (guardEventType.equalsIgnoreCase(eventTypeId)) {
return true;
}
return false;
}
public static boolean isFinal(State state) {
checkArgument(state != null);
if (state instanceof FinalState) {
return true;
}
return false;
}
public static TrapState getTrapState(StateMachine stateMachine) {
checkArgument(stateMachine != null);
for (State s : stateMachine.getStates()) {
if (s instanceof TrapState) {
return (TrapState) s;
}
}
return null;
}
/**
* Flattens hierarchically nested {@link AtomicEventPattern}s. It is
* deterministic for fully ordered case. In mixed or unordered case, it is
* used for building an initial flattened equivalent to initialize the
* back-step trace building algorithm. (See
* {@link StateMachineBuilder#buildStateMachine()}.)
*
* @param eventPattern
* @return
*/
public static List<AtomicEventPattern> flattenEventPatterns(EventPattern eventPattern) {
checkArgument(eventPattern != null);
List<AtomicEventPattern> flattenedList = new ArrayList<AtomicEventPattern>();
if (eventPattern instanceof AtomicEventPattern) {
flattenedList.add((AtomicEventPattern) eventPattern);
return flattenedList;
}
for (EventPattern ep : ((ComplexEventPattern) eventPattern).getCompositionEvents()) {
if (ep instanceof AtomicEventPattern) {
flattenedList.add((AtomicEventPattern) ep);
} else if (ep instanceof ComplexEventPattern) {
ComplexOperator op = ((ComplexEventPattern) ep).getOperator();
if (op == null) {
continue;
}
flattenedList.addAll(flattenEventPatterns(ep));
}
}
return flattenedList;
}
public static Map<AtomicEventPattern, List<Timewindow>> flattenEventPatternsWithTimewindows(
EventPattern eventPattern) {
checkArgument(eventPattern != null);
Map<AtomicEventPattern, List<Timewindow>> flattenedList = new LinkedHashMap<AtomicEventPattern, List<Timewindow>>();
if (eventPattern instanceof AtomicEventPattern) {
addElement(flattenedList, (AtomicEventPattern) eventPattern);
return flattenedList;
}
for (EventPattern ep : ((ComplexEventPattern) eventPattern).getCompositionEvents()) {
if (ep instanceof AtomicEventPattern) {
addElement(flattenedList, (AtomicEventPattern) ep);
} else if (ep instanceof ComplexEventPattern) {
ComplexEventPattern cep = (ComplexEventPattern) ep;
ComplexOperator op = (cep).getOperator();
if (op == null) {
continue;
}
flattenedList.putAll(flattenEventPatternsWithTimewindows(ep));
}
}
return flattenedList;
}
private static void addElement(Map<AtomicEventPattern, List<Timewindow>> map, AtomicEventPattern patternToAdd) {
for (AtomicEventPattern aep : map.keySet()) {
if (aep.equals(patternToAdd)) {
return;
}
}
map.put((AtomicEventPattern) patternToAdd, collectGlobalTimewindows(patternToAdd));
}
private static List<Timewindow> collectGlobalTimewindows(EventPattern eventPattern) {
List<Timewindow> timewindows = new ArrayList<Timewindow>();
while (eventPattern.eContainer() instanceof EventPattern) {
EObject parent = eventPattern.eContainer();
if (parent instanceof AtomicEventPattern) {
eventPattern = (AtomicEventPattern) parent;
continue;
} else if (parent instanceof ComplexEventPattern) {
ComplexEventPattern ep = (ComplexEventPattern) eventPattern.eContainer();
Timewindow timewindow = ep.getGlobalTimewindow();
if (timewindow != null) {
timewindows.add(timewindow);
}
eventPattern = (ComplexEventPattern) parent;
continue;
}
}
return timewindows;
}
}