source: branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringArray.cs @ 9401

Last change on this file since 9401 was 9401, checked in by sforsten, 6 years ago

#2018: renamed "column" to "element" in array types

File size: 8.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Data {
33  [Item("StringArray", "Represents an array of strings.")]
34  [StorableClass]
35  public class StringArray : Item, IEnumerable<string>, IStringConvertibleArray {
36    public static new Image StaticItemImage {
37      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
38    }
39
40    [Storable]
41    protected string[] array;
42
43    [Storable]
44    protected List<string> elementNames;
45    public virtual IEnumerable<string> ElementNames {
46      get { return this.elementNames; }
47      set {
48        if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
49        if (value == null || value.Count() == 0)
50          elementNames = new List<string>();
51        else if (value.Count() != Length)
52          throw new ArgumentException("An element name must be specified for each element.");
53        else
54          elementNames = new List<string>(value);
55        OnElementNamesChanged();
56      }
57    }
58
59    public virtual int Length {
60      get { return array.Length; }
61      protected set {
62        if (ReadOnly) throw new NotSupportedException("Length cannot be set. StringArray is read-only.");
63        if (value != Length) {
64          Array.Resize<string>(ref array, value);
65          while (elementNames.Count > value)
66            elementNames.RemoveAt(elementNames.Count - 1);
67          while (elementNames.Count < value)
68            elementNames.Add("Element " + elementNames.Count);
69          OnElementNamesChanged();
70          OnReset();
71        }
72      }
73    }
74    public virtual string this[int index] {
75      get { return array[index]; }
76      set {
77        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
78        if (value != array[index]) {
79          if ((value != null) || (array[index] != string.Empty)) {
80            array[index] = value != null ? value : string.Empty;
81            OnItemsChanged(new List<int>(1) { index });
82          }
83        }
84      }
85    }
86
87    [Storable]
88    protected bool readOnly;
89    public virtual bool ReadOnly {
90      get { return readOnly; }
91    }
92
93    [StorableHook(HookType.AfterDeserialization)]
94    private void AfterDeserialization() {
95      if (elementNames == null) {
96        elementNames = new List<string>(array.Length);
97        while (elementNames.Count < array.Length)
98          elementNames.Add("Element " + elementNames.Count);
99      }
100    }
101
102    [StorableConstructor]
103    protected StringArray(bool deserializing) : base(deserializing) { }
104    protected StringArray(StringArray original, Cloner cloner)
105      : base(original, cloner) {
106      this.array = (string[])original.array.Clone();
107      this.elementNames = new List<string>(original.elementNames);
108      this.readOnly = original.readOnly;
109    }
110    public StringArray() {
111      array = new string[0];
112      elementNames = new List<string>();
113      readOnly = false;
114    }
115    public StringArray(int length) {
116      array = new string[length];
117      for (int i = 0; i < array.Length; i++)
118        array[i] = string.Empty;
119      elementNames = new List<string>();
120      readOnly = false;
121    }
122    public StringArray(string[] elements) {
123      if (elements == null) throw new ArgumentNullException();
124      array = new string[elements.Length];
125      for (int i = 0; i < array.Length; i++)
126        array[i] = elements[i] == null ? string.Empty : elements[i];
127      elementNames = new List<string>();
128      readOnly = false;
129    }
130
131    public override IDeepCloneable Clone(Cloner cloner) {
132      return new StringArray(this, cloner);
133    }
134
135    public virtual StringArray AsReadOnly() {
136      StringArray readOnlyStringArray = (StringArray)this.Clone();
137      readOnlyStringArray.readOnly = true;
138      return readOnlyStringArray;
139    }
140
141    public override string ToString() {
142      StringBuilder sb = new StringBuilder();
143      sb.Append("[");
144      if (array.Length > 0) {
145        sb.Append(array[0]);
146        for (int i = 1; i < array.Length; i++)
147          sb.Append(";").Append(array[i]);
148      }
149      sb.Append("]");
150      return sb.ToString();
151    }
152
153    public virtual IEnumerator<string> GetEnumerator() {
154      return array.Cast<string>().GetEnumerator();
155    }
156
157    IEnumerator IEnumerable.GetEnumerator() {
158      return GetEnumerator();
159    }
160
161    protected virtual bool Validate(string value, out string errorMessage) {
162      if (value == null) {
163        errorMessage = "Invalid Value (string must not be null)";
164        return false;
165      } else {
166        errorMessage = string.Empty;
167        return true;
168      }
169    }
170    protected virtual string GetValue(int index) {
171      return this[index];
172    }
173    protected virtual bool SetValue(string value, int index) {
174      if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
175      if (value != null) {
176        this[index] = value;
177        return true;
178      } else {
179        return false;
180      }
181    }
182    public virtual bool SetValues(IEnumerable<ArrayValue<string>> arrayValues) {
183      if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
184      if (!arrayValues.All(v => v.Value != null)) return false;
185      List<int> positions = new List<int>();
186      foreach (var v in arrayValues) {
187        if (array[v.Index] != v.Value) {
188          array[v.Index] = v.Value;
189          positions.Add(v.Index);
190        }
191      }
192      OnItemsChanged(positions);
193      return true;
194    }
195
196    public event EventHandler ElementNamesChanged;
197    protected virtual void OnElementNamesChanged() {
198      EventHandler handler = ElementNamesChanged;
199      if (handler != null)
200        handler(this, EventArgs.Empty);
201    }
202    public event EventHandler<ArrayValuesChangedEventArgs> ItemsChanged;
203    protected virtual void OnItemsChanged(IEnumerable<int> indices) {
204      if (ItemsChanged != null)
205        ItemsChanged(this, new ArrayValuesChangedEventArgs(indices));
206      OnToStringChanged();
207    }
208    public event EventHandler Reset;
209    protected virtual void OnReset() {
210      if (Reset != null)
211        Reset(this, EventArgs.Empty);
212      OnToStringChanged();
213    }
214
215    #region IStringConvertibleArray Members
216    int IStringConvertibleArray.Length {
217      get { return Length; }
218      set { Length = value; }
219    }
220    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
221      return Validate(value, out errorMessage);
222    }
223    string IStringConvertibleArray.GetValue(int index) {
224      return GetValue(index);
225    }
226    bool IStringConvertibleArray.SetValue(string value, int index) {
227      return SetValue(value, index);
228    }
229    bool IStringConvertibleArray.SetValue(ArrayValue<string> arrayValue) {
230      return SetValue(arrayValue.Value, arrayValue.Index);
231    }
232    bool IStringConvertibleArray.SetValues(IEnumerable<ArrayValue<string>> arrayValues) {
233      return SetValues(arrayValues);
234    }
235    #endregion
236  }
237}
Note: See TracBrowser for help on using the repository browser.