001: /*--------------------------------------------------------------------------
002: * <copyright>
003: *
004: * Copyright 1999-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: package org.cougaar.glm.plugins.projection;
027:
028: import org.cougaar.glm.ldm.plan.ObjectScheduleElement;
029: import org.cougaar.glm.ldm.plan.PlanScheduleElementType;
030: import org.cougaar.planning.ldm.asset.Asset;
031: import org.cougaar.planning.ldm.measure.Rate;
032: import org.cougaar.planning.ldm.plan.Schedule;
033: import org.cougaar.planning.ldm.plan.ScheduleImpl;
034: import org.cougaar.planning.ldm.plan.ScheduleType;
035: import org.cougaar.util.TimeSpan;
036: import org.cougaar.util.log.Logger;
037: import org.cougaar.util.log.Logging;
038:
039: import java.io.Serializable;
040: import java.util.Enumeration;
041: import java.util.Map;
042: import java.util.Vector;
043:
044: public abstract class ConsumerSpec implements Serializable {
045: protected Object consumer_;
046: protected String resourceType_;
047: protected Schedule mergedSchedule_ = null;
048: private Map multipliers_ = null;
049: private static Logger logger = Logging
050: .getLogger(ConsumerSpec.class);
051:
052: public ConsumerSpec(Object consumer, String type, Map multipliers) {
053: consumer_ = consumer;
054: resourceType_ = type;
055: multipliers_ = multipliers;
056: }
057:
058: public ConsumerSpec(Object consumer, String type) {
059: consumer_ = consumer;
060: resourceType_ = type;
061: }
062:
063: /**
064: * The merged schedule drives the consumer spec.
065: * It is only calculated once unless reset() is called.
066: */
067: public void reset() {
068: mergedSchedule_ = null;
069: }
070:
071: // what is consumed
072: public abstract Enumeration getConsumed();
073:
074: // when is it consumed
075: public abstract Vector getParameterSchedules();
076:
077: /**
078: * at what rate is it consumed
079: * @return -1 if rate is not defined such as when there is
080: * no org activity
081: */
082: public abstract Rate getRate(Asset resource, Vector params);
083:
084: private static final Double ONE = new Double(1.0);
085:
086: public Double getMultiplier(Asset consumed) {
087: return getMultiplier(consumed.getTypeIdentificationPG()
088: .getTypeIdentification());
089: }
090:
091: public Double getMultiplier(String consumedId) {
092: if (multipliers_ == null)
093: return ONE;
094: Double mult = (Double) multipliers_.get(consumedId);
095: if (mult == null)
096: return ONE;
097: return mult;
098: }
099:
100: public static Schedule newObjectSchedule(Enumeration elements) {
101: ScheduleImpl s = new ScheduleImpl();
102: s.setScheduleElementType(PlanScheduleElementType.OBJECT);
103: s.setScheduleType(ScheduleType.OTHER);
104: s.setScheduleElements(elements);
105: return s;
106: }
107:
108: public Object getConsumer() {
109: return consumer_;
110: }
111:
112: public String getConsumedType() {
113: return resourceType_;
114: }
115:
116: // for a particular resource, return the
117: /**
118: * Here is what this method does (Ray Tomlinson). Merges a number
119: * of parameter schedules into a combined schedule. In the
120: * combined schedule, the "parameter" of each element is a Vector
121: * of the parameters from each of the input schedules. For
122: * elements not covered by the input schedule, the corresponding
123: * Vector element is null. The output schedule elements correspond
124: * to the intersections of the elements or inter-element gaps of
125: * the input schedules. No schedule element is generated for time
126: * spans where none of the input schedules has an element.
127: * Conversely, all elements of the merged schedule have at least
128: * one non-null parameter.
129: * There is an assumption that the elements of the input schedules
130: * and the output schedule are non-overlapping.
131: */
132: public Schedule getMergedSchedule() {
133: if (mergedSchedule_ == null) {
134: // sets scheds to Enumerations of schedule elements
135: // sets intervals to the initial schedule element within each schedule
136: Vector scheds = getParameterSchedules();
137: int num_params = scheds.size();
138: ObjectScheduleElement[] intervals = new ObjectScheduleElement[num_params];
139: Enumeration[] enums = new Enumeration[num_params];
140: if (logger.isDebugEnabled()) {
141: logger.debug(num_params + " num params");
142: }
143: ObjectScheduleElement ose;
144: long start = TimeSpan.MAX_VALUE;
145: for (int ii = 0; ii < num_params; ii++) {
146: enums[ii] = ((Schedule) scheds.get(ii))
147: .getAllScheduleElements();
148: if (enums[ii].hasMoreElements()) {
149: ose = (ObjectScheduleElement) enums[ii]
150: .nextElement();
151: intervals[ii] = ose;
152: if (ose.getStartTime() < start) {
153: start = ose.getStartTime();
154: }
155: } else {
156: intervals[ii] = null; // Empty schedule
157: }
158: }
159:
160: Vector result_sched = new Vector();
161: long end = TimeSpan.MIN_VALUE;
162: while (end != TimeSpan.MAX_VALUE) {
163: Vector params = new Vector(num_params);
164: params.setSize(num_params);
165: boolean haveParams = false;
166: end = TimeSpan.MAX_VALUE;
167: for (int ii = 0; ii < num_params; ii++) {
168: params.set(ii, null);// Presume no element for schedule(ii)
169: // check if interval good
170: ose = intervals[ii];
171: if (ose != null) {
172: if (ose.getEndTime() <= start) {
173: // This has already been covered; Step to next
174: if (!enums[ii].hasMoreElements()) {
175: // ran off end of schedule(ii)
176: intervals[ii] = null;
177: continue;
178: }
179: ose = (ObjectScheduleElement) enums[ii]
180: .nextElement();
181: intervals[ii] = ose;
182: }
183: if (ose.getStartTime() > start) {
184: // ose is _not_ part of this result
185: // element, it's later (there is a gap)
186: if (ose.getStartTime() < end) {
187: // This result element ends not later
188: // than the start of this pending element
189: end = ose.getStartTime();
190: }
191: continue;
192: }
193: // search for earliest end time
194: if (ose.getEndTime() < end) {
195: end = ose.getEndTime();
196: }
197: // add current param to list
198: params.set(ii, ose.getObject());
199: haveParams = true;
200: }
201: }
202: if (haveParams) {
203: result_sched.add(new ObjectScheduleElement(start,
204: end, params));
205: }
206: start = end;
207: }
208: mergedSchedule_ = newObjectSchedule(result_sched.elements());
209: if (logger.isDebugEnabled()) {
210: logger.debug("ConsumerSpec created mergedSchedule "
211: + result_sched.size());
212: }
213: }
214: return mergedSchedule_;
215: }
216:
217: // getExtras();
218:
219: /**
220: * @param resource consumed resource
221: * @return schedule quantity schedule of the daily rate of consumption
222: * of the given resource.
223: */
224: public Schedule buildConsumptionRateSchedule(Asset resource) {
225: ObjectScheduleElement ose;
226: Rate rate;
227: // This needs to be changed to a RateScheduleElement once I get the OK from
228: // the other plugin developers - AHF
229: // RateScheduleElement rse;
230: ObjectScheduleElement rse;
231:
232: Vector consumption_rate_schedule = new Vector();
233: Enumeration schedule_elements = getMergedSchedule()
234: .getAllScheduleElements();
235: while (schedule_elements.hasMoreElements()) {
236: ose = (ObjectScheduleElement) schedule_elements
237: .nextElement();
238: rate = getRate(resource, (Vector) ose.getObject());
239: if (rate == null)
240: continue;
241: // rse = GLMFactory.newRateScheduleElement();
242: rse = new ObjectScheduleElement();
243: rse.setObject(rate);
244: // rse.setRate(rate);
245: rse.setStartTime(ose.getStartTime());
246: rse.setEndTime(ose.getEndTime());
247: consumption_rate_schedule.addElement(rse);
248: }
249: return newObjectSchedule(consumption_rate_schedule.elements());
250: // return GLMFactory.newRateSchedule(consumption_rate_schedule.elements());
251: }
252:
253: }
|