/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. */ package org.thingml.xtext.helpers; import org.thingml.xtext.thingML.*; import org.sintef.thingml.constraints.ThingMLHelpers; import java.util.*; /** * Created by ffl on 10.05.2016. */ public class StateHelper { public static List<State> allStates(State self) { if (self instanceof CompositeState) { return CompositeStateHelper.allContainedStates((CompositeState) self); } else { return Collections.singletonList((State) self); } } public static List<State> allStatesIncludingSessions(State self) { if (self instanceof CompositeState) { return CompositeStateHelper.allContainedStatesIncludingSessions((CompositeState) self); } else { return Collections.singletonList((State) self); } } public static List<State> allStatesWithEntry(State self) { final List<State> result = new ArrayList<State>(); for (State s : allStates(self)) { if (s.getEntry() != null) result.add(s); } return result; } public static List<State> allStatesWithExit(State self) { final List<State> result = new ArrayList<State>(); for (State s : allStates(self)) { if (s.getExit() != null) result.add(s); } return result; } public static List<State> allContainingStates(State self) { return ThingMLHelpers.allContainingStates(self); } public static List<Property> allProperties(State self) { return ThingMLHelpers.allProperties(self); } public static List<State> allValidTargetStates(State self) { return ThingMLHelpers.allValidTargetStates(self); } public static List<Handler> allHandlers(State self, Port p, Message m) { Map<Port, Map<Message, List<Handler>>> handlers = allMessageHandlers(self); if (!handlers.containsKey(p) || !handlers.get(p).containsKey(m)) return new ArrayList<Handler>(); else return handlers.get(p).get(m); } public static List<Handler> allHandlersIncludingSessions(State self, Port p, Message m) { Map<Port, Map<Message, List<Handler>>> handlers = allMessageHandlersIncludingSessions(self); if (!handlers.containsKey(p) || !handlers.get(p).containsKey(m)) return new ArrayList<Handler>(); else return handlers.get(p).get(m); } public static Map<Port, Map<Message, List<Handler>>> allMessageHandlers(State self) { Map<Port, Map<Message, List<Handler>>> result = new HashMap<Port, Map<Message, List<Handler>>>(); for (State s : allStates(self)) { //println("Processisng state " + s.getName) List<Handler> handlers = new ArrayList<Handler>(); for (Transition t : s.getOutgoing()) { handlers.add(t); } for (InternalTransition i : s.getInternal()) { handlers.add(i); } for (Handler t : handlers) { //println(" Processisng handler " + t + " Event = " + t.getEvent) for (Event e : t.getEvent()) { if (e instanceof ReceiveMessage) { ReceiveMessage rm = (ReceiveMessage) e; Map<Message, List<Handler>> phdlrs = result.get(rm.getPort()); if (phdlrs == null) { phdlrs = new HashMap<Message, List<Handler>>(); result.put(rm.getPort(), phdlrs); } List<Handler> hdlrs = phdlrs.get(rm.getMessage()); if (hdlrs == null) { hdlrs = new ArrayList<Handler>(); phdlrs.put(rm.getMessage(), hdlrs); } hdlrs.add(t); } } } } /* //add stream handlers if not present if (self instanceof CompositeState) { for (Stream s : ThingMLElementHelper.findContainingThing(self).getStreams()) { ReceiveMessage rMsg; if (s.getInput() instanceof SimpleSource) { rMsg = ((SimpleSource) s.getInput()).getMessage(); addMessageToHandlers(result, rMsg, null); } else if (s.getInput() instanceof JoinSources) { for (Source source : ((JoinSources) s.getInput()).getSources()) { if (source instanceof SimpleSource) { rMsg = ((SimpleSource) source).getMessage(); addMessageToHandlers(result, rMsg, null); } } } else if (s.getInput() instanceof MergeSources) { for (Source source : ((MergeSources) s.getInput()).getSources()) { if (source instanceof SimpleSource) { rMsg = ((SimpleSource) source).getMessage(); addMessageToHandlers(result, rMsg, null); } } } } } */ return result; } /** * Add a new handler to the list of current found handler. * * @param handlers Set of all current handler * @param rm Message to add * @param t */ private static void addMessageToHandlers(Map<Port, Map<Message, List<Handler>>> handlers, ReceiveMessage rm, Handler t) { Map<Message, List<Handler>> phdlrs = handlers.get(rm.getPort()); if (phdlrs == null) { phdlrs = new HashMap<>(); handlers.put(rm.getPort(), phdlrs); } List<Handler> hdlrs = phdlrs.get(rm.getMessage()); if (hdlrs == null) { hdlrs = new ArrayList<>(); phdlrs.put(rm.getMessage(), hdlrs); } if (t != null) hdlrs.add(t); } public static Map<Port, Map<Message, List<Handler>>> allMessageHandlersIncludingSessions(State self) { Map<Port, Map<Message, List<Handler>>> result = new HashMap<Port, Map<Message, List<Handler>>>(); for (State s : allStatesIncludingSessions(self)) { //println("Processisng state " + s.getName) List<Handler> handlers = new ArrayList<Handler>(); for (Transition t : s.getOutgoing()) { handlers.add(t); } for (InternalTransition i : s.getInternal()) { handlers.add(i); } for (Handler t : handlers) { //println(" Processisng handler " + t + " Event = " + t.getEvent) for (Event e : t.getEvent()) { if (e instanceof ReceiveMessage) { ReceiveMessage rm = (ReceiveMessage) e; Map<Message, List<Handler>> phdlrs = result.get(rm.getPort()); if (phdlrs == null) { phdlrs = new HashMap<Message, List<Handler>>(); result.put(rm.getPort(), phdlrs); } List<Handler> hdlrs = phdlrs.get(rm.getMessage()); if (hdlrs == null) { hdlrs = new ArrayList<Handler>(); phdlrs.put(rm.getMessage(), hdlrs); } hdlrs.add(t); } } } } /* //add stream handlers if not present if (self instanceof CompositeState) { for (Stream s : ThingMLElementHelper.findContainingThing(self).getStreams()) { ReceiveMessage rMsg; if (s.getInput() instanceof SimpleSource) { rMsg = ((SimpleSource) s.getInput()).getMessage(); addMessageToHandlers(result, rMsg, null); } else if (s.getInput() instanceof JoinSources) { for (Source source : ((JoinSources) s.getInput()).getSources()) { if (source instanceof SimpleSource) { rMsg = ((SimpleSource) source).getMessage(); addMessageToHandlers(result, rMsg, null); } } } else if (s.getInput() instanceof MergeSources) { for (Source source : ((MergeSources) s.getInput()).getSources()) { if (source instanceof SimpleSource) { rMsg = ((SimpleSource) source).getMessage(); addMessageToHandlers(result, rMsg, null); } } } } } */ return result; } public static boolean canHandle(State self, Port p, Message m) { Map<Port, Map<Message, List<Handler>>> handlers = allMessageHandlers(self); if (!handlers.containsKey(p)) return false; else return handlers.get(p).containsKey(m); } public static boolean hasEmptyHandlers(State self) { return !allEmptyHandlers(self).isEmpty(); } public static boolean canHandleIncludingSessions(State self, Port p, Message m) { Map<Port, Map<Message, List<Handler>>> handlers = allMessageHandlersIncludingSessions(self); if (!handlers.containsKey(p)) return false; else return handlers.get(p).containsKey(m); } public static boolean hasEmptyHandlersIncludingSessions(State self) { return !allEmptyHandlersIncludingSessions(self).isEmpty(); } public static List<Handler> allEmptyHandlers(State self) { final List<Handler> result = new ArrayList<Handler>(); for (State s : allStates(self)) { List<Handler> handlers = new ArrayList<Handler>(); for (Transition t : s.getOutgoing()) { handlers.add(t); } for (InternalTransition i : s.getInternal()) { handlers.add(i); } for (Handler t : handlers) { if (t.getEvent().isEmpty()) { result.add(t); } } } return result; } public static List<Handler> allEmptyHandlersIncludingSessions(State self) { final List<Handler> result = new ArrayList<Handler>(); for (State s : allStatesIncludingSessions(self)) { List<Handler> handlers = new ArrayList<Handler>(); for (Transition t : s.getOutgoing()) { handlers.add(t); } for (InternalTransition i : s.getInternal()) { handlers.add(i); } for (Handler t : handlers) { if (t.getEvent().isEmpty()) { result.add(t); } } } return result; } }