private SMTransition parseTransition(Queue <IXamlElement> token) { // Transition SMTransition transition = new SMTransition(); // Trigger SMTrigger trigger; // Reference String reference; String refTrigger; String condition; // [Start] Transition IXamlElement element = token.Dequeue(); bool attRef = element.Attributes.TryGetValue("To", out reference); bool attTrigger = element.Attributes.TryGetValue("Trigger", out refTrigger); bool attCondition = element.Attributes.TryGetValue("Condition", out condition); // To if (attRef) { transition.To = extractReference(reference); } // Trigger if (attTrigger) { String id = extractReference(refTrigger); if (triggers.ContainsKey(id)) { triggers[id].Transitions.Add(transition); } else { // Warning log.Warn("Warning Trigger created before IActivity was found!"); trigger = new SMTrigger(); trigger.Transitions.Add(transition); triggers.Add(id, trigger); } } // Condition if (attCondition) { transition.Condition = true; } while (!token.Peek().QName.Equals(createQName("Transition"))) { if (token.Peek().QName.Equals(createQName("Transition.Trigger"))) { // [Start] Transition.Trigger token.Dequeue(); // Trigger Reference String triggerRef; if (token.Peek().Attributes.TryGetValue("x:Name", out triggerRef)) { // Activity IActivity activity = moduleFactory.CreateActivity(token.Peek().QName); IActivity triggerActivity; if (activity != null) { triggerActivity = activity.Parse(token); } else { throw new ParseException(String.Format("No Module found for activity '{0}'", QName), initialTokenCount - token.Count, QName); } if (triggers.ContainsKey(triggerRef)) { log.Warn("Warning trigger existent!"); triggers[triggerRef].Trigger = triggerActivity; triggers[triggerRef].Transitions.Add(transition); } else { trigger = new SMTrigger(); trigger.Trigger = triggerActivity; trigger.Transitions.Add(transition); triggers.Add(triggerRef, trigger); } } else { // Activity IActivity activity = moduleFactory.CreateActivity(token.Peek().QName); IActivity triggerActivity; if (activity != null) { triggerActivity = activity.Parse(token); } else { throw new ParseException(String.Format("No Module found for activity '{0}'", QName), initialTokenCount - token.Count, QName); } trigger = new SMTrigger(); trigger.Trigger = triggerActivity; trigger.Transitions.Add(transition); triggerKey++; triggers.Add(triggerKey.ToString(), trigger); } // [End] Transition.Trigger token.Dequeue(); } else if (token.Peek().QName.Equals(createQName("Transition.Condition"))) { // [Start] Transition.Condition token.Dequeue(); transition.Condition = true; // [End] Transition.Condition token.Dequeue(); } else if (token.Peek().QName.Equals(createQName("Transition.Action"))) { // [Start] Transition.Action token.Dequeue(); // Activity IActivity activity = moduleFactory.CreateActivity(token.Peek().QName); if (activity != null) { transition.Action = activity.Parse(token); } else { throw new ParseException(String.Format("No Module found for activity '{0}'", QName), initialTokenCount - token.Count, QName); } // [End] Transition.Action token.Dequeue(); } else if (token.Peek().QName.Equals(createQName("Transition.To"))) { // [Start] Transition.To token.Dequeue(); if (token.Peek().QName.Equals(createQName("State"))) { transition.To = token.Peek().Attributes["x:Name"]; // Recursion parseState(token); } else if (token.Peek().QName.Equals(createQName("Reference", ns_x))) { // [Start] Reference element = token.Dequeue(); reference = element.Attributes["Reference"]; transition.To = reference; // [End] Reference token.Dequeue(); } else { throw new ParseException(String.Format("Unknown tag found in activity '{0}'", QName), initialTokenCount - token.Count, QName); } // [End] Transition.To token.Dequeue(); } else { throw new ParseException(String.Format("Unknown tag found in activity '{0}'", QName), initialTokenCount - token.Count, QName); } } // [End] Transition token.Dequeue(); return(transition); }
public PetriNet Compile(PetriNet phylum) { String prefix = phylum.ActivityCount + ".internal."; Place p1 = phylum.NewPlace(prefix + "initialized"); Place p2 = phylum.NewPlace(prefix + "closed"); // Create States foreach (SMState state in states) { String prefixState = prefix + state.Id + "."; IList <Place> actions = new List <Place>(); // Entry Place closed int entryClosed; Place stp1 = phylum.NewPlace(prefixState + "initialized"); if (state.Final) { // Closed Place stp2 = phylum.NewPlace(prefixState + "closed"); // Activity if (state.Entry is Empty) { // Empty phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; Place entryP2 = phylum.NewPlace(prefix + "internal.closed"); phylum.Merge(stp1, entryP2); phylum.Merge(stp1, stp2); } else { // Entry Place entryP1 = phylum.NewPlace(prefixState + "entry.initialized"); Place entryP2 = phylum.NewPlace(prefixState + "entry.closed"); phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; state.Entry.Compile(phylum); // Merge phylum.Merge(entryP1, entryClosed + ".internal.initialized"); phylum.Merge(entryP2, entryClosed + ".internal.closed"); phylum.Merge(stp1, entryP1); phylum.Merge(entryP2, stp2); } } else { // Entry if (state.Entry is Empty) { phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; Place entryP2 = phylum.NewPlace(entryClosed + ".internal.closed"); phylum.Merge(stp1, entryP2); } else { // Entry Place entryP1 = phylum.NewPlace(prefixState + "entry.initialized"); Place entryP2 = phylum.NewPlace(prefixState + "entry.closed"); phylum.ActivityCount += 1; entryClosed = phylum.ActivityCount; state.Entry.Compile(phylum); // Merge phylum.Merge(entryP1, entryClosed + ".internal.initialized"); phylum.Merge(entryP2, entryClosed + ".internal.closed"); phylum.Merge(stp1, entryP1); } // Exit Place exitP1; Place exitP2; if (state.Exit is Empty) { exitP1 = phylum.NewPlace(prefixState + "exit"); exitP2 = exitP1; } else { exitP1 = phylum.NewPlace(prefixState + "exit.initialized"); exitP2 = phylum.NewPlace(prefixState + "exit.closed"); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; state.Exit.Compile(phylum); // Merge phylum.Merge(exitP1, currentID + ".internal.initialized"); phylum.Merge(exitP2, currentID + ".internal.closed"); } // Transitions for (int i = 1; i <= state.Transitions.Count; i++) { SMTransition transition = state.Transitions[i - 1]; // To Output Places Transition tsplit = phylum.NewTransition(prefixState + "t" + i); Place wait = phylum.NewPlace(prefixState + "t" + i + "wait"); Place to = phylum.NewPlace(prefix + state.Id + ".to" + i + "." + transition.To); // Actions Place actionP1; Place actionP2; if (transition.Action is Empty) { actionP1 = phylum.NewPlace(prefixState + transition.To + i + ".action.initialized"); actionP2 = actionP1; } else { actionP1 = phylum.NewPlace(prefixState + transition.To + i + ".action.initialized"); actionP2 = phylum.NewPlace(prefixState + transition.To + i + ".action.closed"); actions.Add(actionP1); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; transition.Action.Compile(phylum); // Merge phylum.Merge(actionP1, currentID + ".internal.initialized"); phylum.Merge(actionP2, currentID + ".internal.closed"); } // Connect Transition split = phylum.NewTransition(prefixState + transition.To + ".split" + i); phylum.NewArc(actionP2, split); phylum.NewArc(split, exitP1); phylum.NewArc(split, wait); phylum.NewArc(wait, tsplit); // Exit Split phylum.NewArc(exitP2, tsplit); phylum.NewArc(tsplit, to); } // Create Trigger foreach (String key in triggers.Keys) { SMTrigger trigger = triggers[key]; if (trigger.Transitions.Any(t => state.Transitions.Contains(t))) { // Trigger Place triggerIn = phylum.NewPlace(prefixState + "trigger" + key + ".in"); Place triggerOut = phylum.NewPlace(prefixState + "trigger" + key + ".out"); // Activity phylum.ActivityCount += 1; int currentID = phylum.ActivityCount; trigger.Trigger.Compile(phylum); // Merge phylum.Merge(triggerIn, currentID + ".internal.initialized"); phylum.Merge(triggerOut, currentID + ".internal.closed"); // Connect phylum.Merge(entryClosed + ".internal.closed", triggerIn); Transition on = phylum.NewTransition(prefixState + "ontrigger" + key); phylum.NewArc(triggerOut, on); Place runCondition = phylum.NewPlace(prefixState + "runcondition1" + key); phylum.NewArc(on, runCondition); // Conditions Place lastCondition = runCondition; for (int i = 1; i <= trigger.Transitions.Count; i++) { // Null Trigger if (!trigger.Transitions[i - 1].Condition) { Transition start = phylum.NewTransition(prefixState + "astart" + i + key); phylum.NewArc(lastCondition, start); // Connect Action int id = state.Transitions.IndexOf(trigger.Transitions[i - 1]) + 1; phylum.NewArc(start, prefixState + trigger.Transitions[i - 1].To + id + ".action.initialized"); // Flag Transition state.Transitions.First(t => t.Equals(trigger.Transitions[i - 1])).Flag = true; } else { Transition eval = phylum.NewTransition(prefixState + "eval" + i + key); phylum.NewArc(lastCondition, eval); Place condition = phylum.NewPlace(prefixState + "condition" + i + key); phylum.NewArc(eval, condition); // False Transition wrong = phylum.NewTransition(prefixState + "wrong" + i + key); phylum.NewArc(condition, wrong); // Reset if (i == trigger.Transitions.Count) { phylum.NewArc(wrong, triggerIn); } else { Place newRun = phylum.NewPlace(prefixState + "runcondition" + (i + 1) + key); phylum.NewArc(wrong, newRun); lastCondition = newRun; } // True Transition right = phylum.NewTransition(prefixState + "astart" + i + key); phylum.NewArc(condition, right); // Connect Action int id = state.Transitions.IndexOf(trigger.Transitions[i - 1]) + 1; phylum.NewArc(right, prefixState + trigger.Transitions[i - 1].To + id + ".action.initialized"); // Flag Transition state.Transitions.First(t => t.Equals(trigger.Transitions[i - 1])).Flag = true; } } } } // Empty Trigger int emptyTrigger = countEmptyTrigger(state.Transitions); if (emptyTrigger > 0) { // Connect Transition on = phylum.NewTransition(prefixState + "onemptytrigger"); Place trigger = phylum.NewPlace(prefixState + "trigger"); phylum.Merge(entryClosed + ".internal.closed", trigger); phylum.NewArc(trigger, on); Place runCondition = phylum.NewPlace(prefixState + "runcondition1"); phylum.NewArc(on, runCondition); // Conditions Place lastCondition = runCondition; for (int i = 1; i <= state.Transitions.Count; i++) { if (!state.Transitions[i - 1].Flag) { // Null Trigger if (!state.Transitions[i - 1].Condition) { int id = state.Transitions.IndexOf(state.Transitions[i - 1]) + 1; Transition start = phylum.NewTransition(prefixState + "bstart" + i + id); phylum.NewArc(lastCondition, start); // Connect Action phylum.NewArc(start, prefixState + state.Transitions[i - 1].To + id + ".action.initialized"); } else { Transition eval = phylum.NewTransition(prefixState + "eval" + i); phylum.NewArc(lastCondition, eval); Place condition = phylum.NewPlace(prefixState + "condition" + i); phylum.NewArc(eval, condition); // False Transition wrong = phylum.NewTransition(prefixState + "wrong" + i); phylum.NewArc(condition, wrong); // Reset if (i == emptyTrigger) { phylum.NewArc(wrong, trigger); } else { Place newRun = phylum.NewPlace(prefixState + "runcondition" + (i + 1)); phylum.NewArc(wrong, newRun); lastCondition = newRun; } // True int id = i; Transition right = phylum.NewTransition(prefixState + "bstart" + i + id); phylum.NewArc(condition, right); // Connect Action phylum.NewArc(right, prefixState + state.Transitions[i - 1].To + id + ".action.initialized"); } } } } } } // Connect States // Initial State phylum.Merge(p1, prefix + states.First(s => s.Id.Equals(initialState)).Id + ".initialized"); // Final States IList <SMState> finalStates = new List <SMState>(states.Where(s => s.Final == true)); foreach (SMState finalState in finalStates) { phylum.Merge(p2, prefix + finalState.Id + ".closed"); } // Transitions foreach (SMState state in states) { for (int i = 1; i <= state.Transitions.Count; i++) { SMTransition transition = state.Transitions[i - 1]; phylum.Merge(prefix + state.Id + ".to" + i + "." + transition.To, prefix + transition.To + ".initialized"); } } return(phylum); }
private SMTransition parseTransition(Queue<IXamlElement> token) { // Transition SMTransition transition = new SMTransition(); // Trigger SMTrigger trigger; // Reference String reference; String refTrigger; String condition; // [Start] Transition IXamlElement element = token.Dequeue(); bool attRef = element.Attributes.TryGetValue("To", out reference); bool attTrigger = element.Attributes.TryGetValue("Trigger", out refTrigger); bool attCondition = element.Attributes.TryGetValue("Condition", out condition); // To if (attRef) { transition.To = extractReference(reference); } // Trigger if (attTrigger) { String id = extractReference(refTrigger); if (triggers.ContainsKey(id)) { triggers[id].Transitions.Add(transition); } else { // Warning log.Warn("Warning Trigger created before IActivity was found!"); trigger = new SMTrigger(); trigger.Transitions.Add(transition); triggers.Add(id, trigger); } } // Condition if (attCondition) { transition.Condition = true; } while (!token.Peek().QName.Equals(createQName("Transition"))) { if (token.Peek().QName.Equals(createQName("Transition.Trigger"))) { // [Start] Transition.Trigger token.Dequeue(); // Trigger Reference String triggerRef; if (token.Peek().Attributes.TryGetValue("x:Name", out triggerRef)) { // Activity IActivity activity = moduleFactory.CreateActivity(token.Peek().QName); IActivity triggerActivity; if (activity != null) { triggerActivity = activity.Parse(token); } else { throw new ParseException(String.Format("No Module found for activity '{0}'", QName), initialTokenCount - token.Count, QName); } if (triggers.ContainsKey(triggerRef)) { log.Warn("Warning trigger existent!"); triggers[triggerRef].Trigger = triggerActivity; triggers[triggerRef].Transitions.Add(transition); } else { trigger = new SMTrigger(); trigger.Trigger = triggerActivity; trigger.Transitions.Add(transition); triggers.Add(triggerRef, trigger); } } else { // Activity IActivity activity = moduleFactory.CreateActivity(token.Peek().QName); IActivity triggerActivity; if (activity != null) { triggerActivity = activity.Parse(token); } else { throw new ParseException(String.Format("No Module found for activity '{0}'", QName), initialTokenCount - token.Count, QName); } trigger = new SMTrigger(); trigger.Trigger = triggerActivity; trigger.Transitions.Add(transition); triggerKey++; triggers.Add(triggerKey.ToString(), trigger); } // [End] Transition.Trigger token.Dequeue(); } else if (token.Peek().QName.Equals(createQName("Transition.Condition"))) { // [Start] Transition.Condition token.Dequeue(); transition.Condition = true; // [End] Transition.Condition token.Dequeue(); } else if (token.Peek().QName.Equals(createQName("Transition.Action"))) { // [Start] Transition.Action token.Dequeue(); // Activity IActivity activity = moduleFactory.CreateActivity(token.Peek().QName); if (activity != null) { transition.Action = activity.Parse(token); } else { throw new ParseException(String.Format("No Module found for activity '{0}'", QName), initialTokenCount - token.Count, QName); } // [End] Transition.Action token.Dequeue(); } else if (token.Peek().QName.Equals(createQName("Transition.To"))) { // [Start] Transition.To token.Dequeue(); if (token.Peek().QName.Equals(createQName("State"))) { transition.To = token.Peek().Attributes["x:Name"]; // Recursion parseState(token); } else if (token.Peek().QName.Equals(createQName("Reference", ns_x))) { // [Start] Reference element = token.Dequeue(); reference = element.Attributes["Reference"]; transition.To = reference; // [End] Reference token.Dequeue(); } else { throw new ParseException(String.Format("Unknown tag found in activity '{0}'", QName), initialTokenCount - token.Count, QName); } // [End] Transition.To token.Dequeue(); } else { throw new ParseException(String.Format("Unknown tag found in activity '{0}'", QName), initialTokenCount - token.Count, QName); } } // [End] Transition token.Dequeue(); return transition; }