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.lps;
028:
029: import java.util.Collection;
030: import java.util.Iterator;
031:
032: import org.cougaar.core.blackboard.Directive;
033: import org.cougaar.core.domain.LogicProvider;
034: import org.cougaar.core.domain.MessageLogicProvider;
035: import org.cougaar.core.domain.RootPlan;
036: import org.cougaar.planning.ldm.LogPlan;
037: import org.cougaar.planning.ldm.PlanningFactory;
038: import org.cougaar.planning.ldm.asset.Asset;
039: import org.cougaar.planning.ldm.plan.AssetRescind;
040: import org.cougaar.planning.ldm.plan.AssetVerification;
041: import org.cougaar.planning.ldm.plan.AssignedAvailabilityElement;
042: import org.cougaar.planning.ldm.plan.AssignedRelationshipElement;
043: import org.cougaar.planning.ldm.plan.HasRelationships;
044: import org.cougaar.planning.ldm.plan.NewSchedule;
045: import org.cougaar.planning.ldm.plan.Relationship;
046: import org.cougaar.planning.ldm.plan.Schedule;
047: import org.cougaar.planning.ldm.plan.ScheduleElement;
048:
049: import org.cougaar.util.TimeSpans;
050: import org.cougaar.util.log.Logger;
051: import org.cougaar.util.log.Logging;
052:
053: /**
054: * take an incoming AssetVerification Directive and
055: * confirm Asset on the LogPlan w/side-effect of also disseminating to
056: * other subscribers.
057: **/
058: public class ReceiveAssetVerificationLP implements LogicProvider,
059: MessageLogicProvider {
060: private static final Logger logger = Logging
061: .getLogger(ReceiveAssetVerificationLP.class);
062:
063: private final RootPlan rootplan;
064: private final LogPlan logplan;
065: private final PlanningFactory ldmf;
066:
067: public ReceiveAssetVerificationLP(RootPlan rootplan,
068: LogPlan logplan, PlanningFactory ldmf) {
069: this .rootplan = rootplan;
070: this .logplan = logplan;
071: this .ldmf = ldmf;
072: }
073:
074: public void init() {
075: }
076:
077: /**
078: * Verifies that Assets are in the LogPlan. Sends rescinds if not.
079: **/
080: public void execute(Directive dir, Collection changes) {
081: if (dir instanceof AssetVerification) {
082: AssetVerification av = (AssetVerification) dir;
083:
084: // One of ourselves
085: Asset localAsset = logplan.findAsset(av.getAsset());
086: Schedule rescindSchedule = null;
087:
088: if (localAsset == null) {
089: //Rescind everything
090: rescindSchedule = av.getSchedule();
091: } else {
092: if (!(av.getAsset() instanceof HasRelationships)
093: || !(av.getAssignee() instanceof HasRelationships)) {
094: rescindSchedule = getUnmatchedAvailability(av,
095: localAsset);
096: } else {
097: rescindSchedule = getUnmatchedRelationships(av,
098: (HasRelationships) localAsset);
099: }
100: }
101:
102: if ((rescindSchedule != null) && rescindSchedule.size() > 0) {
103: AssetRescind arm = ldmf.newAssetRescind(ldmf
104: .cloneInstance(av.getAsset()), ldmf
105: .cloneInstance(av.getAssignee()),
106: rescindSchedule);
107: rootplan.sendDirective((Directive) arm);
108: }
109: }
110: }
111:
112: /** getUnmatchedAvailability - returns a Schedule with all ScheduleElements which
113: * are not matched by the local availability schedule.
114: *
115: * @param av AssetVerification which schedule is verified
116: * @param localAsset Asset local copy of the asset being verified
117: * @return Schedule of AssignedRelationshipElements which do not match local info
118: */
119: private Schedule getUnmatchedAvailability(AssetVerification av,
120: Asset localAsset) {
121: NewSchedule rescindSchedule = null;
122:
123: Schedule availSchedule = localAsset.getRoleSchedule()
124: .getAvailableSchedule();
125:
126: if (availSchedule == null) {
127: // rescind everything
128: rescindSchedule = ldmf.newAssignedRelationshipSchedule();
129: rescindSchedule.addAll(av.getSchedule());
130: return rescindSchedule;
131: }
132:
133: //iterate over verification schedule and make sure it maps to local info
134: for (Iterator iterator = av.getSchedule().iterator(); iterator
135: .hasNext();) {
136: ScheduleElement verify = (ScheduleElement) iterator.next();
137:
138: Iterator localIterator = availSchedule.iterator();
139:
140: boolean found = false;
141: while (localIterator.hasNext()) {
142: ScheduleElement localAvailability = (ScheduleElement) localIterator
143: .next();
144:
145: if (!(localAvailability instanceof AssignedAvailabilityElement)) {
146: continue;
147: }
148:
149: Asset assignee = ((AssignedAvailabilityElement) localAvailability)
150: .getAssignee();
151:
152: if ((assignee.equals(av.getAssignee()))
153: && (verify.getStartTime() == localAvailability
154: .getStartTime())
155: && (verify.getEndTime() == localAvailability
156: .getEndTime())) {
157: found = true;
158: break;
159: }
160: }
161:
162: if (!found) {
163: if (rescindSchedule == null) {
164: rescindSchedule = ldmf
165: .newAssignedRelationshipSchedule();
166: }
167: ((NewSchedule) rescindSchedule).add(verify);
168: }
169: }
170:
171: return rescindSchedule;
172: }
173:
174: /** getUnmatchedRelationships - returns a Schedule with all AssignedRelationshipElements which
175: * are not matched by the local relationship schedule.
176: *
177: * @param av AssetVerification which schedule is verified
178: * @param localAsset HasRelationships local copy of the asset being verified
179: * @return Schedule of AssignedRelationshipElements which do not match local info
180: */
181: private Schedule getUnmatchedRelationships(AssetVerification av,
182: HasRelationships localAsset) {
183: NewSchedule rescindSchedule = null;
184: //HasRelationships asset = (HasRelationships)av.getAsset();
185: HasRelationships assignee = (HasRelationships) av.getAssignee();
186:
187: Collection localRelationships = localAsset
188: .getRelationshipSchedule().getMatchingRelationships(
189: assignee,
190: TimeSpans.getSpan(av.getSchedule()
191: .getStartTime(), av.getSchedule()
192: .getEndTime()));
193: String assetID = av.getAsset().getItemIdentificationPG()
194: .getItemIdentification();
195: String assigneeID = av.getAssignee().getItemIdentificationPG()
196: .getItemIdentification();
197:
198: //iterate over verification schedule and make sure it maps to local info
199: for (Iterator iterator = av.getSchedule().iterator(); iterator
200: .hasNext();) {
201: AssignedRelationshipElement verify = (AssignedRelationshipElement) iterator
202: .next();
203: String itemIDA = verify.getItemIDA();
204: String itemIDB = verify.getItemIDB();
205:
206: if (!(itemIDA.equals(assetID) && itemIDB.equals(assigneeID))
207: && !(itemIDA.equals(assigneeID) && itemIDB
208: .equals(assetID))) {
209: logger.error("Schedule element - " + verify
210: + " does not match asset - " + av.getAsset()
211: + " - and assignee - " + av.getAssignee());
212: continue;
213: }
214:
215: Iterator localIterator = localRelationships.iterator();
216:
217: boolean found = false;
218: while (localIterator.hasNext()) {
219: Relationship localRelationship = (Relationship) localIterator
220: .next();
221: HasRelationships localA = localRelationship.getA();
222: HasRelationships localB = localRelationship.getB();
223:
224: if ((localA instanceof Asset)
225: && (localB instanceof Asset)) {
226: String localItemIDA = ((Asset) localA)
227: .getItemIdentificationPG()
228: .getItemIdentification();
229: String localItemIDB = ((Asset) localB)
230: .getItemIdentificationPG()
231: .getItemIdentification();
232:
233: if (((verify.getRoleA().equals(
234: localRelationship.getRoleA())
235: && itemIDA.equals(localItemIDA)
236: && verify.getRoleB().equals(
237: localRelationship.getRoleB()) && itemIDB
238: .equals(localItemIDB)) || (verify
239: .getRoleB().equals(
240: localRelationship.getRoleA())
241: && itemIDB.equals(localItemIDA)
242: && verify.getRoleA().equals(
243: localRelationship.getRoleB()) && itemIDA
244: .equals(localItemIDB)))
245: && verify.getStartTime() == localRelationship
246: .getStartTime()
247: && verify.getEndTime() == localRelationship
248: .getEndTime()) {
249: found = true;
250: break;
251: }
252: }
253: }
254:
255: if (!found) {
256: if (rescindSchedule == null) {
257: rescindSchedule = ldmf
258: .newAssignedRelationshipSchedule();
259: }
260: ((NewSchedule) rescindSchedule).add(verify);
261: }
262: }
263:
264: return rescindSchedule;
265: }
266:
267: }
|