object IConfigurationSectionHandler.Create(Object parent, Object configContext, XmlNode section) { StateInfoCollection<Dialog> dialogs = new StateInfoCollection<Dialog>(); Dialog dialog; int dialogIndex = 0; XmlNode dialogNode; int i; string dialogInitial; #if NET40Plus string resourceType, resourceKey; #endif for (i = 0; i < section.ChildNodes.Count; i++) { dialog = new Dialog(); dialogNode = section.ChildNodes[i]; if (dialogNode.NodeType != XmlNodeType.Comment) { if (dialogNode.Attributes["initial"] == null || dialogNode.Attributes["initial"].Value.Length == 0) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.DialogAttributeMissing, "initial")); dialogInitial = dialogNode.Attributes["initial"].Value; dialog.Index = dialogIndex; dialogIndex++; if (dialogNode.Attributes["key"] == null || dialogNode.Attributes["key"].Value.Length == 0) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.DialogAttributeMissing, "key")); dialog.Key = dialogNode.Attributes["key"].Value; dialog.Title = dialogNode.Attributes["title"] != null ? dialogNode.Attributes["title"].Value : string.Empty; #if NET40Plus resourceType = dialogNode.Attributes["resourceType"] != null ? dialogNode.Attributes["resourceType"].Value : "StateInfo"; resourceKey = dialogNode.Attributes["resourceKey"] != null ? dialogNode.Attributes["resourceKey"].Value : string.Empty; if (resourceKey.Length != 0) dialog.TitleFunc = () => (string)HttpContext.GetGlobalResourceObject(resourceType, resourceKey, Thread.CurrentThread.CurrentUICulture); #else dialog.ResourceType = dialogNode.Attributes["resourceType"] != null ? dialogNode.Attributes["resourceType"].Value : "StateInfo"; dialog.ResourceKey = dialogNode.Attributes["resourceKey"] != null ? dialogNode.Attributes["resourceKey"].Value : string.Empty; #endif dialog.Attributes = new StateInfoCollection<string>(); foreach (XmlAttribute attribute in dialogNode.Attributes) dialog.Attributes[attribute.Name] = attribute.Value; if (dialogs[dialogNode.Attributes["key"].Value] != null) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.DuplicateDialogKey, dialogNode.Attributes["key"].Value)); dialogs.Add(dialogNode.Attributes["key"].Value, dialog); ProcessStates(dialog, dialogNode); ProcessTransitions(dialog, dialogNode); dialog.Initial = dialog.States[dialogInitial]; if (dialog.Initial == null) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidDialogInitialKey, dialog.Key, dialogInitial)); } } return dialogs; }
private static void ProcessStates(Dialog dialog, XmlNode dialogNode) { State state; int stateIndex = 0; XmlNode dialogChildNode; string[] derived; int i; bool result; #if NET40Plus string resourceType, resourceKey; #endif for (i = 0; i < dialogNode.ChildNodes.Count; i++) { state = new State(); dialogChildNode = dialogNode.ChildNodes[i]; if (dialogChildNode.NodeType != XmlNodeType.Comment) { if (dialogChildNode.Name == "state") { state.Parent = dialog; state.Index = stateIndex; stateIndex++; if (dialogChildNode.Attributes["key"] == null || dialogChildNode.Attributes["key"].Value.Length == 0) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.StateAttributeMissing, "key")); state.Key = dialogChildNode.Attributes["key"].Value; state.Title = dialogChildNode.Attributes["title"] != null ? dialogChildNode.Attributes["title"].Value : string.Empty; #if NET40Plus resourceType = dialogChildNode.Attributes["resourceType"] != null ? dialogChildNode.Attributes["resourceType"].Value : "StateInfo"; resourceKey = dialogChildNode.Attributes["resourceKey"] != null ? dialogChildNode.Attributes["resourceKey"].Value : string.Empty; if (resourceKey.Length != 0) state.TitleFunc = () => (string)HttpContext.GetGlobalResourceObject(resourceType, resourceKey, Thread.CurrentThread.CurrentUICulture); #else state.ResourceType = dialogChildNode.Attributes["resourceType"] != null ? dialogChildNode.Attributes["resourceType"].Value : "StateInfo"; state.ResourceKey = dialogChildNode.Attributes["resourceKey"] != null ? dialogChildNode.Attributes["resourceKey"].Value : string.Empty; #endif #if NET40Plus state.Route = dialogChildNode.Attributes["route"] != null ? dialogChildNode.Attributes["route"].Value : string.Empty; #endif state.DefaultTypes = new StateInfoCollection<Type>(); if (dialogChildNode.Attributes["defaultTypes"] != null) { if (!TryParseDefaultTypes(dialogChildNode.Attributes["defaultTypes"].Value, state)) { throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.StateAttributeInvalid, state.Key, "defaultTypes")); } } state.Defaults = new StateInfoCollection<object>(); state.FormattedDefaults = new StateInfoCollection<string>(); if (dialogChildNode.Attributes["defaults"] != null) { try { NavigationData navigationData = StateInfoConfig.ParseNavigationDataExpression(dialogChildNode.Attributes["defaults"].Value, state, false); foreach (NavigationDataItem item in navigationData) { state.Defaults[item.Key] = item.Value; state.FormattedDefaults[item.Key] = CrumbTrailManager.FormatURLObject(item.Key, item.Value, state); } } catch (InvalidCastException ice) { throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.StateAttributeInvalid, state.Key, "defaults"), ice); } catch (FormatException fe) { throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.StateAttributeInvalid, state.Key, "defaults"), fe); } catch (OverflowException oe) { throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.StateAttributeInvalid, state.Key, "defaults"), oe); } } derived = new string[] { }; state.DerivedInternal = new Dictionary<string, string>(); if (dialogChildNode.Attributes["derived"] != null) { derived = Regex.Split(dialogChildNode.Attributes["derived"].Value, ","); for (int j = 0; j < derived.Length; j++) { derived[j] = derived[j].Trim(); state.DerivedInternal.Add(derived[j], derived[j]); } } state.Derived = new ReadOnlyCollection<string>(derived); state.TrackCrumbTrail = true; if (dialogChildNode.Attributes["trackCrumbTrail"] != null) { if (bool.TryParse(dialogChildNode.Attributes["trackCrumbTrail"].Value, out result)) state.TrackCrumbTrail = result; else throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.StateAttributeInvalid, state.Key, "trackCrumbTrail")); } if (dialog.States[dialogChildNode.Attributes["key"].Value] != null) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.DuplicateStateKey, dialogChildNode.Attributes["key"].Value, dialog.Key)); state.Attributes = new StateInfoCollection<string>(); foreach (XmlAttribute attribute in dialogChildNode.Attributes) state.Attributes[attribute.Name] = attribute.Value; dialog.States[dialogChildNode.Attributes["key"].Value] = state; } } } }
private static void ProcessTransitions(Dialog dialog, XmlNode dialogNode) { State state; Transition transition; int transitionIndex = 0; XmlNode dialogChildNode, transitionNode; int i, j; for (i = 0; i < dialogNode.ChildNodes.Count; i++) { dialogChildNode = dialogNode.ChildNodes[i]; if (dialogChildNode.NodeType != XmlNodeType.Comment) { if (dialogChildNode.Name == "state") { state = dialog.States[dialogChildNode.Attributes["key"].Value]; transitionIndex = 0; for (j = 0; j < dialogChildNode.ChildNodes.Count; j++) { transitionNode = dialogChildNode.ChildNodes[j]; if (transitionNode.NodeType != XmlNodeType.Comment) { transition = new Transition(); transition.Parent = state; transition.Index = transitionIndex; transitionIndex++; if (transitionNode.Attributes["key"] == null || transitionNode.Attributes["key"].Value.Length == 0) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.TransitionAttributeMissing, "key")); transition.Key = transitionNode.Attributes["key"].Value; if (transitionNode.Attributes["to"] == null || transitionNode.Attributes["to"].Value.Length == 0) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.TransitionAttributeMissing, "to")); transition.To = dialog.States[transitionNode.Attributes["to"].Value]; if (transition.To == null) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidTransitionToKey, state.Key, transitionNode.Attributes["to"].Value)); if (state.Transitions[transitionNode.Attributes["key"].Value] != null) throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, Resources.DuplicateTransitionKey, transitionNode.Attributes["key"].Value, state.Key)); state.Transitions[transitionNode.Attributes["key"].Value] = transition; } } } } } }
private static Dictionary<int, HashSet<int>> CalculateDepths(Dialog dialog, List<TransitionElement> transEls) { var depths = new Dictionary<int, HashSet<int>>(); var trans = from s in dialog.States from t in s.Transitions orderby Math.Abs(t.To.Index - t.Parent.Index) select new TransitionElement(t); foreach (var transitionElement in trans) { transEls.Add(transitionElement); CalculateDepth(depths, transitionElement); } return depths; }