001: /*
002: * <copyright>
003: *
004: * Copyright 1997-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.util;
028:
029: import java.lang.reflect.InvocationTargetException;
030: import java.lang.reflect.Method;
031: import java.util.ArrayList;
032: import java.util.Collection;
033: import java.util.Iterator;
034:
035: /**
036: * A Collection which implements a set of TimeSpan elements
037: * which are maintained sorted first by start time and then by
038: * end time. The order of temporally-equivalent but non-equal
039: * objects is undefined but stable.
040: **/
041: public class NonOverlappingTimeSpanSet extends TimeSpanSet {
042:
043: // constructors
044: public NonOverlappingTimeSpanSet() {
045: super ();
046: }
047:
048: public NonOverlappingTimeSpanSet(int i) {
049: super (i);
050: }
051:
052: public NonOverlappingTimeSpanSet(NonOverlappingTimeSpanSet set) {
053: super (set.size());
054:
055: unsafeUpdate(set);
056: }
057:
058: public NonOverlappingTimeSpanSet(Collection c) {
059: super (c.size());
060:
061: // insert them carefully.
062: for (Iterator i = c.iterator(); i.hasNext();) {
063: add(i.next());
064: }
065: }
066:
067: //Add check for overlapping
068: public boolean add(Object o) {
069: if (!(o instanceof TimeSpan)) {
070: throw new ClassCastException();
071: }
072:
073: Collection collection = intersectingSet((TimeSpan) o);
074: if (collection.size() != 0) {
075: throw new IllegalArgumentException();
076: } else {
077: return super .add(o);
078: }
079: }
080:
081: /**
082: * @return the element which intersects with
083: * the specified time. Will return null if time is not
084: * covered by the set.
085: **/
086: public TimeSpan intersects(final long time) {
087: Collection collection = intersectingSet(time);
088:
089: switch (collection.size()) {
090:
091: case 0:
092: return null;
093:
094: case 1:
095: return (TimeSpan) (collection.iterator().next());
096:
097: default:
098: throw new RuntimeException("Overlapping elements");
099: }
100: }
101:
102: /**
103: * @return a NonOverlappingTimeSpanSet with no gaps. Continuous tiling
104: * generated by filling all gaps with the specified filler.
105: * @param filler NewTimeSpan to be used to fill gaps. Must be cloneable.
106: **/
107: public NonOverlappingTimeSpanSet fill(NewTimeSpan filler) {
108: if (!(filler instanceof Cloneable)) {
109: throw new ClassCastException(
110: "org.cougaar.util.NonOverlappingTimeSpanSet.fill(): "
111: + filler + " does not implement cloneable");
112: }
113:
114: Method clone;
115: try {
116: clone = filler.getClass().getMethod("clone", new Class[0]);
117: } catch (NoSuchMethodException nsme) {
118: throw new IllegalArgumentException(
119: "org.cougaar.util.NonOverlappingTimeSpanSet.fill(): "
120: + filler
121: + " does not have a clone() method");
122: }
123:
124: long start = TimeSpan.MIN_VALUE;
125:
126: NonOverlappingTimeSpanSet fill = new NonOverlappingTimeSpanSet();
127:
128: Object[] cloneArgs = new Object[0];
129: for (int i = 0; i < size(); i++) {
130: TimeSpan ts = (TimeSpan) get(i);
131: if (ts.getStartTime() > start) {
132: try {
133: NewTimeSpan fillerClone = (NewTimeSpan) clone
134: .invoke(filler, cloneArgs);
135: fillerClone.setTimeSpan(start, ts.getStartTime());
136: fill.add(fillerClone);
137: } catch (IllegalAccessException iae) {
138: iae.printStackTrace();
139: throw new IllegalArgumentException(
140: "org.cougaar.util.NonOverlappingTimeSpanSet.fill(): unable to execute clone method on "
141: + filler);
142: } catch (InvocationTargetException ite) {
143: ite.printStackTrace();
144: throw new IllegalArgumentException(
145: "org.cougaar.util.NonOverlappingTimeSpanSet.fill(): unable to execute clone method on "
146: + filler);
147: }
148: }
149: fill.add(ts);
150:
151: start = ts.getEndTime();
152: }
153:
154: if (start != TimeSpan.MAX_VALUE) {
155: try {
156: NewTimeSpan fillerClone = (NewTimeSpan) clone.invoke(
157: filler, cloneArgs);
158: fillerClone.setTimeSpan(start, TimeSpan.MAX_VALUE);
159: fill.add(fillerClone);
160: } catch (IllegalAccessException iae) {
161: iae.printStackTrace();
162: throw new IllegalArgumentException(
163: "org.cougaar.util.NonOverlappingTimeSpanSet.fill(): unable to execute clone method on "
164: + filler);
165: } catch (InvocationTargetException ite) {
166: ite.printStackTrace();
167: throw new IllegalArgumentException(
168: "org.cougaar.util.NonOverlappingTimeSpanSet.fill(): unable to execute clone method on "
169: + filler);
170: }
171: }
172:
173: return fill;
174: }
175: }
|