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.glm.execution.eg;
027:
028: import org.cougaar.util.OptionPane;
029: import org.cougaar.util.Random;
030: import org.cougaar.glm.execution.common.FailureConsumptionRate;
031:
032: import java.util.Enumeration;
033: import java.util.Hashtable;
034: import java.util.Properties;
035: import java.util.StringTokenizer;
036:
037: import java.awt.GridBagConstraints;
038: import java.awt.GridBagLayout;
039: import java.awt.event.ActionEvent;
040: import java.awt.event.ActionListener;
041:
042: import javax.swing.JComboBox;
043: import javax.swing.JComponent;
044: import javax.swing.JLabel;
045: import javax.swing.JPanel;
046: import javax.swing.JTextField;
047:
048: /**
049: * Example F/C plugin illustrating how one might write a plugin that
050: * applies to a certain class of supply and how to use the GUI
051: * configuration features. Consult the default plugin for more mundane
052: * matters.
053: **/
054: public class POLSpecialPlugin implements FailureConsumptionPlugin,
055: TimeConstants {
056:
057: private String prefix = "POL";
058: private static final long MIN_INTERVAL = ONE_DAY;
059:
060: private static final Random random = new Random();
061: private EventGenerator theEventGenerator = null;
062:
063: private static Hashtable consumers = new Hashtable();
064: private static Hashtable fuelTypes = new Hashtable();
065: private static Hashtable hash = new Hashtable();
066:
067: private JComboBox cb1 = new JComboBox();
068: private JComboBox cb2 = new JComboBox();
069: private JComboBox cb3 = new JComboBox();
070:
071: private JTextField start = new JTextField(20);
072: private JTextField end = new JTextField(20);
073: private JTextField mult = new JTextField(20);
074:
075: private class ComboBoxActionListener implements ActionListener {
076: public void actionPerformed(ActionEvent e) {
077: if ((cb1.getSelectedItem() != null)
078: && (cb2.getSelectedItem() != null)
079: && (cb3.getSelectedItem() != null)) {
080: TripletKey tk_temp = new TripletKey((String) fuelTypes
081: .get(cb1.getSelectedItem()), (String) consumers
082: .get(cb2.getSelectedItem()), (String) cb3
083: .getSelectedItem());
084: TripletValue tv = (TripletValue) hash.get(tk_temp);
085: if (tv != null) {
086: start.setText(new EGDate(tv.getStartDate())
087: .toString());
088: end.setText(new EGDate(tv.getEndDate()).toString());
089: mult.setText(new Double(tv.getMultiplier())
090: .toString());
091: } else {
092: start.setText("");
093: end.setText("");
094: mult.setText("");
095: }
096: }
097: }
098: }
099:
100: private class TripletKey {
101: private String fuelType;
102: private String consumer;
103: private String cluster;
104: private int hashCode;
105:
106: public TripletKey(String ft, String co, String cl) {
107: fuelType = ft;
108: consumer = co;
109: cluster = cl;
110: hashCode = ft.hashCode() + co.hashCode() + cl.hashCode();
111: }
112:
113: public String getFuelType() {
114: return fuelType;
115: }
116:
117: public String getConsumer() {
118: return consumer;
119: }
120:
121: public String getCluster() {
122: return cluster;
123: }
124:
125: public boolean equals(Object o) {
126: TripletKey tk = (TripletKey) o;
127: if (tk.getFuelType().equals(fuelType)
128: && tk.getConsumer().equals(consumer)
129: && tk.getCluster().equals(cluster)) {
130: return true;
131: } else {
132: return false;
133: }
134: }
135:
136: public int hashCode() {
137: return hashCode;
138: }
139: }
140:
141: private class TripletValue {
142: private long startDate;
143: private long endDate;
144: private double multiplier;
145:
146: public TripletValue(long start, long end, double mult) {
147: startDate = start;
148: endDate = end;
149: multiplier = mult;
150: }
151:
152: public long getStartDate() {
153: return startDate;
154: }
155:
156: public long getEndDate() {
157: return endDate;
158: }
159:
160: public double getMultiplier() {
161: return multiplier;
162: }
163: }
164:
165: private class POLItem extends FailureConsumptionPluginItem {
166: long previousTime = 0L;
167: TripletKey tk;
168: TripletKey tkAll;
169:
170: public POLItem(FailureConsumptionRate aRate,
171: long theExecutionTime,
172: FailureConsumptionSegment aSegment) {
173: super (aRate);
174: previousTime = Math.max(theExecutionTime,
175: aRate.theStartTime);
176: tk = new TripletKey(aRate.theItemIdentification,
177: aRate.theConsumerId, aSegment.theSource);
178: tkAll = new TripletKey(aRate.theItemIdentification,
179: aRate.theConsumerId, "All Clusters");
180: }
181:
182: private AnnotatedDouble getQPerMilli(long executionTime) {
183: if (executionTime - previousTime < MIN_INTERVAL) {
184: return new AnnotatedDouble(0.0);
185: }
186: double multiplier = 1.0;
187: TripletValue tv = (TripletValue) hash.get(tk);
188: if (tv == null) {
189: tv = (TripletValue) hash.get(tkAll);
190: }
191: if (tv != null) {
192: long startDate = tv.getStartDate();
193: long endDate = tv.getEndDate();
194: if (startDate <= executionTime
195: && endDate > executionTime) {
196: multiplier = tv.getMultiplier();
197: }
198: }
199: double result = ((theFailureConsumptionRate.theRateValue
200: * multiplier / theFailureConsumptionRate.theRateMultiplier) / ONE_DAY);
201: return new AnnotatedDouble(result);
202: }
203:
204: public AnnotatedDouble getQuantity(long executionTime) {
205: AnnotatedDouble v = getQPerMilli(executionTime);
206: if (v.value <= 0.0) {
207: v.value = 0.0;
208: return v;
209: }
210: long elapsed = executionTime - previousTime;
211: previousTime = executionTime;
212: v.value = random.nextPoisson(elapsed * v.value);
213: return v;
214: }
215:
216: public long getTimeQuantum(long executionTime) {
217: AnnotatedDouble v = getQPerMilli(executionTime);
218: return previousTime + ((long) (1.0 / v.value))
219: - executionTime;
220: }
221: }
222:
223: /**
224: * @return the name of this plugin
225: **/
226: public String getPluginName() {
227: return "POL Special";
228: }
229:
230: public String getDescription() {
231: return "Special plugin for POL items that uses a fixed rate";
232: }
233:
234: public boolean isConfigurable() {
235: return true;
236: }
237:
238: public void setParameter(String parameter) {
239: prefix = parameter; // parameter is item prefix.
240: }
241:
242: private static void addItem(JPanel message, int x, int y,
243: JComponent c) {
244: GridBagConstraints gbc = new GridBagConstraints();
245: gbc.gridx = x;
246: gbc.gridy = y;
247: gbc.anchor = gbc.WEST;
248: message.add(c, gbc);
249: }
250:
251: public void configure(java.awt.Component c) {
252: String fuelType;
253: String consumer;
254: String cluster;
255:
256: JPanel message = new JPanel(new GridBagLayout());
257:
258: cb1.addActionListener(new ComboBoxActionListener());
259: cb1.removeAllItems();
260: if (!fuelTypes.isEmpty()) {
261: Enumeration fuelTypesEnum = fuelTypes.keys();
262: while (fuelTypesEnum.hasMoreElements()) {
263: cb1.addItem(fuelTypesEnum.nextElement());
264: }
265: }
266:
267: cb2.addActionListener(new ComboBoxActionListener());
268: cb2.removeAllItems();
269: if (!consumers.isEmpty()) {
270: Enumeration consumersEnum = consumers.keys();
271: while (consumersEnum.hasMoreElements()) {
272: cb2.addItem(consumersEnum.nextElement());
273: }
274: }
275:
276: cb3.addActionListener(new ComboBoxActionListener());
277: cb3.removeAllItems();
278: if (theEventGenerator != null) {
279: // First, add an "All" option for clusters
280: cb3.addItem("All Clusters");
281:
282: // Get the cluster names from the EventGenerator and add to the list
283: String[] clusterNames = theEventGenerator.getClusterNames();
284: for (int i = 0; i < clusterNames.length; i++) {
285: cb3.addItem(clusterNames[i]);
286: }
287: }
288:
289: TripletKey tk_temp = new TripletKey((String) fuelTypes.get(cb1
290: .getSelectedItem()), (String) consumers.get(cb2
291: .getSelectedItem()), (String) cb3.getSelectedItem());
292: TripletValue tv = (TripletValue) hash.get(tk_temp);
293: if (tv != null) {
294: start.setText(new EGDate(tv.getStartDate()).toString());
295: end.setText(new EGDate(tv.getEndDate()).toString());
296: mult.setText(new Double(tv.getMultiplier()).toString());
297: } else {
298: start.setText("");
299: end.setText("");
300: mult.setText("");
301: }
302:
303: addItem(message, 0, 0, new JLabel("POL Item"));
304: addItem(message, 1, 0, cb1);
305:
306: addItem(message, 0, 1, new JLabel("Consumer"));
307: addItem(message, 1, 1, cb2);
308:
309: addItem(message, 0, 2, new JLabel("Cluster"));
310: addItem(message, 1, 2, cb3);
311:
312: addItem(message, 0, 3, new JLabel("Start Time"));
313: addItem(message, 1, 3, start);
314:
315: addItem(message, 0, 4, new JLabel("End Time"));
316: addItem(message, 1, 4, end);
317:
318: addItem(message, 0, 5, new JLabel("Multiplier"));
319: addItem(message, 1, 5, mult);
320: int result = OptionPane.showOptionDialog(c, message,
321: "Configure " + getPluginName(),
322: OptionPane.OK_CANCEL_OPTION,
323: OptionPane.QUESTION_MESSAGE, null, null, null);
324:
325: if (result == OptionPane.OK_OPTION) {
326: try {
327: fuelType = (String) cb1.getSelectedItem();
328: consumer = (String) cb2.getSelectedItem();
329: cluster = (String) cb3.getSelectedItem();
330: long guiStart = new EGDate(start.getText()).getTime();
331: long guiEnd = new EGDate(end.getText()).getTime();
332: TripletKey tk = new TripletKey((String) fuelTypes
333: .get(fuelType), (String) consumers
334: .get(consumer), cluster);
335: TripletValue tripVal = new TripletValue(guiStart,
336: guiEnd, Double.parseDouble(mult.getText()));
337: hash.put(tk, tripVal);
338:
339: } catch (Exception e) {
340: // Ignore errors.
341: System.out
342: .println("POLSpecialPlugin: All values were not entered!");
343: // System.out.println("Exception: " + e.getMessage());
344: }
345: }
346: }
347:
348: public void save(Properties props, String prefix) {
349: props.setProperty(prefix + "fuelTypes",
350: getSimpleHashAsString(fuelTypes));
351: props.setProperty(prefix + "consumers",
352: getSimpleHashAsString(consumers));
353: props.setProperty(prefix + "hash", getHashAsString(hash));
354: }
355:
356: public void restore(Properties props, String prefix) {
357: try {
358: String fuelArrayString = props.getProperty(prefix
359: + "fuelTypes");
360: fuelTypes = parseSimpleHashString(fuelArrayString);
361: String hashString = props.getProperty(prefix + "hash");
362: hash = parseHashString(hashString);
363: String consumersArrayString = props.getProperty(prefix
364: + "consumers");
365: consumers = parseSimpleHashString(consumersArrayString);
366: } catch (Exception e) {
367: // State not present in props
368: }
369: }
370:
371: public Hashtable parseSimpleHashString(String hs) {
372: StringTokenizer st = new StringTokenizer(hs.substring(1, hs
373: .length() - 1), "!");
374: Hashtable h = new Hashtable();
375: while (st.hasMoreTokens()) {
376: String str1 = st.nextToken();
377: StringTokenizer st2 = new StringTokenizer(str1, "=");
378: h.put(st2.nextToken().trim(), st2.nextToken().trim());
379: }
380: return h;
381: }
382:
383: public String getSimpleHashAsString(Hashtable h) {
384: String key = "";
385: StringBuffer buff = new StringBuffer();
386: boolean firstTime = true;
387: buff.append("{");
388: Enumeration e = h.keys();
389: while (e.hasMoreElements()) {
390: if (!firstTime) {
391: buff.append("!");
392: }
393: key = (String) e.nextElement();
394: // buff.append("(" + key + ")=");
395: // buff.append("(" + h.get(key) + ")");
396: buff.append(key + "=");
397: buff.append(h.get(key));
398: firstTime = false;
399: }
400: buff.append("}");
401: return buff.toString();
402: }
403:
404: /**
405: * Returns the string representation of a Hashtable in the form:
406: *
407: * [(1,2,3):(500,500,2.3);(4,5,6):(1000, 1000, 5.66)]
408: *
409: * where (1,2,3) and (4,5,6) are the keys
410: * and (500,500,2.3) and (1000, 1000, 5.66) are the values
411: **/
412: public String getHashAsString(Hashtable h) {
413: StringBuffer buff = new StringBuffer();
414: boolean firstTime = true;
415: buff.append("[");
416: Enumeration e = h.keys();
417: while (e.hasMoreElements()) {
418: if (!firstTime) {
419: buff.append(";");
420: }
421: TripletKey tkTemp = (TripletKey) e.nextElement();
422: buff.append("(" + tkTemp.getFuelType() + ","
423: + tkTemp.getConsumer() + "," + tkTemp.getCluster()
424: + "):");
425: TripletValue tkVal = (TripletValue) h.get(tkTemp);
426: buff.append("(" + tkVal.getStartDate() + ","
427: + tkVal.getEndDate() + "," + tkVal.getMultiplier()
428: + ")");
429: firstTime = false;
430: }
431: buff.append("]");
432: return buff.toString();
433: }
434:
435: /**
436: * Parses a string representation of a Hashtable and
437: * returns the resulting Hashtable.
438: *
439: * Ex: [(1,2,3):(500,500,2.3);(4,5,6):(1000,1000,5.66)]
440: **/
441: public Hashtable parseHashString(String hs) {
442: Hashtable ht = new Hashtable();
443:
444: // Strip off square brackets at beginning and end of string
445: // and split the string by the ";" which separate the slots
446: // of the Hashtable
447: StringTokenizer str = new StringTokenizer(hs.substring(1, hs
448: .length() - 1), ";");
449:
450: while (str.hasMoreTokens()) {
451: String str1 = str.nextToken();
452:
453: // Split the string by ":" which separate the hash keys from the hash values
454: StringTokenizer st2 = new StringTokenizer(str1, ":");
455: String str2 = st2.nextToken();
456:
457: // Split the string by "," which separate the values which make up the
458: // TripletKey and TripletValue objects
459: StringTokenizer st3 = new StringTokenizer(str2.substring(1,
460: str2.length() - 1), ",");
461: TripletKey key = new TripletKey(st3.nextToken(), st3
462: .nextToken(), st3.nextToken());
463:
464: String str3 = st2.nextToken();
465: StringTokenizer st4 = new StringTokenizer(str3.substring(1,
466: str3.length() - 1), ",");
467:
468: TripletValue value = new TripletValue(Long.parseLong(st4
469: .nextToken()), Long.parseLong(st4.nextToken()),
470: Double.parseDouble(st4.nextToken()));
471:
472: ht.put(key, value);
473: }
474: return ht;
475: }
476:
477: public void setEventGenerator(EventGenerator eg) {
478: theEventGenerator = eg;
479: }
480:
481: /**
482: * Create a FailureConsumptionItem for this plugin to handle a
483: * particular FailureConsumptionRate.
484: **/
485: public FailureConsumptionPluginItem createFailureConsumptionItem(
486: FailureConsumptionRate aRate,
487: FailureConsumptionSegment aSegment, long theExecutionTime,
488: FailureConsumptionPluginItem aFailureConsumptionPluginItem) {
489:
490: // Check if it's fuel (by FSC)
491: // NOTE: We may need to check by the NSN if the FSC doesn't work
492: if ((aRate.theItemIdentification.startsWith("NSN/9130"))
493: || (aRate.theItemIdentification.startsWith("NSN/9140"))) {
494: if (!fuelTypes.containsValue(aRate.theItemIdentification)) {
495: fuelTypes.put(aRate.theItemName,
496: aRate.theItemIdentification);
497: }
498: if (!consumers.containsValue(aRate.theConsumerId)) {
499: consumers.put(aRate.theConsumer, aRate.theConsumerId);
500: }
501: }
502:
503: if (aFailureConsumptionPluginItem instanceof POLItem
504: && aFailureConsumptionPluginItem.theFailureConsumptionRate == aRate) {
505: return aFailureConsumptionPluginItem;
506: }
507:
508: // TripletKey tk_temp = new TripletKey(aRate.theItemIdentification, aRate.theConsumerId, aSegment.theSource);
509: // TripletValue tk_val = (TripletValue)(hash.get(tk_temp));
510: // if (tk_val == null) {
511: // tk_temp = new TripletKey(aRate.theItemIdentification, aRate.theConsumerId, "All Clusters");
512: // tk_val = (TripletValue)(hash.get(tk_temp));
513: // }
514: // if (tk_val != null) {
515: return new POLItem(aRate, theExecutionTime, aSegment);
516: // }
517: // return null;
518: }
519: }
|