001: /*
002: * <copyright>
003: *
004: * Copyright 2001-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.core.plugin;
028:
029: import java.io.IOException;
030: import java.io.PrintWriter;
031: import java.text.DateFormat;
032: import java.text.SimpleDateFormat;
033: import java.util.Collection;
034: import java.util.Date;
035:
036: import javax.servlet.http.HttpServlet;
037: import javax.servlet.http.HttpServletRequest;
038: import javax.servlet.http.HttpServletResponse;
039:
040: import org.cougaar.core.agent.service.alarm.Alarm;
041: import org.cougaar.core.service.DemoControlService;
042: import org.cougaar.core.service.LoggingService;
043: import org.cougaar.core.service.ServletService;
044:
045: /**
046: * This component provides {@link javax.servlet.Servlet} access
047: * to the {@link DemoControlService} for setting the demo (aka
048: * "execution") time of the local node.
049: * <p>
050: * One plugin paramter if present and Boolean <tt>true</tt> will
051: * cause the plugin to print the system and demo time every 10
052: * secs (as measured by system and demo time)
053: *
054: * @see org.cougaar.core.service.DemoControlService
055: */
056: public class DemoTimeControlPlugin extends ComponentPlugin {
057:
058: private boolean debug = false;
059:
060: long lastScenarioTime = 0;
061: long lastRealTime = 0;
062:
063: ServletService servletService;
064: DemoControlService demoControlService;
065: LoggingService loggingService;
066:
067: DateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
068:
069: private String printTime(String pfx) {
070: long scenarioNow = alarmService.currentTimeMillis();
071: long realNow = System.currentTimeMillis();
072: long scenarioDelta = scenarioNow - lastScenarioTime;
073: long realDelta = realNow - lastRealTime;
074:
075: String ret = "\n" + pfx + "Time at "
076: + this .getAgentIdentifier().getAddress()
077: + ". Scenario Time is " + scenarioNow + "["
078: + scenarioDelta + "]" + "{"
079: + fmt.format(new Date(scenarioNow)) + "}"
080: + " Real Time is " + realNow + "[" + realDelta + "]"
081: + "{" + fmt.format(new Date(realNow)) + "}"
082: + "\nOffset = " + (scenarioNow - realNow);
083:
084: System.err.println(ret);
085: lastScenarioTime = scenarioNow;
086: lastRealTime = realNow;
087: return ret;
088: }
089:
090: private class MyAlarm implements Alarm {
091: long exp;
092: boolean realTime;
093:
094: public MyAlarm(long delta, boolean realTime) {
095: if (realTime)
096: this .exp = System.currentTimeMillis() + delta;
097: else
098: this .exp = alarmService.currentTimeMillis() + delta;
099:
100: this .realTime = realTime;
101: }
102:
103: public long getExpirationTime() {
104: return exp;
105: }
106:
107: public void expire() {
108: printTime(realTime ? "Real " : "Demo ");
109: if (realTime)
110: alarmService.addRealTimeAlarm(new MyAlarm(10000, true));
111: else
112: alarmService.addAlarm(new MyAlarm(10000, false));
113:
114: }
115:
116: public String toString() {
117: return "<" + exp + ">";
118: }
119:
120: public boolean cancel() {
121: return false;
122: }
123:
124: /**
125: * @see org.cougaar.core.agent.service.alarm.Alarm#hasExpired()
126: */
127: public boolean hasExpired() {
128: return false;
129: }
130:
131: }
132:
133: /**
134: * @see org.cougaar.core.blackboard.BlackboardClientComponent#setupSubscriptions()
135: */
136: protected void setupSubscriptions() {
137: Collection params = this .getParameters();
138: if (params.contains("true"))
139: debug = true;
140: if (debug) {
141: System.err
142: .println("timeControl plugin loaded at scenario time:"
143: + alarmService.currentTimeMillis());
144: printTime("setup");
145: }
146:
147: try {
148: servletService.register("/timeControl", new MyServlet());
149: } catch (Exception ex) {
150: System.err
151: .println("Unable to register timeControl servlet");
152: ex.printStackTrace();
153: }
154:
155: }
156:
157: /**
158: * @see org.cougaar.core.blackboard.BlackboardClientComponent#execute()
159: */
160: protected void execute() {
161: if (debug) {
162: printTime("execute");
163: alarmService.addRealTimeAlarm(new MyAlarm(10000, true));
164: alarmService.addRealTimeAlarm(new MyAlarm(10000, false));
165: }
166: }
167:
168: protected void updateTime(String advance, String rate,
169: String changeTime) {
170: if (loggingService.isDebugEnabled()) {
171: loggingService.debug("Time to advance = " + advance
172: + "; New Rate = " + rate + "; Change Time is "
173: + changeTime);
174: }
175: if ((advance == null) && (rate == null))
176: return;
177:
178: long l_advance = 0;
179: if (advance != null) {
180: try {
181: l_advance = Long.parseLong(advance);
182: } catch (NumberFormatException nfe) {
183: System.err.println("Bad advance");
184: nfe.printStackTrace();
185: }
186: }
187: double d_rate = 1.0;
188: if (rate != null) {
189: try {
190: d_rate = Double.parseDouble(rate);
191: } catch (NumberFormatException nfe) {
192: System.err.println("Bad rate");
193: nfe.printStackTrace();
194: }
195: }
196:
197: long newTime = alarmService.currentTimeMillis() + l_advance;
198: long quantization = 1L;
199: if (l_advance >= 86400000L) {
200: // Quantize to nearest day if step is a multiple of one day
201: if ((l_advance % 86400000L) == 0L) {
202: quantization = 86400000L;
203: }
204: } else if ((l_advance % 3600000L) == 0L) {
205: // Quantize to nearest hour if step is a multiple of one hour
206: quantization = 3600000;
207: }
208: newTime = (newTime / quantization) * quantization;
209:
210: if (changeTime != null && changeTime.length() > 0) {
211: long l_changeTime = 0;
212: if (changeTime != null) {
213: try {
214: l_changeTime = Long.parseLong(changeTime);
215: } catch (NumberFormatException nfe) {
216: System.err.println("Bad change time");
217: nfe.printStackTrace();
218: }
219: }
220: demoControlService.setNodeTime(newTime, d_rate,
221: l_changeTime);
222: } else {
223: demoControlService.setNodeTime(newTime, d_rate);
224: }
225: }
226:
227: protected void doit(HttpServletRequest req, HttpServletResponse res)
228: throws IOException {
229:
230: updateTime(req.getParameter("timeAdvance"), req
231: .getParameter("executionRate"), req
232: .getParameter("changeTime"));
233:
234: PrintWriter out = res.getWriter();
235: out.println("<html><head></head><body>");
236:
237: out.println("<FORM METHOD=\"GET\" ACTION=\"timeControl\">");
238: out.println("<table>");
239: out.println("<tr><td>Scenario Time</td><td>"
240: + fmt
241: .format(new Date(alarmService
242: .currentTimeMillis())) + "</td></tr>");
243: out.println("<tr><td>Test Time</td><td>"
244: + System.currentTimeMillis() + "</td></tr>");
245: out
246: .println("<tr><td>Time Advance (millisecs)</td><td><input type=\"text\" name=\"timeAdvance\" size=10 value=\""
247: + 0 + "\"> <i>1 Day = 86400000</i></td></tr>");
248: out
249: .println("<tr><td>Execution Rate</td><td><input type=\"text\" name=\"executionRate\" size=10 value=\""
250: + demoControlService.getExecutionRate()
251: + "\"> <i>(required)</i></td></tr>");
252: out
253: .println("<tr><td>Real Time for Change to take Effect</td><td><input type=\"text\" name=\"changeTime\" size=10 value=\""
254: + "" + "\"> </td></tr>");
255: out.println("</table>");
256: out.println("<INPUT TYPE=\"submit\" Value=\"Submit\">");
257: out.println("</FORM>");
258: out.println("</body>");
259: // demoControlService.advanceTime(0, 2.0);
260: }
261:
262: private class MyServlet extends HttpServlet {
263: public void doGet(HttpServletRequest req,
264: HttpServletResponse res) throws IOException {
265: doit(req, res);
266: }
267:
268: public void doPost(HttpServletRequest req,
269: HttpServletResponse res) throws IOException {
270: doit(req, res);
271: }
272: }
273:
274: /**
275: * Returns the servletService.
276: * @return ServletService
277: */
278: public ServletService getServletService() {
279: return servletService;
280: }
281:
282: /**
283: * Sets the servletService.
284: * @param servletService The servletService to set
285: */
286: public void setServletService(ServletService servletService) {
287: this .servletService = servletService;
288: }
289:
290: /**
291: * Returns the demoControlService.
292: * @return DemoControlService
293: */
294: public DemoControlService getDemoControlService() {
295: return demoControlService;
296: }
297:
298: /**
299: * Sets the demoControlService.
300: * @param demoControlService The demoControlService to set
301: */
302: public void setDemoControlService(
303: DemoControlService demoControlService) {
304: this .demoControlService = demoControlService;
305: }
306:
307: /**
308: * Returns the loggingService.
309: * @return LoggingService
310: */
311: public LoggingService getLoggingService() {
312: return loggingService;
313: }
314:
315: /**
316: * Sets the loggingService.
317: * @param loggingService The loggingService to set
318: */
319: public void setLoggingService(LoggingService loggingService) {
320: this.loggingService = loggingService;
321: }
322:
323: }
|