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.mlm.plugin.organization;
028:
029: import java.util.Collection;
030: import java.util.Enumeration;
031: import java.util.Vector;
032:
033: import org.cougaar.core.blackboard.IncrementalSubscription;
034: import org.cougaar.core.component.ServiceRevokedEvent;
035: import org.cougaar.core.component.ServiceRevokedListener;
036: import org.cougaar.core.plugin.ComponentPlugin;
037: import org.cougaar.core.service.LoggingService;
038: import org.cougaar.glm.ldm.Constants;
039: import org.cougaar.glm.ldm.asset.Organization;
040: import org.cougaar.planning.ldm.PlanningFactory;
041: import org.cougaar.planning.ldm.asset.AbstractAsset;
042: import org.cougaar.planning.ldm.asset.Asset;
043: import org.cougaar.planning.ldm.plan.AllocationResult;
044: import org.cougaar.planning.ldm.plan.Expansion;
045: import org.cougaar.planning.ldm.plan.NewPrepositionalPhrase;
046: import org.cougaar.planning.ldm.plan.NewTask;
047: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
048: import org.cougaar.planning.ldm.plan.Task;
049: import org.cougaar.planning.ldm.plan.Verb;
050: import org.cougaar.planning.plugin.util.PluginHelper;
051: import org.cougaar.planning.service.LDMService;
052: import org.cougaar.util.UnaryPredicate;
053:
054: /**
055: * Vesion of GLSExpander without SD support, for use with minitestconfig, eg.
056: * The GLSMiniExpanderPlugin will take the intial GetLogSupport task received by
057: * an agent and expand it into getlogsupport for subordinates.
058: **/
059: public class GLSMiniExpanderPlugin extends ComponentPlugin {
060: /** Subscription to hold collection of input tasks **/
061: private IncrementalSubscription expandableTasks;
062:
063: /** Subscription to the Expansions I create */
064: private IncrementalSubscription myExpansions;
065:
066: /**
067: * The Socrates subscription
068: **/
069: private IncrementalSubscription mySelfOrgs;
070:
071: /** for knowing when we get our self org asset **/
072: private Organization selfOrgAsset = null;
073:
074: /**
075: * Parameters are the types of determinerequirements to generate.
076: **/
077: String[] myParams = null;
078: PlanningFactory theLDMF = null;
079:
080: /**
081: * Override the setupSubscriptions() in ComponentPlugin
082: * Get an LDMService for factory calls
083: * Use the blackboard service inherited from ComponentPlugin
084: **/
085: protected void setupSubscriptions() {
086:
087: //System.out.println("setupSubscriptions: "+getAgentIdentifier());
088: //get the LDM service to access the object factories from my bindingsite's servicebroker
089: LDMService ldmService = null;
090: if (theLDMF == null) {
091: ldmService = (LDMService) getBindingSite()
092: .getServiceBroker().getService(this ,
093: LDMService.class,
094: new ServiceRevokedListener() {
095: public void serviceRevoked(
096: ServiceRevokedEvent re) {
097: theLDMF = null;
098: }
099: });
100: }
101: //use the service
102: theLDMF = ldmService.getFactory();
103:
104: Collection params = getParameters();
105: if (params != null) {
106: myParams = (String[]) params.toArray(new String[params
107: .size()]);
108: } else {
109: myParams = new String[0];
110: }
111:
112: // subscribe using the blackboardservice - blackboard variable(representing the service)
113: //is inherited from ComponentPlugin
114: mySelfOrgs = (IncrementalSubscription) blackboard
115: .subscribe(selfOrgAssetPred);
116:
117: if (blackboard.didRehydrate()) {
118: processOrgAssets(mySelfOrgs.elements()); // May already be there
119: }
120: }
121:
122: private void setupSubscriptions2() {
123:
124: /** Predicate for finding input GLS Task. It must be a GLS FOR us **/
125: final UnaryPredicate myTaskPred = new UnaryPredicate() {
126: public boolean execute(Object o) {
127:
128: if (o instanceof Task) {
129: Task task = (Task) o;
130: Verb verb = task.getVerb();
131: if (verb.equals(Constants.Verb.GetLogSupport)) {
132: PrepositionalPhrase pp = task
133: .getPrepositionalPhrase(Constants.Preposition.FOR);
134: if (pp != null) {
135: return pp.getIndirectObject().equals(
136: selfOrgAsset);
137: }
138: }
139: }
140: return false;
141: }
142: };
143: expandableTasks = (IncrementalSubscription) blackboard
144: .subscribe(myTaskPred);
145:
146: /** Predicate for watching our expansions **/
147: final UnaryPredicate myExpansionPred = new UnaryPredicate() {
148: public boolean execute(Object o) {
149:
150: if (o instanceof Expansion) {
151: Expansion exp = (Expansion) o;
152: return myTaskPred.execute(exp.getTask());
153: }
154: return false;
155: }
156: };
157: myExpansions = (IncrementalSubscription) blackboard
158: .subscribe(myExpansionPred);
159: }
160:
161: /**
162: * The predicate for the Socrates subscription
163: **/
164: private static UnaryPredicate selfOrgAssetPred = new UnaryPredicate() {
165: public boolean execute(Object o) {
166:
167: if (o instanceof Organization) {
168: Organization org = (Organization) o;
169: return org.isSelf();
170: }
171: return false;
172: }
173: };
174:
175: /**
176: * Plugin execute method is called every time one of our
177: * subscriptions has something to do
178: **/
179: protected void execute() {
180:
181: if (mySelfOrgs.hasChanged()) {
182: processOrgAssets(mySelfOrgs.getAddedList());
183: }
184:
185: if (expandableTasks == null) {
186: return; // Still waiting for ourself
187: }
188: if (expandableTasks.hasChanged()) {
189: Enumeration e = expandableTasks.getAddedList();
190: while (e.hasMoreElements()) {
191: Task task = (Task) e.nextElement();
192: if (task.getPlanElement() != null) {
193: logger
194: .warn("GLSMiniExpanderPlugin.execute - strange, task "
195: + task.getUID()
196: + "\nhas already been expanded with p.e.:\n"
197: + task.getPlanElement()
198: + "\nSo skipping already expanded task.");
199: } else {
200: expand(task);
201: }
202: }
203: }
204: if (myExpansions.hasChanged()) {
205: PluginHelper.updateAllocationResult(myExpansions);
206: }
207: }
208:
209: private void processOrgAssets(Enumeration e) {
210: if (e.hasMoreElements()) {
211: selfOrgAsset = (Organization) e.nextElement();
212: // Setup our other subscriptions now that we know ourself
213: if (expandableTasks == null) {
214: setupSubscriptions2();
215: }
216: }
217: }
218:
219: /**
220: * Expand a task into a GLS for subordinates plus
221: * DETERMINEREQUIREMENTS for all types specified by params.
222: * @param task The Task to expand.
223: **/
224: public void expand(Task task) {
225: Vector subtasks = new Vector();
226: subtasks.addElement(createForSubordinatesTask(task));
227:
228: for (int i = 0; i < myParams.length; i++) {
229: subtasks.addElement(createDetermineRequirementsTask(task,
230: myParams[i]));
231: }
232:
233: AllocationResult estResult = PluginHelper
234: .createEstimatedAllocationResult(task, theLDMF, 0.0,
235: true);
236: Expansion exp = PluginHelper.wireExpansion(task, subtasks,
237: theLDMF, estResult);
238:
239: //use the helper to publish the expansion and the wf subtasks all in one
240: PluginHelper.publishAddExpansion(blackboard, exp);
241: }
242:
243: /**
244: * Create the for subordinates task resulting from the given
245: * parent Task.
246: * @param task Parent task to be used in creating an expanded gls task
247: * @return NewTask the new expanded task.
248: **/
249: private NewTask createForSubordinatesTask(Task task) {
250: // Create copy of parent Task
251: NewTask subtask = createTask(task);
252: subtask.setVerb(Constants.Verb.GetLogSupport);
253:
254: Vector prepphrases = new Vector();
255:
256: // make the "subordinates" abstract asset and add a prep phrase with it
257: Asset subasset_proto = theLDMF.createPrototype(Asset.class,
258: "Subordinates");
259: Asset subasset = theLDMF.createInstance(subasset_proto);
260: NewPrepositionalPhrase newpp = theLDMF.newPrepositionalPhrase();
261: newpp.setPreposition(Constants.Preposition.FOR);
262: newpp.setIndirectObject(theLDMF.cloneInstance(subasset));
263: prepphrases.addElement(newpp);
264:
265: Enumeration origpp = task.getPrepositionalPhrases();
266: while (origpp.hasMoreElements()) {
267: PrepositionalPhrase app = (PrepositionalPhrase) origpp
268: .nextElement();
269: if (app.getPreposition().equals("WithC0")) {
270: // long c0 = ((Long)app.getIndirectObject()).longValue();
271: // newpp.setPreposition("WithC0");
272: // newpp.setIndirectObject(new Long(c0));
273: prepphrases.addElement(app);
274: }
275: }
276: subtask.setPrepositionalPhrases(prepphrases.elements());
277: return subtask;
278: }
279:
280: /**
281: * Creates a DETERMINEREQUIREMENTS task of the specified type
282: * @return Task The DetermineRequirements task
283: **/
284: public Task createDetermineRequirementsTask(Task task,
285: String ofTypePreposition) {
286: NewTask subtask = createTask(task);
287: subtask.setVerb(Constants.Verb.DetermineRequirements);
288:
289: Vector prepphrases = new Vector();
290:
291: // get the existing prep phrase(s) - look for FOR <Agentname>
292: // and add that one to the new subtask
293: Enumeration origpp = task.getPrepositionalPhrases();
294: while (origpp.hasMoreElements()) {
295: PrepositionalPhrase app = (PrepositionalPhrase) origpp
296: .nextElement();
297: if ((app.getPreposition().equals(Constants.Preposition.FOR))
298: && (app.getIndirectObject() instanceof Asset)) {
299: prepphrases.addElement(app);
300: }
301: }
302: Asset io_proto = theLDMF.createPrototype(AbstractAsset.class,
303: ofTypePreposition);
304: Asset indirectobj = theLDMF.createInstance(io_proto);
305: NewPrepositionalPhrase pp = theLDMF.newPrepositionalPhrase();
306: pp.setPreposition(Constants.Preposition.OFTYPE);
307: pp.setIndirectObject(indirectobj);
308: prepphrases.addElement(pp);
309: subtask.setPrepositionalPhrases(prepphrases.elements());
310: return subtask;
311: }
312:
313: /**
314: * Create a subtask of the parent
315: * @param task the Parent
316: * @return Newtask the newly created subtask
317: **/
318: private NewTask createTask(Task task) {
319: NewTask subtask = theLDMF.newTask();
320: subtask.setParentTask(task);
321: subtask.setSource(this .getAgentIdentifier());
322: if (task.getDirectObject() != null) {
323: subtask.setDirectObject(theLDMF.cloneInstance(task
324: .getDirectObject()));
325: } else {
326: subtask.setDirectObject(null);
327: }
328:
329: subtask.setPlan(task.getPlan());
330: synchronized (task) {
331: subtask.setPreferences(task.getPreferences());
332: }
333: return subtask;
334: }
335:
336: /** rely upon load-time introspection to set these services - don't worry about revokation. */
337: public final void setLoggingService(LoggingService logger) {
338: this .logger = logger;
339: }
340:
341: /**
342: * Everybody needs a logger
343: **/
344: protected LoggingService logger;
345: }
|