Source Code Cross Referenced for ExecutionTimer.java in  » Science » Cougaar12_4 » org » cougaar » core » agent » service » alarm » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Cougaar12_4 » org.cougaar.core.agent.service.alarm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.core.agent.service.alarm;
028:
029:        import java.text.DateFormat;
030:        import java.text.ParseException;
031:        import java.text.SimpleDateFormat;
032:        import java.util.Calendar;
033:        import java.util.Date;
034:        import java.util.GregorianCalendar;
035:
036:        import org.cougaar.bootstrap.SystemProperties;
037:        import org.cougaar.util.log.Logger;
038:        import org.cougaar.util.log.Logging;
039:
040:        /**
041:         * A Timer for execution time (artificial "execution" or "scenario"
042:         * time), which is a modifiable offset from real time with a rate
043:         * multiplier.
044:         * <p>
045:         * Control the advancement of Execution time. Execution time is a
046:         * monotonically increasing value whose rate can be controlled through
047:         * the API implemented in this class. Execution time is nominally the
048:         * same everywhere in the society. Small descrepancies may exist when
049:         * the parameters of the exeuction time advancement are altered.
050:         * Execution time is represented by a rate of advancement and an
051:         * offset. The rate of advancment may be zero (time stands still) or
052:         * any positive value. Excessively high rates may lead to anomalous
053:         * behavior.
054:         * <p>
055:         * The equation of time is Te = Ts * Km + Ko where:<pre>
056:         *  Te is Execution time
057:         *  Ts is system time (System.currentTimeMillis())
058:         *  Km is the (positive) rate of advancement
059:         *  Ko is the offset
060:         * </pre>
061:         * <p>
062:         * The System.currentTimeMillis() is presumed to be in sync in all
063:         * agents within a few milliseconds by using NTP (Network Time
064:         * Protocol). The maximum offset of the system clocks limits the
065:         * maximum value that Km can have without introducing serious
066:         * anomalies.
067:         * <p>
068:         * It is necessary for execution time to be monotonic. Monotonicity
069:         * must be achieved even in the face of delays in propagating changes
070:         * in the parameters of execution time advancement. The message that
071:         * is used to alter the execution time advancement parameters
072:         * specifically allows for the change to occur at some future time and
073:         * it is expected that that will be the norm, but if the message
074:         * transmission is delayed or if insufficient time is allowed, the
075:         * equation of time must be altered to assure monotonicity.
076:         * Furthermore, a succession of time advancement must ultimately
077:         * result in all agents using the same time parameters. This is
078:         * achieved by defining a sorting order on the time parameters that
079:         * establishes a dominance relation between all such parameter sets.
080:         * <p>
081:         * Time change messages contain:<pre>
082:         *   New rate
083:         *   New offset
084:         *   Changeover (real) time
085:         * </pre>
086:         * <p> 
087:         * The changeover time is the first order sorting factor. If the changeover
088:         * times are equal, the parameters yielding the highest execution time value
089:         * at the changeover time dominate. If the execution times at the
090:         * changeover time are equal, the change with the highest offset
091:         * dominates.  
092:         * <p> 
093:         * The changeover time in this message is used as an offset from the
094:         * current system time --- at current system time + changeover the new parameters
095:         * will take effect.  Normally, though, an absolute real time sync point should be
096:         * specified to ensure that all nodes change parameters at the same time (again,
097:         * assuming all host clocks are synchronized using NTP).  An absolute real time
098:         * change time can be specified using the ExecutionTimer.Parameters.create method,
099:         * and setting changeIsAbsolute = true.
100:         * <p>
101:         * We want the execution timer to have the ability to initialize the natural-time
102:         * clock to a particular time. This is
103:         * problematic since we represent execution time as an offset from
104:         * system time. Computing that offset consistently across all
105:         * agents means that we have to compute a time (in the past) at
106:         * which the parameters became effective and then compute the offset
107:         * relative to that.
108:         * <p>
109:         * If org.cougaar.core.society.startTime is provided, we can 
110:         * synchronize from a common baseline point to reasonable accuracy.
111:         * Otherwise, there is no way for all agents to reliably
112:         * compute the same value, so we'll assume simultaneous starts.
113:         * 
114:         * @property org.cougaar.core.agent.startTime The date to use as the
115:         * start of execution for demonstration purposes.  Accepts date/time
116:         * in the form of <em>MM/dd/yyy_H:mm:ss</em>, <em>MM/dd/yyy H:mm:ss</em>,
117:         * or <em>MM/dd/yyy</em>.  The time sequence is optional and defaults to
118:         * midnight on the specified date. 
119:         * agentStartTime must be in GMT.  Note that if society.startTime is
120:         * not fully specified, a multi-node society can have significant 
121:         * natural-time clock skew across the members.
122:         *
123:         * @property org.cougaar.core.society.startTime The real date-time stamp
124:         * when the society was started.  If supplied, can be used to synchronize
125:         * the execution times of nodes which were started at different real times.
126:         * society.startTime must be in GMT and ought to be generally
127:         * slightly in the past.  Format example: "09/12/2003 13:00:00"
128:         *
129:         * @property org.cougaar.core.society.timeOffset Specify an offset (in milliseconds)
130:         * from real time to use as execution time.  This is an alternative to
131:         * using agent.startTime and society.startTime (if timeOffset is specified, then
132:         * these other properties are ignored).  Typical usage would be to specify
133:         * the execution-time offset when (re)starting a node to match the other nodes
134:         * in the society.
135:         */
136:        public class ExecutionTimer extends Timer {
137:            private static final Logger logger = Logging
138:                    .getLogger("org.cougaar.core.agent.service.alarm.ExecutionTimer");
139:
140:            public static final long DEFAULT_CHANGE_DELAY = 10000L;
141:
142:            public static class Parameters implements  Comparable,
143:                    java.io.Serializable {
144:                public final long theOffset; // The offset (Ko)
145:                public final double theRate; // The advancement rate (Km)
146:                public final long theChangeTime; // The changeover time
147:
148:                public Parameters(double aRate, long anOffset, long aChangeTime) {
149:                    theRate = aRate;
150:                    theOffset = anOffset;
151:                    theChangeTime = aChangeTime;
152:                }
153:
154:                public long computeTime(long now) {
155:                    return (long) (now * theRate) + theOffset;
156:                }
157:
158:                public int compareTo(Object o) {
159:                    Parameters other = (Parameters) o;
160:                    long diff = this .theChangeTime - other.theChangeTime;
161:                    if (diff < 0L)
162:                        return -1;
163:                    if (diff > 0L)
164:                        return 1;
165:                    diff = this .computeTime(this .theChangeTime)
166:                            - other.computeTime(other.theChangeTime);
167:                    if (diff < 0L)
168:                        return -1;
169:                    if (diff > 0L)
170:                        return 1;
171:                    diff = this .theOffset - other.theOffset;
172:                    if (diff < 0L)
173:                        return -1;
174:                    if (diff > 0L)
175:                        return 1;
176:                    return 0;
177:                }
178:
179:                public String toString() {
180:                    return ("Time = "
181:                            + new Date(computeTime(theChangeTime)).toString()
182:                            + "*" + theRate + "@" + new Date(theChangeTime)
183:                            .toString());
184:                }
185:            }
186:
187:            /**
188:             * Description of a Parameters change (relative to some implicit Parameters)
189:             */
190:            public static class Change {
191:                public final long theOffsetDelta; // Step in the offset
192:                public final double theRate; // New rate is absolute
193:                public final long theChangeTimeDelta; // Change time relative to some other Parameters
194:
195:                public Change(double aRate, long anOffsetDelta,
196:                        long aChangeTimeDelta) {
197:                    theOffsetDelta = anOffsetDelta;
198:                    theRate = aRate;
199:                    theChangeTimeDelta = aChangeTimeDelta;
200:                }
201:            }
202:
203:            /**
204:             * An array of Parameters. The array is sorted in the order in which
205:             * they are to be applied. The 0-th element is the current setting.
206:             */
207:            Parameters[] theParameters = new Parameters[] {
208:                    new Parameters(1.0, 0L, 0L), null, // Allow up to five new parameters
209:                    null, null, null, };
210:            private int theParameterCount = 1;
211:
212:            long theCurrentExecutionTime; // This assures monotonicity
213:
214:            /**
215:             * Create Parameters that jump time by a specified amount and
216:             * continue at a new rate thereafter.
217:             */
218:            public Parameters create(long millis, boolean millisIsAbsolute,
219:                    double newRate) {
220:                synchronized (sem) {
221:                    return create(millis, millisIsAbsolute, newRate, false,
222:                            DEFAULT_CHANGE_DELAY);
223:                }
224:            }
225:
226:            /**
227:             * Create Parameters that jump time by a specified amount and
228:             * continue at a new rate thereafter. The new rate is 0.0 if running
229:             * is false, the current rate if running is true and the current
230:             * rate is greater than 0.0 or 1.0 if running is true and the
231:             * current rate is stopped.
232:             */
233:            public Parameters create(long millis, boolean millisIsAbsolute,
234:                    double newRate, boolean forceRunning) {
235:                synchronized (sem) {
236:                    return create(millis, millisIsAbsolute, newRate,
237:                            forceRunning, DEFAULT_CHANGE_DELAY);
238:                }
239:            }
240:
241:            /**
242:             * Create Parameters that jump time by a specified amount and
243:             * continue at a new rate thereafter. The new rate is 0.0 if running
244:             * is false, the current rate if running is true and the current
245:             * rate is greater than 0.0 or 1.0 if running is true and the
246:             * current rate is stopped.
247:             * @deprecated Use the version that allows specifying absolute change time instead
248:             */
249:            public Parameters create(long millis, boolean millisIsAbsolute,
250:                    double newRate, boolean forceRunning, long changeDelay) {
251:                synchronized (sem) {
252:                    long changeTime = getNow() + changeDelay;
253:                    return create(millis, millisIsAbsolute, newRate,
254:                            forceRunning, changeTime, theParameters[0]);
255:                }
256:            }
257:
258:            /**
259:             * Create Parameters that jump time by a specified amount and
260:             * continue at a new rate thereafter. The new rate is 0.0 if running
261:             * is false, the current rate if running is true and the current
262:             * rate is greater than 0.0 or 1.0 if running is true and the
263:             * current rate is stopped.  
264:             * The new parameters can go into effect at a time relative to
265:             * the current system time (changeIsAbsolute == false), or at a
266:             * specific system time (changeIsAbsolute == true)
267:             */
268:            public Parameters create(long millis, boolean millisIsAbsolute,
269:                    double newRate, boolean forceRunning, long changeTime,
270:                    boolean changeIsAbsolute) {
271:                synchronized (sem) {
272:                    if (!changeIsAbsolute)
273:                        changeTime = getNow() + changeTime;
274:                    return create(millis, millisIsAbsolute, newRate,
275:                            forceRunning, changeTime, theParameters[0]);
276:                }
277:            }
278:
279:            private Parameters create(long millis, boolean millisIsAbsolute,
280:                    double newRate, boolean forceRunning, long changeTime,
281:                    Parameters relativeTo) {
282:                long valueAtChangeTime = relativeTo.computeTime(changeTime);
283:                if (Double.isNaN(newRate))
284:                    newRate = relativeTo.theRate;
285:                if (Double.isInfinite(newRate)) {
286:                    throw new IllegalArgumentException("Illegal infinite rate");
287:                }
288:                if (newRate < 0.0) {
289:                    throw new IllegalArgumentException(
290:                            "Illegal negative rate: " + newRate);
291:                }
292:                if (forceRunning) {
293:                    if (newRate == 0.0) {
294:                        newRate = relativeTo.theRate;
295:                    }
296:                    if (newRate == 0.0) {
297:                        newRate = 1.0;
298:                    }
299:                }
300:                if (millisIsAbsolute) {
301:                    millis = millis - valueAtChangeTime;
302:                }
303:                if (millis < 0L) {
304:                    throw new IllegalArgumentException(
305:                            "Illegal negative advancement:" + millis);
306:                }
307:                long newOffset = valueAtChangeTime + millis
308:                        - (long) (changeTime * newRate);
309:                return new Parameters(newRate, newOffset, changeTime);
310:            }
311:
312:            /**
313:             * Creates a series of changes. The first change is relative to the
314:             * current Parameters, the subsequent changes are relative to the
315:             * previous change.
316:             */
317:            public Parameters[] create(Change[] changes) {
318:                synchronized (sem) {
319:                    Parameters[] result = new Parameters[changes.length];
320:                    Parameters prev = theParameters[0];
321:                    long changeTime = getNow();
322:                    for (int i = 0; i < changes.length; i++) {
323:                        Change change = changes[i];
324:                        if (change.theChangeTimeDelta <= 0.0) {
325:                            throw new IllegalArgumentException(
326:                                    "Illegal non-positive change time delta: "
327:                                            + change.theChangeTimeDelta);
328:                        }
329:                        changeTime += change.theChangeTimeDelta;
330:                        result[i] = create(change.theOffsetDelta, false,
331:                                change.theRate, false, changeTime, prev);
332:                        prev = result[i];
333:                    }
334:                    return result;
335:                }
336:            }
337:
338:            /**
339:             * Get the current real time and insure that the current parameters
340:             * are compatible with the real time being returned. The pending
341:             * parameters become current if their time of applicability has been
342:             * reached.
343:             */
344:            private long getNow() {
345:                long now = System.currentTimeMillis();
346:                while (theParameterCount > 1
347:                        && theParameters[1].theChangeTime <= now) {
348:                    System.arraycopy(theParameters, 1, theParameters, 0,
349:                            --theParameterCount);
350:                    theParameters[theParameterCount] = null;
351:                }
352:                return now;
353:            }
354:
355:            /**
356:             * Get the current execution time in millis.
357:             */
358:            public long currentTimeMillis() {
359:                synchronized (sem) {
360:                    long now = getNow();
361:                    long newTime = theParameters[0].computeTime(now);
362:                    if (newTime > theCurrentExecutionTime) {
363:                        theCurrentExecutionTime = newTime; // Only advance time, never decreases
364:                    }
365:                    return theCurrentExecutionTime;
366:                }
367:            }
368:
369:            /**
370:             * Insert new Parameters into theParameters. If the new parameters
371:             * apply before the last element of theParameters, ignore them.
372:             * Otherwise, append the new parameters overwriting the last parameters if necessary.
373:             */
374:            public void setParameters(Parameters parameters) {
375:                synchronized (sem) {
376:                    getNow(); // Bring parameters up-to-now
377:                    if (parameters
378:                            .compareTo(theParameters[theParameterCount - 1]) > 0) {
379:                        if (theParameterCount < theParameters.length) {
380:                            if (logger.isInfoEnabled()) {
381:                                logger.info("Setting parameters "
382:                                        + theParameterCount + " to "
383:                                        + parameters);
384:                            }
385:                            theParameters[theParameterCount++] = parameters;
386:                        } else {
387:                            if (logger.isInfoEnabled()) {
388:                                logger.info("Setting parameters "
389:                                        + (theParameterCount - 1) + " to "
390:                                        + parameters);
391:                            }
392:                            theParameters[theParameterCount - 1] = parameters;
393:                        }
394:                    }
395:                }
396:                requestRun();
397:            }
398:
399:            protected long getMaxWait() {
400:                if (theParameterCount > 1) {
401:                    return theParameters[1].theChangeTime
402:                            - System.currentTimeMillis();
403:                } else {
404:                    return 100000000L;
405:                }
406:            }
407:
408:            public double getRate() {
409:                synchronized (sem) {
410:                    getNow(); // Bring parameters up-to-now
411:                    return theParameters[0].theRate;
412:                }
413:            }
414:
415:            /**
416:             */
417:            public ExecutionTimer() {
418:                long offset = computeInitialOffset();
419:                if (offset != 0L) {
420:                    if (logger.isWarnEnabled()) {
421:                        logger.warn("Starting Time set to "
422:                                + new Date(System.currentTimeMillis() + offset)
423:                                + " offset=" + offset + "ms");
424:                    }
425:                    theParameters[0] = new Parameters(1.0, offset, 0L);
426:                }
427:            }
428:
429:            private long computeInitialOffset() {
430:                long offset = 0L;
431:
432:                // society.timeOffset wins if specified
433:                {
434:                    offset = SystemProperties.getLong(
435:                            "org.cougaar.core.society.timeOffset", DATE_ERROR);
436:                    if (offset != DATE_ERROR) {
437:                        if (logger.isInfoEnabled()) {
438:                            logger
439:                                    .info("Exact time set by society.timeOffset ("
440:                                            + offset + ")");
441:                        }
442:                        return offset;
443:                    }
444:                }
445:                offset = 0L; // reset so not == DATE_ERROR
446:
447:                long now = System.currentTimeMillis();
448:                ParsedPropertyDate adt = new ParsedPropertyDate(
449:                        "org.cougaar.core.agent.startTime");
450:                ParsedPropertyDate sdt = new ParsedPropertyDate(
451:                        "org.cougaar.core.society.startTime");
452:
453:                long target = adt.time;
454:                if (target == DATE_ERROR) {
455:                    if (adt.date != DATE_ERROR) {
456:                        if (logger.isWarnEnabled()) {
457:                            logger
458:                                    .warn("Inexact agent.startTime specified:  Will default to midnight.");
459:                        }
460:                        target = adt.date;
461:                    }
462:                }
463:
464:                if (target != DATE_ERROR) { // fully-specified agent start time?
465:                    if (sdt.time != DATE_ERROR) { // fully-specified society start time?
466:                        // then we can compute exact offset
467:                        offset = target - sdt.time;
468:                        if (logger.isInfoEnabled()) {
469:                            logger
470:                                    .info("Exact time set by agent-society times ("
471:                                            + offset + ")");
472:                        }
473:                    } else {
474:                        if (sdt.date != DATE_ERROR) {
475:                            // useless: only partially-specified society start!
476:                            logger
477:                                    .error("Ignoring partially-specified society.startTime "
478:                                            + new Date(sdt.date));
479:                            // fall through...
480:                        }
481:
482:                        // no useful society.startTime: accept the skew, but complain
483:                        offset = target - now;
484:                        if (logger.isWarnEnabled()) { // check in case someone turns it off
485:                            logger
486:                                    .warn("Multi-node societies will have execution-time clock skew: Set org.cougaar.core.society.startTime or society.timeOffset to avoid this problem.");
487:                        }
488:                    }
489:                }
490:                return offset;
491:            }
492:
493:            private static final long DATE_ERROR = Long.MIN_VALUE;
494:
495:            private static class ParsedPropertyDate {
496:                String name;
497:                String value;
498:                long time = DATE_ERROR;
499:                long date = DATE_ERROR;
500:
501:                ParsedPropertyDate(String propertyName) {
502:                    this .name = propertyName;
503:                    value = SystemProperties.getProperty(name);
504:
505:                    if (value != null) {
506:                        try {
507:                            DateFormat f;
508:                            try {
509:                                // try full date with "_" separator
510:                                f = (new SimpleDateFormat("MM/dd/yyy_H:mm:ss"));
511:                                time = f.parse(value).getTime();
512:                            } catch (ParseException e1) {
513:                                // try full date with " " separator
514:                                f = (new SimpleDateFormat("MM/dd/yyy H:mm:ss"));
515:                                time = f.parse(value).getTime();
516:                            }
517:                            // get midnight of specified date
518:                            Calendar c = f.getCalendar();
519:                            c.setTimeInMillis(time);
520:                            c.set(Calendar.HOUR, 0);
521:                            c.set(Calendar.MINUTE, 0);
522:                            c.set(Calendar.SECOND, 0);
523:                            c.set(Calendar.MILLISECOND, 0);
524:                            date = c.getTimeInMillis();
525:                        } catch (ParseException e) {
526:                            // try with just the date
527:                            try {
528:                                DateFormat f = (new SimpleDateFormat(
529:                                        "MM/dd/yyy"));
530:                                time = f.parse(value).getTime();
531:                            } catch (ParseException e1) {
532:                                if (logger.isDebugEnabled())
533:                                    logger.debug("Failed to parse property "
534:                                            + propertyName
535:                                            + " as date+time or just time: "
536:                                            + value, e1);
537:                            }
538:                        }
539:                    }
540:                }
541:            }
542:
543:            protected String getName() {
544:                return "ExecutionTimer";
545:            }
546:
547:            /* /////////////////////////////////////////////////////// 
548:
549:            // point test 
550:
551:            public static void main(String args[]) {
552:              // create a timer
553:              ExecutionTimer timer = new ExecutionTimer();
554:              timer.start();
555:
556:              System.err.println("currentTimeMillis() = "+timer.currentTimeMillis());
557:              // test running advance
558:              timer.addAlarm(timer.createTestAlarm(60*60*1000)); // 60 min
559:              timer.addAlarm(timer.createTestAlarm(60*60*1000+30*1000)); // 60min+30sec
560:              timer.addAlarm(timer.createTestAlarm(30*60*1000)); // 30 min
561:              timer.addAlarm(timer.createTestAlarm(5*1000));// 5 sec
562:              timer.addAlarm(timer.createTestAlarm(10*1000)); // 10 sec
563:              timer.addAlarm(timer.createTestAlarm(10*1000)); // 10 sec (again)
564:              timer.sleep(15*1000);      // wait 10 seconds      
565:              System.err.println("advancing running time 60 minutes");
566:              timer.advanceRunningOffset(60*60*1000);
567:              timer.sleep(20*1000);      // wait 20sec
568:              System.err.println("done waiting for running time.");
569:
570:              // stopped tests
571:              System.err.println("Trying stopped tests:");
572:              long t = timer.currentTimeMillis()+10*1000;
573:              timer.advanceStoppedTime(t);
574:              System.err.println("currentTimeMillis() = "+timer.currentTimeMillis());
575:              timer.addAlarm(timer.createTestAlarm(5*1000));// 5 sec
576:              timer.addAlarm(timer.createTestAlarm(10*1000)); // 10 sec
577:              timer.addAlarm(timer.createTestAlarm(30*60*1000)); // 30 min
578:              timer.addAlarm(timer.createTestAlarm(60*60*1000)); // 60 min
579:              timer.addAlarm(timer.createTestAlarm(60*60*1000+30*1000)); // 60min+30sec
580:              timer.sleep(15*1000);      // wait 10 seconds      
581:              System.err.println("advancing stopped time 5 seconds");
582:              timer.advanceStoppedTime(t+5*1000);
583:              timer.sleep(1*1000);      // sleep a second
584:              System.err.println("advancing stopped time to 10 seconds");
585:              timer.advanceStoppedTime(t+10*1000);
586:              timer.sleep(1*1000);      // sleep a second
587:              System.err.println("advancing stopped time to 60 minutes");
588:              timer.advanceStoppedTime(t+60*60*1000);
589:              timer.sleep(1*1000);      // wait 20sec
590:              System.err.println("starting clock");
591:              timer.startRunning();
592:              timer.sleep(20*1000);      // wait 20sec
593:              System.err.println("done waiting for running time.");
594:
595:
596:              System.exit(0);
597:            }
598:
599:            public void sleep(long millis) {
600:              try {
601:                synchronized(this) {
602:                  this.wait(millis);
603:                }
604:              } catch (InterruptedException ie) {}
605:            }
606:              
607:
608:            Alarm createTestAlarm(long delta) {
609:              return new TestAlarm(delta);
610:            }
611:            private class TestAlarm implements Alarm {
612:              long exp;
613:              public TestAlarm(long delta) { this.exp = currentTimeMillis()+delta; }
614:              public long getExpirationTime() {return exp;}
615:              public void expire() { System.err.println("Alarm "+exp+" expired.");}
616:              public String toString() { return "<"+exp+">";}
617:              public boolean cancel() {}  // doesn't support cancel
618:            }
619:
620:            /* */
621:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.