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.plugin.legacy;
028:
029: import org.cougaar.core.agent.service.alarm.Alarm;
030: import org.cougaar.planning.ldm.plan.AllocationResult;
031: import org.cougaar.planning.ldm.plan.Expansion;
032: import org.cougaar.planning.ldm.plan.NewTask;
033: import org.cougaar.planning.ldm.plan.Task;
034: import org.cougaar.planning.plugin.util.PluginHelper;
035: import org.cougaar.util.StateModelException;
036:
037: /** SimplePlugin is a replacement for SimplifiedPlugin and
038: * SimplifiedFatPlugin.
039: * Call setThreadingChoice(SINGLE_THREAD) in constructor or before this
040: * load is invoked to get the equivalent of SimplifiedFatPlugin.
041: **/
042:
043: public abstract class SimplePlugin extends PluginAdapter {
044:
045: private long minDelay = 0L;
046: private long maxDelay = 0L;
047: private Alarm minTimer = null;
048: private Alarm maxTimer = null;
049:
050: public void load(Object object) throws StateModelException {
051: if (getThreadingChoice() == UNSPECIFIED_THREAD)
052: setThreadingChoice(SHARED_THREAD);
053:
054: super .load(object);
055: }
056:
057: public final void initialize() throws StateModelException {
058: super .initialize();
059: }
060:
061: public final void start() throws StateModelException {
062: super .start();
063: }
064:
065: public final void suspend() throws StateModelException {
066: super .suspend();
067: }
068:
069: public final void resume() throws StateModelException {
070: super .resume();
071: }
072:
073: public final void stop() throws StateModelException {
074: super .stop();
075: }
076:
077: protected void setExecutionDelay(long minDelay, long maxDelay) {
078: this .minDelay = minDelay;
079: this .maxDelay = Math.max(minDelay, maxDelay);
080: }
081:
082: /** call initialize within an open transaction. **/
083: protected final void prerun() {
084: try {
085: openTransaction();
086: setupSubscriptions();
087: } catch (Exception e) {
088: synchronized (System.err) {
089: System.err.println(getMessageAddress().toString() + "/"
090: + this + " caught " + e);
091: e.printStackTrace();
092: }
093: } finally {
094: closeTransactionDontReset();
095: }
096: }
097:
098: /** Called during initialization to set up subscriptions.
099: * More precisely, called in the plugin's Thread of execution
100: * inside of a transaction before execute will ever be called.
101: **/
102: protected abstract void setupSubscriptions();
103:
104: /** Call execute in the right context.
105: * Note that this transaction boundary does NOT reset
106: * any subscription changes.
107: * @see #execute() documentation for details
108: **/
109: protected final void cycle() {
110: boolean doExecute = false; // Synonymous with resetTransaction
111: try {
112: openTransaction();
113: if (wasAwakened()
114: || (getBlackboardService().haveCollectionsChanged())) {
115: if (minTimer != null) {
116: if (minTimer.hasExpired() || maxTimer.hasExpired()) {
117: minTimer.cancel();
118: maxTimer.cancel();
119: minTimer = null;
120: maxTimer = null;
121: doExecute = true;
122: } else {
123: minTimer.cancel();
124: minTimer = wakeAfterRealTime(minDelay);
125: }
126: } else if (minDelay > 0) {
127: minTimer = wakeAfterRealTime(minDelay);
128: maxTimer = wakeAfterRealTime(maxDelay);
129: } else {
130: doExecute = true;
131: }
132: }
133: if (doExecute) {
134: execute();
135: }
136: } catch (Exception e) {
137: synchronized (System.err) {
138: System.err.println(getMessageAddress().toString() + "/"
139: + this + " caught " + e);
140: e.printStackTrace();
141: }
142: doExecute = true;
143: } finally {
144: closeTransaction(doExecute);
145: }
146: }
147:
148: /**
149: * Called inside of an open transaction whenever the plugin was
150: * explicitly told to run or when there are changes to any of
151: * our subscriptions.
152: **/
153: protected abstract void execute();
154:
155: //
156: // Utility methods go here
157: //
158:
159: /**
160: * Returns an AllocationResult with specified <confidenceRating> and <success>
161: * based on the preferences of Task <t>. If <t> has no preferences, returns
162: * a null AllocationResult.
163: */
164: public AllocationResult createEstimatedAllocationResult(Task t,
165: double confidenceRating, boolean success) {
166: return PluginHelper.createEstimatedAllocationResult(t,
167: getFactory(), confidenceRating, success);
168: }
169:
170: /**
171: * Creates a subtask from <parent> with same Verb, PrepositionalPhrases,
172: * DirectObject, Plan, Preferences, and Context as <parent>. Creates
173: * an expansion containing the subtask with null estimated allocation
174: * result. Publishes both subtask and expansion.
175: */
176: public void createPublishExpansion(Task parent) {
177: NewTask subtask = PluginHelper
178: .makeSubtask(parent, getFactory());
179: //at this point, could change some of the prepositional phrases or other
180: //properties of the subtask
181: //could also make a vector of subtasks instead of just one
182: Expansion expansion = PluginHelper.wireExpansion(parent,
183: subtask, getFactory());
184: //alternatively, use a different wireExpansion method to pass in an estimated
185: //allocation result or to use vectors of subtasks
186: // publish the Expansion and the workflow's subtasks.
187: PluginHelper.publishAddExpansion(getBlackboardService(),
188: expansion);
189: }
190:
191: }
|