001: /*
002: *
003: * <copyright>
004: *
005: * Copyright 1997-2004 BBNT Solutions, LLC
006: * under sponsorship of the Defense Advanced Research Projects
007: * Agency (DARPA).
008: *
009: * You can redistribute this software and/or modify it under the
010: * terms of the Cougaar Open Source License as published on the
011: * Cougaar Open Source Website (www.cougaar.org).
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
014: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
015: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
016: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
017: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
018: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
019: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
020: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
021: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
022: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
023: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
024: *
025: * </copyright>
026: */
027:
028: package org.cougaar.planning.ldm.lps;
029:
030: import java.io.FilterWriter;
031: import java.io.IOException;
032: import java.io.InputStream;
033: import java.io.PrintWriter;
034: import java.io.Writer;
035: import java.lang.reflect.Method;
036: import java.net.URLDecoder;
037: import java.net.URLEncoder;
038: import java.text.SimpleDateFormat;
039: import java.util.ArrayList;
040: import java.util.Arrays;
041: import java.util.Calendar;
042: import java.util.Collection;
043: import java.util.Collections;
044: import java.util.Comparator;
045: import java.util.Date;
046: import java.util.Enumeration;
047: import java.util.HashMap;
048: import java.util.Iterator;
049: import java.util.List;
050:
051: import javax.servlet.ServletException;
052: import javax.servlet.http.HttpServlet;
053: import javax.servlet.http.HttpServletRequest;
054: import javax.servlet.http.HttpServletResponse;
055:
056: import org.cougaar.core.blackboard.UniqueObjectSet;
057: import org.cougaar.core.mts.MessageAddress;
058: import org.cougaar.core.servlet.ComponentServlet;
059: import org.cougaar.core.service.BlackboardQueryService;
060: import org.cougaar.core.util.UID;
061: import org.cougaar.core.util.UniqueObject;
062: import org.cougaar.planning.ldm.LogPlan;
063: import org.cougaar.planning.ldm.asset.AggregateAsset;
064: import org.cougaar.planning.ldm.asset.Asset;
065: import org.cougaar.planning.ldm.asset.AssetGroup;
066: import org.cougaar.planning.ldm.asset.ClusterPG;
067: import org.cougaar.planning.ldm.asset.ItemIdentificationPG;
068: import org.cougaar.planning.ldm.asset.LocationSchedulePG;
069: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
070: import org.cougaar.planning.ldm.measure.AbstractMeasure;
071: import org.cougaar.planning.ldm.plan.Aggregation;
072: import org.cougaar.planning.ldm.plan.Allocation;
073: import org.cougaar.planning.ldm.plan.AllocationResult;
074: import org.cougaar.planning.ldm.plan.AllocationforCollections;
075: import org.cougaar.planning.ldm.plan.AspectScorePoint;
076: import org.cougaar.planning.ldm.plan.AspectScoreRange;
077: import org.cougaar.planning.ldm.plan.AspectType;
078: import org.cougaar.planning.ldm.plan.AspectValue;
079: import org.cougaar.planning.ldm.plan.AssetAssignment;
080: import org.cougaar.planning.ldm.plan.AssetTransfer;
081: import org.cougaar.planning.ldm.plan.Composition;
082: import org.cougaar.planning.ldm.plan.Disposition;
083: import org.cougaar.planning.ldm.plan.Expansion;
084: import org.cougaar.planning.ldm.plan.ItineraryElement;
085: import org.cougaar.planning.ldm.plan.Location;
086: import org.cougaar.planning.ldm.plan.LocationRangeScheduleElement;
087: import org.cougaar.planning.ldm.plan.LocationScheduleElement;
088: import org.cougaar.planning.ldm.plan.MPTask;
089: import org.cougaar.planning.ldm.plan.Plan;
090: import org.cougaar.planning.ldm.plan.PlanElement;
091: import org.cougaar.planning.ldm.plan.PlanElementSet;
092: import org.cougaar.planning.ldm.plan.Preference;
093: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
094: import org.cougaar.planning.ldm.plan.Role;
095: import org.cougaar.planning.ldm.plan.RoleSchedule;
096: import org.cougaar.planning.ldm.plan.Schedule;
097: import org.cougaar.planning.ldm.plan.ScheduleElement;
098: import org.cougaar.planning.ldm.plan.ScoringFunction;
099: import org.cougaar.planning.ldm.plan.Task;
100: import org.cougaar.planning.ldm.plan.TimeAspectValue;
101: import org.cougaar.planning.ldm.plan.Verb;
102: import org.cougaar.planning.ldm.plan.Workflow;
103: import org.cougaar.planning.plugin.util.PluginHelper;
104: import org.cougaar.util.ConfigFinder;
105: import org.cougaar.util.PropertyTree;
106: import org.cougaar.util.Sortings;
107: import org.cougaar.util.TimeSpan;
108: import org.cougaar.util.UnaryPredicate;
109: import org.cougaar.util.log.Logger;
110: import org.cougaar.util.log.LoggerAdapter;
111: import org.w3c.dom.Document;
112: import org.w3c.dom.Element;
113:
114: /**
115: * Perform some basic consistency checking on Tasks and PlanElements
116: */
117: public class ConsistencyChecker {
118:
119: /**
120: * @param type the kind of task we are checking - or more
121: * appropriately, when:<pre>
122: * Added Task, Changed Task, Added PE's Task, Removed PE's Task.
123: * </pre>
124: */
125: public static boolean isTaskConsistent(MessageAddress self,
126: Logger logger, LogPlan logplan, Task t, String type) {
127:
128: // New local tasks should have a parent on the BBoard
129: // That parent when tracing down should claim this task
130: // If the parent was expanded, then it's Exp should be same
131: // as the task's workflow's Exp, and similarly the Workflows
132: // should be the same. And the Exp should be on the BBoard
133: // 1: pT on bb (if local task claiming a pT)
134: // 2: pT has PE
135: // 3: pT's PE is on bb
136: // 4: If pT is Exp, it's workflow == t.getWorkflow != null
137: // 5: if had workflow, it claims this task
138: // 6: else if pT's PE is All, it's getAllocationTaskUID() == t.getUID()
139: // 7: else if pT's PE is Agg???? This task should be the MPTask
140: // Note: Could put public helper in TaskImpl that takes
141: // result of logplan.findTask(pUID), logplan.findPlanElement(parent)
142: // -- or a ref to the logplan I suppose --,
143: // and the self MessageAddress
144: // Maybe cleaner that way?
145:
146: // If using Debug logging, then do all checks
147: // even after one fails
148: boolean debug = false;
149: if (logger.isDebugEnabled())
150: debug = true;
151: boolean result = true;
152:
153: // Infrastructure could have removed this task already,
154: // leaving it in an inconsistent state not worth checking
155: Task bT = logplan.findTask(t.getUID());
156: if (bT == null) {
157: if (logger.isDebugEnabled())
158: logger.debug(self + ": " + type
159: + " removed by the time I looked: " + t);
160: return true;
161: } else if (bT != t) {
162: if (logger.isInfoEnabled())
163: logger
164: .info(self
165: + ": "
166: + type
167: + " doesn't match what logplan had for this UID. Checking task: "
168: + t + ". LogPlan has: " + bT);
169: if (!debug)
170: return false;
171: else
172: result = false;
173: }
174:
175: UID pUID = t.getParentTaskUID();
176: MessageAddress dest = t.getSource();
177: Workflow w = t.getWorkflow();
178: // If pUID is non-null && local,
179: if (pUID != null
180: && (self == dest || self.equals(dest.getPrimary()))) {
181: // 1: this UID should be on the LogPlan.
182: Task parent = logplan.findTask(pUID);
183: if (parent == null) {
184: // PROBLEM: Local task claims parent not on LogPlan
185: if (logger.isInfoEnabled())
186: logger
187: .info(self
188: + ": "
189: + type
190: + " (local)'s parent not found on LogPlan: "
191: + t);
192: // Should later remove this task
193: if (!debug)
194: return false;
195: else
196: result = false;
197:
198: // Local task with parent avail
199: if (w == null) {
200: // Added task whose parent is missing with no workflow.
201: // Nothing more to check.
202: return result;
203: } else {
204: // Look at the workflow: Does it contain me?
205: boolean hasSub = false;
206: synchronized (w) {
207: Enumeration en = w.getTasks();
208: while (en.hasMoreElements()) {
209: Task subT = (Task) en.nextElement();
210: if (subT == t) {
211: hasSub = true;
212: break;
213: }
214: }
215: }
216:
217: if (!hasSub) {
218: if (logger.isInfoEnabled())
219: logger
220: .info(self
221: + ": "
222: + type
223: + "'s workflow does not contain this task. Task: "
224: + t + ", workflow: " + w);
225: if (!debug)
226: return false;
227: else
228: result = false;
229: }
230:
231: // Does it point to the same task as I point to?
232: Task wPTask = w.getParentTask();
233: if (wPTask != null) {
234: if (wPTask.getUID().equals(pUID)) {
235: parent = wPTask;
236: if (logger.isDebugEnabled())
237: logger
238: .debug(self
239: + ": "
240: + type
241: + " whose parent was missing had a workflow that still pointed to the parent task. Task: "
242: + t);
243: } else {
244: if (logger.isInfoEnabled())
245: logger
246: .info(self
247: + ": "
248: + type
249: + " whose parent was missing had a workflow that pointed to a different parent task. Task: "
250: + t + ", workflow: "
251: + w);
252: // So the parent was not on the LogPlan, and the workflow
253: // pointed to a different parent. Bail out.
254: // FIXME: Could check to see if that wf's parent task refers back to this workflow and/or is on the bboard & of course it's planelement
255: return false;
256: }
257: } else {
258: // local task with no parent but workflow also missing parent
259: // is a rescind in progress? From above,
260: // this task will be marked inconsistent already
261: if (logger.isInfoEnabled())
262: logger
263: .info(self
264: + ": "
265: + type
266: + " with missing parent whose workflow's parent link is null. Task: "
267: + t);
268: return false;
269: }
270: } // missing parent but had a workflow
271: } // end of block handling missing parent task
272:
273: // Get here means the local parent was found.
274:
275: // 2: It should also have a non-null PE
276: PlanElement ppe = parent.getPlanElement();
277: PlanElement bppe = logplan.findPlanElement(parent);
278: if (ppe == null) {
279: // problem
280: if (logger.isInfoEnabled())
281: logger.info(self
282: + ": "
283: + type
284: + "'s parent has no PE. Task: "
285: + t
286: + ". Logplan lists pe: "
287: + (bppe != null ? (bppe.getUID() + ":")
288: : "") + bppe);
289: // Should later remove both this task and the parent!!! FIXME!!!
290: // Or maybe the parent is OK?
291: if (!debug)
292: return false;
293: else
294: result = false;
295:
296: // If the parent has no plan element, what else can I check?
297: if (w == null) {
298: // Added task whose parent's planelement is missing with no workflow.
299: // Nothing more to check.
300: if (logger.isInfoEnabled())
301: logger
302: .info(self
303: + " "
304: + type
305: + " whose parent task's planelement is missing and has no workflow. Task: "
306: + t + ", parent: " + parent);
307: return result;
308: } else {
309: // Look at the workflow: Does it contain me?
310: boolean hasSub = false;
311: synchronized (w) {
312: Enumeration en = w.getTasks();
313: while (en.hasMoreElements()) {
314: Task subT = (Task) en.nextElement();
315: if (subT == t) {
316: hasSub = true;
317: break;
318: }
319: }
320: }
321:
322: if (!hasSub) {
323: if (logger.isInfoEnabled())
324: logger
325: .info(self
326: + ": "
327: + type
328: + "'s workflow does not contain this task. Task: "
329: + t + ", workflow: " + w);
330: if (!debug)
331: return false;
332: else
333: result = false;
334: }
335:
336: // Does it point to the same task as I point to?
337: Task wPTask = w.getParentTask();
338: if (wPTask != null) {
339: if (wPTask == parent) {
340: if (logger.isDebugEnabled())
341: logger
342: .debug(self
343: + ": "
344: + type
345: + " whose parent's PE was missing had a workflow that still pointed to the parent task. Task: "
346: + t);
347: } else {
348: if (logger.isInfoEnabled())
349: logger
350: .info(self
351: + ": "
352: + type
353: + " whose parent's PE was missing had a workflow that pointed to a different parent task. Task: "
354: + t + ", workflow: "
355: + w);
356: // So the parent's PE was not on the LogPlan, and the workflow
357: // pointed to a different parent. Bail out.
358: // FIXME: Could check to see if that wf's parent task refers back to this workflow and/or is on the bboard & of course it's planelement
359: return false;
360: }
361: } else {
362: // This task's workflow didn't point back to the task's parent!
363: if (logger.isInfoEnabled())
364: logger
365: .info(self
366: + ": "
367: + type
368: + " had parent missing PE & a workflow without a parent task. Task: "
369: + t + ", workflow: " + w);
370: return false;
371: }
372: } // missing parent's PE but had a workflow
373: return false;
374: } // handle no PE from parent task
375: // At this point we've handled missing parent or parent missing PE.
376: // Below we'll handle non-local task or not pointing
377: // to a parent
378:
379: // 3: That PE should be on the LogPlan
380: if (bppe != ppe) {
381: // problem
382: if (logger.isInfoEnabled())
383: logger
384: .info(self
385: + ": "
386: + type
387: + "'s parent's PE not on LogPlan consistently. Task: "
388: + t
389: + ", parent's PE: "
390: + (ppe != null ? (ppe.getUID()
391: + ":" + ppe) : ppe
392: .toString())
393: + ", but LogPlan says: "
394: + (bppe != null ? (bppe.getUID()
395: + ":" + bppe) : bppe
396: .toString()));
397: // Should later remove both this task and the parent!!! FIXME!!!
398: // Should also probably remove both the planElement's referred
399: // to here.... FIXME!!!
400: // Or maybe the parent is OK, but the task and PEs are not?
401: if (!debug)
402: return false;
403: else
404: result = false;
405: }
406:
407: if (ppe == null && bppe != null) {
408: // If we get here the parent listed no PE,
409: // but the blackboard PE is not. Use that to continue to debug
410: ppe = bppe;
411: }
412:
413: // That PE should be an Expansion or Aggregation (maybe Alloc too?)
414: // 4: If the PE is an Expansion, then t.getWorkflow below
415: // should be non-null and == exp.getWorkflow()
416: if (ppe instanceof Expansion) {
417: Workflow pw = ((Expansion) ppe).getWorkflow();
418: if (pw == null) {
419: if (logger.isInfoEnabled())
420: logger
421: .info(self
422: + ": "
423: + type
424: + "'s parent's expansion had no workflow. Task: "
425: + t + ", Expansion: "
426: + ppe.getUID() + ":" + ppe);
427: // Should remove the task, parent, and Expansion?
428: // Or maybe just the task? FIXME!!!
429: if (!debug)
430: return false;
431: else
432: result = false;
433: }
434:
435: if (w == null) {
436: if (logger.isInfoEnabled())
437: logger
438: .info(self
439: + ": "
440: + type
441: + "'s parent was Expanded, but this task has no workflow. Task: "
442: + t);
443: // Task is clearly bad. But is parent OK? FIXME
444: if (!debug)
445: return false;
446: else
447: result = false;
448: }
449:
450: if (w != pw) {
451: if (logger.isInfoEnabled())
452: logger
453: .info(self
454: + ": "
455: + type
456: + "'s parent's expansion's workflow not same as this task's workflow. Task: "
457: + t + " claims workflow: " + w
458: + ", but parent has workflow: "
459: + pw);
460: // Added task is bad. parent may be OK though? FIXME!
461: // All sub's of the added task's workflow are also suspect
462: if (!debug)
463: return false;
464: else
465: result = false;
466: }
467:
468: // 4.5: Extra check.
469: if (w != null && w.getParentTask() == null) {
470: if (logger.isInfoEnabled())
471: logger
472: .info(self
473: + ": "
474: + type
475: + "'s workflow's parent is null. Task: "
476: + t + ", workflow: " + w);
477: // The task and all subs of the workflow are bad. FIXME
478: // But the parent task pointed to this workflow, so is the
479: // parent task also bad?
480: if (!debug)
481: return false;
482: else
483: result = false;
484: }
485:
486: if (w != null && w.getParentTask() != parent) {
487: if (logger.isInfoEnabled())
488: logger.info(self + ": " + type
489: + "'s parent not same as " + type
490: + "'s workflow's parent. Task: " + t
491: + ", workflow: " + w);
492: // The workflow is pointed 2 from 2 directions, but it's upwards
493: // pointer is bad. Huh?
494: if (!debug)
495: return false;
496: else
497: result = false;
498: }
499:
500: if (w != null) {
501: // 5: Confirm that workflow has this subtask
502: boolean hasSub = false;
503: synchronized (w) {
504: Enumeration en = w.getTasks();
505: while (en.hasMoreElements()) {
506: Task subT = (Task) en.nextElement();
507: if (subT == t) {
508: hasSub = true;
509: break;
510: }
511: }
512: }
513:
514: if (!hasSub) {
515: if (logger.isInfoEnabled())
516: logger
517: .info(self
518: + ": "
519: + type
520: + "'s workflow does not contain this task. Task: "
521: + t + ", workflow: " + w);
522: if (!debug)
523: return false;
524: else
525: result = false;
526: }
527: }
528:
529: // end of parent was expanded check
530: } else if (ppe instanceof Allocation) {
531: // 6: ppe Allocation must have this t's UID as allocTaskUID
532: UID aUID = ((AllocationforCollections) ppe)
533: .getAllocationTaskUID();
534: if (aUID == null) {
535: if (logger.isInfoEnabled())
536: logger
537: .info(self
538: + ": "
539: + type
540: + "'s parent's allocation says AllocTask is null? Task: "
541: + t + ", parent's alloc: "
542: + ppe.getUID() + ":" + ppe);
543: // Task is bad. Allocation & parent may be OK FIXME
544: if (!debug)
545: return false;
546: else
547: result = false;
548: } else if (aUID != t.getUID()) {
549: if (logger.isInfoEnabled())
550: logger
551: .info(self
552: + ": "
553: + type
554: + "'s parent's allocation's allocTask not same as this task. Task: "
555: + t + ", allocation: "
556: + ppe.getUID() + ":" + ppe);
557: // Task is bad. Alloc & parent may be OK - FIXME
558: if (!debug)
559: return false;
560: else
561: result = false;
562: }
563: } else if (ppe instanceof Aggregation) {
564: // 7: If ppe is Aggregation?
565: // This task should be the MPTask
566: Composition c = ((Aggregation) ppe).getComposition();
567: if (c == null) {
568: if (logger.isInfoEnabled())
569: logger
570: .info(self
571: + ": "
572: + type
573: + "'s parent's Aggregation PE had no composition. Task: "
574: + t + " aggregation: "
575: + ppe.getUID() + ":" + ppe);
576: if (!debug)
577: return false;
578: else
579: result = false;
580: } else {
581: // Could check that composition has the parent task as a parent
582: MPTask mpt = c.getCombinedTask();
583: if (mpt == null) {
584: if (logger.isInfoEnabled())
585: logger
586: .info(self
587: + ": "
588: + type
589: + "'s parent's aggregation's composition had no CombinedTask. Task: "
590: + t + ", aggregation: "
591: + ppe.getUID() + ":" + ppe);
592: if (!debug)
593: return false;
594: else
595: result = false;
596: } else if (mpt != t) {
597: if (logger.isInfoEnabled())
598: logger
599: .info(self
600: + ": "
601: + type
602: + "'s parent's aggregation's MPTask not same as this task. Task: "
603: + t + ", mptask: " + mpt
604: + ", aggregation: "
605: + ppe.getUID() + ":" + ppe);
606: if (!debug)
607: return false;
608: else
609: result = false;
610: }
611: }
612: } // switch on type of parent PE
613: } else if (w != null) {
614: // task with no parent or parent is remote
615: // Had no parent but it says it has a workflow?
616: if (logger.isInfoEnabled())
617: logger.info(self + ": " + type
618: + " had no or non-local parent. Task Source: "
619: + dest + ". For comparison, dest: "
620: + t.getDestination()
621: + ". But it has a workflow! Task: " + t
622: + ", workflow: " + w);
623: // Keep going? Does the workflow have a parent? Does
624: // that parent exist? If so, maybe remove that parent
625: // so it propogates back down to the Expansion & clears out
626: // the workflow and removes the task?
627: // Does the workflow contain this task?
628: if (!debug)
629: return false;
630: else
631: result = false;
632:
633: // Look at the workflow: Does it contain me?
634: boolean hasSub = false;
635: synchronized (w) {
636: Enumeration en = w.getTasks();
637: while (en.hasMoreElements()) {
638: Task subT = (Task) en.nextElement();
639: if (subT == t) {
640: hasSub = true;
641: break;
642: }
643: }
644: }
645:
646: if (!hasSub) {
647: if (logger.isInfoEnabled())
648: logger
649: .info(self
650: + ": "
651: + type
652: + "'s workflow does not contain this task. Task: "
653: + t + ", workflow: " + w);
654: if (!debug)
655: return false;
656: else
657: result = false;
658: }
659:
660: // Does it point to the same task as I point to?
661: Task wPTask = w.getParentTask();
662: if (wPTask != null) {
663: if (wPTask.getUID().equals(pUID)) {
664: if (logger.isDebugEnabled())
665: logger
666: .debug(self
667: + ": "
668: + type
669: + " whose parent was missing or remote had a workflow that still pointed to the parent task. Task: "
670: + t + ", workflow: " + w);
671: } else {
672: if (logger.isInfoEnabled())
673: logger
674: .info(self
675: + ": "
676: + type
677: + " whose parent was missing or remote had a workflow that pointed to a different parent task. Task: "
678: + t + ", workflow: " + w);
679: // So the parent was not on the LogPlan, and the workflow
680: // pointed to a different parent. Bail out.
681: // FIXME: Could check to see if that wf's parent task refers back to this workflow and/or is on the bboard & of course it's planelement
682: }
683: } else {
684: if (logger.isInfoEnabled())
685: logger
686: .info(self
687: + ": "
688: + type
689: + " with remote or missing parent had a workflow with no parent. Task: "
690: + t + ", workflow " + w);
691: }
692: } // missing or remote parent but had a workflow
693:
694: // Task with no or non-local parent and no workflow. Just fine.
695: return result;
696: }
697:
698: /**
699: * @return true if the PlanElement should exist on the blackboard,
700: * or false if it should be publishRemove'd
701: */
702: public static boolean isPlanElementConsistent(MessageAddress self,
703: Logger logger, LogPlan logplan, PlanElement pe,
704: boolean checkConsistency) {
705: boolean result = true;
706:
707: Task task = pe.getTask();
708: // Could check that the PE is still on the LogPlan at this point...
709: if (logplan.findTask(task) == null) {
710: if (logger.isDebugEnabled()) {
711: logger
712: .debug(self
713: + ": Removing added planelement [task not found in the logplan] for "
714: + task + " as " + pe.getUID() + ":"
715: + pe);
716: }
717: //removePlanElement(pe, true);
718: result = false;
719:
720: // FIXME: Log that I expect removal of any child task from this PE?
721:
722: // Unless we're doing debug logging, skip out here.
723: if (!logger.isDebugEnabled())
724: return result;
725: }
726:
727: if (!checkConsistency)
728: return result;
729:
730: // With the ASO fix, the below is hopefully extra:
731: PlanElement bPE = logplan.findPlanElement(task);
732: PlanElement tPE = task.getPlanElement();
733: if (bPE == null) {
734: // added PE not on LogPlan
735: // This is OK if the PE were since removed.
736: if (tPE == null) {
737: // And it's task doesn't point to it
738: // In other words, it's been removed
739: if (logger.isDebugEnabled())
740: logger
741: .debug(self
742: + ": Added PE not on Task or LogPlan. Removed? "
743: + pe.getUID() + ":" + pe);
744: } else if (tPE != pe) {
745: // And it's task points to a different PE
746: // w/o ASO change, another thread may be adding a new PE
747: // after this PE was removed. With that change,
748: // this is an error.
749: if (logger.isInfoEnabled())
750: logger
751: .info(self
752: + ": Added PE not on LogPlan (nothing is), but task points to another PE. Is another add in progress after this was removed? PE: "
753: + pe.getUID() + ":" + pe
754: + ", task: " + task
755: + ", Task's new PE: "
756: + tPE.getUID() + ":" + tPE);
757: }
758: } else if (bPE != pe) {
759: // added PE not on LogPlan, another is.
760: // This is OK if another add has already completed
761: // We must watch though, w/o ASO change, for inconsistent pointers
762: if (bPE == tPE) {
763: // And its task points to this other PE
764: // Does the other PE point to this task? Presumably?
765: // This could happen if this PE were removed
766: // And another added before this LP ran.
767:
768: // This is a strange thing for a PE to do, but i guess so...
769: // I see lots of these allocate to InventoryAssets, PackaedPOL,
770: // MaintainedItem -- diff UID, alloc to same NSN
771: if (logger.isDebugEnabled())
772: logger
773: .debug(self
774: + ": Added PE apparently since removed & replaced. Added: "
775: + pe.getUID() + ":" + pe
776: + " replaced with " + bPE.getUID()
777: + ":" + bPE + " for task " + task);
778: } else if (tPE == null) {
779: // Added PE's task points to no PE, but has a different
780: // PE on the LogPlan. This shouldn't happen
781: if (logger.isWarnEnabled())
782: logger
783: .warn(self
784: + ": Added PE not on task or LogPlan. Removed? Task points to no PE, but LogPlan points to a different PE!?! Task: "
785: + task + ", LogPlan's PE: "
786: + bPE.getUID() + ":" + bPE);
787: } else if (tPE == pe) {
788: // Added PE's task points to it (ie no publishRemove called),
789: // but has a different PE on the LogPlan - ie
790: // another publishAdd finished after this one. Maybe
791: // Add 1 starts, then remove, then add #2 finishes, then add #1
792: // finishes, then this LP runs?
793: if (logger.isWarnEnabled())
794: logger
795: .warn(self
796: + ": Added PE is ref'ed by its task, but LogPlan has another. Added PE: "
797: + pe.getUID() + ":" + pe
798: + ", Task: " + task
799: + ", LogPlan's PE: " + bPE.getUID()
800: + ":" + bPE);
801: } else {
802: // Added PE's Task points to 1 PE, LogPlan to another, and neither
803: // are the PE that was just added!
804: if (logger.isWarnEnabled())
805: logger
806: .warn(self
807: + ": Added PE not ref'ed, and Task and LogPlan point to different PEs. Task "
808: + task + ", Task's PE: "
809: + tPE.getUID() + ":" + tPE
810: + ", LogPlan's PE: " + bPE.getUID()
811: + ":" + bPE);
812: }
813: } else {
814: // LogPlan has this PE. Does the task?
815: if (tPE == null) {
816: // w/o ASO change it means a remove is in progress
817: // With that change, this is an error.
818: if (logger.isInfoEnabled())
819: logger
820: .info(self
821: + ": Added PE on LogPlan but Task has none. Is PE removal in progress? PE: "
822: + pe.getUID() + ":" + pe
823: + ", Task: " + task);
824: } else if (tPE != pe) {
825: // Huh? W/o ASO change this may mean the first add was in
826: // progress, a remove started but didn't finish,
827: // then another add started (changing the task pointer),
828: // and only now is the first add finishing.
829: if (logger.isInfoEnabled())
830: logger
831: .info(self
832: + ": Added PE on LogPlan but Task already points to a different PE. Another remove and add both in progress? PE: "
833: + pe.getUID() + ":" + pe
834: + ", Task: " + task
835: + ", Task's PE: " + tPE.getUID()
836: + ":" + tPE);
837: }
838: // Task has what LogPlan has which is this PE. Normal case.
839: }
840:
841: // Other to do: If it's an Expansion, does it have a workflow?
842:
843: // if !isTaskConsistent(task) then deferRescind(task)
844:
845: return result;
846: }
847: }
|