Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CloningRefactorBranch/HeuristicLab.Core/OperatorGroup.cs @ 885

Last change on this file since 885 was 885, checked in by gkronber, 15 years ago

Refactored cloning in HL.Core, HL.Data and HL.Constraints

#285 (Cloning could be improved by creating objects at the bottom of the cloning chain with 'new' instead of the top with Activator.CreateInstance())

File size: 9.0 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  /// Representation of a group of operators (can also include subgroups).
30  /// </summary>
31  public class OperatorGroup : StorableBase, IOperatorGroup {
32    private string myName;
33    /// <summary>
34    /// Gets or sets the name of the current operator group.
35    /// </summary>
36    /// <remarks>Calls <see cref="OnNameChanged"/> in the setter.</remarks>
37    public string Name {
38      get { return myName; }
39      set {
40        if (myName != value) {
41          myName = value;
42          OnNameChanged();
43        }
44      }
45    }
46    private List<IOperatorGroup> mySubGroups;
47    /// <summary>
48    /// Gets all subgroups of the current instance.
49    /// <note type="caution"> The subgroups are returned read-only.</note>
50    /// </summary>
51    public ICollection<IOperatorGroup> SubGroups {
52      get { return mySubGroups.AsReadOnly(); }
53    }
54    private List<IOperator> myOperators;
55    /// <summary>
56    /// Gets all operators of the current instance.
57    /// <note type="caution"> The operators are returned read-only.</note>
58    /// </summary>
59    public ICollection<IOperator> Operators {
60      get { return myOperators.AsReadOnly(); }
61    }
62
63    /// <summary>
64    /// Initializes a new instance of <see cref="OperatorGroup"/> having "Anonymous" as name.
65    /// </summary>
66    public OperatorGroup() {
67      myName = "Anonymous";
68      mySubGroups = new List<IOperatorGroup>();
69      myOperators = new List<IOperator>();
70    }
71
72    /// <summary>
73    /// Copy constructor to create a deep clone of an OperatorGroup instance.
74    /// </summary>
75    /// <param name="original">The instance to be cloned.</param>
76    public OperatorGroup(OperatorGroup original) : this(original, new Dictionary<Guid, object>()) {}
77
78    /// <summary>
79    /// Copy constructor to create a deep clone of an OperatorGroup instance reusing
80    /// already cloned object references.
81    /// </summary>
82    /// <param name="original">The original instance to be cloned</param>
83    /// <param name="clonedObjects">Already cloned objects (for referential integrity).</param>
84    protected OperatorGroup(OperatorGroup original, IDictionary<Guid, object> clonedObjects) : base(original, clonedObjects) {
85      this.myName = original.myName;
86      mySubGroups = new List<IOperatorGroup>();
87      myOperators = new List<IOperator>();
88      foreach (IOperatorGroup group in original.SubGroups)
89        AddSubGroup((IOperatorGroup)Auxiliary.Clone(group, clonedObjects));
90      foreach (IOperator op in original.Operators)
91        AddOperator((IOperator)Auxiliary.Clone(op, clonedObjects));
92    }
93
94    /// <summary>
95    /// Clones the current instance (deep clone).
96    /// </summary>
97    /// <remarks>Uses copy constructor to create the deep clone.</remarks>
98    /// <param name="clonedObjects">Dictionary of all already cloned objects. (Needed for referential integrity.)</param>
99    /// <returns>The cloned object as <see cref="OperatorGroup"/>.</returns>
100    public override object Clone(IDictionary<Guid, object> clonedObjects) {
101      return new OperatorGroup(this, clonedObjects);
102    }
103
104    /// <summary>
105    /// Adds the given subgroup (<paramref name="group"/>) to the current instance.
106    /// </summary>
107    /// <param name="group">The subgroup to add.</param>
108    public virtual void AddSubGroup(IOperatorGroup group) {
109      mySubGroups.Add(group);
110    }
111    /// <summary>
112    /// Removes the given subgroup (<paramref name="group"/>) from the current instance.
113    /// </summary>
114    /// <param name="group">The subgroup to remove.</param>
115    public virtual void RemoveSubGroup(IOperatorGroup group) {
116      mySubGroups.Remove(group);
117    }
118    /// <summary>
119    /// Ads the given operator <paramref name="op"/> to the current instance.
120    /// </summary>
121    /// <param name="op">The operator to add.</param>
122    public virtual void AddOperator(IOperator op) {
123      myOperators.Add(op);
124    }
125    /// <summary>
126    /// Removes the given operator <paramref name="op"/> from the current instance.
127    /// </summary>
128    /// <param name="op">The operator to remove.</param>
129    public virtual void RemoveOperator(IOperator op) {
130      myOperators.Remove(op);
131    }
132
133    /// <summary>
134    /// Occurs when the name of the operator was changed.
135    /// </summary>
136    public event EventHandler NameChanged;
137    /// <summary>
138    /// Fires a new <c>NameChanged</c> event.
139    /// </summary>
140    protected virtual void OnNameChanged() {
141      if (NameChanged != null) {
142        NameChanged(this, new EventArgs());
143      }
144    }
145
146    #region Persistence Methods
147    /// <summary>
148    /// Saves the current instance as <see cref="XmlNode"/> in the specified <paramref name="document"/>.
149    /// </summary>
150    /// <remarks>Calls <see cref="StorableBase.GetXmlNode"/> of base class <see cref="ItemBase"/>.<br/>
151    /// A quick overview how the single elements of the current instance are saved:
152    /// <list type="bullet">
153    /// <item>
154    /// <term>Name: </term>
155    /// <description>Saved as an <see cref="XmlAttribute"/> with attribute name <c>Name</c>.</description>
156    /// </item>
157    /// <item>
158    /// <term>Sub groups: </term>
159    /// <description>A child node is created with tag name <c>SubGroups</c>. Beyond this child node
160    /// all sub operator groups are saved as child nodes themselves.</description>
161    /// </item>
162    /// <item>
163    /// <term>Operators: </term>
164    /// <description>A child node is created with tag name <c>Operators</c>. Beyond this child node
165    /// all operators are saved as child nodes themselves.</description>
166    /// </item>
167    /// </list>
168    /// </remarks>
169    /// <param name="name">The (tag)name of the <see cref="XmlNode"/>.</param>
170    /// <param name="document">The <see cref="XmlDocument"/> where to save the data.</param>
171    /// <param name="persistedObjects">The dictionary of all already persisted objects. (Needed to avoid cycles.)</param>
172    /// <returns>The saved <see cref="XmlNode"/>.</returns>
173    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid,IStorable> persistedObjects) {
174      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
175      XmlAttribute nameAttribute = document.CreateAttribute("Name");
176      nameAttribute.Value = Name;
177      node.Attributes.Append(nameAttribute);
178      XmlNode subGroupsNode = document.CreateNode(XmlNodeType.Element, "SubGroups", null);
179      foreach (IOperatorGroup group in SubGroups)
180        subGroupsNode.AppendChild(PersistenceManager.Persist(group, document, persistedObjects));
181      node.AppendChild(subGroupsNode);
182      XmlNode operatorsNode = document.CreateNode(XmlNodeType.Element, "Operators", null);
183      foreach (IOperator op in Operators)
184        operatorsNode.AppendChild(PersistenceManager.Persist(op, document, persistedObjects));
185      node.AppendChild(operatorsNode);
186      return node;
187    }
188    /// <summary>
189    /// Loads the persisted operator group from the specified <paramref name="node"/>.
190    /// </summary>
191    /// <remarks>See <see cref="GetXmlNode"/> to get information about how the data must be saved. <br/>
192    /// Calls <see cref="StorableBase.Populate"/> of base class <see cref="StorableBase"/>.</remarks>
193    /// <param name="node">The <see cref="XmlNode"/> where the boolean value is saved.</param>
194    /// <param name="restoredObjects">The dictionary of all already restored objects.
195    /// (Needed to avoid cycles.)</param>
196    public override void Populate(XmlNode node, IDictionary<Guid,IStorable> restoredObjects) {
197      base.Populate(node, restoredObjects);
198      myName = node.Attributes["Name"].Value;
199      XmlNode subGroupsNode = node.SelectSingleNode("SubGroups");
200      foreach (XmlNode subGroupNode in subGroupsNode.ChildNodes)
201        AddSubGroup((IOperatorGroup)PersistenceManager.Restore(subGroupNode, restoredObjects));
202      XmlNode operatorsNode = node.SelectSingleNode("Operators");
203      foreach (XmlNode operatorNode in operatorsNode.ChildNodes)
204        AddOperator((IOperator)PersistenceManager.Restore(operatorNode, restoredObjects));
205    }
206    #endregion
207  }
208}
Note: See TracBrowser for help on using the repository browser.