Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core/3.3/Scope.cs @ 1732

Last change on this file since 1732 was 1732, checked in by epitzer, 15 years ago

Clear collection members before filling in deserialized values. (#603)

File size: 12.3 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;
26using HeuristicLab.Persistence.Default.Decomposers.Storable;
27
28namespace HeuristicLab.Core {
29  /// <summary>
30  /// Hierarchical container of variables (and of subscopes).
31  /// </summary>
32  public class Scope : ItemBase, IScope {
33
34    [Storable]
35    private IScope parent;
36
37    [Storable]
38    private string myName;
39    /// <summary>
40    /// Gets the name of the current scope.
41    /// </summary>
42    public string Name {
43      get { return myName; }
44    }
45   
46    private IDictionary<string, IVariable> myVariables;
47    /// <inheritdoc/>   
48    public ICollection<IVariable> Variables {
49      get { return myVariables.Values; }
50    }
51
52    [Storable(Name="Variables")]
53    private List<IVariable> VariablePersistence {
54      get { return new List<IVariable>(myVariables.Values); }
55      set {
56        myVariables.Clear();
57        foreach (IVariable var in value) {
58          AddVariable(var);
59        }
60      }
61    }
62   
63    [Storable]
64    private IDictionary<string, string> myAliases;
65    /// <inheritdoc/>
66    public IEnumerable<KeyValuePair<string, string>> Aliases {
67      get { return myAliases; }
68    }
69
70    [Storable]
71    private List<IScope> mySubScopes;
72    /// <summary>
73    /// Gets all subscopes of the current instance.
74    /// <note type="caution"> The subscopes are returned as read-only.</note>
75    /// </summary>
76    public IList<IScope> SubScopes {
77      get { return mySubScopes.AsReadOnly(); }
78    }
79
80    /// <summary>
81    /// Initializes a new instance of <see cref="Scope"/> having "Anonymous" as default name.
82    /// </summary>
83    public Scope() {
84      myName = "Anonymous";
85      myVariables = new Dictionary<string, IVariable>();
86      myAliases = new Dictionary<string, string>();
87      mySubScopes = new List<IScope>();
88    }
89    /// <summary>
90    /// Initializes a new instance of <see cref="Scope"/> with the given <paramref name="name"/>.
91    /// </summary>
92    /// <param name="name">The name of the scope.</param>
93    public Scope(string name)
94      : this() {
95      if (name != null) myName = name;
96    }
97
98    /// <inheritdoc/>
99    public void SetParent(IScope scope) {
100      parent = scope;
101    }
102
103    /// <summary>
104    /// Creates a new instance of <see cref="ScopeView"/> to represent the current instance visually.
105    /// </summary>
106    /// <returns>The created view as <see cref="ScopeView"/>.</returns>
107    public override IView CreateView() {
108      return new ScopeView(this);
109    }
110
111    /// <inheritdoc/>
112    public IVariable GetVariable(string name) {
113      IVariable variable;
114      if (myVariables.TryGetValue(name, out variable))
115        return variable;
116      else
117        return null;
118    }
119    /// <inheritdoc/>
120    public void AddVariable(IVariable variable) {
121      myVariables.Add(variable.Name, variable);
122      variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
123      variable.NameChanged += new EventHandler(Variable_NameChanged);
124      OnVariableAdded(variable);
125    }
126
127    /// <inheritdoc/>
128    public void RemoveVariable(string name) {
129      IVariable variable;
130      if (myVariables.TryGetValue(name, out variable)) {
131        variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
132        variable.NameChanged -= new EventHandler(Variable_NameChanged);
133        myVariables.Remove(name);
134        OnVariableRemoved(variable);
135      }
136    }
137    private void Variable_NameChanging(object sender, NameChangingEventArgs e) {
138      e.Cancel = myVariables.ContainsKey(e.Name);
139    }
140    private void Variable_NameChanged(object sender, EventArgs e) {
141      IVariable variable = (IVariable)sender;
142      string oldName = null;
143      foreach (KeyValuePair<string, IVariable> element in myVariables) {
144        if (element.Value == variable)
145          oldName = element.Key;
146      }
147      myVariables.Remove(oldName);
148      myVariables.Add(variable.Name, variable);
149    }
150    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool)"/>
151    public T GetVariableValue<T>(string name, bool recursiveLookup) where T : class, IItem {
152      return GetVariableValue<T>(name, recursiveLookup, true);
153    }
154    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool, bool)"/>
155    public T GetVariableValue<T>(string name, bool recursiveLookup, bool throwOnError) where T : class, IItem {
156      return (T)GetVariableValue(name, recursiveLookup, throwOnError);
157    }
158    /// <inheritdoc cref="IScope.GetVariableValue(string, bool)"/>
159    public IItem GetVariableValue(string name, bool recursiveLookup) {
160      return GetVariableValue(name, recursiveLookup, true);
161    }
162    /// <inheritdoc cref="IScope.GetVariableValue(string, bool, bool)"/>
163    public IItem GetVariableValue(string name, bool recursiveLookup, bool throwOnError) {
164      IVariable variable;
165      name = TranslateName(name);
166      if (myVariables.TryGetValue(name, out variable)) {
167        return variable.Value;
168      } else {
169        if (recursiveLookup && (parent != null))
170          return parent.GetVariableValue(name, recursiveLookup, throwOnError);
171        else {
172          if (throwOnError)
173            throw new ArgumentException("Variable " + name + " not found");
174          else
175            return null;
176        }
177      }
178    }
179    /// <inheritdoc/>
180    public string TranslateName(string name) {
181      while (myAliases.ContainsKey(name))
182        name = myAliases[name];
183      if (parent != null)
184        name = parent.TranslateName(name);
185      return name;
186    }
187    /// <inheritdoc/>
188    public void AddAlias(string alias, string name) {
189      RemoveAlias(alias);
190      if (alias != name) {
191        myAliases.Add(alias, name);
192        OnAliasAdded(alias);
193      }
194    }
195    /// <inheritdoc/>
196    public void RemoveAlias(string alias) {
197      if (myAliases.ContainsKey(alias)) {
198        myAliases.Remove(alias);
199        OnAliasRemoved(alias);
200      }
201    }
202
203    /// <inheritdoc/>
204    public void AddSubScope(IScope scope) {
205      scope.SetParent(this);
206      mySubScopes.Add(scope);
207      OnSubScopeAdded(scope, mySubScopes.Count - 1);
208    }
209    /// <inheritdoc/>
210    public void RemoveSubScope(IScope scope) {
211      int index = mySubScopes.IndexOf(scope);
212      if (mySubScopes.Remove(scope)) {
213        scope.SetParent(null);
214        OnSubScopeRemoved(scope, index);
215      }
216    }
217    /// <inheritdoc/>
218    public void ReorderSubScopes(int[] sequence) {
219      IScope[] scopes = mySubScopes.ToArray();
220      mySubScopes.Clear();
221      for (int i = 0; i < scopes.Length; i++)
222        mySubScopes.Add(scopes[sequence[i]]);
223      OnSubScopesReordered();
224    }
225    /// <inheritdoc/>
226    public IScope GetScope(Guid guid) {
227      if (Guid == guid) return this;
228      else {
229        for (int i = 0; i < mySubScopes.Count; i++) {
230          IScope s = mySubScopes[i].GetScope(guid);
231          if (s != null) return s;
232        }
233      }
234      return null;
235    }
236    /// <inheritdoc/>
237    public IScope GetScope(string name) {
238      if (Name == name) return this;
239      else {
240        for (int i = 0; i < mySubScopes.Count; i++) {
241          IScope s = mySubScopes[i].GetScope(name);
242          if (s != null) return s;
243        }
244      }
245      return null;
246    }
247
248    /// <inheritdoc/>
249    public void Clear() {
250      string[] variableNames = new string[Variables.Count];
251      int i = 0;
252      foreach (IVariable variable in Variables) {
253        variableNames[i] = variable.Name;
254        i++;
255      }
256      for (int j = 0; j < variableNames.Length; j++)
257        RemoveVariable(variableNames[j]);
258
259      KeyValuePair<string, string>[] aliases = new KeyValuePair<string, string>[myAliases.Count];
260      myAliases.CopyTo(aliases, 0);
261      for (int j = 0; j < aliases.Length; j++)
262        RemoveAlias(aliases[j].Key);
263
264      while (SubScopes.Count > 0)
265        RemoveSubScope(SubScopes[0]);
266    }
267
268    /// <inheritdoc/>
269    public override object Clone(IDictionary<Guid, object> clonedObjects) {
270      Scope clone = (Scope)base.Clone(clonedObjects);
271      clone.myName = Name;
272
273      foreach (IVariable variable in myVariables.Values)
274        clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects));
275      foreach (KeyValuePair<string, string> alias in myAliases)
276        clone.AddAlias(alias.Key, alias.Value);
277      for (int i = 0; i < SubScopes.Count; i++)
278        clone.AddSubScope((IScope)Auxiliary.Clone(SubScopes[i], clonedObjects));
279
280      return clone;
281    }
282
283    /// <inheritdoc />
284    public event EventHandler<VariableEventArgs> VariableAdded;
285    /// <summary>
286    /// Fires a new <c>VariableAdded</c> event.
287    /// </summary>
288    /// <param name="variable">The variable that has been added.</param>
289    protected virtual void OnVariableAdded(IVariable variable) {
290      if (VariableAdded != null)
291        VariableAdded(this, new VariableEventArgs(variable));
292    }
293    /// <inheritdoc />
294    public event EventHandler<VariableEventArgs> VariableRemoved;
295    /// <summary>
296    /// Fires a new <c>VariableRemoved</c>.
297    /// </summary>
298    /// <param name="variable">The variable that has been deleted.</param>
299    protected virtual void OnVariableRemoved(IVariable variable) {
300      if (VariableRemoved != null)
301        VariableRemoved(this, new VariableEventArgs(variable));
302    }
303    /// <inheritdoc />
304    public event EventHandler<AliasEventArgs> AliasAdded;
305    /// <summary>
306    /// Fires a new <c>AliasAdded</c> event.
307    /// </summary>
308    /// <param name="alias">The alias that has been added.</param>
309    protected virtual void OnAliasAdded(string alias) {
310      if (AliasAdded != null)
311        AliasAdded(this, new AliasEventArgs(alias));
312    }
313    /// <inheritdoc/>
314    public event EventHandler<AliasEventArgs> AliasRemoved;
315    /// <summary>
316    /// Fires a new <c>AliasRemoved</c> event.
317    /// </summary>
318    /// <param name="alias">The alias that has been deleted.</param>
319    protected virtual void OnAliasRemoved(string alias) {
320      if (AliasRemoved != null)
321        AliasRemoved(this, new AliasEventArgs(alias));
322    }
323    /// <inheritdoc/>
324    public event EventHandler<ScopeIndexEventArgs> SubScopeAdded;
325    /// <summary>
326    /// Fires a new <c>SubScopeAdded</c> event.
327    /// </summary>
328    /// <param name="scope">The sub scope that has been added.</param>
329    /// <param name="index">The index where the scope has been added.</param>
330    protected virtual void OnSubScopeAdded(IScope scope, int index) {
331      if (SubScopeAdded != null)
332        SubScopeAdded(this, new ScopeIndexEventArgs(scope, index));
333    }
334    /// <inheritdoc/>
335    public event EventHandler<ScopeIndexEventArgs> SubScopeRemoved;
336    /// <summary>
337    /// Fires a new <c>SubScopeRemoved</c> event.
338    /// </summary>
339    /// <param name="scope">The sub scope that has been deleted.</param>
340    /// <param name="index">The position of the sub scope.</param>
341    protected virtual void OnSubScopeRemoved(IScope scope, int index) {
342      if (SubScopeRemoved != null)
343        SubScopeRemoved(this, new ScopeIndexEventArgs(scope, index));
344    }
345    /// <inheritdoc />
346    public event EventHandler SubScopesReordered;
347    /// <summary>
348    /// Fires a new <c>SubScopesReordered</c> event
349    /// </summary>
350    protected virtual void OnSubScopesReordered() {
351      if (SubScopesReordered != null)
352        SubScopesReordered(this, new EventArgs());
353    }
354  }
355}
Note: See TracBrowser for help on using the repository browser.