#region License Information /* HeuristicLab * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Text; using System.Xml; using HeuristicLab.Common; namespace HeuristicLab.Core { /// /// Hierarchical container of variables (and of subscopes). /// public class Scope : ItemBase, IScope { private IScope parent; private string myName; /// /// Gets the name of the current scope. /// public string Name { get { return myName; } } private IDictionary myVariables; /// public ICollection Variables { get { return myVariables.Values; } } private IDictionary myAliases; /// public IEnumerable> Aliases { get { return myAliases; } } private List mySubScopes; /// /// Gets all subscopes of the current instance. /// The subscopes are returned as read-only. /// public IList SubScopes { get { return mySubScopes.AsReadOnly(); } } /// /// Initializes a new instance of having "Anonymous" as default name. /// public Scope() { myName = "Anonymous"; myVariables = new Dictionary(); myAliases = new Dictionary(); mySubScopes = new List(); } /// /// Initializes a new instance of with the given . /// /// The name of the scope. public Scope(string name) : this() { if (name != null) myName = name; } /// public void SetParent(IScope scope) { parent = scope; } /// /// Creates a new instance of to represent the current instance visually. /// /// The created view as . public override IView CreateView() { return new ScopeView(this); } /// public IVariable GetVariable(string name) { IVariable variable; if (myVariables.TryGetValue(name, out variable)) return variable; else return null; } /// public void AddVariable(IVariable variable) { myVariables.Add(variable.Name, variable); variable.NameChanging += new EventHandler>(Variable_NameChanging); variable.NameChanged += new EventHandler(Variable_NameChanged); OnVariableAdded(variable); } /// public void RemoveVariable(string name) { IVariable variable; if (myVariables.TryGetValue(name, out variable)) { variable.NameChanging -= new EventHandler>(Variable_NameChanging); variable.NameChanged -= new EventHandler(Variable_NameChanged); myVariables.Remove(name); OnVariableRemoved(variable); } } private void Variable_NameChanging(object sender, CancelEventArgs e) { e.Cancel = myVariables.ContainsKey(e.Value); } private void Variable_NameChanged(object sender, EventArgs e) { IVariable variable = (IVariable)sender; string oldName = null; foreach (KeyValuePair element in myVariables) { if (element.Value == variable) oldName = element.Key; } myVariables.Remove(oldName); myVariables.Add(variable.Name, variable); } /// public T GetVariableValue(string name, bool recursiveLookup) where T : class, IItem { return GetVariableValue(name, recursiveLookup, true); } /// public T GetVariableValue(string name, bool recursiveLookup, bool throwOnError) where T : class, IItem { return (T)GetVariableValue(name, recursiveLookup, throwOnError); } /// public IItem GetVariableValue(string name, bool recursiveLookup) { return GetVariableValue(name, recursiveLookup, true); } /// public IItem GetVariableValue(string name, bool recursiveLookup, bool throwOnError) { IVariable variable; name = TranslateName(name); if (myVariables.TryGetValue(name, out variable)) { return variable.Value; } else { if (recursiveLookup && (parent != null)) return parent.GetVariableValue(name, recursiveLookup, throwOnError); else { if (throwOnError) throw new ArgumentException("Variable " + name + " not found"); else return null; } } } /// public string TranslateName(string name) { while (myAliases.ContainsKey(name)) name = myAliases[name]; if (parent != null) name = parent.TranslateName(name); return name; } /// public void AddAlias(string alias, string name) { RemoveAlias(alias); if (alias != name) { myAliases.Add(alias, name); OnAliasAdded(alias); } } /// public void RemoveAlias(string alias) { if (myAliases.ContainsKey(alias)) { myAliases.Remove(alias); OnAliasRemoved(alias); } } /// public void AddSubScope(IScope scope) { scope.SetParent(this); mySubScopes.Add(scope); OnSubScopeAdded(scope, mySubScopes.Count - 1); } /// public void RemoveSubScope(IScope scope) { int index = mySubScopes.IndexOf(scope); if (mySubScopes.Remove(scope)) { scope.SetParent(null); OnSubScopeRemoved(scope, index); } } /// public void ReorderSubScopes(int[] sequence) { IScope[] scopes = mySubScopes.ToArray(); mySubScopes.Clear(); for (int i = 0; i < scopes.Length; i++) mySubScopes.Add(scopes[sequence[i]]); OnSubScopesReordered(); } /// public IScope GetScope(Guid guid) { if (Guid == guid) return this; else { for (int i = 0; i < mySubScopes.Count; i++) { IScope s = mySubScopes[i].GetScope(guid); if (s != null) return s; } } return null; } /// public IScope GetScope(string name) { if (Name == name) return this; else { for (int i = 0; i < mySubScopes.Count; i++) { IScope s = mySubScopes[i].GetScope(name); if (s != null) return s; } } return null; } /// public void Clear() { string[] variableNames = new string[Variables.Count]; int i = 0; foreach (IVariable variable in Variables) { variableNames[i] = variable.Name; i++; } for (int j = 0; j < variableNames.Length; j++) RemoveVariable(variableNames[j]); KeyValuePair[] aliases = new KeyValuePair[myAliases.Count]; myAliases.CopyTo(aliases, 0); for (int j = 0; j < aliases.Length; j++) RemoveAlias(aliases[j].Key); while (SubScopes.Count > 0) RemoveSubScope(SubScopes[0]); } /// public override object Clone(IDictionary clonedObjects) { Scope clone = (Scope)base.Clone(clonedObjects); clone.myName = Name; foreach (IVariable variable in myVariables.Values) clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects)); foreach (KeyValuePair alias in myAliases) clone.AddAlias(alias.Key, alias.Value); for (int i = 0; i < SubScopes.Count; i++) clone.AddSubScope((IScope)Auxiliary.Clone(SubScopes[i], clonedObjects)); return clone; } /// public event EventHandler> VariableAdded; /// /// Fires a new VariableAdded event. /// /// The variable that has been added. protected virtual void OnVariableAdded(IVariable variable) { if (VariableAdded != null) VariableAdded(this, new EventArgs(variable)); } /// public event EventHandler> VariableRemoved; /// /// Fires a new VariableRemoved. /// /// The variable that has been deleted. protected virtual void OnVariableRemoved(IVariable variable) { if (VariableRemoved != null) VariableRemoved(this, new EventArgs(variable)); } /// public event EventHandler> AliasAdded; /// /// Fires a new AliasAdded event. /// /// The alias that has been added. protected virtual void OnAliasAdded(string alias) { if (AliasAdded != null) AliasAdded(this, new EventArgs(alias)); } /// public event EventHandler> AliasRemoved; /// /// Fires a new AliasRemoved event. /// /// The alias that has been deleted. protected virtual void OnAliasRemoved(string alias) { if (AliasRemoved != null) AliasRemoved(this, new EventArgs(alias)); } /// public event EventHandler> SubScopeAdded; /// /// Fires a new SubScopeAdded event. /// /// The sub scope that has been added. /// The index where the scope has been added. protected virtual void OnSubScopeAdded(IScope scope, int index) { if (SubScopeAdded != null) SubScopeAdded(this, new EventArgs(scope, index)); } /// public event EventHandler> SubScopeRemoved; /// /// Fires a new SubScopeRemoved event. /// /// The sub scope that has been deleted. /// The position of the sub scope. protected virtual void OnSubScopeRemoved(IScope scope, int index) { if (SubScopeRemoved != null) SubScopeRemoved(this, new EventArgs(scope, index)); } /// public event EventHandler SubScopesReordered; /// /// Fires a new SubScopesReordered event /// protected virtual void OnSubScopesReordered() { if (SubScopesReordered != null) SubScopesReordered(this, new EventArgs()); } #region Persistence Methods /// /// Saves the current instance as in the given . /// /// /// Calls of base class .
/// A quick overview how the single elements of the current instance are saved: /// /// /// Name: /// Saved as an having the tag name Name. /// /// /// Variables: /// A child node is created with the tag name Variables. Beyond this child node, /// all variables are saved as child nodes. /// /// /// Aliases: /// A child node is created with the tag name Aliases. Beyond this child node, /// all aliases are saved as child nodes with the tag name Alias. Each alias has an /// with the tag name "Alias", holding the alias, and an attribute /// with the tag name Name, holding the name of the alias. /// /// /// Sub scopes: /// A child node is created with the tag name SubScopes. Beyond this child node, /// all sub scopes are saved as child nodes. /// /// ///
/// The (tag)name of the . /// The where to save the data. /// The dictionary of all already persisted objects. (Needed to avoid cycles.) /// The saved . public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary persistedObjects) { XmlNode node = base.GetXmlNode(name, document, persistedObjects); XmlAttribute nameAttribute = document.CreateAttribute("Name"); nameAttribute.Value = Name.ToString(); node.Attributes.Append(nameAttribute); XmlNode variables = document.CreateNode(XmlNodeType.Element, "Variables", null); foreach (IVariable variable in Variables) variables.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects)); node.AppendChild(variables); XmlNode aliases = document.CreateNode(XmlNodeType.Element, "Aliases", null); foreach (KeyValuePair alias in myAliases) { XmlNode aliasNode = document.CreateNode(XmlNodeType.Element, "Alias", null); XmlAttribute keyAttribute = document.CreateAttribute("Alias"); keyAttribute.Value = alias.Key; aliasNode.Attributes.Append(keyAttribute); XmlAttribute valueAttribute = document.CreateAttribute("Name"); valueAttribute.Value = alias.Value; aliasNode.Attributes.Append(valueAttribute); aliases.AppendChild(aliasNode); } node.AppendChild(aliases); XmlNode subScopes = document.CreateNode(XmlNodeType.Element, "SubScopes", null); for (int i = 0; i < SubScopes.Count; i++) subScopes.AppendChild(PersistenceManager.Persist(SubScopes[i], document, persistedObjects)); node.AppendChild(subScopes); return node; } /// /// Loads the persisted scope from the specified . /// /// See to get further information on how the current instance must /// be saved.
/// Calls of base class .
/// The where the boolean value is saved. /// The dictionary of all already restored objects. /// (Needed to avoid cycles.) public override void Populate(XmlNode node, IDictionary restoredObjects) { base.Populate(node, restoredObjects); myName = node.Attributes["Name"].Value; XmlNode variables = node.SelectSingleNode("Variables"); foreach (XmlNode variableNode in variables.ChildNodes) { IVariable variable = (IVariable)PersistenceManager.Restore(variableNode, restoredObjects); AddVariable(variable); } XmlNode aliases = node.SelectSingleNode("Aliases"); if (aliases != null) { foreach (XmlNode aliasNode in aliases.ChildNodes) AddAlias(aliasNode.Attributes["Alias"].Value, aliasNode.Attributes["Name"].Value); } XmlNode subScopes = node.SelectSingleNode("SubScopes"); for (int i = 0; i < subScopes.ChildNodes.Count; i++) { IScope scope = (IScope)PersistenceManager.Restore(subScopes.ChildNodes[i], restoredObjects); AddSubScope(scope); } } #endregion } }