/// <summary> /// Loads the state/tranistion information for an XML config file. /// </summary> /// <remarks> /// The path to the config file to load is specified in the application's config file /// appSettings section, with the "statesConfigPath" setting. /// </remarks> /// <returns>A <b></b> object with the state/transition information loaded from the /// config file.</returns> public StateInfo LoadStates() { List<IState> states = new List<IState>(); StateInfo info = new StateInfo(); try { // get the path to the states.config file from web.config String statesConfigPath = ConfigurationManager.AppSettings["statesConfigPath"]; if (statesConfigPath == null) { throw new Exception("No states.config path in config file."); } // make the XmlDocument object for the states.config file & load it XmlDocument stateSettings = new XmlDocument(); stateSettings.Load(AppInfo.BasePath + statesConfigPath); //====================================================== // load the transition groups //====================================================== // get the "transitiongroup" nodes XmlNodeList transGroupNodes = stateSettings.SelectNodes("/states/" + TRANSITION_GROUP_NAME); Hashtable transGroups = new Hashtable(); foreach (XmlNode groupNode in transGroupNodes) { try { string name = groupNode.Attributes[NAME_ATTRIBUTE].Value; List<Transition> transitions = this.LoadTransitions(groupNode); transGroups.Add(name, transitions); } catch (Exception) {} } //====================================================== // load the config settings //====================================================== // read the config settings from the states file XmlNode configNode = stateSettings.SelectSingleNode("/states/config"); if (configNode != null) { try { bool trace = bool.Parse(configNode.Attributes["trace"].Value); info.AddConfig("trace", trace); } catch (Exception) {} } //====================================================== // load the states //====================================================== // get the "state" nodes XmlNodeList stateNodes = stateSettings.SelectNodes("/states/state"); IState state = null; NameValueCollection attributes = new NameValueCollection(); foreach (XmlNode stateNode in stateNodes) { try { string type = stateNode.Attributes[TYPE_ATTRIBUTE].Value; long id = long.Parse(stateNode.Attributes[ID_ATTRIBUTE].Value); attributes.Clear(); foreach (XmlAttribute attr in stateNode.Attributes) { attributes.Add(attr.Name, attr.Value); } state = StateFactory.MakeState(type, id, attributes); if (state == null) { throw new ApplicationException("Null state exception."); } } catch (Exception e) { LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("Failed to make state: node = {0}", stateNode.OuterXml), e); } // if we successfully generated the state... // if (state != null) { if (state is BaseState) { // load the state's transitions List<Transition> transitions = this.LoadTransitions(stateNode); foreach (Transition trans in transitions) { try { ((BaseState)state).AddTransition(trans); } catch (Exception e) { throw new ApplicationException( string.Format("Invalid transition '{0}' in state {1}.", trans.Name, state.Id), e); } } // add the transitions from transition groups if there are any XmlNodeList groupNodes = stateNode.SelectNodes(TRANSITION_GROUP_NAME); foreach (XmlNode groupNode in groupNodes) { try { // get the name of the tranistion group string name = groupNode.Attributes[NAME_ATTRIBUTE].Value; // if no transition group is defined for the given name, throw exception if (!transGroups.ContainsKey(name)) { throw new ApplicationException(string.Format( "No transition group defined for '{0}'. State = {1}.", name, state.Id)); } // add the transitions from the transition group to the state foreach (Transition trans in (List<Transition>)transGroups[name]) { ((BaseState)state).AddTransition(trans.Clone(state.Id)); } } catch (Exception e) { LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("ConfigSmStateDao.LoadStates: failure loading transitiongroup (" + groupNode.OuterXml + "): "), e); } } } states.Add(state); // } } // dump the local transition groups hashtable transGroups.Clear(); LogManager.GetCurrentClassLogger().Debug( debugMessage => debugMessage("ConfigSmStateDao - successfully loaded page config settings")); } catch (Exception e) { LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("ConfigSmStateDao.LoadStates: "), e); throw; } info.States = states.ToArray(); return info; }
/// <summary> /// Loads the state/tranistion information for an XML config file. /// </summary> /// <remarks> /// The path to the config file to load is specified in the application's config file /// appSettings section, with the "statesConfigPath" setting. /// </remarks> /// <returns>A <b></b> object with the state/transition information loaded /// from the config file.</returns> public StateInfo LoadStates() { StateInfo info = new StateInfo(); Hashtable transGroups = new Hashtable(); try { // get the path to the states.config directory from web.config string statesConfigPath = AppInfo.BasePath + ConfigurationManager.AppSettings["statesDiagramPath"]; if (statesConfigPath == null) { throw new ApplicationException("No states.config path in config file."); } // read all the .graphml files in the directory. // XmlDocument stateSettings = new XmlDocument(); // Key is the StateID, value is the element representing the state Dictionary<long, IState> states = new Dictionary<long, IState>(); // key is the id of the node, value is the transition name Dictionary<string, Dictionary<string, long>> transitionGroups = new Dictionary<string, Dictionary<string, long>>(); Dictionary<long, List<string>> stateTransitionGroups = new Dictionary<long, List<string>>(); if (Directory.Exists(statesConfigPath)) { if (Directory.GetFiles(statesConfigPath, "*.graphml", SearchOption.TopDirectoryOnly).Length > 0) { string[] graphmlFiles = Directory.GetFiles(statesConfigPath, "*.graphml", SearchOption.TopDirectoryOnly); foreach (string fileName in graphmlFiles) { PreProcessGraphmlFile(fileName); } foreach (string fileName in graphmlFiles) { ProcessGraphmlFile(fileName, states, transitionGroups, stateTransitionGroups); } foreach (KeyValuePair<long, List<string>> kvp in stateTransitionGroups) { long fromStateId = kvp.Key; IState state = states[fromStateId]; foreach (string stateTransitionGroup in kvp.Value) { if (transitionGroups.ContainsKey(stateTransitionGroup)) { Dictionary<string, long> transitionGroup = transitionGroups[stateTransitionGroup]; foreach (KeyValuePair<string, long> trans in transitionGroup) { long toStateId = trans.Value; Transition transition = new Transition(fromStateId, toStateId, trans.Key, null); try { ((BaseState)state).AddTransition(transition); } catch { this.log.Debug(debug => debug("Attempting to add a transition ({0}) to a state ({1}) that already exists.", trans.Key, toStateId)); } } } else { this.log.Debug(debug => debug("Unable to locate transition group {0} for stateid {1}", stateTransitionGroup, fromStateId)); } } } } else { this.log.Error(error => error("LoadStates: No States config files found")); throw new IndexOutOfRangeException("LoadStates: No States config files found"); } } else { this.log.Error(error => error("LoadStates: No States Folder found")); throw new NotSupportedException("LoadStates: No States Folder found"); } info.States = states.Values.ToArray(); this.log.Info(infoMessage => infoMessage("Successfully loaded page config settings")); } catch (Exception e) { this.log.Error(error => error("Error occured in LoadStates: ", e)); throw; } finally { transGroups.Clear(); } return info; }