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.generic;
028:
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.Hashtable;
032: import java.util.Iterator;
033: import java.util.Set;
034: import java.util.Vector;
035:
036: import org.cougaar.core.blackboard.AnonymousChangeReport;
037: import org.cougaar.core.blackboard.ChangeReport;
038: import org.cougaar.core.blackboard.IncrementalSubscription;
039: import org.cougaar.glm.ldm.asset.Organization;
040: import org.cougaar.planning.ldm.plan.RelationshipSchedule;
041: import org.cougaar.planning.ldm.plan.Transferable;
042: import org.cougaar.planning.ldm.plan.TransferableTransfer;
043: import org.cougaar.planning.plugin.legacy.SimplePlugin;
044: import org.cougaar.util.ConfigFinder;
045: import org.cougaar.util.Filters;
046: import org.cougaar.util.UnaryPredicate;
047: import org.w3c.dom.Document;
048: import org.w3c.dom.Element;
049: import org.w3c.dom.Node;
050: import org.w3c.dom.NodeList;
051:
052: /**
053: * PropagationPlugin propagates Transferables based on xml files in parameter list
054: *
055: *
056: */
057:
058: public class PropagationPlugin extends SimplePlugin {
059:
060: private Vector roles = new Vector();
061:
062: private IncrementalSubscription organizations;
063:
064: private ArrayList subscriptionCollection;
065:
066: private static UnaryPredicate allOrganizationPred = new UnaryPredicate() {
067: public boolean execute(Object o) {
068: if (o instanceof Organization) {
069: return true;
070: } else {
071: return false;
072: }
073: }
074: };
075:
076: protected void setupSubscriptions() {
077:
078: organizations = (IncrementalSubscription) subscribe(allOrganizationPred);
079:
080: subscriptionCollection = new ArrayList(13);
081: Vector pv = getParameters();
082: if ((pv == null) || (pv.size() == 0)) {
083: throw new RuntimeException(
084: "PropagationPlugin requires a parameter");
085: } else {
086: for (Iterator pi = pv.iterator(); pi.hasNext();) {
087: String xmlfilename = (String) pi.next();
088: parseFile(xmlfilename);
089: }
090: }
091: }
092:
093: protected void transfer(Transferable t, Organization org) {
094: if ((t == null) || (org == null))
095: return;
096:
097: TransferableTransfer tt;
098: try {
099: tt = theLDMF.createTransferableTransfer(t, org);
100: } catch (Exception e) {
101: return;
102: }
103: if (tt == null) {
104: } else {
105: publishAdd(tt);
106: }
107: }
108:
109: public synchronized void execute() {
110:
111: for (Iterator subIt = subscriptionCollection.iterator(); subIt
112: .hasNext();) {
113: TransferableSubscriptions currentSubscriptions = (TransferableSubscriptions) subIt
114: .next();
115:
116: UnaryPredicate destPred = currentSubscriptions
117: .getDestinationPredicate();
118: ArrayList alreadySent = new ArrayList();
119:
120: if (organizations.hasChanged()) {
121: Collection adds = organizations.getAddedCollection();
122: if (adds != null) {
123: for (Iterator iterator = Filters.filter(adds,
124: destPred).iterator(); iterator.hasNext();) {
125: Organization org = (Organization) iterator
126: .next();
127:
128: // Transfer all existing transferables to a new destination
129: for (Iterator transferables = currentSubscriptions
130: .getTransferableSubscription()
131: .getCollection().iterator(); transferables
132: .hasNext();) {
133: transfer((Transferable) transferables
134: .next(), org);
135: }
136: alreadySent.add(org);
137: }
138: }
139:
140: // BOZO - Missing logic to rescind transferables from destinations
141: // which are no longer valid. Also sending all transferables each
142: // time a valid destination changes.
143: Collection changes = organizations
144: .getChangedCollection();
145: if (changes != null) {
146: for (Iterator iterator = Filters.filter(changes,
147: destPred).iterator(); iterator.hasNext();) {
148: Organization org = (Organization) iterator
149: .next();
150: boolean isRelationshipChange = false;
151: Set changeReports = organizations
152: .getChangeReports(org);
153: if ((changeReports != AnonymousChangeReport.SET)
154: && (changeReports != null)) {
155: for (Iterator i = changeReports.iterator(); i
156: .hasNext();) {
157: ChangeReport changeReport = (ChangeReport) i
158: .next();
159: if (changeReport instanceof RelationshipSchedule.RelationshipScheduleChangeReport) {
160: isRelationshipChange = true;
161: break;
162: }
163: }
164: }
165: if (isRelationshipChange) {
166: for (Iterator transferables = currentSubscriptions
167: .getTransferableSubscription()
168: .getCollection().iterator(); transferables
169: .hasNext();) {
170: transfer((Transferable) transferables
171: .next(), org);
172: }
173: alreadySent.add(org);
174: }
175: }
176: }
177:
178: // BOZO - No logic to rescind transferable from organizations which
179: // have been removed
180:
181: }
182:
183: IncrementalSubscription ts = currentSubscriptions
184: .getTransferableSubscription();
185:
186: if (ts.hasChanged()) {
187: Collection destinations = Filters.filter(organizations
188: .getCollection(), destPred);
189:
190: Collection adds = ts.getAddedCollection();
191: if (adds != null) {
192: for (Iterator transferables = ts
193: .getAddedCollection().iterator(); transferables
194: .hasNext();) {
195: Transferable t = (Transferable) transferables
196: .next();
197:
198: Iterator iterator = destinations.iterator();
199: while (iterator.hasNext()) {
200: Organization org = (Organization) iterator
201: .next();
202: // we already sent these
203: if (!alreadySent.contains(org))
204: transfer(t, org);
205: }
206: }
207: }
208:
209: // send modified transferable to existing destinations;
210: Collection changes = ts.getChangedCollection();
211: if (changes != null) {
212: for (Iterator transferables = ts
213: .getChangedCollection().iterator(); transferables
214: .hasNext();) {
215: Transferable t = (Transferable) transferables
216: .next();
217:
218: Iterator iterator = destinations.iterator();
219: while (iterator.hasNext()) {
220: Organization org = (Organization) iterator
221: .next();
222: transfer(t, org);
223: }
224: }
225: }
226: }
227: }
228: }
229:
230: private void parseFile(String xmlfilename) {
231: Document doc;
232:
233: try {
234: doc = ConfigFinder.getInstance().parseXMLConfigFile(
235: xmlfilename);
236: if (doc == null) {
237: System.err.println("XML Parser could not handle file "
238: + xmlfilename);
239: return;
240: }
241: } catch (Exception e) {
242: e.printStackTrace();
243: return;
244: }
245:
246: Element root = doc.getDocumentElement();
247: Hashtable transferableSubscriptions = new Hashtable(13);
248:
249: if (root.getNodeName().equals("Propagations")) {
250: NodeList nlist = root.getChildNodes();
251: int nlength = nlist.getLength();
252: for (int i = 0; i < nlength; i++) {
253: Node propNode = nlist.item(i);
254: if (propNode.getNodeType() == Node.ELEMENT_NODE) {
255: if (propNode.getNodeName().equals(
256: "TransferablePropagation")) {
257: String className = propNode.getAttributes()
258: .getNamedItem("class").getNodeValue();
259:
260: TransferablePredicate tp = null;
261: try {
262: Class cl = theLDM.getLDMClassLoader()
263: .loadClass(className);
264: /*
265: if (OplanContributor.class.isAssignableFrom(cl)) {
266: System.err.println("Warning: "+xmlfilename+
267: " specifies propagation of OplanContributor \""+
268: className+"\": Will ignore.");
269: // leave tp alone to bail out.
270: } else { */
271: tp = new TransferablePredicate(cl);
272: //}
273: } catch (Exception e) {
274: e.printStackTrace();
275: }
276: if (tp != null) {
277: parseProp(propNode);
278: String caps[] = new String[roles.size()];
279: caps = (String[]) roles.toArray(caps);
280:
281: DestinationPredicate dp = new DestinationPredicate(
282: caps, getAgentIdentifier());
283:
284: IncrementalSubscription ts = (IncrementalSubscription) transferableSubscriptions
285: .get(tp);
286: if (ts == null) {
287: ts = (IncrementalSubscription) subscribe(tp);
288: transferableSubscriptions.put(tp, ts);
289: }
290:
291: TransferableSubscriptions fh = new TransferableSubscriptions(
292: ts, dp);
293: subscriptionCollection.add(fh);
294: }
295: }
296: }
297: }
298: }
299: }
300:
301: private void parseProp(Node propNode) {
302: roles = new Vector();
303: NodeList nlist = propNode.getChildNodes();
304: int nlength = nlist.getLength();
305: for (int i = 0; i < nlength; i++) {
306: Node subNode = nlist.item(i);
307: if (subNode.getNodeType() == Node.ELEMENT_NODE) {
308: if (subNode.getNodeName().equals("role")) {
309: String value = subNode.getFirstChild()
310: .getNodeValue();
311: roles.add(value.trim());
312: } else
313: System.out.println(subNode.getNodeName());
314: }
315: }
316: }
317: }
|