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.planning.ldm.plan;
028:
029: import java.io.IOException;
030: import java.io.ObjectInputStream;
031: import java.io.ObjectOutputStream;
032: import java.util.ArrayList;
033: import java.util.Enumeration;
034: import java.util.HashSet;
035: import java.util.List;
036:
037: import org.cougaar.core.persist.ActivePersistenceObject;
038: import org.cougaar.core.util.UID;
039: import org.cougaar.core.util.UniqueObject;
040: import org.cougaar.util.Enumerator;
041: import org.cougaar.util.log.Logger;
042:
043: /** MPTask implementation - MPTasks should only be created or used if they are
044: * attached to MPWorkflows. MPTasks always have multiple ParentTasks.
045: **/
046:
047: public final class MPTaskImpl extends TaskImpl implements MPTask,
048: NewMPTask, ActivePersistenceObject {
049:
050: //private transient Vector parenttasks = new Vector();
051: private transient List parenttasks = new ArrayList();
052: private Composition comp;
053:
054: /** Constructor that takes no args */
055: public MPTaskImpl(UID uid) {
056: super (uid);
057: }
058:
059: /**
060: * Returns the base or parent tasks of
061: * a given task, where the given task is
062: * an aggregation expansion of the base tasks. The
063: * These tasks are members of MPWorkflows.
064: * @return Enumeration{Task} that are the "parenttasks"
065: **/
066:
067: public Enumeration getParentTasks() {
068: synchronized (parenttasks) {
069: List copy = new ArrayList(parenttasks);
070: return new Enumerator(copy);
071: }
072: //return parenttasks.elements();
073: }
074:
075: /**
076: * Override getParentTask in Task.java and return null.
077: * Dump stack as this shouldn't be called for MPTask, because
078: * MPTasks have more than one parent.
079: **/
080: public Task getParentTask() {
081: Thread.dumpStack();
082: return null;
083: }
084:
085: /**
086: * The Composition object that created this task.
087: * @return Composition
088: * @see org.cougaar.planning.ldm.plan.Composition
089: */
090: public Composition getComposition() {
091: if (comp == null) {
092: System.err
093: .println("MPTask is MALFORMED - The composition is null!");
094: Thread.dumpStack();
095: }
096: return comp;
097: }
098:
099: /**
100: * Do not allow this to be called on an MPTask, since there are by
101: * definition more than one Parent Task of an MPTask.
102: **/
103: public void setParentTask(Task parentTask) {
104: throw new RuntimeException(
105: "This method is NOT to be called for an MPTask. MPTasks have more than one Parent Task, use: setParentTasks(Enum)");
106: }
107:
108: public void setParentTaskUID(UID parentTaskuid) {
109: throw new RuntimeException(
110: "This method is NOT to be called for an MPTask. MPTasks have more than one Parent Task, use: setParentTasks(Enum)");
111: }
112:
113: /**
114: * Sets the base or parent tasks of
115: * a given task, where the given task is
116: * an aggregation expansion of the base tasks.
117: * Note that an MPTask contains multiple ParentTasks.
118: * If the Context of the MPTask hasn't been set, the
119: * Context will be set the be the union of Contexts of the parenttasks
120: * @param pt - Enumeration of Tasks which are the "parenttasks"
121: **/
122:
123: public void setParentTasks(Enumeration pt) {
124: synchronized (parenttasks) {
125: parenttasks.clear();
126: while (pt.hasMoreElements()) {
127: Task t = (Task) pt.nextElement();
128: if (t instanceof Task) {
129: parenttasks.add(t);
130: } else {
131: // buzzz... wrong answer - tryed to pass in a null!
132: throw new IllegalArgumentException(
133: "MPTask.setParentTask(Enumeration pt): all elements of pt must be Tasks");
134: }
135: }
136: }
137: if (getContext() == null) {
138: setMPContext();
139: }
140: }
141:
142: /**
143: * Set the Composition that created this task.
144: * @param aComposition
145: */
146: public void setComposition(Composition aComposition) {
147: comp = aComposition;
148: }
149:
150: /* for infrastructure only */
151: protected void removeParentTask(Task ptask) {
152: synchronized (parenttasks) {
153: parenttasks.remove(ptask);
154: }
155: }
156:
157: //
158: // serialization
159: //
160:
161: /** serialize tasks making certain that references to other tasks and
162: * workflows are appropriately proxied.
163: */
164: private void writeObject(ObjectOutputStream stream)
165: throws IOException {
166: stream.defaultWriteObject();
167:
168: stream.writeObject(parenttasks);
169: }
170:
171: private void readObject(ObjectInputStream stream)
172: throws ClassNotFoundException, IOException {
173: stream.defaultReadObject();
174: parenttasks = (ArrayList) stream.readObject();
175: }
176:
177: // ActivePersistenceObject
178: public void postRehydration(Logger logger) {
179: // If the composition points to any Aggregations that were not rehydrated,
180: // then collapse the list of aggregations
181: NewComposition comp = (NewComposition) getComposition();
182: List aggregations = comp.getAggregations();
183: List newAggregations = null;
184: for (int i = 0, n = aggregations.size(); i < n; i++) {
185: Aggregation agg = (Aggregation) aggregations.get(i);
186: if (agg == null) {
187: logger
188: .warn("Removing null aggregation from composition of "
189: + this );
190: if (newAggregations == null) {
191: newAggregations = new ArrayList(n - 1);
192: newAggregations.addAll(aggregations.subList(0, i));
193: }
194: } else if (newAggregations != null) {
195: newAggregations.add(agg);
196: }
197: }
198: if (newAggregations != null) {
199: comp.setAggregations(newAggregations);
200: }
201: }
202:
203: public void checkRehydration(Logger logger) {
204: // okay
205: }
206:
207: public boolean skipUnpublishedPersist(Logger logger) {
208: // persist me as usual
209: return false;
210: }
211:
212: // for UI
213:
214: public String[] getParentTaskIDs() {
215: synchronized (parenttasks) {
216: String UUIDs[] = new String[parenttasks.size()];
217: for (int i = 0; i < parenttasks.size(); i++)
218: UUIDs[i] = ((UniqueObject) (parenttasks.get(i)))
219: .getUID().toString();
220: return UUIDs;
221: }
222: }
223:
224: public String getParentTaskID(int i) {
225: String UUIDs[] = getParentTaskIDs();
226: if (i < UUIDs.length)
227: return UUIDs[i];
228: else
229: return null;
230: }
231:
232: /**
233: * Set the Context of the MPTask to be the union of the Contexts in the parenttasks
234: * This works only if the Contexts are instances of ContextOfUIDs
235: * Any Context that is not a ContextOfUIDs will not be included
236: */
237: private void setMPContext() {
238: synchronized (parenttasks) {
239: HashSet union = new HashSet(5);
240: for (int i = 0; i < parenttasks.size(); i++) {
241: Context c = ((Task) parenttasks.get(i)).getContext();
242: if (c instanceof ContextOfUIDs) {
243: UID[] uids = (UID[]) ((ContextOfUIDs) c).toArray();
244: for (int j = 0; j < uids.length; j++) {
245: union.add(uids[j]);
246: }
247: }
248: ContextOfUIDs newContext = new ContextOfUIDs(union);
249: if (newContext.size() > 0)
250: setContext(newContext);
251: }
252: }
253: }
254: }
|