0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 2002-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: */
0026:
0027: package org.cougaar.servicediscovery.plugin;
0028:
0029: import org.cougaar.core.blackboard.IncrementalSubscription;
0030: import org.cougaar.core.service.LoggingService;
0031: import org.cougaar.planning.ldm.asset.Asset;
0032: import org.cougaar.planning.ldm.plan.AspectType;
0033: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
0034: import org.cougaar.planning.ldm.plan.Role;
0035: import org.cougaar.planning.ldm.plan.Schedule;
0036: import org.cougaar.planning.ldm.plan.Task;
0037: import org.cougaar.planning.plugin.legacy.SimplePlugin;
0038: import org.cougaar.servicediscovery.Constants;
0039: import org.cougaar.servicediscovery.SDDomain;
0040: import org.cougaar.servicediscovery.SDFactory;
0041: import org.cougaar.servicediscovery.description.Lineage;
0042: import org.cougaar.servicediscovery.description.LineageImpl;
0043: import org.cougaar.servicediscovery.description.LineageScheduleElement;
0044: import org.cougaar.servicediscovery.transaction.LineageRelay;
0045: import org.cougaar.util.UnaryPredicate;
0046:
0047: import java.util.ArrayList;
0048: import java.util.Collection;
0049: import java.util.Iterator;
0050: import java.util.List;
0051:
0052: /**
0053: * LineagePlugin generates the Lineages for the Agent.
0054: */
0055: public class LineagePlugin extends SimplePlugin {
0056: private IncrementalSubscription myReportForDutySubscription;
0057: private IncrementalSubscription mySuperiorLineageRelaySubscription;
0058: private IncrementalSubscription mySubordinateLineageRelaySubscription;
0059: private IncrementalSubscription myLineageSubscription;
0060:
0061: private String myAgentName;
0062:
0063: private LoggingService myLoggingService;
0064: private SDFactory mySDFactory;
0065:
0066: private ArrayList myExecuteAdds;
0067: private ArrayList myExecuteRemoves;
0068: private ArrayList myExecuteChanges;
0069:
0070: private static final UnaryPredicate myLineagePred = new LineagePredicate();
0071:
0072: private static final class LineagePredicate implements
0073: UnaryPredicate {
0074: public boolean execute(Object o) {
0075: return (o instanceof Lineage);
0076: }
0077: }
0078:
0079: private static final UnaryPredicate myReportForDutyPred = new ReportForDutyPredicate();
0080:
0081: private static final class ReportForDutyPredicate implements
0082: UnaryPredicate {
0083: public boolean execute(Object o) {
0084: return (o instanceof Task && ((Task) o).getVerb().equals(
0085: Constants.Verbs.ReportForDuty));
0086: }
0087: }
0088:
0089: private final UnaryPredicate mySubordinateLineageRelayPred = new SubordinateLineageRelayPredicate();
0090:
0091: private final class SubordinateLineageRelayPredicate implements
0092: UnaryPredicate {
0093: public boolean execute(Object o) {
0094: return (o instanceof LineageRelay && ((LineageRelay) o)
0095: .getAgentName().equals(myAgentName));
0096: }
0097: }
0098:
0099: private final UnaryPredicate mySuperiorLineageRelayPred = new SuperiorLineageRelayPredicate();
0100:
0101: private final class SuperiorLineageRelayPredicate implements
0102: UnaryPredicate {
0103: public boolean execute(Object o) {
0104: return (o instanceof LineageRelay && !((LineageRelay) o)
0105: .getAgentName().equals(myAgentName));
0106: }
0107: }
0108:
0109: public void setLoggingService(LoggingService loggingService) {
0110: myLoggingService = loggingService;
0111: }
0112:
0113: protected void setupSubscriptions() {
0114: myAgentName = getBindingSite().getAgentIdentifier().toString();
0115:
0116: myReportForDutySubscription = (IncrementalSubscription) subscribe(myReportForDutyPred);
0117: mySubordinateLineageRelaySubscription = (IncrementalSubscription) subscribe(mySubordinateLineageRelayPred);
0118: mySuperiorLineageRelaySubscription = (IncrementalSubscription) subscribe(mySuperiorLineageRelayPred);
0119: myLineageSubscription = (IncrementalSubscription) subscribe(myLineagePred);
0120:
0121: mySDFactory = (SDFactory) getFactory(SDDomain.SD_NAME);
0122:
0123: myExecuteAdds = new ArrayList();
0124: myExecuteRemoves = new ArrayList();
0125: myExecuteChanges = new ArrayList();
0126:
0127: }
0128:
0129: public void execute() {
0130: if (myReportForDutySubscription.hasChanged()) {
0131:
0132: Collection addedRFDs = myReportForDutySubscription
0133: .getAddedCollection();
0134: for (Iterator adds = addedRFDs.iterator(); adds.hasNext();) {
0135: Task task = (Task) adds.next();
0136: Collection roles = (Collection) findIndirectObject(
0137: task,
0138: org.cougaar.planning.Constants.Preposition.AS);
0139:
0140: for (Iterator iterator = roles.iterator(); iterator
0141: .hasNext();) {
0142: Role role = (Role) iterator.next();
0143:
0144: if (role.equals(Constants.Roles.SUPPORTSUBORDINATE)) {
0145: addSupportLineage(task);
0146: } else {
0147: addCommandLineage(task);
0148: }
0149: }
0150: }
0151:
0152: Collection changedRFDs = myReportForDutySubscription
0153: .getChangedCollection();
0154: for (Iterator changes = changedRFDs.iterator(); changes
0155: .hasNext();) {
0156: Task task = (Task) changes.next();
0157: modifyLineage(task);
0158: }
0159:
0160: Collection removedRFDs = myReportForDutySubscription
0161: .getRemovedCollection();
0162: for (Iterator removes = removedRFDs.iterator(); removes
0163: .hasNext();) {
0164: Task task = (Task) removes.next();
0165: modifyLineage(task);
0166: }
0167:
0168: // On remove -
0169: // should publish remove lineage relay to superior
0170: // remove published lineage list associated with the superior
0171: }
0172:
0173: if (mySubordinateLineageRelaySubscription.hasChanged()) {
0174: Collection addedSubordinateRelays = mySubordinateLineageRelaySubscription
0175: .getAddedCollection();
0176:
0177: for (Iterator adds = addedSubordinateRelays.iterator(); adds
0178: .hasNext();) {
0179: updateSubordinate((LineageRelay) adds.next());
0180: }
0181:
0182: //Nothing required for modifications or removes
0183: }
0184:
0185: if (mySuperiorLineageRelaySubscription.hasChanged()) {
0186:
0187: Collection changedSuperiorRelays = mySuperiorLineageRelaySubscription
0188: .getChangedCollection();
0189: for (Iterator changes = changedSuperiorRelays.iterator(); changes
0190: .hasNext();) {
0191: updateLineage((LineageRelay) changes.next());
0192: }
0193:
0194: // I believe both relay add/removes should only be initiated by this
0195: // plugin.
0196: }
0197:
0198: if (myLineageSubscription.hasChanged()) {
0199: if (myLoggingService.isDebugEnabled()) {
0200: myLoggingService
0201: .debug(myAgentName
0202: + ": execute lineage list subscription has changed.");
0203: }
0204: updateSubordinates();
0205: }
0206:
0207: // Done with all execute related publishing.
0208: myExecuteAdds.clear();
0209: myExecuteRemoves.clear();
0210: myExecuteChanges.clear();
0211: }
0212:
0213: protected void localPublishAdd(Object o) {
0214: myExecuteAdds.add(o);
0215: publishAdd(o);
0216: }
0217:
0218: protected void localPublishRemove(Object o) {
0219: myExecuteRemoves.add(o);
0220: publishRemove(o);
0221: }
0222:
0223: protected void localPublishChange(Object o) {
0224: myExecuteChanges.add(o);
0225: publishChange(o);
0226: }
0227:
0228: protected void localPublishChange(Object o, Collection changes) {
0229: myExecuteChanges.add(o);
0230: publishChange(o, changes);
0231: }
0232:
0233: protected void addCommandLineage(Task rfdTask) {
0234: LineageRelay relay = findRelay(rfdTask);
0235: Lineage localLineage = findLocalLineage(rfdTask);
0236: boolean addLocalLineage = (localLineage == null);
0237:
0238: if (addLocalLineage) {
0239: localLineage = createLocalLineage(rfdTask);
0240: }
0241:
0242: if (relay == null) {
0243: Asset super ior = (Asset) findIndirectObject(rfdTask,
0244: org.cougaar.planning.Constants.Preposition.FOR);
0245: relay = mySDFactory.newLineageRelay(super ior.getClusterPG()
0246: .getMessageAddress());
0247: if (myLoggingService.isDebugEnabled()) {
0248: myLoggingService.debug(getAgentIdentifier()
0249: + ": addCommandLineage() publishAdd of "
0250: + relay.getUID() + " to "
0251: + relay.getAgentName());
0252: }
0253:
0254: if (addLocalLineage) {
0255: localPublishAdd(localLineage);
0256: }
0257: localPublishAdd(relay);
0258: } else {
0259: Lineage relayLineage = findRelayLineage(rfdTask);
0260:
0261: Schedule updatedSchedule = null;
0262: if (relayLineage == null) {
0263: updatedSchedule = constructLineageSchedule(
0264: localLineage, true);
0265: } else {
0266: updatedSchedule = updateLineageSchedule(localLineage,
0267: relayLineage, true);
0268: }
0269:
0270: if (!localLineage.getSchedule().equals(updatedSchedule)) {
0271: ((LineageImpl) localLineage)
0272: .setSchedule(updatedSchedule);
0273: if (addLocalLineage) {
0274: localPublishAdd(localLineage);
0275: } else {
0276: localPublishChange(localLineage);
0277: }
0278: }
0279: }
0280: }
0281:
0282: protected void addSupportLineage(Task rfdTask) {
0283: LineageImpl lineage = (LineageImpl) findLocalLineage(rfdTask);
0284:
0285: if (lineage != null) {
0286: lineage
0287: .setSchedule(constructLineageSchedule(lineage, true));
0288: localPublishChange(lineage);
0289:
0290: if (myLoggingService.isDebugEnabled()) {
0291: myLoggingService.debug(getAgentIdentifier()
0292: + ": addSupportLineage: publishChange of "
0293: + lineage.getUID());
0294: }
0295: } else {
0296: ArrayList list = new ArrayList();
0297: Asset super ior = (Asset) findIndirectObject(rfdTask,
0298: org.cougaar.planning.Constants.Preposition.FOR);
0299: String scaName = super ior.getClusterPG()
0300: .getMessageAddress().toString();
0301:
0302: list.add(scaName);
0303: // Okay to support oneself but don't add duplicate entries to the
0304: // lineage
0305: if (!myAgentName.equals(scaName)) {
0306: list.add(myAgentName);
0307: }
0308:
0309: lineage = (LineageImpl) mySDFactory.newLineage(
0310: Lineage.SUPPORT, list);
0311: lineage
0312: .setSchedule(constructLineageSchedule(lineage, true));
0313:
0314: localPublishAdd(lineage);
0315:
0316: if (myLoggingService.isDebugEnabled()) {
0317: myLoggingService.debug(getAgentIdentifier()
0318: + ": addSupportLineage: publishAdd of "
0319: + lineage.getUID() + " " + lineage);
0320: }
0321: }
0322:
0323: }
0324:
0325: protected Schedule constructLineageSchedule(Lineage lineage,
0326: boolean local) {
0327: Role lineageRole = ((lineage.getType() == Lineage.SUPPORT) && (!local)) ? Lineage
0328: .typeToRole(Lineage.OPCON)
0329: : Lineage.typeToRole(lineage.getType());
0330:
0331: /*
0332: Role lineageRole = ((lineage.getType() == Lineage.SUPPORT) && (local)) ?
0333: Lineage.typeToRole(lineage.getType()) :
0334: Constants.Role.SUPERIOR;
0335: */
0336:
0337: // Use converse for comparison to RFD tasks
0338: lineageRole = lineageRole.getConverse();
0339:
0340: List lineageList = lineage.getList();
0341: Schedule lineageSchedule = SDFactory.newLineageSchedule();
0342:
0343: int listLength = lineageList.size();
0344: String super iorName = (listLength >= 2) ? (String) lineageList
0345: .get(listLength - 2) : null;
0346:
0347: if (super iorName == null) {
0348: if ((lineage.getType() == Lineage.SUPPORT)
0349: && (lineageList.size() == 1)) {
0350: // Okay to support yourself.
0351: super iorName = (String) lineageList.get(0);
0352: } else {
0353: myLoggingService
0354: .error(getAgentIdentifier()
0355: + ": constructLineageSchedule() lineage - "
0356: + lineage
0357: + " does not include a superior."
0358: + " Unable to construct schedule from RFD tasks.");
0359: return lineageSchedule;
0360: }
0361: }
0362:
0363: if (myLoggingService.isDebugEnabled()) {
0364: myLoggingService.debug(getAgentIdentifier()
0365: + ": constructLineageSchedule() " + "looking for "
0366: + lineageRole + " RFDs to " + super iorName
0367: + " list = " + lineageList);
0368: }
0369:
0370: for (Iterator rfdIterator = myReportForDutySubscription
0371: .iterator(); rfdIterator.hasNext();) {
0372: Task task = (Task) rfdIterator.next();
0373:
0374: Asset taskSuperior = (Asset) findIndirectObject(task,
0375: org.cougaar.planning.Constants.Preposition.FOR);
0376: String taskSuperiorName = taskSuperior.getClusterPG()
0377: .getMessageAddress().toString();
0378: if (taskSuperiorName.equals(super iorName)) {
0379:
0380: Collection roles = (Collection) findIndirectObject(
0381: task,
0382: org.cougaar.planning.Constants.Preposition.AS);
0383:
0384: for (Iterator roleIterator = roles.iterator(); roleIterator
0385: .hasNext();) {
0386: Role role = (Role) roleIterator.next();
0387:
0388: if (myLoggingService.isDebugEnabled()) {
0389: myLoggingService
0390: .debug(getAgentIdentifier()
0391: + ": constructLineageSchedule() comparing "
0392: + role + " to " + lineageRole);
0393: }
0394: if (role.equals(lineageRole)) {
0395: long startTime = (long) task
0396: .getPreferredValue(AspectType.START_TIME);
0397: long endTime = (long) task
0398: .getPreferredValue(AspectType.END_TIME);
0399:
0400: if (myLoggingService.isDebugEnabled()) {
0401: myLoggingService
0402: .debug(getAgentIdentifier()
0403: + ": constructLineageSchedule() found a match");
0404: }
0405: lineageSchedule.add(SDFactory
0406: .newLineageScheduleElement(startTime,
0407: endTime));
0408: }
0409: }
0410: }
0411: }
0412:
0413: if (myLoggingService.isDebugEnabled()) {
0414: myLoggingService.debug(getAgentIdentifier()
0415: + ": constructLineageSchedule() returning "
0416: + lineageSchedule);
0417: }
0418: return lineageSchedule;
0419: }
0420:
0421: protected void modifyLineage(Task rfdTask) {
0422: Lineage localLineage = findLocalLineage(rfdTask);
0423: if (localLineage == null) {
0424: myLoggingService
0425: .error(getAgentIdentifier()
0426: + " modifyLineage():"
0427: + " unable to find matching local lineage for RFD task "
0428: + rfdTask);
0429: return;
0430: }
0431:
0432: Lineage relayLineage = findRelayLineage(rfdTask);
0433:
0434: Schedule updatedSchedule = null;
0435: if (relayLineage == null) {
0436: updatedSchedule = constructLineageSchedule(localLineage,
0437: true);
0438: } else {
0439: updatedSchedule = updateLineageSchedule(localLineage,
0440: relayLineage, true);
0441: }
0442:
0443: if (!localLineage.getSchedule().equals(updatedSchedule)) {
0444: ((LineageImpl) localLineage).setSchedule(updatedSchedule);
0445: localPublishChange(localLineage);
0446: }
0447: }
0448:
0449: protected void updateLineage(LineageRelay relay) {
0450: Collection localLineages = getMatchingLineages(relay);
0451: Collection relayLineages = new ArrayList(relay.getLineages());
0452:
0453: // Find and update all exact lineage matches
0454: for (Iterator relayLineageIterator = relayLineages.iterator(); relayLineageIterator
0455: .hasNext();) {
0456: Lineage relayLineage = (Lineage) relayLineageIterator
0457: .next();
0458:
0459: if (myLoggingService.isDebugEnabled()) {
0460: myLoggingService.debug(getAgentIdentifier()
0461: + ": updateLineage() - "
0462: + " looking for an exact match for "
0463: + relayLineage);
0464: }
0465:
0466: Lineage localLineage = findExactMatch(relayLineage,
0467: localLineages);
0468:
0469: if (localLineage != null) {
0470: localLineages.remove(localLineage);
0471: relayLineageIterator.remove();
0472:
0473: // Modify local lineage schedule if necessary
0474: Schedule relaySchedule = relayLineage.getSchedule();
0475: Schedule localSchedule = localLineage.getSchedule();
0476:
0477: if (!relaySchedule.equals(localSchedule)) {
0478: Schedule modifiedSchedule = updateLineageSchedule(
0479: localLineage, relayLineage, false);
0480:
0481: if (!modifiedSchedule.equals(localSchedule)) {
0482: if (!modifiedSchedule.isEmpty()) {
0483: ((LineageImpl) localLineage)
0484: .setSchedule(modifiedSchedule);
0485: localPublishChange(localLineage);
0486: } else {
0487: if (myLoggingService.isDebugEnabled()) {
0488: myLoggingService
0489: .debug(getAgentIdentifier()
0490: + " removing Lineage: "
0491: + localLineage
0492: + " which is never active.");
0493: }
0494: localPublishRemove(localLineage);
0495: }
0496: }
0497: }
0498: }
0499: }
0500:
0501: // Find and update all the other lineages
0502: for (Iterator relayLineageIterator = relayLineages.iterator(); relayLineageIterator
0503: .hasNext();) {
0504: Lineage relayLineage = (Lineage) relayLineageIterator
0505: .next();
0506:
0507: if (myLoggingService.isDebugEnabled()) {
0508: myLoggingService.debug(getAgentIdentifier()
0509: + ": updateLineage() - "
0510: + " looking for a match for "
0511: + relayLineage.getType() + " "
0512: + relayLineage.getList());
0513: }
0514:
0515: LineageImpl localLineage = (LineageImpl) findMatch(
0516: relayLineage, localLineages);
0517: boolean newLineage = (localLineage == null);
0518:
0519: if (!newLineage) {
0520: localLineages.remove(localLineage);
0521: } else {
0522: localLineage = (LineageImpl) mySDFactory
0523: .newLineage(relayLineage.getType());
0524: }
0525:
0526: ArrayList list = new ArrayList(relayLineage.getList());
0527: list.add(myAgentName);
0528: localLineage.setList(list);
0529:
0530: if (newLineage) {
0531: localLineage.setSchedule(constructLineageSchedule(
0532: localLineage, false));
0533: }
0534:
0535: // Modify local lineage schedule if necessary
0536: Schedule relaySchedule = relayLineage.getSchedule();
0537: Schedule localSchedule = localLineage.getSchedule();
0538:
0539: if (!relaySchedule.equals(localSchedule)) {
0540: Schedule modifiedSchedule = updateLineageSchedule(
0541: localLineage, relayLineage, false);
0542: ((LineageImpl) localLineage)
0543: .setSchedule(modifiedSchedule);
0544: }
0545:
0546: // Don't publish lineage which is never valid
0547: if (localLineage.getSchedule().isEmpty()) {
0548: if (newLineage) {
0549: if (myLoggingService.isDebugEnabled()) {
0550: myLoggingService.debug(getAgentIdentifier()
0551: + " ignoring Lineage " + localLineage
0552: + " which is never active.");
0553: }
0554: } else {
0555: if (myLoggingService.isDebugEnabled()) {
0556: myLoggingService.debug(getAgentIdentifier()
0557: + " removing Lineage " + localLineage
0558: + " which is never active.");
0559: }
0560: localPublishRemove(localLineage);
0561: }
0562: } else {
0563: if (newLineage) {
0564: if (myLoggingService.isDebugEnabled()) {
0565: myLoggingService.debug(getAgentIdentifier()
0566: + ": updateLineage() "
0567: + "adding lineage - " + localLineage);
0568: }
0569: localPublishAdd(localLineage);
0570: } else {
0571: if (myLoggingService.isDebugEnabled()) {
0572: myLoggingService
0573: .debug(getAgentIdentifier()
0574: + ": updateLineage() modifying lineage - "
0575: + localLineage);
0576: }
0577: localPublishChange(localLineage);
0578: }
0579: }
0580: }
0581:
0582: // Remove any left over local lineages - they are no longer valid.
0583: for (Iterator iterator = localLineages.iterator(); iterator
0584: .hasNext();) {
0585: Lineage lineage = (Lineage) iterator.next();
0586:
0587: // Make an exception for SCA lineages initiated by the local agent
0588: if ((lineage.getType() != Lineage.SUPPORT)
0589: || (!lineage.getRoot().equals(relay.getAgentName()))) {
0590: localPublishRemove(lineage);
0591:
0592: if (myLoggingService.isDebugEnabled()) {
0593: myLoggingService.debug(getAgentIdentifier()
0594: + ": updateLineage() "
0595: + " removing local lineage "
0596: + lineage.getType() + " "
0597: + lineage.getList()
0598: + ". Not found in relay lineages from "
0599: + relay.getAgentName());
0600: }
0601: }
0602: }
0603: }
0604:
0605: protected void updateSubordinate(LineageRelay relay) {
0606: ArrayList lineages = new ArrayList();
0607: boolean adconFound = false;
0608: boolean opconFound = false;
0609:
0610: for (Iterator iterator = myLineageSubscription.iterator(); iterator
0611: .hasNext();) {
0612: Lineage localLineage = (Lineage) iterator.next();
0613: lineages.add(mySDFactory.copyLineage(localLineage));
0614: if (myLoggingService.isDebugEnabled()) {
0615: myLoggingService.debug(myAgentName
0616: + ": updateSubordinate localLineage "
0617: + localLineage);
0618: }
0619: if (localLineage.getType() == Lineage.ADCON) {
0620: adconFound = true;
0621: }
0622:
0623: if (localLineage.getType() == Lineage.OPCON) {
0624: opconFound = true;
0625: }
0626: }
0627:
0628: if (!adconFound) {
0629: if (myLoggingService.isDebugEnabled()) {
0630: myLoggingService
0631: .debug(myAgentName
0632: + ": updateSubordinate local ADCON Lineage not found");
0633: }
0634: lineages.add(addLineageSeed(Lineage.ADCON));
0635: }
0636:
0637: if (!opconFound) {
0638: if (myLoggingService.isDebugEnabled()) {
0639: myLoggingService
0640: .debug(myAgentName
0641: + ": updateSubordinate local OPCON Lineage not found");
0642: }
0643:
0644: lineages.add(addLineageSeed(Lineage.OPCON));
0645: }
0646:
0647: relay.setLineages(lineages);
0648:
0649: if (myLoggingService.isDebugEnabled()) {
0650: myLoggingService.debug(getAgentIdentifier()
0651: + " updateSubordinate: publishChange of "
0652: + relay.getUID());
0653: }
0654:
0655: localPublishChange(relay);
0656: }
0657:
0658: protected void updateSubordinates() {
0659: for (Iterator iterator = mySubordinateLineageRelaySubscription
0660: .iterator(); iterator.hasNext();) {
0661: updateSubordinate((LineageRelay) iterator.next());
0662: }
0663: }
0664:
0665: protected Object findIndirectObject(Task task, String prep) {
0666: PrepositionalPhrase pp = task.getPrepositionalPhrase(prep);
0667: if (pp == null) {
0668: myLoggingService.error(getAgentIdentifier()
0669: + ": findIndirectObject - didn't find a " + prep
0670: + " prepositional phrase in " + task);
0671: return null;
0672: } else {
0673: return pp.getIndirectObject();
0674: }
0675: }
0676:
0677: protected Schedule updateLineageSchedule(Lineage localLineage,
0678: Lineage relayLineage, boolean local) {
0679: Schedule relaySchedule = relayLineage.getSchedule();
0680: Schedule constructedSchedule = constructLineageSchedule(
0681: localLineage, local);
0682: Schedule modifiedSchedule = SDFactory.newLineageSchedule();
0683:
0684: if (myLoggingService.isDebugEnabled()) {
0685: myLoggingService.debug(getAgentIdentifier()
0686: + ": updateLineageSchedule() "
0687: + " relaySchedule = " + relayLineage
0688: + " constructedSchedule = " + constructedSchedule);
0689: }
0690:
0691: for (Iterator iterator = new ArrayList(constructedSchedule)
0692: .iterator(); iterator.hasNext();) {
0693: LineageScheduleElement constructedScheduleElement = (LineageScheduleElement) iterator
0694: .next();
0695: Collection relayScheduleElements = relaySchedule
0696: .getOverlappingScheduleElements(
0697: constructedScheduleElement.getStartTime(),
0698: constructedScheduleElement.getEndTime());
0699:
0700: if (relayScheduleElements.size() > 0) {
0701: for (Iterator intersectingIterator = relayScheduleElements
0702: .iterator(); intersectingIterator.hasNext();) {
0703: LineageScheduleElement relayScheduleElement = (LineageScheduleElement) intersectingIterator
0704: .next();
0705: if (relayScheduleElement
0706: .equals(constructedScheduleElement)) {
0707: modifiedSchedule
0708: .add(constructedScheduleElement);
0709: } else {
0710: long start = Math.max(relayScheduleElement
0711: .getStartTime(),
0712: constructedScheduleElement
0713: .getStartTime());
0714: long end = Math
0715: .min(relayScheduleElement.getEndTime(),
0716: constructedScheduleElement
0717: .getEndTime());
0718: modifiedSchedule.add(SDFactory
0719: .newLineageScheduleElement(start, end));
0720: }
0721: }
0722: }
0723: }
0724:
0725: if ((modifiedSchedule.size() == 0)
0726: && (myLoggingService.isDebugEnabled())) {
0727: myLoggingService
0728: .debug(getAgentIdentifier()
0729: + ": updateLineageSchedule() "
0730: + " no overlap between relay Schedule and constructed schedule.");
0731: }
0732:
0733: return modifiedSchedule;
0734: }
0735:
0736: protected Role getRFDRole(Task rfdTask) {
0737: Collection roles = (Collection) findIndirectObject(rfdTask,
0738: org.cougaar.planning.Constants.Preposition.AS);
0739:
0740: if ((roles == null) || (roles.size() == 0)) {
0741: myLoggingService.error(getAgentIdentifier()
0742: + ": getRFDRole() RFD task - " + rfdTask
0743: + " does not specify a role.");
0744: return null;
0745: } else if (roles.size() > 1) {
0746: myLoggingService.error(getAgentIdentifier()
0747: + ": getRFDRole() expected 1 role in RFD task - "
0748: + rfdTask + ". Found " + roles.size() + ": "
0749: + roles + ". Will ignore all but the first role.");
0750:
0751: }
0752:
0753: Role taskRole = null;
0754: for (Iterator iterator = roles.iterator(); iterator.hasNext();) {
0755: taskRole = (Role) iterator.next();
0756: break;
0757: }
0758:
0759: return taskRole;
0760: }
0761:
0762: protected String getSuperiorName(Task rfdTask) {
0763: Asset super ior = (Asset) findIndirectObject(rfdTask,
0764: org.cougaar.planning.Constants.Preposition.FOR);
0765:
0766: if (super ior != null) {
0767: return super ior.getClusterPG().getMessageAddress()
0768: .toString();
0769: } else {
0770: myLoggingService.error(getAgentIdentifier()
0771: + ": getSuperiorName - RFD task " + rfdTask
0772: + " does not specify a superior.");
0773: return null;
0774: }
0775: }
0776:
0777: protected Lineage findLocalLineage(Task rfdTask) {
0778: Lineage lineage = null;
0779:
0780: for (Iterator iterator = myLineageSubscription.iterator(); iterator
0781: .hasNext();) {
0782: Lineage nextLineage = (Lineage) iterator.next();
0783:
0784: if (matchRFDTask(rfdTask, nextLineage)) {
0785: lineage = nextLineage;
0786: break;
0787: }
0788: }
0789:
0790: if (lineage == null) {
0791: // look in recent adds
0792: for (Iterator iterator = myExecuteAdds.iterator(); iterator
0793: .hasNext();) {
0794: Object next = iterator.next();
0795:
0796: if (next instanceof Lineage) {
0797: if (matchRFDTask(rfdTask, (Lineage) next)) {
0798: lineage = (Lineage) next;
0799: break;
0800: }
0801: }
0802: }
0803: }
0804:
0805: if ((lineage == null) && (myLoggingService.isDebugEnabled())) {
0806: myLoggingService.debug(getAgentIdentifier()
0807: + ": findLocalLineage() no " + getRFDRole(rfdTask)
0808: + " lineage to " + getSuperiorName(rfdTask));
0809: }
0810:
0811: return lineage;
0812: }
0813:
0814: protected Lineage findRelayLineage(Task rfdTask) {
0815: LineageRelay relay = findRelay(rfdTask);
0816:
0817: if (relay == null) {
0818: return null;
0819: }
0820:
0821: Role rfdRole = getRFDRole(rfdTask);
0822: if (rfdRole == null) {
0823: return null;
0824: }
0825:
0826: int lineageType = Lineage.roleToType(rfdRole.getConverse());
0827:
0828: if (lineageType == Lineage.SUPPORT) {
0829: // No pertinent info from Superior
0830: return null;
0831: }
0832:
0833: Lineage lineage = null;
0834:
0835: for (Iterator relayLineageIterator = relay.getLineages()
0836: .iterator(); relayLineageIterator.hasNext();) {
0837: Lineage relayLineage = (Lineage) relayLineageIterator
0838: .next();
0839: if (relayLineage.getType() == lineageType) {
0840: lineage = relayLineage;
0841: break;
0842: }
0843: }
0844:
0845: if ((lineage == null) && (myLoggingService.isDebugEnabled())) {
0846: myLoggingService.debug(getAgentIdentifier()
0847: + ": findRelayLineage() no " + rfdRole
0848: + " lineage to " + relay.getAgentName());
0849: }
0850:
0851: return lineage;
0852: }
0853:
0854: protected Lineage addLineageSeed(int lineageType) {
0855: ArrayList list = new ArrayList();
0856: list.add(myAgentName);
0857: Lineage lineage = mySDFactory.newLineage(lineageType, list,
0858: SDFactory.DEFAULT_TIME_SPAN);
0859:
0860: if (myLoggingService.isDebugEnabled()) {
0861: myLoggingService.debug(getAgentIdentifier()
0862: + ": adding initial lineage - " + lineage);
0863: }
0864:
0865: return lineage;
0866: }
0867:
0868: protected Lineage createLocalLineage(Task rfdTask) {
0869: Role rfdRole = getRFDRole(rfdTask);
0870: if (rfdRole == null) {
0871: return null;
0872: }
0873:
0874: int lineageType = Lineage.roleToType(rfdRole.getConverse());
0875: ArrayList list = new ArrayList();
0876: Asset super ior = (Asset) findIndirectObject(rfdTask,
0877: org.cougaar.planning.Constants.Preposition.FOR);
0878: String super iorName = super ior.getClusterPG()
0879: .getMessageAddress().toString();
0880:
0881: list.add(super iorName);
0882: list.add(myAgentName);
0883:
0884: long startTime = (long) rfdTask
0885: .getPreferredValue(AspectType.START_TIME);
0886: long endTime = (long) rfdTask
0887: .getPreferredValue(AspectType.END_TIME);
0888:
0889: Lineage localLineage = mySDFactory.newLineage(lineageType,
0890: list, SDFactory.newLineageScheduleElement(startTime,
0891: endTime));
0892:
0893: if (myLoggingService.isDebugEnabled()) {
0894: myLoggingService.debug(getAgentIdentifier()
0895: + ": createLocalLineage() localLineage "
0896: + localLineage);
0897: }
0898:
0899: return localLineage;
0900: }
0901:
0902: protected boolean match(Lineage localLineage, Lineage relayLineage) {
0903: if (localLineage.getType() == relayLineage.getType()) {
0904: if (localLineage.getType() == Lineage.SUPPORT) {
0905: return localLineage.getRoot().equals(
0906: relayLineage.getRoot());
0907: } else {
0908: String lineageSuperior = (localLineage.getList().size() > 1) ? (String) localLineage
0909: .getList().get(
0910: localLineage.getList().size() - 2)
0911: : "";
0912: return lineageSuperior.equals((String) relayLineage
0913: .getLeaf());
0914: }
0915: } else {
0916: return false;
0917: }
0918: }
0919:
0920: protected Collection getMatchingLineages(LineageRelay relay) {
0921: ArrayList localLineages = new ArrayList();
0922:
0923: for (Iterator iterator = myLineageSubscription.iterator(); iterator
0924: .hasNext();) {
0925: Lineage lineage = (Lineage) iterator.next();
0926: String lineageSuperior = (lineage.getList().size() > 1) ? (String) lineage
0927: .getList().get(lineage.getList().size() - 2)
0928: : "";
0929:
0930: if (lineageSuperior.equals(relay.getAgentName())) {
0931: localLineages.add(lineage);
0932: }
0933: }
0934:
0935: return localLineages;
0936: }
0937:
0938: protected Lineage findExactMatch(Lineage relayLineage,
0939: Collection localLineages) {
0940: ArrayList updatedList = new ArrayList();
0941: updatedList.addAll(relayLineage.getList());
0942: updatedList.add(myAgentName);
0943:
0944: for (Iterator iterator = localLineages.iterator(); iterator
0945: .hasNext();) {
0946: Lineage localLineage = (Lineage) iterator.next();
0947: if ((localLineage.getType() == relayLineage.getType())
0948: && (localLineage.getList().equals(updatedList))) {
0949: return localLineage;
0950: }
0951: }
0952: return null;
0953: }
0954:
0955: protected Lineage findMatch(Lineage relayLineage,
0956: Collection localLineages) {
0957: // Must be exact for SCA lineages
0958: if (relayLineage.getType() == Lineage.SUPPORT) {
0959: return findExactMatch(relayLineage, localLineages);
0960: }
0961:
0962: for (Iterator iterator = localLineages.iterator(); iterator
0963: .hasNext();) {
0964: Lineage localLineage = (Lineage) iterator.next();
0965: if (localLineage.getType() == relayLineage.getType()) {
0966: return localLineage;
0967: }
0968: }
0969: return null;
0970: }
0971:
0972: protected LineageRelay findRelay(Task rfdTask) {
0973: String super iorName = getSuperiorName(rfdTask);
0974:
0975: if (super iorName == null) {
0976: return null;
0977: }
0978:
0979: if (myLoggingService.isDebugEnabled()) {
0980: myLoggingService.debug(getAgentIdentifier()
0981: + ": findRelay() - " + "reporting to "
0982: + super iorName);
0983: }
0984:
0985: LineageRelay relay = null;
0986: for (Iterator relayIterator = mySuperiorLineageRelaySubscription
0987: .iterator(); relayIterator.hasNext();) {
0988:
0989: LineageRelay next = (LineageRelay) relayIterator.next();
0990:
0991: if (next.getAgentName().equals(super iorName)) {
0992: relay = next;
0993: break;
0994: } else {
0995: if (myLoggingService.isDebugEnabled()) {
0996: myLoggingService.debug(getAgentIdentifier()
0997: + ": findRelay() - " + " relay to "
0998: + next.getAgentName() + " does not match.");
0999: }
1000: }
1001: }
1002:
1003: if (relay == null) {
1004: // look in recent adds
1005: for (Iterator relayIterator = myExecuteAdds.iterator(); relayIterator
1006: .hasNext();) {
1007:
1008: Object next = relayIterator.next();
1009: if (next instanceof LineageRelay) {
1010: LineageRelay nextRelay = (LineageRelay) next;
1011: if (nextRelay.getAgentName().equals(super iorName)) {
1012: relay = nextRelay;
1013: break;
1014: } else {
1015: if (myLoggingService.isDebugEnabled()) {
1016: myLoggingService.debug(getAgentIdentifier()
1017: + ": findRelay() - "
1018: + " recently added relay to "
1019: + nextRelay.getAgentName()
1020: + " does not match.");
1021: }
1022: }
1023: }
1024: }
1025: }
1026:
1027: if (myLoggingService.isDebugEnabled()) {
1028: myLoggingService.debug(getAgentIdentifier()
1029: + ": findRelay() - " + "returning " + relay);
1030: }
1031:
1032: return relay;
1033: }
1034:
1035: protected boolean matchRFDTask(Task rfdTask, Lineage localLineage) {
1036: String super iorName = getSuperiorName(rfdTask);
1037:
1038: if (super iorName == null) {
1039: return false;
1040: }
1041:
1042: Role rfdRole = getRFDRole(rfdTask);
1043: if (rfdRole == null) {
1044: return false;
1045: }
1046:
1047: int taskType = Lineage.roleToType(rfdRole.getConverse());
1048:
1049: if (localLineage.getType() == taskType) {
1050: int length = localLineage.getList().size();
1051: String lineageSuperior = (length >= 2) ? (String) localLineage
1052: .getList().get(length - 2)
1053: : ((localLineage.getType() == Lineage.SUPPORT) && (length == 1)) ?
1054: // Okay to support yourself.
1055: (String) localLineage.getList().get(0)
1056: : null;
1057:
1058: return (super iorName.equals(lineageSuperior));
1059: } else {
1060: return false;
1061: }
1062: }
1063:
1064: }
|