001: /*
002: * <copyright>
003: *
004: * Copyright 2002-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.adaptivity;
028:
029: import java.io.Serializable;
030: import java.util.ArrayList;
031: import java.util.List;
032:
033: public class OMCRangeList implements Serializable {
034: public static final OMCRangeList ALL_DOUBLE_RANGE_LIST = new OMCRangeList(
035: Double.MIN_VALUE, Double.MAX_VALUE);
036:
037: public static final OMCRangeList ALL_INTEGER_RANGE_LIST = new OMCRangeList(
038: Integer.MIN_VALUE, Integer.MAX_VALUE);
039:
040: public static final OMCRangeList ALL_LONG_RANGE_LIST = new OMCRangeList(
041: Long.MIN_VALUE, Long.MAX_VALUE);
042:
043: public static final OMCRangeList ALL_STRING_RANGE_LIST = new OMCRangeList(
044: "", "\ffff");
045:
046: OMCRange[] allowedValues;
047:
048: public OMCRangeList(OMCRange[] av) {
049: allowedValues = av;
050: }
051:
052: public OMCRangeList(OMCRange av) {
053: allowedValues = new OMCRange[] { av };
054: }
055:
056: public OMCRangeList(double v) {
057: this (new OMCRange[] { new OMCPoint(v) });
058: }
059:
060: public OMCRangeList(int v) {
061: this (new OMCRange[] { new OMCPoint(v) });
062: }
063:
064: public OMCRangeList(Comparable v) {
065: this (new OMCRange[] { new OMCPoint(v) });
066: }
067:
068: public OMCRangeList(int[] vs) {
069: this (createRange(vs));
070: }
071:
072: public OMCRangeList(double[] vs) {
073: this (createRange(vs));
074: }
075:
076: public OMCRangeList(Comparable[] vs) {
077: this (createRange(vs));
078: }
079:
080: public OMCRangeList(double min, double max) {
081: this (createRange(new Double(min), new Double(max)));
082: }
083:
084: public OMCRangeList(int min, int max) {
085: this (createRange(new Integer(min), new Integer(max)));
086: }
087:
088: public OMCRangeList(long min, long max) {
089: this (createRange(new Long(min), new Long(max)));
090: }
091:
092: public OMCRangeList(Comparable min, Comparable max) {
093: this (createRange(min, max));
094: }
095:
096: private static OMCRange[] createRange(int[] vs) {
097: Comparable[] cs = new Comparable[vs.length];
098: for (int i = 0; i < vs.length; i++) {
099: cs[i] = new Integer(vs[i]);
100: }
101: return createRange(cs);
102: }
103:
104: private static OMCRange[] createRange(double[] vs) {
105: Comparable[] cs = new Comparable[vs.length];
106: for (int i = 0; i < vs.length; i++) {
107: cs[i] = new Double(vs[i]);
108: }
109: return createRange(cs);
110: }
111:
112: private static OMCRange[] createRange(Comparable[] vs) {
113: OMCRange[] result = new OMCRange[vs.length];
114: for (int i = 0; i < vs.length; i++) {
115: result[i] = new OMCPoint(vs[i]);
116: }
117: return result;
118: }
119:
120: private static OMCRange[] createRange(Comparable min, Comparable max) {
121: OMCRange[] result = { new OMCRange(min, max) };
122: return result;
123: }
124:
125: public Comparable getMax() {
126: Comparable max = allowedValues[0].getMax();
127: for (int i = 1; i < allowedValues.length; i++) {
128: OMCRange range = allowedValues[i];
129: Comparable tmax = range.getMax();
130: if (tmax.compareTo(max) > 0)
131: max = tmax;
132: }
133: return max;
134: }
135:
136: public Comparable getMin() {
137: Comparable min = allowedValues[0].getMin();
138: for (int i = 1; i < allowedValues.length; i++) {
139: OMCRange range = allowedValues[i];
140: Comparable tmin = range.getMin();
141: if (tmin.compareTo(min) < 0)
142: min = tmin;
143: }
144: return min;
145: }
146:
147: /**
148: * Return a value that is the equivalent under the IN
149: * ConstraintOperator to this value under the given operator. For
150: * example, if the operator is LESSTHANOREQUAL, and this value is a
151: * single value, the returned value will be the range from the
152: * minimum value to the single value. This allows ConstraintPhrases
153: * to be converted to a form that can be directly combined with
154: * other ConstraintPhrases from other Plays.
155: **/
156: public OMCRangeList applyOperator(ConstraintOperator op) {
157: if (op.equals(ConstraintOperator.GREATERTHAN)) {
158: Comparable max = getMax();
159: return new OMCRangeList(ComparableHelper.increment(max),
160: ComparableHelper.getMax(max));
161: }
162: if (op.equals(ConstraintOperator.GREATERTHANOREQUAL)) {
163: Comparable max = getMax();
164: return new OMCRangeList(max, ComparableHelper.getMax(max));
165: }
166: if (op.equals(ConstraintOperator.LESSTHAN)) {
167: Comparable min = getMin();
168: return new OMCRangeList(ComparableHelper.getMin(min),
169: ComparableHelper.decrement(min));
170: }
171: if (op.equals(ConstraintOperator.LESSTHANOREQUAL)) {
172: Comparable min = getMin();
173: return new OMCRangeList(ComparableHelper.getMin(min), min);
174: }
175: if (op.equals(ConstraintOperator.EQUAL))
176: return this ;
177: if (op.equals(ConstraintOperator.ASSIGN))
178: return this ;
179: if (op.equals(ConstraintOperator.NOTIN)
180: || op.equals(ConstraintOperator.NOTEQUAL)) {
181: OMCRangeList newValue = complementRange(allowedValues[0]);
182: for (int i = 1; i < allowedValues.length; i++) {
183: newValue = newValue
184: .intersect(complementRange(allowedValues[i]));
185: }
186: return newValue;
187: }
188: if (op.equals(ConstraintOperator.IN))
189: return this ;
190: return this ;
191: }
192:
193: private OMCRangeList complementRange(OMCRange range) {
194: Comparable min = range.getMin();
195: Comparable max = range.getMax();
196: OMCRange[] compRange = {
197: new OMCRange(ComparableHelper.getMin(min),
198: ComparableHelper.decrement(min)),
199: new OMCRange(ComparableHelper.increment(max),
200: ComparableHelper.getMax(max)) };
201: return new OMCRangeList(compRange);
202: }
203:
204: public OMCRangeList intersect(OMCRangeList that) {
205: List result = new ArrayList(allowedValues.length);
206: OMCRange[] thatAllowedValues = that.getAllowedValues();
207: for (int i = 0; i < allowedValues.length; i++) {
208: Comparable this Min = allowedValues[i].getMin();
209: Comparable this Max = allowedValues[i].getMax();
210: for (int j = 0; j < thatAllowedValues.length; j++) {
211: Comparable thatMin = thatAllowedValues[j].getMin();
212: Comparable thatMax = thatAllowedValues[j].getMax();
213: if (thatMin.compareTo(this Max) > 0)
214: continue; // No overlap
215: if (this Min.compareTo(thatMax) > 0)
216: continue; // No overlap
217: Comparable newMin;
218: Comparable newMax;
219: if (this Min.compareTo(thatMin) < 0) {
220: newMin = thatMin;
221: } else {
222: newMin = this Min;
223: }
224: if (this Max.compareTo(thatMax) > 0) {
225: newMax = thatMax;
226: } else {
227: newMax = this Max;
228: }
229: result.add(new OMCRange(newMin, newMax));
230: }
231: }
232: return new OMCRangeList((OMCRange[]) result
233: .toArray(new OMCRange[result.size()]));
234: }
235:
236: public Comparable getEffectiveValue() {
237: return allowedValues[0].getMin();
238: }
239:
240: public OMCRange[] getAllowedValues() {
241: return allowedValues;
242: }
243:
244: public boolean isAllowed(Comparable v) {
245: if (v.getClass() != getEffectiveValue().getClass())
246: return false; // Wrong class (exception?)
247: for (int i = 0; i < allowedValues.length; i++) {
248: if (allowedValues[i].contains(v)) {
249: return true;
250: }
251: }
252: return false;
253: }
254:
255: public boolean isEmpty() {
256: return allowedValues.length == 0;
257: }
258:
259: public int hashCode() {
260: int hc = 0;
261: for (int i = 0; i < this .allowedValues.length; i++) {
262: hc = 31 * hc + allowedValues[i].hashCode();
263: }
264: return hc;
265: }
266:
267: public boolean equals(Object o) {
268: if (!(o instanceof OMCRangeList))
269: return false;
270: OMCRangeList that = (OMCRangeList) o;
271: if (this .allowedValues.length != that.allowedValues.length)
272: return false;
273: for (int i = 0; i < this .allowedValues.length; i++) {
274: if (!this .allowedValues[i].equals(that.allowedValues[i]))
275: return false;
276: }
277: return true;
278: }
279:
280: public String toString() {
281: StringBuffer buf = new StringBuffer();
282: buf.append('{');
283: for (int i = 0; i < allowedValues.length; i++) {
284: if (i > 0)
285: buf.append(',');
286: buf.append(allowedValues[i]);
287: }
288: buf.append('}');
289: return buf.toString();
290: }
291:
292: static OMCRangeList[] v = {
293: new OMCRangeList(new OMCRange[] { new OMCPoint(1.0),
294: new OMCPoint(3.0), new OMCThruRange(3.5, 5.0) }),
295: new OMCRangeList(
296: new OMCRange[] { new OMCThruRange(2.5, 4.6) }),
297: new OMCRangeList(new OMCRange[] { new OMCPoint(3.0),
298: new OMCPoint(5.5), }) };
299:
300: public static void main(String[] args) {
301: OMCRangeList o = new OMCRangeList("Abc");
302: OMCRangeList x = o.applyOperator(ConstraintOperator.NOTEQUAL);
303: System.out.println(o + " -> " + x);
304: }
305: }
|