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.beans.IntrospectionException;
030: import java.beans.PropertyDescriptor;
031: import java.io.IOException;
032: import java.io.ObjectInputStream;
033: import java.io.ObjectOutputStream;
034: import java.util.Collection;
035: import java.util.Enumeration;
036: import java.util.List;
037: import java.util.ListIterator;
038:
039: import org.cougaar.core.blackboard.Subscriber;
040: import org.cougaar.core.blackboard.ActiveSubscriptionObject;
041: import org.cougaar.core.blackboard.Blackboard;
042: import org.cougaar.util.log.Logger;
043:
044: /** ExpansionImpl.java
045: * Implementation for expansion - a form of PlanElement
046: *
047: */
048:
049: public class ExpansionImpl extends PlanElementImpl implements
050: Expansion, NewExpansion {
051:
052: static final long serialVersionUID = 34303612634065165L;
053:
054: private transient Workflow workflow; // changed to transient : Persistence
055:
056: public ExpansionImpl() {
057: }
058:
059: /* Constructor that assumes there is not a good estimated result at this time.
060: * @param p
061: * @param t
062: * @param wf
063: * @return Expansion
064: */
065: public ExpansionImpl(Plan p, Task t, Workflow wf) {
066: super (p, t);
067: this .workflow = wf;
068:
069: setContext();
070: }
071:
072: /* Constructor that takes an estimated result
073: * @param p
074: * @param t
075: * @param wf
076: * @param estimatedresult
077: * @return Expansion
078: */
079: public ExpansionImpl(Plan p, Task t, Workflow wf,
080: AllocationResult estimatedresult) {
081: super (p, t);
082: workflow = wf;
083: estAR = estimatedresult;
084: setContext();
085: }
086:
087: /** @return Workflow - Return the Workflow that represents the expansion of the task*/
088: public Workflow getWorkflow() {
089: return workflow;
090: }
091:
092: public void removingFromBlackboard(Subscriber s, boolean commit) {
093: super .removingFromBlackboard(s, commit);
094:
095: // Task t = getTask();
096: Workflow w = getWorkflow();
097: if (w == null)
098: return; // if already disconnected...
099:
100: if (ActiveSubscriptionObject.deferCommit) { /* this is an expensive test if we're going to waste it */
101: if (!w.isPropagatingToSubtasks()) { // if we're not auto-propagating
102: for (Enumeration e = w.getTasks(); e.hasMoreElements();) {
103: NewTask wfstask = (NewTask) e.nextElement();
104: Blackboard.getTracker().checkpoint(commit, wfstask,
105: "getParentTask");
106: }
107: }
108: }
109:
110: if (!commit)
111: return;
112:
113: if (w.isPropagatingToSubtasks()) { // if we're auto-propagating
114: WorkflowImpl wi = (WorkflowImpl) w;
115:
116: // rescind all subtasks of the workflow
117: List sts = wi.clearSubTasks(); // atomic get and clear the list
118: ListIterator it = sts.listIterator();
119: while (it.hasNext()) {
120: NewTask asub = (NewTask) it.next();
121: s.publishRemove(asub);
122: }
123: } else { // we're not auto-propagating
124: // disconnect the WF from the parent task
125: ((NewWorkflow) w).setParentTask(null);
126:
127: // FIXME: Is it really OK to re-use a workflow and its sub-tasks in a new task?
128:
129: for (Enumeration e = w.getTasks(); e.hasMoreElements();) {
130: NewTask wfstask = (NewTask) e.nextElement();
131: wfstask.setParentTask(null);
132: // Let the remover clear this pointer,
133: // but use it in the meantime if necessary.
134: // Note that removing the subtask will then clear
135: // this pointer, if not already done (via ASO method)
136: // wfstask.setWorkflow(null);
137: }
138: // the plugin should reattach this workflow to a parent task.
139: }
140: }
141:
142: /** Called by an Expander Plugin to get the latest copy of the allocationresults
143: * for each subtask.
144: * Information is stored in a List which contains a SubTaskResult for each subtask.
145: * Each of the SubTaskResult objects contain the following information:
146: * Task - the subtask, boolean - whether the result changed,
147: * AllocationResult - the result used by the aggregator for this sub-task.
148: * The boolean indicates whether the AllocationResult changed since the
149: * last time the collection was cleared by the plugin (which should be
150: * the last time the plugin looked at the list).
151: * @return List of SubTaskResultObjects one for each subtask
152: */
153: public SubtaskResults getSubTaskResults() {
154: return workflow.getSubtaskResults();
155: }
156:
157: private void writeObject(ObjectOutputStream stream)
158: throws IOException {
159: synchronized (workflow) { // Protect the integrity of the workflow
160: stream.defaultWriteObject();
161: stream.writeObject(workflow);
162: }
163: }
164:
165: private void readObject(ObjectInputStream stream)
166: throws ClassNotFoundException, IOException {
167: stream.defaultReadObject();
168: workflow = (Workflow) stream.readObject();
169: }
170:
171: /** Sets the non-null Contexts of the subtasks in the workflow to be
172: * that of the parent task
173: **/
174: private void setContext() {
175: Context context = task.getContext();
176: // No sense in going through all the subtasks if the parent's Context was never set.
177: if (context == null)
178: return;
179:
180: // Set the Context of the subtasks to be the Context of the parent task
181: for (Enumeration e = workflow.getTasks(); e.hasMoreElements();) {
182: Object o = e.nextElement();
183: if (o instanceof TaskImpl) {
184: TaskImpl subtask = (TaskImpl) o;
185: if (subtask.getContext() == null) {
186: subtask.setContext(context);
187: }
188: }
189: }
190: }
191:
192: public String toString() {
193: return "[Expansion " + getUID() + " to " + workflow + "]";
194: }
195:
196: // beaninfo
197: protected void addPropertyDescriptors(Collection c)
198: throws IntrospectionException {
199: super .addPropertyDescriptors(c);
200: c.add(new PropertyDescriptor("workflow", ExpansionImpl.class,
201: "getWorkflow", null));
202: }
203:
204: /**
205: * Fix an object once rehydration has completed.
206: * <p>
207: * This is used as a last-minute cleanup, in case the
208: * object requires special deserialization work.
209: */
210: public void postRehydration(Logger logger) {
211: super .postRehydration(logger);
212:
213: Workflow wf = getWorkflow();
214: if (wf != null) {
215: for (Enumeration tasks = wf.getTasks(); tasks
216: .hasMoreElements();) {
217: NewTask subtask = (NewTask) tasks.nextElement();
218: Workflow owf = subtask.getWorkflow();
219: if (owf != wf) {
220: subtask.setWorkflow(wf);
221: if (owf != null) {
222: logger
223: .warn("Reset task's " + subtask
224: + " workflow from " + owf
225: + " to " + wf);
226: }
227: }
228:
229: if (logger.isDebugEnabled()) {
230: PlanElement subtaskPE = subtask.getPlanElement(); /*UCK*/
231: if (subtaskPE == null) {
232: logger.debug("Subtask " + subtask.getUID()
233: + " not disposed");
234: } else {
235: logger.debug("Subtask " + subtask.getUID()
236: + " disposed " + hc(subtaskPE));
237: }
238: }
239: }
240: }
241: }
242: }
|