001: /*
002: * <copyright>
003: *
004: * Copyright 2001-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.lib.vishnu.client;
027:
028: import org.cougaar.lib.callback.UTILExpandableTaskCallback;
029: import org.cougaar.lib.callback.UTILExpansionCallback;
030: import org.cougaar.lib.callback.UTILFilterCallback;
031: import org.cougaar.lib.callback.UTILGenericListener;
032: import org.cougaar.lib.filter.UTILExpanderPlugin;
033: import org.cougaar.planning.ldm.asset.Asset;
034: import org.cougaar.planning.ldm.plan.Expansion;
035: import org.cougaar.planning.ldm.plan.Task;
036:
037: import java.util.Date;
038: import java.util.List;
039: import java.util.Vector;
040:
041: /**
042: * <pre>
043: * A simple expander base class.
044: *
045: * Must subclass to get full behavior.
046: *
047: * Especially consider overriding handleAssignment to make the subtasks
048: * appropriate for your application.
049: *
050: * </pre>
051: * @see #handleAssignment
052: */
053: public class VishnuExpanderPlugin extends VishnuPlugin implements
054: UTILExpanderPlugin {
055: /**
056: * <pre>
057: * Provide the callback that is paired with the buffering thread, which is a
058: * listener. The buffering thread is the listener to the callback
059: *
060: * Creates an instance of the ExpandableTaskCallback, which means the plugin
061: * is looking for tasks that are naked, and not yet expanded or part of workflows.
062: *
063: * </pre>
064: * @param bufferingThread -- the thread the callback informs when there are new input tasks
065: * @return an ExpandableTaskCallback with the buffering thread as its listener
066: * @see org.cougaar.lib.callback.UTILWorkflowCallback
067: */
068: protected UTILFilterCallback createThreadCallback(
069: UTILGenericListener bufferingThread) {
070: if (isInfoEnabled())
071: debug(getName() + " : Filtering for Expandable Tasks...");
072:
073: myInputTaskCallback = new UTILExpandableTaskCallback(
074: bufferingThread, logger);
075: return myInputTaskCallback;
076: }
077:
078: /**
079: * Implemented for UTILBufferingPlugin
080: *
081: * Got an ill-formed task, now handle it, by
082: * publishing a failed expansion for the task.
083: * @param t badly-formed task to handle
084: */
085: public void handleIllFormedTask(Task t) {
086: reportIllFormedTask(t);
087: Object obj = expandHelper.makeFailedExpansion(null, ldmf, t);
088: publishAddWithCheck(obj);
089: }
090:
091: /**
092: * create the expansion callback
093: */
094: protected UTILFilterCallback createExpansionCallback() {
095: if (isInfoEnabled())
096: debug(getName() + " : Filtering for Expansions...");
097:
098: return new UTILExpansionCallback(this , logger);
099: }
100:
101: /**
102: * Implemented for UTILExpansionListener
103: *
104: * Gives plugin a way to filter out which expanded tasks it's
105: * interested in.
106: *
107: * @param t Task that has been expanded (getTask of Expansion)
108: * @return true if task is interesting to this plugin
109: */
110: public boolean interestingExpandedTask(Task t) {
111: return interestingTask(t);
112: }
113:
114: /**
115: * At least one constraint has been violated. It's up to the plugin how to deal
116: * with the violation(s).
117: *
118: * Ideally, this will not happen very often, and when it does, we should hear about it.
119: *
120: * @param exp that failed
121: * @param violatedConstraints of Constraints that have been violated
122: */
123: public void handleConstraintViolation(Expansion exp,
124: List violatedConstraints) {
125: }
126:
127: /**
128: * Implemented for UTILExpansionListener
129: *
130: * Does the plugin want to change the expansion?
131: *
132: * For instance, although no individual preference may have been exceeded,
133: * the total score for the expansion may exceed some threshold, and so the
134: * plugin may want to alter the expansion.
135: *
136: * Defaults to FALSE.
137: *
138: * @param exp to check
139: * @return true if plugin wants to change expansion
140: */
141: public boolean wantToChangeExpansion(Expansion exp) {
142: return false;
143: }
144:
145: /**
146: * The plugin changes the expansion. Only called if wantToChangeExpansion returns true.
147: *
148: * Default does nothing.
149: *
150: * @see #wantToChangeExpansion
151: * @param exp to change
152: */
153: public void changeExpansion(Expansion exp) {
154: }
155:
156: /**
157: * publish the change
158: *
159: * @see #wantToChangeExpansion
160: * @param exp to change
161: */
162: public void publishChangedExpansion(Expansion exp) {
163: publishChange(exp);
164: }
165:
166: /**
167: * Report to superior that the expansion has changed. Includes a pass
168: * through to the UTILPluginAdapter's updateAllocationResult.
169: * Updates and publishes allocation result of expansion.
170: *
171: * @param exp Expansion that has changed.
172: * @see org.cougaar.lib.filter.UTILPluginAdapter#updateAllocationResult
173: */
174: public void reportChangedExpansion(Expansion exp) {
175: if (logger.isDebugEnabled())
176: debug(getName()
177: + " : reporting changed expansion to superior.");
178: updateAllocationResult(exp);
179: }
180:
181: /**
182: * Handle a successful expansion
183: * Also must remove the GSTaskGroup from the GSS SchedulerResult
184: * storage
185: *
186: * @param exp Expansion that has succeeded.
187: */
188: public void handleSuccessfulExpansion(Expansion exp,
189: List successfulSubtasks) {
190: if (isInfoEnabled())
191: debug(getName() + " : got successful expansion for task "
192: + exp.getTask().getUID());
193: }
194:
195: /**
196: * Handle a failed expansion
197: * Also must remove the GSTaskGroup from the GSS SchedulerResult
198: * storage
199: *
200: * @param exp Expansion that has succeeded.
201: */
202: public void handleFailedExpansion(Expansion exp, List failedSubtasks) {
203: if (isInfoEnabled())
204: debug(getName() + " : got failed expansion for task "
205: + exp.getTask().getUID());
206: }
207:
208: /**
209: * The idea is to add subscriptions (via the filterCallback), and when
210: * they change, to have the callback react to the change, and tell
211: * the listener (many times the plugin) what to do.
212: *
213: * Override and call super to add new filters, or override
214: * createXXXCallback to change callback behaviour.
215: */
216: public void setupFilters() {
217: super .setupFilters();
218:
219: addFilter(createExpansionCallback());
220: }
221:
222: /**
223: * Makes expansions given the task-to-asset assignment.<p>
224: *
225: * If the task has a setup or wrapup duration, and expansion is made and
226: * then the subtasks get allocated with the setup and wrapup durations. <p>
227: *
228: * Subclasses should override with a method that attaches information representing
229: * the assignment via a preposition and also call <code>makeSetupAndWrapupTasks</code> to
230: * create the optional setup and wrapup tasks. Probably a downstream allocator will
231: * use the preposition information to create an allocation to the assigned asset.
232: *
233: * @see org.cougaar.lib.vishnu.client.VishnuPlugin#makeSetupAndWrapupTasks
234: * @param task task being assigned to asset
235: * @param asset asset handling the task
236: * @param start start of the main task
237: * @param end end of the main task
238: * @param setupStart start of a setup task, equal to start if there is no setup task
239: * @param wrapupEnd end of a wrapup task, equal to end if there is no wrapup task
240: **/
241: public void handleAssignment(Task task, Asset asset, Date start,
242: Date end, Date setupStart, Date wrapupEnd, String contribs,
243: String taskText) {
244: makeSetupWrapupExpansion(task, asset, start, end, setupStart,
245: wrapupEnd);
246: }
247:
248: /**
249: * Implemented for UTILGenericListener interface
250: *
251: * This method Expands the given Task and publishes the PlanElement.
252: * The method expandTask should be implemented by child classes.
253: * @param t the task to be expanded.
254: */
255: public void handleTask(Task t) {
256: }
257:
258: /**
259: * Here's where we react to a rescinded task.
260: *
261: * does nothing by default
262: */
263: public void handleRemovedTask(Task t) {
264: }
265:
266: /**
267: * Implemented for expand.rPlugin interface
268: *
269: * The guts of the expansion.
270: *
271: * Default does nothing! Subclass should override.
272: */
273: public Vector getSubtasks(Task t) {
274: debug(getName()
275: + " : WARNING - getSubtasks should be overriden."
276: + " Default does nothing.");
277: return new Vector();
278: }
279:
280: protected UTILExpandableTaskCallback myInputTaskCallback;
281: }
|