source: trunk/sources/HeuristicLab.Core/3.3/Constraints/Constraint.cs @ 3613

Last change on this file since 3613 was 3613, checked in by mkommend, 12 years ago

updated Constraints (ticket #996)

File size: 6.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
25using System.Text;
26using HeuristicLab.Common;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Core {
30  [StorableClass]
31  public abstract class Constraint : Item, IConstraint {
32    protected Constraint() {
33      this.Active = false;
34      if (AllowedConstraintOperations != null && AllowedConstraintOperations.Count() != 0)
35        this.ConstraintOperation = AllowedConstraintOperations.ElementAt(0);
36    }
37    [StorableConstructor]
38    protected Constraint(bool deserializing) {
39    }
40    protected Constraint(IItem constrainedValue, ConstraintOperation constraintOperation, object constraintData)
41      : this() {
42      this.ConstrainedValue = constrainedValue;
43      this.ConstraintOperation = constraintOperation;
44      this.ConstraintData = constraintData;
45    }
46    protected Constraint(IItem constrainedValue, ConstraintOperation constraintOperation, object constraintData, bool active) {
47      this.ConstrainedValue = constrainedValue;
48      this.ConstraintOperation = constraintOperation;
49      this.ConstraintData = constraintData;
50      this.Active = active;
51    }
52
53    [Storable]
54    private bool active;
55    public bool Active {
56      get { return this.active; }
57      set {
58        if (this.active != value) {
59          this.active = value;
60          this.OnActiveChanged();
61        }
62      }
63    }
64
65    [Storable]
66    private IItem constrainedValue;
67    public IItem ConstrainedValue {
68      get { return this.constrainedValue; }
69      set {
70        if (value == null)
71          throw new ArgumentNullException("Constraint value cannot be null.");
72        if (this.constrainedValue != value) {
73          this.constrainedValue = value;
74          this.OnConstrainedValueChanged();
75          this.OnToStringChanged();
76        }
77      }
78    }
79
80    [Storable]
81    private object constraintData;
82    public object ConstraintData {
83      get { return this.constraintData; }
84      set {
85        if (this.constraintData != value) {
86          this.constraintData = value;
87          this.OnConstraintDataChanged();
88          this.OnToStringChanged();
89        }
90      }
91    }
92
93    public abstract IEnumerable<ConstraintOperation> AllowedConstraintOperations { get; }
94    [Storable]
95    private ConstraintOperation constraintOperation;
96    public ConstraintOperation ConstraintOperation {
97      get { return this.constraintOperation; }
98      set {
99        if (value == null)
100          throw new ArgumentNullException("Comparison operation cannot be null.");
101        if (!AllowedConstraintOperations.Contains(value))
102          throw new ArgumentException("Comparison operation is not contained in the allowed ComparisonOperations.");
103        if (this.constraintOperation != value) {
104          this.constraintOperation = value;
105          this.OnConstraintOperationChanged();
106          this.OnToStringChanged();
107        }
108      }
109    }
110
111    /// <summary>
112    /// This method is called to determine which member of the constrained value should be compared.
113    /// </summary>
114    /// <returns></returns>
115    protected virtual IItem GetConstrainedMember() {
116      return this.constrainedValue;
117    }
118    public bool Check() {
119      if (!Active)
120        return true;
121
122      IItem constrainedMember = this.GetConstrainedMember();
123      return this.Check(constrainedMember);
124    }
125    protected abstract bool Check(object constrainedMember);
126
127    public bool Check(out string errorMessage) {
128      errorMessage = string.Empty;
129      if (!Active)
130        return true;
131
132      IItem constrainedMember = this.GetConstrainedMember();
133      return this.Check(constrainedMember, out errorMessage);
134    }
135
136    protected abstract bool Check(object constrainedMember, out string errorMessage);
137
138    #region events
139    public event EventHandler ActiveChanged;
140    protected virtual void OnActiveChanged() {
141      EventHandler handler = ActiveChanged;
142      if (handler != null)
143        handler(this, EventArgs.Empty);
144    }
145
146    public event EventHandler ConstrainedValueChanged;
147    protected virtual void OnConstrainedValueChanged() {
148      EventHandler handler = ConstrainedValueChanged;
149      if (handler != null)
150        handler(this, EventArgs.Empty);
151    }
152
153    public event EventHandler ConstraintDataChanged;
154    protected virtual void OnConstraintDataChanged() {
155      EventHandler handler = ConstraintDataChanged;
156      if (handler != null)
157        handler(this, EventArgs.Empty);
158    }
159
160    public event EventHandler ConstraintOperationChanged;
161    protected virtual void OnConstraintOperationChanged() {
162      EventHandler handler = ConstraintOperationChanged;
163      if (handler != null)
164        handler(this, EventArgs.Empty);
165    }
166    #endregion
167
168    #region overriden item methods
169    public override string ToString() {
170      IItem constrainedMember = GetConstrainedMember();
171      string s = string.Empty;
172      if (constrainedMember != null)
173        s += constrainedMember.ToString() + " ";
174
175      if (constraintOperation != null)
176        s += ConstraintOperation.ToString() + " ";
177
178      if (constraintData != null)
179        s += constraintData.ToString();
180      else
181        s += "null";
182
183      s += ".";
184      return s;
185    }
186
187    public override IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
188      Constraint clone = (Constraint)base.Clone(cloner);
189      clone.constrainedValue = null;  //mkommend: intentional set to null and must be reset in the clone
190
191      IItem constraintDataItem = this.constraintData as IItem;
192      ICloneable constraintDataCloneable = this.constraintData as ICloneable;
193      if (constraintDataItem != null)
194        clone.constraintData = cloner.Clone(constraintDataItem);
195      else if (constraintDataCloneable != null)
196        clone.constraintData = constraintDataCloneable.Clone();
197      else
198        clone.constraintData = constraintData;
199
200      clone.constraintOperation = this.constraintOperation;
201
202      return clone;
203    }
204    #endregion
205  }
206}
Note: See TracBrowser for help on using the repository browser.