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: package org.cougaar.mlm.plugin.sample;
027:
028: import java.awt.Container;
029: import java.awt.GridBagConstraints;
030: import java.awt.GridBagLayout;
031: import java.text.NumberFormat;
032: import java.util.Enumeration;
033: import java.util.HashMap;
034: import java.util.HashSet;
035: import java.util.Iterator;
036: import java.util.TreeSet;
037:
038: import javax.swing.JFrame;
039: import javax.swing.JLabel;
040: import javax.swing.JScrollPane;
041: import javax.swing.JTextArea;
042:
043: import org.cougaar.core.blackboard.IncrementalSubscription;
044: import org.cougaar.mlm.plugin.UICoordinator;
045: import org.cougaar.planning.ldm.plan.Alert;
046: import org.cougaar.planning.ldm.plan.Allocation;
047: import org.cougaar.planning.ldm.plan.AllocationResult;
048: import org.cougaar.planning.ldm.plan.NewAlert;
049: import org.cougaar.planning.ldm.plan.NewAlertParameter;
050: import org.cougaar.planning.plugin.legacy.SimplePlugin;
051: import org.cougaar.util.UnaryPredicate;
052:
053: /**
054: * The AllocationsAssessorPlugin publishes an Alert for each
055: * failed allocations in it's collection
056: *
057: *
058: */
059:
060: public class AllocationAssessorPlugin extends SimplePlugin {
061: private static final boolean BRIEF = false; // True for task id only
062:
063: /** frame displaying messages **/
064: private JFrame frame;
065:
066: static NumberFormat confidenceFormat = NumberFormat
067: .getPercentInstance();
068:
069: /** Display Allocation Results **/
070: JTextArea failedTaskIds = new JTextArea(6, 30);
071: JLabel allocCountLabel = new JLabel(" 0 failed allocations");
072: JScrollPane failedTaskPane = new JScrollPane(failedTaskIds,
073: JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
074: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
075:
076: /** Display Allocation Results **/
077: JTextArea succeededTaskIds = new JTextArea(6, 30);
078: JLabel succeededCountLabel = new JLabel(
079: " 0 successful allocations");
080: JScrollPane succeededTaskPane = new JScrollPane(succeededTaskIds,
081: JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
082: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
083:
084: /** Subscription to hold collection of input tasks **/
085: private IncrementalSubscription myalloc;
086:
087: /** Keep track of Allocations that come through. **/
088: private HashMap allocationAlerts = new HashMap();
089:
090: private HashSet allocationSuccesses = new HashSet();
091:
092: /** Look for failed allocations **/
093: private static UnaryPredicate allocPred() {
094: return new UnaryPredicate() {
095: public boolean execute(Object o) {
096: return (o instanceof Allocation);
097: }
098: };
099: }
100:
101: /** GUI to display failed allocation info **/
102: private void createGUI() {
103: frame = new JFrame("AllocationAssessorPlugin for "
104: + getMessageAddress());
105: Container panel = frame.getContentPane();
106: panel.setLayout(new GridBagLayout());
107: GridBagConstraints gbc = new GridBagConstraints();
108: gbc.weightx = 1.0;
109: gbc.fill = GridBagConstraints.HORIZONTAL;
110: gbc.gridx = 0;
111: gbc.gridy = 0;
112: panel.add(allocCountLabel, gbc);
113: gbc.gridy = 2;
114: panel.add(succeededCountLabel, gbc);
115: gbc.gridy = 1;
116: gbc.fill = GridBagConstraints.BOTH;
117: gbc.weighty = 1.0;
118: panel.add(failedTaskPane, gbc);
119: gbc.gridy = 3;
120: panel.add(succeededTaskPane, gbc);
121: frame.pack();
122: UICoordinator.setBounds(frame);
123: frame.setVisible(true);
124: }
125:
126: /**
127: * Overrides the setupSubscriptions() in the SimplePlugin.
128: */
129: protected void setupSubscriptions() {
130: getSubscriber().setShouldBePersisted(false);
131: myalloc = (IncrementalSubscription) subscribe(allocPred());
132: createGUI();
133: }
134:
135: private String getAllocationString(Allocation alloc) {
136: String confidence = "";
137: AllocationResult ar = alloc.getReportedResult();
138: if (ar == null) {
139: confidence = "<no result>";
140: } else {
141: confidence = confidenceFormat.format(ar
142: .getConfidenceRating())
143: + " ";
144: }
145: if (BRIEF) {
146: return confidence + alloc.getTask().getUID().toString();
147: } else {
148: return confidence + alloc.getTask().toString();
149: }
150: }
151:
152: private void updateGUI() {
153: allocCountLabel.setText(allocationAlerts.size()
154: + " failed allocations");
155: TreeSet names = new TreeSet();
156: for (Iterator iter = allocationAlerts.keySet().iterator(); iter
157: .hasNext();) {
158: names.add(getAllocationString((Allocation) iter.next()));
159: }
160: StringBuffer buf = new StringBuffer();
161: for (Iterator iter = names.iterator(); iter.hasNext();) {
162: buf.append(iter.next());
163: buf.append("\n");
164: }
165: String newText = buf.substring(0);
166: if (!failedTaskIds.equals(newText)) {
167: failedTaskIds.setText(newText);
168: }
169: succeededCountLabel.setText(allocationSuccesses.size()
170: + " successful allocations");
171: names.clear();
172: for (Iterator iter = allocationSuccesses.iterator(); iter
173: .hasNext();) {
174: names.add(getAllocationString((Allocation) iter.next()));
175: }
176: buf.setLength(0);
177: for (Iterator iter = names.iterator(); iter.hasNext();) {
178: buf.append(iter.next());
179: buf.append("\n");
180: }
181: newText = buf.substring(0);
182: if (!succeededTaskIds.getText().equals(newText)) {
183: succeededTaskIds.setText(newText);
184: }
185: }
186:
187: /** Creates and publishes alert for failed allocations **/
188: public void createAlert(Allocation alloc) {
189: NewAlert alert = theLDMF.newAlert();
190: NewAlertParameter[] params = new NewAlertParameter[1];
191: params[0] = theLDMF.newAlertParameter();
192: params[0].setParameter(alloc);
193: params[0].setDescription("Failed Allocation");
194: alert
195: .setAlertText("Allocation Failed for :"
196: + alloc.toString());
197: alert.setAlertParameters(params);
198: publishAdd(alert);
199: allocationAlerts.put(alloc, alert);
200: }
201:
202: public void removeAlert(Allocation alloc) {
203: Alert alert = (Alert) allocationAlerts.get(alloc);
204: if (alert == null)
205: return; // Shouldn't happen
206: publishRemove(alert);
207: allocationAlerts.remove(alloc);
208: }
209:
210: private void addFailedDisposition(Allocation alloc) {
211: if (allocationAlerts.containsKey(alloc))
212: return;
213: createAlert(alloc);
214: }
215:
216: private void removeFailedDisposition(Allocation alloc) {
217: if (!allocationAlerts.containsKey(alloc))
218: return;
219: removeAlert(alloc);
220: }
221:
222: private void addSucceededAllocation(Allocation alloc) {
223: if (allocationSuccesses.contains(alloc))
224: return;
225: allocationSuccesses.add(alloc);
226: }
227:
228: private void removeSucceededAllocation(Allocation alloc) {
229: if (!allocationSuccesses.contains(alloc))
230: return;
231: allocationSuccesses.remove(alloc);
232: }
233:
234: private void removeAllocation(Allocation alloc) {
235: removeFailedDisposition(alloc);
236: removeSucceededAllocation(alloc);
237: }
238:
239: private boolean checkAllocations(Enumeration allocations,
240: boolean addOk) {
241: boolean doUpdate = false;
242: while (allocations.hasMoreElements()) {
243: Allocation alloc = (Allocation) allocations.nextElement();
244: if (!addOk) {
245: if (!allocationAlerts.containsKey(alloc)
246: && !allocationSuccesses.contains(alloc)) {
247: continue; // Probably rescinded
248: }
249: }
250: AllocationResult ar = alloc.getReportedResult();
251: if (ar == null || ar.isSuccess()) {
252: removeFailedDisposition(alloc);
253: addSucceededAllocation(alloc);
254: } else {
255: removeSucceededAllocation(alloc);
256: addFailedDisposition(alloc);
257: }
258: doUpdate = true;
259: }
260: return doUpdate;
261: }
262:
263: private boolean removeAllocations(Enumeration allocations) {
264: boolean doUpdate = false;
265: while (allocations.hasMoreElements()) {
266: Allocation alloc = (Allocation) allocations.nextElement();
267: removeAllocation(alloc);
268: doUpdate = true;
269: }
270: return doUpdate;
271: }
272:
273: /* CCV2 execute method */
274: /* This will be called every time a alloc matches the above predicate */
275: /* Note: Failed Allocations only come through on the changed list.
276: Since Allocations are changed by other Plugins after we see them
277: here, we need to keep track of the ones we've seen so we don't
278: act on them more than once.
279: */
280: public synchronized void execute() {
281: boolean doUpdate = false;
282: doUpdate |= checkAllocations(myalloc.getAddedList(), true);
283: doUpdate |= checkAllocations(myalloc.getChangedList(), false);
284: doUpdate |= removeAllocations(myalloc.getRemovedList());
285: if (doUpdate)
286: updateGUI();
287: }
288: }
|