2 // Copyright (c) Microsoft Corporation. All rights reserved.
5 namespace System.Activities.Core.Presentation
7 using System.Activities.Presentation.Validation;
8 using System.Activities.Statements;
9 using System.Collections.Generic;
12 internal class StateMachineValidationErrorSourceLocator : IValidationErrorSourceLocator
14 public List<object> FindSourceDetailFromActivity(Activity errorSource, object errorSourceDetail)
16 if (errorSourceDetail == null)
18 return new List<object> { errorSource };
22 return FindRelativePath((StateMachine)errorSource, errorSourceDetail);
26 // case 1: StateMachine -> Default expression of StateMachine's variable -> ...
27 // case 2: StateMachine -> InternalState -> ...
28 public void ReplaceParentChainWithSource(Activity parentActivity, List<object> parentChain)
30 Activity lastActivity = parentChain[parentChain.Count - 1] as Activity;
31 StateMachine stateMachine = (StateMachine)parentActivity;
33 foreach (Variable variable in stateMachine.Variables)
35 if (variable != null && variable.Default == lastActivity)
37 parentChain.Add(stateMachine);
42 if (parentChain.Count > 1)
44 // assume lastActivity is InternalState
46 // remove InternalState
47 parentChain.RemoveAt(parentChain.Count - 1);
49 Activity targetActivity = (Activity)parentChain[parentChain.Count - 1];
51 // the targetActivity will be available in the path
52 parentChain.RemoveAt(parentChain.Count - 1);
54 List<object> path = FindRelativePath(stateMachine, targetActivity);
56 foreach (object pathObject in path)
58 parentChain.Add(pathObject);
63 private static List<object> FindRelativePath(StateMachine machine, object descendent)
65 List<object> path = FindDescendentFromStateMachine(machine, descendent);
70 private static List<object> FindDescendentFromStateMachine(StateMachine machine, object descendent)
72 List<object> path = new List<object>();
74 foreach (State state in machine.States)
76 if (state == descendent)
80 else if (state.Entry == descendent)
85 else if (state.Exit == descendent)
92 Transition foundTransition = null;
93 bool transitionAlone = false;
94 foreach (Transition transition in state.Transitions)
96 foundTransition = transition;
97 if (transition == descendent)
99 transitionAlone = true;
102 else if (transition.Trigger == descendent)
106 else if (transition.Action == descendent)
110 else if (transition.Condition == descendent)
116 foundTransition = null;
120 if (foundTransition != null)
123 if (!transitionAlone)
125 path.Add(foundTransition);
131 bool isVariableError = false;
132 foreach (Variable variable in state.Variables)
134 if (variable.Default == descendent)
136 isVariableError = true;
148 path.Add(descendent);