001: /*--------------------------------------------------------------------------
002: * <copyright>
003: *
004: * Copyright 1999-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: package org.cougaar.glm.plugins;
027:
028: import org.cougaar.core.blackboard.IncrementalSubscription;
029: import org.cougaar.core.util.UID;
030: import org.cougaar.glm.ldm.oplan.Oplan;
031: import org.cougaar.glm.ldm.oplan.OrgActivity;
032: import org.cougaar.glm.ldm.plan.GeolocLocation;
033: import org.cougaar.planning.ldm.plan.ContextOfUIDs;
034: import org.cougaar.util.UnaryPredicate;
035:
036: import java.util.Collection;
037: import java.util.Enumeration;
038: import java.util.HashMap;
039: import java.util.Iterator;
040: import java.util.Map;
041: import java.util.Vector;
042:
043: /**
044: * Defines common functions described in SimplePlugin.
045: * The plugin is decorated with the proper BasicProcessor at run time
046: * by the PluginDecorator.
047: * @see PluginDecorator
048: */
049: public abstract class GLMDecorationPlugin extends DecorationPlugin {
050: private static final String SYNCHRONOUS_MODE_PROP = "org.cougaar.glm.plugins.synchronous";
051: /**
052: * Map keyed by OPlan UID of ClusterOPlans *
053: */
054: public Map ClusterOPlans_ = new HashMap();
055: public IncrementalSubscription oplans_;
056: public boolean oplanChanged_ = false, orgActChanged_ = false,
057: clusterOplanChanged_ = false;
058: /**
059: * Map keyed by OPlan UID to an org activity subscription *
060: */
061: private Map orgActivitySubscriptionOfOPlanUID = new HashMap();
062:
063: // oplan
064: static class OplanPredicate implements UnaryPredicate {
065: public boolean execute(Object o) {
066: return (o instanceof Oplan);
067: }
068: }
069:
070: static class OplanOrgActivitiesPredicate implements UnaryPredicate {
071: UID oplanUID_;
072:
073: public OplanOrgActivitiesPredicate(UID uid) {
074: oplanUID_ = uid;
075: }
076:
077: public boolean execute(Object o) {
078: if (o instanceof OrgActivity) {
079: if (oplanUID_.equals(((OrgActivity) o).getOplanUID())) {
080: return true;
081: }
082: }
083: return false;
084: }
085: }
086:
087: private void getClusterOPlans() {
088: Collection c = query(new UnaryPredicate() {
089: public boolean execute(Object o) {
090: return o instanceof ClusterOPlan;
091: }
092: });
093: for (Iterator i = c.iterator(); i.hasNext();) {
094: ClusterOPlan coplan = (ClusterOPlan) i.next();
095: ClusterOPlans_.put(coplan.getOplanUID(), coplan);
096: //ClusterOPlans_.put(oplanUID, coplan);
097:
098: UID oplanUID = coplan.getOplanUID();
099: IncrementalSubscription oplanActivities = (IncrementalSubscription) orgActivitySubscriptionOfOPlanUID
100: .get(oplanUID);
101: if (oplanActivities == null) {
102: oplanActivities = (IncrementalSubscription) subscribe(new OplanOrgActivitiesPredicate(
103: oplanUID));
104: monitorPluginSubscription(oplanActivities);
105: orgActivitySubscriptionOfOPlanUID.put(oplanUID,
106: oplanActivities);
107: }
108: }
109: }
110:
111: protected void setupSubscriptions() {
112: super .setupSubscriptions();
113: oplans_ = (IncrementalSubscription) subscribe(new OplanPredicate());
114: monitorPluginSubscription(oplans_);
115:
116: if (didRehydrate()) {
117: getClusterOPlans();
118: doUpdateOplans();
119: }
120: }
121:
122: private static Object syncLock = new Object();
123: private static boolean syncLocked = false;
124: private static boolean synchronousMode = System.getProperty(
125: SYNCHRONOUS_MODE_PROP, "false").equals("true");
126:
127: private void syncStart() {
128: synchronized (syncLock) {
129: while (syncLocked) {
130: try {
131: syncLock.wait();
132: } catch (InterruptedException ie) {
133: }
134: }
135: syncLocked = true;
136: }
137: if (logger.isDebugEnabled()) {
138: logger.debug("---------- BEGIN execute() "
139: + getShortClassName() + "(" + clusterId_ + ")"
140: + " ----------");
141: }
142: }
143:
144: private void syncFinish() {
145: if (logger.isDebugEnabled()) {
146: logger.debug("------------ END execute() "
147: + getShortClassName() + "(" + clusterId_ + ")"
148: + " ----------");
149: }
150: synchronized (syncLock) {
151: syncLocked = false;
152: syncLock.notify();
153: }
154: }
155:
156: private String shortClassName = null;
157:
158: private String getShortClassName() {
159: if (shortClassName == null) {
160: String s = getClass().getName();
161: int ix = s.lastIndexOf('.');
162: if (ix >= 0)
163: s = s.substring(ix + 1);
164: shortClassName = s;
165: }
166: return shortClassName;
167: }
168:
169: /**
170: * Invokes all of the processors used to decorate this plugin.
171: * The first time execute() is invoked, it configures the plugin by
172: * setting the task processor, and unsubscribing to 'self'
173: * (subscribed in setSubscriptions()).
174: */
175: public synchronized void execute() {
176: if (synchronousMode)
177: syncStart();
178: try {
179: super .execute();
180: if (!invoke_)
181: return;
182: oplanChanged_ = false;
183: orgActChanged_ = false;
184: clusterOplanChanged_ = updateOplans();
185: orgActChanged_ = updateOrgActivities();
186: oplanChanged_ = clusterOplanChanged_ || orgActChanged_;
187: runProcessors();
188: } finally {
189: if (synchronousMode)
190: syncFinish();
191: }
192: }
193:
194: private boolean updateOplans() {
195: boolean oplanChange = false;
196: if (logger.isDebugEnabled()) {
197: logger.debug("starting updateOplans");
198: }
199: if (isSubscriptionChanged(oplans_)) {
200: doUpdateOplans();
201: oplanChange = true;
202: }
203: return oplanChange;
204: }
205:
206: // Process Oplan subscription
207: private void doUpdateOplans() {
208: if (logger.isDebugEnabled()) {
209: logger.debug("Updating the Oplans!");
210: }
211: Enumeration en;
212: // Create new ClusterOPlan objects for each added Oplan
213: if (oplans_.getAddedList().hasMoreElements()) {
214: en = oplans_.getAddedList();
215: while (en.hasMoreElements()) {
216: Oplan oplan = (Oplan) en.nextElement();
217: UID oplanUID = oplan.getUID();
218: IncrementalSubscription oplanActivities = (IncrementalSubscription) orgActivitySubscriptionOfOPlanUID
219: .get(oplanUID);
220: if (oplanActivities == null) {
221: oplanActivities = (IncrementalSubscription) subscribe(new OplanOrgActivitiesPredicate(
222: oplanUID));
223: monitorPluginSubscription(oplanActivities);
224: orgActivitySubscriptionOfOPlanUID.put(oplanUID,
225: oplanActivities);
226: }
227: ClusterOPlan coplan = (ClusterOPlan) ClusterOPlans_
228: .get(oplanUID);
229: if (coplan == null) {
230: coplan = new ClusterOPlan(clusterId_, oplan);
231: ClusterOPlans_.put(oplanUID, coplan);
232: publishAdd(coplan);
233: }
234: }
235: }
236: // Remove ClusterOPlan objects that are no longer relevant
237: if (oplans_.getRemovedList().hasMoreElements()) {
238: en = oplans_.getRemovedList();
239: while (en.hasMoreElements()) {
240: Oplan oplan = (Oplan) en.nextElement();
241: UID oplanUID = oplan.getUID();
242: ClusterOPlan coplan = (ClusterOPlan) ClusterOPlans_
243: .get(oplanUID);
244: // Remove ClusterOPlan from array
245: ClusterOPlans_.remove(oplanUID);
246: // Cancel subscription
247: IncrementalSubscription s = (IncrementalSubscription) orgActivitySubscriptionOfOPlanUID
248: .remove(oplanUID);
249: if (s != null)
250: unsubscribe(s);
251: publishRemove(coplan);
252: break;
253: }
254: }
255: if (ClusterOPlans_.isEmpty()) {
256: if (logger.isErrorEnabled()) {
257: logger.error(" updateOplans no OPLAN");
258: }
259: }
260: }
261:
262: // Each ClusterOPlan updates its own OrgActivities if needed
263: private boolean updateOrgActivities() {
264: Iterator en = ClusterOPlans_.values().iterator();
265: boolean update = false;
266: while (en.hasNext()) {
267: ClusterOPlan coplan = (ClusterOPlan) en.next();
268: IncrementalSubscription s = (IncrementalSubscription) orgActivitySubscriptionOfOPlanUID
269: .get(coplan.getOplanUID());
270: update = update || coplan.updateOrgActivities(s);
271: }
272: return update;
273: }
274:
275: public Vector getOPlans() {
276: return new Vector(ClusterOPlans_.values());
277: }
278:
279: public ClusterOPlan findOPlan(UID oplanUID) {
280: return (ClusterOPlan) ClusterOPlans_.get(oplanUID);
281: }
282:
283: public ClusterOPlan findOPlan(Oplan oplan) {
284: return findOPlan(oplan.getUID());
285: }
286:
287: // returns location from first oplan w/ info on that time.
288: public GeolocLocation getGeoLoc(long time) {
289: Enumeration oplans = getOPlans().elements();
290: ClusterOPlan oplan;
291: GeolocLocation geo;
292: while (oplans.hasMoreElements()) {
293: oplan = (ClusterOPlan) oplans.nextElement();
294: geo = oplan.getGeoLoc(time);
295: if (geo != null)
296: return geo;
297: }
298: return null;
299:
300: }
301:
302: public boolean oplanChanged() {
303: return oplanChanged_;
304: }
305:
306: public ClusterOPlan getOperativeOPlan(long time,
307: ContextOfUIDs context) {
308: // GLMDebug.DEBUG(this.getClass().getName(), clusterId_,"getOperativeOPlan- context is: " + context);
309: for (int i = 0, n = context.size(); i < n; i++) {
310: ClusterOPlan oplan = findOPlan(context.get(i));
311: if (oplan != null) {
312: if ((oplan.getStartTime() <= time)
313: && (oplan.getEndTime() > time)) {
314: return oplan;
315: }
316: }
317: }
318: return null;
319: }
320:
321: }
|