Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core/Scope.cs @ 781

Last change on this file since 781 was 776, checked in by vdorfer, 16 years ago

Created API documentation for HeuristicLab.Core namespace (#331)

File size: 16.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.Xml;
26
27namespace HeuristicLab.Core {
28  /// <summary>
29  /// Hierarchical container of variables (and of subscopes).
30  /// </summary>
31  public class Scope : ItemBase, IScope {
32    private IScope parent;
33
34    private string myName;
35    /// <summary>
36    /// Gets the name of the current scope.
37    /// </summary>
38    public string Name {
39      get { return myName; }
40    }
41
42    private IDictionary<string, IVariable> myVariables;
43    /// <inheritdoc/>
44    public ICollection<IVariable> Variables {
45      get { return myVariables.Values; }
46    }
47    private IDictionary<string, string> myAliases;
48    /// <inheritdoc/>
49    public IEnumerable<KeyValuePair<string, string>> Aliases {
50      get { return myAliases; }
51    }
52    private List<IScope> mySubScopes;
53    /// <summary>
54    /// Gets all subscopes of the current instance.
55    /// <note type="caution"> The subscopes are returned as read-only.</note>
56    /// </summary>
57    public IList<IScope> SubScopes {
58      get { return mySubScopes.AsReadOnly(); }
59    }
60
61    /// <summary>
62    /// Initializes a new instance of <see cref="Scope"/> having "Anonymous" as default name.
63    /// </summary>
64    public Scope() {
65      myName = "Anonymous";
66      myVariables = new Dictionary<string, IVariable>();
67      myAliases = new Dictionary<string, string>();
68      mySubScopes = new List<IScope>();
69    }
70    /// <summary>
71    /// Initializes a new instance of <see cref="Scope"/> with the given <paramref name="name"/>.
72    /// </summary>
73    /// <param name="name">The name of the scope.</param>
74    public Scope(string name)
75      : this() {
76      if (name != null) myName = name;
77    }
78
79    /// <inheritdoc/>
80    public void SetParent(IScope scope) {
81      parent = scope;
82    }
83
84    /// <summary>
85    /// Creates a new instance of <see cref="ScopeView"/> to represent the current instance visually.
86    /// </summary>
87    /// <returns>The created view as <see cref="ScopeView"/>.</returns>
88    public override IView CreateView() {
89      return new ScopeView(this);
90    }
91
92    /// <inheritdoc/>
93    public IVariable GetVariable(string name) {
94      IVariable variable;
95      if (myVariables.TryGetValue(name, out variable))
96        return variable;
97      else
98        return null;
99    }
100    /// <inheritdoc/>
101    public void AddVariable(IVariable variable) {
102      myVariables.Add(variable.Name, variable);
103      variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
104      variable.NameChanged += new EventHandler(Variable_NameChanged);
105      OnVariableAdded(variable);
106    }
107
108    /// <inheritdoc/>
109    public void RemoveVariable(string name) {
110      IVariable variable;
111      if (myVariables.TryGetValue(name, out variable)) {
112        variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
113        variable.NameChanged -= new EventHandler(Variable_NameChanged);
114        myVariables.Remove(name);
115        OnVariableRemoved(variable);
116      }
117    }
118    private void Variable_NameChanging(object sender, NameChangingEventArgs e) {
119      e.Cancel = myVariables.ContainsKey(e.Name);
120    }
121    private void Variable_NameChanged(object sender, EventArgs e) {
122      IVariable variable = (IVariable)sender;
123      string oldName = null;
124      foreach (KeyValuePair<string, IVariable> element in myVariables) {
125        if (element.Value == variable)
126          oldName = element.Key;
127      }
128      myVariables.Remove(oldName);
129      myVariables.Add(variable.Name, variable);
130    }
131    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool)"/>
132    public T GetVariableValue<T>(string name, bool recursiveLookup) where T : class, IItem {
133      return GetVariableValue<T>(name, recursiveLookup, true);
134    }
135    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool, bool)"/>
136    public T GetVariableValue<T>(string name, bool recursiveLookup, bool throwOnError) where T : class, IItem {
137      return (T)GetVariableValue(name, recursiveLookup, throwOnError);
138    }
139    /// <inheritdoc cref="IScope.GetVariableValue(string, bool)"/>
140    public IItem GetVariableValue(string name, bool recursiveLookup) {
141      return GetVariableValue(name, recursiveLookup, true);
142    }
143    /// <inheritdoc cref="IScope.GetVariableValue(string, bool, bool)"/>
144    public IItem GetVariableValue(string name, bool recursiveLookup, bool throwOnError) {
145      IVariable variable;
146      name = TranslateName(name);
147      if (myVariables.TryGetValue(name, out variable)) {
148        return variable.Value;
149      } else {
150        if (recursiveLookup && (parent != null))
151          return parent.GetVariableValue(name, recursiveLookup, throwOnError);
152        else {
153          if (throwOnError)
154            throw new ArgumentException("Variable " + name + " not found");
155          else
156            return null;
157        }
158      }
159    }
160    /// <inheritdoc/>
161    public string TranslateName(string name) {
162      while (myAliases.ContainsKey(name))
163        name = myAliases[name];
164      if (parent != null)
165        name = parent.TranslateName(name);
166      return name;
167    }
168    /// <inheritdoc/>
169    public void AddAlias(string alias, string name) {
170      RemoveAlias(alias);
171      if (alias != name) {
172        myAliases.Add(alias, name);
173        OnAliasAdded(alias);
174      }
175    }
176    /// <inheritdoc/>
177    public void RemoveAlias(string alias) {
178      if (myAliases.ContainsKey(alias)) {
179        myAliases.Remove(alias);
180        OnAliasRemoved(alias);
181      }
182    }
183
184    /// <inheritdoc/>
185    public void AddSubScope(IScope scope) {
186      scope.SetParent(this);
187      mySubScopes.Add(scope);
188      OnSubScopeAdded(scope, mySubScopes.Count - 1);
189    }
190    /// <inheritdoc/>
191    public void RemoveSubScope(IScope scope) {
192      int index = mySubScopes.IndexOf(scope);
193      if (mySubScopes.Remove(scope)) {
194        scope.SetParent(null);
195        OnSubScopeRemoved(scope, index);
196      }
197    }
198    /// <inheritdoc/>
199    public void ReorderSubScopes(int[] sequence) {
200      IScope[] scopes = mySubScopes.ToArray();
201      mySubScopes.Clear();
202      for (int i = 0; i < scopes.Length; i++)
203        mySubScopes.Add(scopes[sequence[i]]);
204      OnSubScopesReordered();
205    }
206    /// <inheritdoc/>
207    public IScope GetScope(Guid guid) {
208      if (Guid == guid) return this;
209      else {
210        for (int i = 0; i < mySubScopes.Count; i++) {
211          IScope s = mySubScopes[i].GetScope(guid);
212          if (s != null) return s;
213        }
214      }
215      return null;
216    }
217    /// <inheritdoc/>
218    public IScope GetScope(string name) {
219      if (Name == name) return this;
220      else {
221        for (int i = 0; i < mySubScopes.Count; i++) {
222          IScope s = mySubScopes[i].GetScope(name);
223          if (s != null) return s;
224        }
225      }
226      return null;
227    }
228
229    /// <inheritdoc/>
230    public void Clear() {
231      string[] variableNames = new string[Variables.Count];
232      int i = 0;
233      foreach (IVariable variable in Variables) {
234        variableNames[i] = variable.Name;
235        i++;
236      }
237      for (int j = 0; j < variableNames.Length; j++)
238        RemoveVariable(variableNames[j]);
239
240      KeyValuePair<string, string>[] aliases = new KeyValuePair<string,string>[myAliases.Count];
241      myAliases.CopyTo(aliases, 0);
242      for (int j = 0; j < aliases.Length; j++)
243        RemoveAlias(aliases[j].Key);
244
245      while (SubScopes.Count > 0)
246        RemoveSubScope(SubScopes[0]);
247    }
248
249    /// <inheritdoc/>
250    public override object Clone(IDictionary<Guid, object> clonedObjects) {
251      Scope clone = (Scope)base.Clone(clonedObjects);
252      clone.myName = Name;
253
254      foreach (IVariable variable in myVariables.Values)
255        clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects));
256      foreach (KeyValuePair<string, string> alias in myAliases)
257        clone.AddAlias(alias.Key, alias.Value);
258      for (int i = 0; i < SubScopes.Count; i++)
259        clone.AddSubScope((IScope)Auxiliary.Clone(SubScopes[i], clonedObjects));
260
261      return clone;
262    }
263
264    /// <inheritdoc />
265    public event EventHandler<VariableEventArgs> VariableAdded;
266    /// <summary>
267    /// Fires a new <c>VariableAdded</c> event.
268    /// </summary>
269    /// <param name="variable">The variable that has been added.</param>
270    protected virtual void OnVariableAdded(IVariable variable) {
271      if (VariableAdded != null)
272        VariableAdded(this, new VariableEventArgs(variable));
273    }
274    /// <inheritdoc />
275    public event EventHandler<VariableEventArgs> VariableRemoved;
276    /// <summary>
277    /// Fires a new <c>VariableRemoved</c>.
278    /// </summary>
279    /// <param name="variable">The variable that has been deleted.</param>
280    protected virtual void OnVariableRemoved(IVariable variable) {
281      if (VariableRemoved != null)
282        VariableRemoved(this, new VariableEventArgs(variable));
283    }
284    /// <inheritdoc />
285    public event EventHandler<AliasEventArgs> AliasAdded;
286    /// <summary>
287    /// Fires a new <c>AliasAdded</c> event.
288    /// </summary>
289    /// <param name="alias">The alias that has been added.</param>
290    protected virtual void OnAliasAdded(string alias) {
291      if (AliasAdded != null)
292        AliasAdded(this, new AliasEventArgs(alias));
293    }
294    /// <inheritdoc/>
295    public event EventHandler<AliasEventArgs> AliasRemoved;
296    /// <summary>
297    /// Fires a new <c>AliasRemoved</c> event.
298    /// </summary>
299    /// <param name="alias">The alias that has been deleted.</param>
300    protected virtual void OnAliasRemoved(string alias) {
301      if (AliasRemoved != null)
302        AliasRemoved(this, new AliasEventArgs(alias));
303    }
304    /// <inheritdoc/>
305    public event EventHandler<ScopeIndexEventArgs> SubScopeAdded;
306    /// <summary>
307    /// Fires a new <c>SubScopeAdded</c> event.
308    /// </summary>
309    /// <param name="scope">The sub scope that has been added.</param>
310    /// <param name="index">The index where the scope has been added.</param>
311    protected virtual void OnSubScopeAdded(IScope scope, int index) {
312      if (SubScopeAdded != null)
313        SubScopeAdded(this, new ScopeIndexEventArgs(scope, index));
314    }
315    /// <inheritdoc/>
316    public event EventHandler<ScopeIndexEventArgs> SubScopeRemoved;
317    /// <summary>
318    /// Fires a new <c>SubScopeRemoved</c> event.
319    /// </summary>
320    /// <param name="scope">The sub scope that has been deleted.</param>
321    /// <param name="index">The position of the sub scope.</param>
322    protected virtual void OnSubScopeRemoved(IScope scope, int index) {
323      if (SubScopeRemoved != null)
324        SubScopeRemoved(this, new ScopeIndexEventArgs(scope, index));
325    }
326    /// <inheritdoc />
327    public event EventHandler SubScopesReordered;
328    /// <summary>
329    /// Fires a new <c>SubScopesReordered</c> event
330    /// </summary>
331    protected virtual void OnSubScopesReordered() {
332      if (SubScopesReordered != null)
333        SubScopesReordered(this, new EventArgs());
334    }
335
336    #region Persistence Methods
337    /// <summary>
338    /// Saves the current instance as <see cref="XmlNode"/> in the given <paramref name="document"/>.
339    /// </summary>
340    /// <remarks>
341    /// Calls <see cref="StorableBase.GetXmlNode"/> of base class <see cref="ItemBase"/>.<br/>
342    /// A quick overview how the single elements of the current instance are saved:
343    /// <list type="bullet">
344    /// <item>
345    /// <term>Name: </term>
346    /// <description>Saved as an <see cref="XmlAttribute"/> having the tag name <c>Name</c>.</description>
347    /// </item>
348    /// <item>
349    /// <term>Variables: </term>
350    /// <description>A child node is created with the tag name <c>Variables</c>. Beyond this child node,
351    /// all variables are saved as child nodes.</description>
352    /// </item>
353    /// <item>
354    /// <term>Aliases: </term>
355    /// <description>A child node is created with the tag name <c>Aliases</c>. Beyond this child node,
356    /// all aliases are saved as child nodes with the tag name <c>Alias</c>. Each alias has an
357    /// <see cref="XmlAttribute"/> with the tag name "Alias", holding the alias, and an attribute
358    /// with the tag name <c>Name</c>, holding the name of the alias.</description>
359    /// </item>
360    /// <item>
361    /// <term>Sub scopes: </term>
362    /// <description>A child node is created with the tag name <c>SubScopes</c>. Beyond this child node,
363    /// all sub scopes are saved as child nodes.</description>
364    /// </item>
365    /// </list>
366    /// </remarks>
367    /// <param name="name">The (tag)name of the <see cref="XmlNode"/>.</param>
368    /// <param name="document">The <see cref="XmlDocument"/> where to save the data.</param>
369    /// <param name="persistedObjects">The dictionary of all already persisted objects. (Needed to avoid cycles.)</param>
370    /// <returns>The saved <see cref="XmlNode"/>.</returns>
371    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid,IStorable> persistedObjects) {
372      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
373      XmlAttribute nameAttribute = document.CreateAttribute("Name");
374      nameAttribute.Value = Name.ToString();
375      node.Attributes.Append(nameAttribute);
376
377      XmlNode variables = document.CreateNode(XmlNodeType.Element, "Variables", null);
378      foreach (IVariable variable in Variables)
379        variables.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects));
380      node.AppendChild(variables);
381
382      XmlNode aliases = document.CreateNode(XmlNodeType.Element, "Aliases", null);
383      foreach (KeyValuePair<string, string> alias in myAliases) {
384        XmlNode aliasNode = document.CreateNode(XmlNodeType.Element, "Alias", null);
385        XmlAttribute keyAttribute = document.CreateAttribute("Alias");
386        keyAttribute.Value = alias.Key;
387        aliasNode.Attributes.Append(keyAttribute);
388        XmlAttribute valueAttribute = document.CreateAttribute("Name");
389        valueAttribute.Value = alias.Value;
390        aliasNode.Attributes.Append(valueAttribute);
391        aliases.AppendChild(aliasNode);
392      }
393      node.AppendChild(aliases);
394
395      XmlNode subScopes = document.CreateNode(XmlNodeType.Element, "SubScopes", null);
396      for (int i = 0; i < SubScopes.Count; i++)
397        subScopes.AppendChild(PersistenceManager.Persist(SubScopes[i], document, persistedObjects));
398      node.AppendChild(subScopes);
399
400      return node;
401    }
402    /// <summary>
403    /// Loads the persisted scope from the specified <paramref name="node"/>.
404    /// </summary>
405    /// <remarks>See <see cref="GetXmlNode"/> to get further information on how the current instance must
406    /// be saved. <br/>
407    /// Calls <see cref="StorableBase.Populate"/> of base class <see cref="ItemBase"/>.</remarks>
408    /// <param name="node">The <see cref="XmlNode"/> where the boolean value is saved.</param>
409    /// <param name="restoredObjects">The dictionary of all already restored objects.
410    /// (Needed to avoid cycles.)</param>
411    public override void Populate(XmlNode node, IDictionary<Guid,IStorable> restoredObjects) {
412      base.Populate(node, restoredObjects);
413      myName = node.Attributes["Name"].Value;
414
415      XmlNode variables = node.SelectSingleNode("Variables");
416      foreach (XmlNode variableNode in variables.ChildNodes) {
417        IVariable variable = (IVariable)PersistenceManager.Restore(variableNode, restoredObjects);
418        AddVariable(variable);
419      }
420
421      XmlNode aliases = node.SelectSingleNode("Aliases");
422      if (aliases != null) {
423        foreach (XmlNode aliasNode in aliases.ChildNodes)
424          AddAlias(aliasNode.Attributes["Alias"].Value, aliasNode.Attributes["Name"].Value);
425      }
426
427      XmlNode subScopes = node.SelectSingleNode("SubScopes");
428      for (int i = 0; i < subScopes.ChildNodes.Count; i++) {
429        IScope scope = (IScope)PersistenceManager.Restore(subScopes.ChildNodes[i], restoredObjects);
430        AddSubScope(scope);
431      }
432    }
433    #endregion
434  }
435}
Note: See TracBrowser for help on using the repository browser.