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 java.io.IOException;
029: import java.util.ArrayList;
030: import java.util.Arrays;
031: import java.util.Calendar;
032: import java.util.Collection;
033: import java.util.Date;
034: import java.util.GregorianCalendar;
035: import java.util.Iterator;
036: import java.util.Properties;
037: import java.util.Enumeration;
038: import java.util.SortedSet;
039: import java.util.TreeSet;
040: import javax.swing.JComponent;
041: import org.cougaar.glm.execution.common.*;
042:
043: /**
044: * Keeps track of the inventory schedules and decide if/when to
045: * generate a report.
046: **/
047: public class InventoryScheduleManager extends ManagerBase implements
048: ScheduleManager {
049: private InventoryReportManager theInventoryReportManager;
050:
051: public InventoryScheduleManager(EventGenerator anEventGenerator,
052: InventoryReportManager anInventoryReportManager) {
053: super (anEventGenerator);
054: theInventoryReportManager = anInventoryReportManager;
055: }
056:
057: /**
058: * Override base class to suppress log file writing for this
059: * manager. The enableLog method simply does nothing leaving the log
060: * file disabled.
061: **/
062: public void enableLog(String prefix) {
063: // No logging of inventory schedules
064: }
065:
066: protected String getLogFileName(String prefix) {
067: throw new RuntimeException("Unimplemented method");
068: }
069:
070: public String getGUITitle() {
071: return "Inventory Schedules";
072: }
073:
074: public FilterGUI createFilterGUI(EventGenerator anEventGenerator) {
075: return new InventoryScheduleFilterGUI(anEventGenerator);
076: }
077:
078: public Object[] getHandlers() {
079: return new Object[] { new EGInventoryReportScheduleHandler(this ), };
080: }
081:
082: protected Class getPluginInterface() {
083: return InventoryPlugin.class;
084: }
085:
086: protected Class getDefaultPluginClass() {
087: return InventoryDefaultPlugin.class;
088: }
089:
090: private void applyPlugins(TimedInventoryReport tir) {
091: long theExecutionTime = theEventGenerator.getExecutionTime();
092: for (Iterator i = getEnabledPlugins(); i.hasNext();) {
093: InventoryPlugin thePlugin = (InventoryPlugin) i.next();
094: if (thePlugin.apply(tir, theExecutionTime))
095: return;
096: }
097: }
098:
099: /**
100: * step values for finding nearest following date. They must
101: * alternate in sign, be monotonically decreasing and end with
102: * positive 1. Each step is applied until the result crosses zero
103: * and starts getting worse.
104: **/
105: private static final int[] steps = { 10000, -5000, 2000, -1000,
106: 500, -200, 100, -50, 20, -10, 5, -2, 1 };
107:
108: /**
109: * Steps the steppable to the closest time just before the given time.
110: **/
111: private static void stepToTime(SteppedInventoryReportSchedule sirs,
112: long executionTime) {
113: for (int j = 0; j < steps.length; j++) {
114: int step = steps[j];
115: long diff;
116: while ((diff = (sirs.getTime() - executionTime)) * step < 0) {
117: sirs.step(step);
118: }
119: /************************************ debug *********************/
120: sirs.step(-1); // Make it past due so it fires immediately
121: }
122: }
123:
124: public void receiveInventoryReportSchedules(String source,
125: InventoryReportSchedule[] inventoryReportSchedules) {
126: long executionTime = theEventGenerator.getExecutionTime();
127: for (int i = 0; i < inventoryReportSchedules.length; i++) {
128: InventoryReportSchedule irs = inventoryReportSchedules[i];
129: Object key = SteppedInventoryReportSchedule.getKey(source,
130: irs);
131: SteppedInventoryReportSchedule sirs = (SteppedInventoryReportSchedule) map
132: .get(key);
133: if (irs.isRescind()) {
134: if (sirs != null) {
135: removeFromSchedule(sirs);
136: }
137: } else {
138: if (sirs == null) {
139: sirs = new SteppedInventoryReportSchedule(source,
140: irs, this );
141: } else {
142: removeFromSchedule(sirs); // We could be altering the sort order
143: sirs.theInventoryReportSchedule = irs;
144: }
145: // Step the scheduled date until it is just after the current execution time
146: stepToTime(sirs, executionTime);
147: addToSchedule(sirs);
148: }
149: }
150: finishScheduleUpdate();
151: advanceTime(executionTime);
152: }
153:
154: public void requestInventoryReport(String source,
155: String itemIdentification, long aReportDate)
156: throws IOException {
157: Object[] handlers = { new EGInventoryReportHandler(this ), };
158: InventoryReportListener l = theEventGenerator
159: .createInventoryReportListener(source, handlers,
160: itemIdentification, aReportDate);
161: if (l != null) {
162: theEventGenerator.addListener(l);
163: theEventGenerator.startListener(l);
164: }
165: }
166:
167: public void receiveInventoryReports(String source,
168: InventoryReport[] inventoryReports) {
169: TimedInventoryReport[] reports = new TimedInventoryReport[inventoryReports.length];
170: for (int i = 0; i < inventoryReports.length; i++) {
171: reports[i] = new TimedInventoryReport(source,
172: inventoryReports[i], theInventoryReportManager);
173: applyPlugins(reports[i]);
174: }
175: theInventoryReportManager.receiveInventoryReports(source,
176: reports);
177: }
178:
179: protected ManagerTableModel createTableModel() {
180: return new InventoryScheduleTableModel();
181: }
182:
183: public static String getNameForCalendarField(int field) {
184: switch (field) {
185: case Calendar.MINUTE:
186: return "Minutely";
187: case Calendar.HOUR_OF_DAY:
188: case Calendar.HOUR:
189: return "Hourly";
190: case Calendar.DAY_OF_MONTH: // synonym of DATE
191: case Calendar.DAY_OF_WEEK:
192: case Calendar.DAY_OF_YEAR:
193: return "Daily";
194: case Calendar.WEEK_OF_MONTH:
195: case Calendar.DAY_OF_WEEK_IN_MONTH:
196: case Calendar.WEEK_OF_YEAR:
197: return "Weekly";
198: case Calendar.MONTH:
199: return "Monthly";
200: case Calendar.YEAR:
201: return "Yearly";
202: default:
203: return "step " + field;
204: }
205: }
206:
207: private class InventoryScheduleTableModel extends ManagerTableModel {
208: private static final int ENABLE_COLUMN = 0;
209: private static final int CLUSTER_COLUMN = 1;
210: private static final int SCHEDULED_DATE_COLUMN = 2;
211: private static final int STEP_COLUMN = 3;
212: private static final int ITEM_COLUMN = 4;
213: private static final int ANNOTATION_COLUMN = 5;
214: private static final int NCOLUMNS = 6;
215: private/*ns*/final int ITEM_WIDTH = getCellWidth("Inventory: NSN/XXXXXXXXXXXXX");
216:
217: public int getColumnCount() {
218: return NCOLUMNS;
219: }
220:
221: public int getPreferredColumnWidth(int col) {
222: switch (col) {
223: case ENABLE_COLUMN:
224: return SEND_WIDTH;
225: case CLUSTER_COLUMN:
226: return CLUSTER_WIDTH;
227: case SCHEDULED_DATE_COLUMN:
228: return DATE_WIDTH;
229: case STEP_COLUMN:
230: return STEP_WIDTH;
231: case ITEM_COLUMN:
232: return ITEM_WIDTH;
233: case ANNOTATION_COLUMN:
234: return ANNOTATION_WIDTH;
235: }
236: return 75;
237: }
238:
239: public int getMinColumnWidth(int col) {
240: switch (col) {
241: case ENABLE_COLUMN:
242: return SEND_WIDTH;
243: case CLUSTER_COLUMN:
244: return CLUSTER_WIDTH / 2;
245: case SCHEDULED_DATE_COLUMN:
246: return DATE_WIDTH;
247: case STEP_COLUMN:
248: return STEP_WIDTH;
249: case ITEM_COLUMN:
250: return ITEM_WIDTH / 2;
251: case ANNOTATION_COLUMN:
252: return ANNOTATION_WIDTH / 2;
253: }
254: return 75;
255: }
256:
257: public int getMaxColumnWidth(int col) {
258: switch (col) {
259: case ENABLE_COLUMN:
260: return SEND_WIDTH;
261: case CLUSTER_COLUMN:
262: return CLUSTER_WIDTH;
263: case SCHEDULED_DATE_COLUMN:
264: return DATE_WIDTH;
265: case STEP_COLUMN:
266: return STEP_WIDTH;
267: case ITEM_COLUMN:
268: return Integer.MAX_VALUE;
269: case ANNOTATION_COLUMN:
270: return Integer.MAX_VALUE;
271: }
272: return 75;
273: }
274:
275: public String getColumnName(int col) {
276: switch (col) {
277: case ENABLE_COLUMN:
278: return "Send";
279: case CLUSTER_COLUMN:
280: return "Cluster";
281: case SCHEDULED_DATE_COLUMN:
282: return "Scheduled Time";
283: case STEP_COLUMN:
284: return "Period";
285: case ITEM_COLUMN:
286: return "Item";
287: case ANNOTATION_COLUMN:
288: return "Comment";
289: }
290: return null;
291: }
292:
293: public Class getColumnClass(int col) {
294: switch (col) {
295: case ENABLE_COLUMN:
296: return Boolean.class;
297: case CLUSTER_COLUMN:
298: return String.class;
299: case SCHEDULED_DATE_COLUMN:
300: return EGDate.class;
301: case STEP_COLUMN:
302: return String.class;
303: case ITEM_COLUMN:
304: return String.class;
305: case ANNOTATION_COLUMN:
306: return Object.class;
307: }
308: return null;
309: }
310:
311: public boolean isCellEditable(int row, int col) {
312: theEventGenerator.setPaused(true);
313: return col == ENABLE_COLUMN;
314: }
315:
316: public boolean cellHasBeenEdited(int row, int col) {
317: return false; // No real cells are editable
318: }
319:
320: public void setValueAt(Object newValue, int row, int col) {
321: SteppedInventoryReportSchedule sirs = (SteppedInventoryReportSchedule) getRowObject(row);
322: if (sirs == null)
323: return;
324: switch (col) {
325: case ENABLE_COLUMN:
326: sirs.setEnabled(((Boolean) newValue).booleanValue());
327: break;
328: case SCHEDULED_DATE_COLUMN:
329: break;
330: case STEP_COLUMN:
331: break;
332: case ITEM_COLUMN:
333: break;
334: }
335: }
336:
337: public Object getValue(int col, Object rowObject) {
338: SteppedInventoryReportSchedule sirs = (SteppedInventoryReportSchedule) rowObject;
339: if (sirs == null)
340: return null;
341: switch (col) {
342: case ENABLE_COLUMN:
343: return new Boolean(sirs.isEnabled());
344: case CLUSTER_COLUMN:
345: return sirs.theSource;
346: case SCHEDULED_DATE_COLUMN:
347: return new EGDate(sirs.getTime());
348: case STEP_COLUMN:
349: return getNameForCalendarField(sirs.theInventoryReportSchedule.theStep);
350: case ITEM_COLUMN:
351: return sirs.theInventoryReportSchedule.theItemIdentification;
352: case ANNOTATION_COLUMN:
353: return sirs.getAnnotation();
354: }
355: return null;
356: }
357: }
358: }
|