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.debug.ui;
028:
029: import java.awt.event.ActionEvent;
030: import java.awt.event.ActionListener;
031: import java.util.Date;
032: import java.util.Enumeration;
033: import java.util.Vector;
034:
035: import org.cougaar.core.blackboard.IncrementalSubscription;
036: import org.cougaar.core.mts.MessageAddress;
037: import org.cougaar.glm.ldm.asset.PhysicalAsset;
038: import org.cougaar.planning.ldm.asset.AggregateAsset;
039: import org.cougaar.planning.ldm.asset.Asset;
040: import org.cougaar.util.UnaryPredicate;
041:
042: /** Creates the values for a bar graph displaying assets owned by the cluster.
043: */
044:
045: public class UIAssets implements UIBarGraphSource, UISubscriber {
046: private UIPlugin uiPlugin;
047: private Vector listeners;
048: private MessageAddress clusterId;
049: private Date startDate;
050: private int numberOfXIntervals;
051: private String xLegend;
052: private String xLabels[];
053: private int numberOfYIntervals;
054: private String yLegend;
055: private String yLabels[];
056: private String legend[] = new String[0]; // not used
057: private int numberOfBars;
058: // for each bar, the y-value for the xth interval
059: private int values[][] = new int[1][];
060: private boolean contiguous;
061: private Vector myAssets = new Vector(10);
062:
063: /** Display the assets assigned to the cluster in a bar graph.
064: The x-axis is type of asset (i.e. truck, tank, HET) and
065: the y-axis is the quantity of that asset.
066: @param uiPlugin this user interface plugin
067: @param planName the name of the plan for which to display assets
068: @param clusterId the cluster for which to display assets
069: @exception UINoPlanException thrown when the plan does not exist
070: */
071:
072: public UIAssets(UIPlugin uiPlugin, String planName,
073: MessageAddress clusterId, Object listener)
074: throws UINoPlanException {
075: listeners = new Vector(1);
076: listeners.addElement(listener);
077: this .uiPlugin = uiPlugin;
078: contiguous = false; // don't make bars in bar graph contiguous
079: }
080:
081: /** Can't start subscription in constructor, because you could
082: get a subscriptionChanged before the UIBarGraphDisplay is ready.
083: */
084:
085: public void startSubscription() {
086: uiPlugin.subscribe(this , assetPredicate());
087: }
088:
089: private static UnaryPredicate assetPredicate() {
090: return new UnaryPredicate() {
091: public boolean execute(Object o) {
092: //System.out.println("Predicate called with: " + o.toString());
093: return (o instanceof Asset);
094: }
095: };
096: }
097:
098: public synchronized void subscriptionChanged(
099: IncrementalSubscription container) {
100: //System.out.println("Container changed");
101: Enumeration added = container.getAddedList();
102: while (added.hasMoreElements())
103: myAssets.addElement(added.nextElement());
104: Enumeration removed = container.getRemovedList();
105: while (removed.hasMoreElements())
106: myAssets.removeElement(removed.nextElement());
107: recomputeAssets();
108: //////////////////////
109: // clusterCollection = uiPlugin.getClusterCollection(clusterId);
110: // plan = clusterCollection.getPlan(planName);
111: // if (plan == null)
112: // throw new UINoPlanException("There is no plan in cluster: " +
113: // clusterId.getAddress() +
114: // " named: " + planName);
115: // computeAssets();
116: //////////////////////
117: }
118:
119: private void computeAssets() {
120: Vector assetNames = new Vector(10);
121: Vector assetCounts = new Vector(10);
122: // count the assets
123: for (int j = 0; j < myAssets.size(); j++) {
124: Asset asset = (Asset) myAssets.elementAt(j);
125: if (asset instanceof AggregateAsset) {
126: AggregateAsset aa = (AggregateAsset) asset;
127: String name = UIAsset.getName(aa.getAsset());
128: if ((name == null) || name.equals(""))
129: continue;
130: int quantity = 1;
131: quantity = (int) aa.getQuantity();
132: int i = assetNames.indexOf(name);
133: if (i == -1) {
134: assetNames.addElement(name);
135: assetCounts.addElement(new Integer(quantity));
136: } else {
137: Integer count = (Integer) assetCounts.elementAt(i);
138: assetCounts.setElementAt(new Integer(count
139: .intValue()
140: + quantity), i);
141: }
142:
143: } else if (asset instanceof PhysicalAsset) {
144: String name = UIAsset.getName(asset);
145: if ((name == null) || name.equals(""))
146: continue;
147: int i = assetNames.indexOf(name);
148: if (i == -1) {
149: assetNames.addElement(name);
150: assetCounts.addElement(new Integer(1));
151: } else {
152: Integer count = (Integer) assetCounts.elementAt(i);
153: assetCounts.setElementAt(new Integer(count
154: .intValue() + 1), i);
155: }
156: }
157: }
158: int nAssets = assetNames.size();
159: xLegend = "Assets";
160: yLegend = "Quantity";
161: numberOfXIntervals = nAssets;
162: xLabels = new String[nAssets];
163: assetNames.copyInto(xLabels);
164: values[0] = new int[nAssets];
165: for (int i = 0; i < nAssets; i++) {
166: Integer count = (Integer) assetCounts.elementAt(i);
167: values[0][i] = count.intValue();
168: }
169: int maxAssetCount = 0;
170: for (int i = 0; i < nAssets; i++)
171: maxAssetCount = Math.max(maxAssetCount, values[0][i]);
172: numberOfYIntervals = maxAssetCount;
173: yLabels = new String[numberOfYIntervals];
174: for (int i = 0; i < numberOfYIntervals; i++)
175: yLabels[i] = String.valueOf(i + 1);
176: }
177:
178: /** Number of different assets.
179: @return number of different assets
180: */
181:
182: public int getNumberOfXIntervals() {
183: return numberOfXIntervals;
184: }
185:
186: /** "Assets"
187: @return "Assets"
188: */
189:
190: public String getXLegend() {
191: return xLegend;
192: }
193:
194: /** Asset names.
195: @return names of the assets
196: */
197:
198: public String[] getXLabels() {
199: return xLabels;
200: }
201:
202: /** Maximum quantity of any one asset.
203: @return maximum quantity of any one asset
204: */
205:
206: public int getNumberOfYIntervals() {
207: return numberOfYIntervals;
208: }
209:
210: /** "Quantity"
211: @return "Quantity"
212: */
213:
214: public String getYLegend() {
215: return yLegend;
216: }
217:
218: /** Quantity of assets.
219: @return numeric labels for quantities of assets
220: */
221:
222: public String[] getYLabels() {
223: return yLabels;
224: }
225:
226: /** Not used.
227: @return empty
228: */
229:
230: public String[] getLegend() {
231: return legend;
232: }
233:
234: /** Quantity of each asset.
235: @return for each asset (with the same name), the quantity of that asset
236: */
237:
238: public int[][] getValues() {
239: return values;
240: }
241:
242: /** Should the bars in the bar graph be contiguous.
243: @return false
244: */
245:
246: public boolean getContiguous() {
247: return contiguous;
248: }
249:
250: /** Listen for changes in type or number of assets assigned to the
251: cluster.
252: @param listener object to notify when assets change
253: */
254:
255: public void registerListener(ActionListener listener) {
256: // MIK
257: // listeners.addElement(listener);
258: }
259:
260: /** Handle added, deleted or changed events on the asset collection.
261: Update the information to display and notify any listeners on this object.
262: The UIBarGraphDisplay object listens for changes
263: and invokes methods in the UIBarGraph object to get
264: the updated values from this object and repaint the graph.
265: @param e event (new, changed, or deleted object)
266: */
267:
268: /*
269: public synchronized void dispatchEvent( ObjectEvent e)
270: {
271: handleEvent( e );
272: }
273: */
274: /*
275: private void handleEvent(ObjectEvent e)
276: {
277: switch( e.getEventID() )
278: {
279: case ObjectEvent.NEW_OBJECT:
280: processNewObjectEvent(e);
281: break;
282: case ObjectEvent.DELETE_OBJECT:
283: processDeleteObjectEvent(e);
284: break;
285: case ObjectEvent.CHANGE_OBJECT:
286: processChangedObjectEvent(e);
287: default:
288: System.err.println("Unrecognized event listener event: "+e);
289: break;
290: }
291: }
292: */
293:
294: /** In response to any addition, change or deletion to the assets,
295: recompute the information for the bar graph display
296: and notify listeners of the change.
297: The UIBarGraphDisplay object listens for changes
298: and invokes methods in the UIBarGraph object to get
299: the updated values from this object and repaint the graph.
300: */
301:
302: private void recomputeAssets() {
303: computeAssets();
304: for (int i = 0; i < listeners.size(); i++) {
305: ActionListener listener = (ActionListener) listeners
306: .elementAt(i);
307: listener.actionPerformed(new ActionEvent(this , 0, ""));
308: }
309: }
310:
311: /** New asset was added.
312: @param e the new object event
313: */
314:
315: /*
316: public synchronized void processNewObjectEvent(ObjectEvent e) {
317: recomputeAssets();
318: }
319: */
320:
321: /** Asset was changed.
322: @param e the change object event
323: */
324:
325: /* public synchronized void processChangedObjectEvent(ObjectEvent e) {
326: recomputeAssets();
327: }
328: */
329: /** Asset was deleted.
330: @param e the deleted object event
331: */
332:
333: /*
334: public synchronized void processDeleteObjectEvent(ObjectEvent e) {
335: recomputeAssets();
336: }
337: */
338:
339: /** Called to force an update of the asset information.
340: */
341:
342: public void update() {
343: recomputeAssets();
344: }
345: }
|