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.assessor;
028:
029: import java.text.MessageFormat;
030: import java.util.ArrayList;
031: import java.util.Collection;
032: import java.util.Date;
033: import java.util.Iterator;
034:
035: import org.cougaar.core.blackboard.IncrementalSubscription;
036: import org.cougaar.glm.ldm.Constants;
037: import org.cougaar.glm.ldm.asset.Organization;
038: import org.cougaar.planning.ldm.asset.ItemIdentificationPG;
039: import org.cougaar.planning.ldm.plan.NewReport;
040: import org.cougaar.planning.ldm.plan.Relationship;
041: import org.cougaar.planning.ldm.plan.RelationshipSchedule;
042: import org.cougaar.planning.ldm.plan.Role;
043: import org.cougaar.planning.plugin.legacy.SimplePlugin;
044: import org.cougaar.util.TimeSpan;
045: import org.cougaar.util.UnaryPredicate;
046:
047: /**
048: * The SupportingUnitAssessorPlugin monitors organization assets and generates
049: * an Report if one is added/modified/deleted.
050: *
051: */
052:
053: public class SupportingUnitAssessorPlugin extends SimplePlugin {
054:
055: private IncrementalSubscription mySelfOrgSubscription;
056: private String[] myMessageArgs;
057:
058: /* Changes to formats ==> changes to getMessageArgs()
059: */
060: private final MessageFormat myFormat = new MessageFormat(
061: "Cluster {0}: {1} has changed: supporting and subordinate relationships {2}.");
062:
063: private final MessageFormat myRemoveFormat = new MessageFormat(
064: "Cluster {0}: {1} has been removed: supporting and subordinate relationships {2}.");
065:
066: /**
067: * selfOrgPred - returns an UnaryPredicate to find self organizations.
068: *
069: * @return UnaryPredicate
070: */
071: private UnaryPredicate selfOrgPred() {
072: return new UnaryPredicate() {
073: public boolean execute(Object o) {
074: boolean match = false;
075:
076: if (o instanceof Organization) {
077: Organization org = (Organization) o;
078:
079: return (org.isSelf());
080: } else {
081: return false;
082: }
083: }
084: };
085: }
086:
087: /**
088: * execute - CCV2 execute method - called whenever IncrementalSubscription
089: * has changed.
090: *
091: */
092: public synchronized void execute() {
093: if (mySelfOrgSubscription.hasChanged()) {
094: checkAdd(mySelfOrgSubscription.getAddedCollection());
095: checkChange(mySelfOrgSubscription.getChangedCollection());
096: checkRemove(mySelfOrgSubscription.getRemovedCollection());
097: }
098: }
099:
100: /**
101: * setUpSubscriptions - sets up subscription to screen for supporting
102: * organization assets
103: */
104: protected void setupSubscriptions() {
105: initMessageArgs();
106: mySelfOrgSubscription = (IncrementalSubscription) subscribe(selfOrgPred());
107: }
108:
109: /**
110: * initMessageArgs - initializes message argument array. Changes to
111: * message formats (myAddFormat, myModifyFormat, myRemoveFormat) must be
112: * accompanied with cahnges to initMessageArgs.
113: *
114: * Using one arg array for all formats at this point. Cluster name at
115: * index 0.
116: */
117: private void initMessageArgs() {
118: myMessageArgs = new String[3];
119:
120: myMessageArgs[0] = getMessageAddress().toString();
121: }
122:
123: /**
124: * checkAdd - handle new self organizations
125: * Generates an Report for each.
126: *
127: * @param newOrgs Collection of the added self orgs
128: */
129: private void checkAdd(Collection newOrgs) {
130: if (newOrgs == null) {
131: return;
132: }
133:
134: Iterator iterator = newOrgs.iterator();
135:
136: while (iterator.hasNext()) {
137: Organization org = (Organization) iterator.next();
138: Collection supportingRelationships = findSupportingRelationships(org);
139:
140: if (supportingRelationships.size() > 0) {
141: NewReport report = getFactory().newReport();
142:
143: report.setDate(new Date(getAlarmService()
144: .currentTimeMillis()));
145: report.setText(myFormat.format(getMessageArgs(org,
146: supportingRelationships)));
147:
148: System.out.println(report.getText());
149:
150: publishAdd(report);
151: }
152: }
153: }
154:
155: /**
156: * checkChange - handle all the modified self orgs
157: * Generates an Report for each.
158: * BOZO - do we really want to know about all changes?
159: *
160: * @param changedOrgs Collection of all the modified self Orgs.
161: */
162: private void checkChange(Collection changedOrgs) {
163: if (changedOrgs == null) {
164: return;
165: }
166:
167: Iterator iterator = changedOrgs.iterator();
168:
169: while (iterator.hasNext()) {
170: Organization org = (Organization) iterator.next();
171: Collection supportingRelationships = findSupportingRelationships(org);
172:
173: if (supportingRelationships.size() > 0) {
174: NewReport report = getFactory().newReport();
175:
176: report.setDate(new Date(getAlarmService()
177: .currentTimeMillis()));
178: report.setText(myFormat.format(getMessageArgs(org,
179: supportingRelationships)));
180:
181: System.out.println(report.getText());
182: publishAdd(report);
183: }
184: }
185: }
186:
187: /**
188: * checkRemove - handle all the removed self orgs
189: * Generates an Report for each.
190: *
191: * @param removedOrgs Collection of all the removed self orgs
192: */
193: private void checkRemove(Collection removedOrgs) {
194: if (removedOrgs == null) {
195: return;
196: }
197:
198: Iterator iterator = removedOrgs.iterator();
199:
200: while (iterator.hasNext()) {
201: Organization org = (Organization) iterator.next();
202: Collection supportingRelationships = findSupportingRelationships(org);
203:
204: if (supportingRelationships.size() > 0) {
205: NewReport report = getFactory().newReport();
206:
207: report.setDate(new Date(getAlarmService()
208: .currentTimeMillis()));
209: report.setText(myRemoveFormat.format(getMessageArgs(
210: org, supportingRelationships)));
211:
212: System.out.println(report.getText());
213:
214: publishAdd(report);
215: }
216: }
217: }
218:
219: private static Role SUPERIOR = Role.getRole("Superior");
220:
221: /**
222: * findSupportingRelationships - returns all supporting relationships for
223: * the specified organization
224: *
225: * @param org Organization
226: * @return Collection supporting relationships
227: */
228: private Collection findSupportingRelationships(Organization org) {
229: RelationshipSchedule schedule = org.getRelationshipSchedule();
230:
231: Collection subordinates = org.getSubordinates(
232: TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
233:
234: Collection providers = schedule.getMatchingRelationships(
235: Constants.RelationshipType.PROVIDER_SUFFIX,
236: TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
237:
238: ArrayList supporting = new ArrayList(providers);
239:
240: for (Iterator iterator = subordinates.iterator(); iterator
241: .hasNext();) {
242: supporting.add(iterator.next());
243: }
244:
245: return supporting;
246: }
247:
248: /**
249: * getMessageArgs - returns array of message arguments to be used
250: * with message formats.
251: * Changes to message formats must be coordinated with changes to
252: * getMessageArgs.
253: *
254: * @param org Organization
255: * @return String[] info from org which will be used by the message
256: * formattor.
257: */
258: private String[] getMessageArgs(Organization org,
259: Collection supportingRelationships) {
260: //myMessageArgs[0] set to cluster name
261:
262: myMessageArgs[1] = getName(org);
263:
264: boolean first = true;
265: String supportInfo = "";
266: RelationshipSchedule schedule = org.getRelationshipSchedule();
267: for (Iterator iterator = supportingRelationships.iterator(); iterator
268: .hasNext();) {
269: Relationship relationship = (Relationship) iterator.next();
270: String start = (relationship.getStartTime() == TimeSpan.MIN_VALUE) ? "TimeSpan.MIN_VALUE"
271: : new Date(relationship.getStartTime()).toString();
272: String end = (relationship.getEndTime() == TimeSpan.MAX_VALUE) ? "TimeSpan.MAX_VALUE"
273: : new Date(relationship.getEndTime()).toString();
274:
275: String text = supportInfo + " "
276: + schedule.getOtherRole(relationship) + " "
277: + schedule.getOther(relationship) + " start:"
278: + start + " end:" + end;
279: if (first) {
280: supportInfo = text;
281: first = false;
282: } else {
283: supportInfo = supportInfo + ", " + text;
284: }
285: }
286:
287: myMessageArgs[2] = supportInfo;
288: return myMessageArgs;
289: }
290:
291: /**
292: * getName - return organization's name
293: *
294: * @param org Organization
295: * @return String
296: */
297: private static String getName(Organization org) {
298: ItemIdentificationPG itemIdentificationPG = org
299: .getItemIdentificationPG();
300:
301: return itemIdentificationPG.getNomenclature();
302: }
303: }
|