Source Code Cross Referenced for SchedulerMgr.java in  » Content-Management-System » webman » de » webman » util » scheduler » 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 » Content Management System » webman » de.webman.util.scheduler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package de.webman.util.scheduler;
002:
003:        import de.webman.util.registry.Manager;
004:        import de.webman.util.registry.RegistryException;
005:        import de.webman.util.log4j.WebmanCategory;
006:        import org.apache.log4j.Category;
007:        import java.io.File;
008:        import java.io.IOException;
009:        import java.io.BufferedInputStream;
010:        import java.io.FileInputStream;
011:        import java.util.List;
012:        import java.util.Iterator;
013:        import java.util.Map;
014:        import java.util.HashMap;
015:        import java.util.ArrayList;
016:        import org.w3c.dom.Node;
017:        import org.w3c.dom.Document;
018:        import org.w3c.dom.Element;
019:        import org.xml.sax.SAXException;
020:        import org.xml.sax.InputSource;
021:        import javax.xml.parsers.DocumentBuilderFactory;
022:        import javax.xml.parsers.DocumentBuilder;
023:        import javax.xml.parsers.ParserConfigurationException;
024:        import java.text.SimpleDateFormat;
025:        import java.text.ParseException;
026:        import java.util.GregorianCalendar;
027:        import java.util.Calendar;
028:        import java.util.Date;
029:
030:        /**
031:         * The central scheduler manager, implementing the {@link
032:         * de.webman.util.Manager} protocol.<p>
033:         * 
034:         * How to use ** TODO **<p>
035:         *
036:         * Format of the xml-config file:<p>
037:         *
038:         * <code><pre>
039:         * <scheduler>
040:         *    <service id="gc-run"
041:         *             factory-class="de.webman.util.gc.GGSchedulerFactory"
042:         *             frequency="once"
043:         *             at-date="12.05.2002" at-time="20:10:45">
044:         *      <param key="init-file" value="gc.xml" relative="true"/>
045:         *    </service>
046:         *    <service id="sync-run"
047:         *             factory-class="de.webman.sync.SyncSchedulerFactory"
048:         *             frequency="15" 
049:         *             freq-unit="minutes" />
050:         * </scheduler>
051:         * </pre></code>
052:         *
053:         * <code><pre>
054:         * <!ELEMENT scheduler (service*)>
055:         * <!ELEMENT service (param*)>
056:         * <!ATTLIST service id CDATA #IMPLIED
057:         *                   factory-class CDATA #REQUIRED
058:         *                   frequency CDATA #REQUIRED -- may take "once" or any int number --
059:         *                   freq-unit CDATA #IMPLIED -- "seconds|minutes|hours|days", defaults to minutes --
060:         *                   delay CDATA #IMPLIED -- may take any int number, defaults to 0 --
061:         *                   delay-unit CDATA #IMPLIED -- "seconds|minutes|hours|days", defaults to minutes -- 
062:         *                   start-date CDATA #IMPLIED -- a date in form tt.mm.yyyy --
063:         *                   start-time CDATA #IMPLIED -- a time in form hh:mm:ss --
064:         *                   stop-date CDATA #IMPLIED -- a date in form tt.mm.yyyy --
065:         *                   stop-time CDATA #IMPLIED -- a time in form hh:mm:ss --
066:         *                   />
067:         * </pre></code>
068:         *
069:         * @author <a href="mailto:gregor@webman.de">Gregor Klinke</a>
070:         * @version $Revision: 1.2 $
071:         **/
072:        public class SchedulerMgr implements  Manager {
073:            /* $Id: SchedulerMgr.java,v 1.2 2002/04/12 12:45:53 gregor Exp $ */
074:            /**
075:             * logging facility
076:             **/
077:            private static Category cat = Category
078:                    .getInstance(SchedulerMgr.class);
079:
080:            /**
081:             * constants for time calculations (sec)
082:             **/
083:            public static final int MILLISECONDS_PER_SEC = 1000;
084:            /**
085:             * constants for time calculations (min)
086:             **/
087:            public static final int MILLISECONDS_PER_MIN = 1000 * 60;
088:            /**
089:             * constants for time calculations (hour)
090:             **/
091:            public static final int MILLISECONDS_PER_HOUR = 1000 * 60 * 60;
092:            /**
093:             * constants for time calculations (day)
094:             **/
095:            public static final int MILLISECONDS_PER_DAY = 1000 * 60 * 60 * 24;
096:
097:            /**
098:             * date parser used for the date setting 
099:             **/
100:            private static SimpleDateFormat date_format;
101:
102:            /**
103:             * date parser used for the time setting 
104:             **/
105:            private static SimpleDateFormat time_format;
106:
107:            /* ----------------------------------------------------------------------
108:               creating and initializing 
109:               ---------------------------------------------------------------------- */
110:            /* initialize the settings for date and time parsing */
111:            static {
112:                date_format = new SimpleDateFormat("dd.MM.yyyy");
113:                date_format.setLenient(false);
114:
115:                time_format = new SimpleDateFormat("HH:mm:ss");
116:                time_format.setLenient(false);
117:            }
118:
119:            /**
120:             * constructor reserved for used by the factory
121:             * @param basedir the base directory to use for configuration
122:             * @throws RegistryException if anything failed
123:             **/
124:            SchedulerMgr(String basedir) throws RegistryException {
125:                cat.info("setup scheduler system");
126:
127:                try {
128:                    File syncfile = new File(basedir,
129:                            "WEB-INF/classes/scheduler.xml");
130:                    readXMLStream(new BufferedInputStream(new FileInputStream(
131:                            syncfile)));
132:
133:                    // kick off!
134:                    startThread();
135:
136:                    cat.info("scheduler system started successfully");
137:                } catch (SchedulerException se) {
138:                    throw new RegistryException(se);
139:                } catch (IOException ioe) {
140:                    cat
141:                            .info("no 'scheduler.xml' found.  No schedulers started");
142:                }
143:            }
144:
145:            /* ----------------------------------------------------------------------
146:               reading the configuration file and setting up the registered
147:               schedulers
148:               ---------------------------------------------------------------------- */
149:            /* ----------------------------------------------------------------------
150:               read configuration
151:               ---------------------------------------------------------------------- */
152:            /**
153:             * reads a xml config file.  for the xml structure see above
154:             * @param in the stream to read the XML structure from
155:             * @throws IOException guess what
156:             * @throws SchedulerException something wrong with the scheduler setup
157:             * @throws RegistryException something generaly wrong (mostly: can't find 
158:             *  XML file, etc.)
159:             **/
160:            private void readXMLStream(BufferedInputStream in)
161:                    throws IOException, RegistryException, SchedulerException {
162:                DocumentBuilderFactory factory = DocumentBuilderFactory
163:                        .newInstance();
164:                factory.setNamespaceAware(false);
165:                factory.setValidating(false);
166:
167:                Document doc = null;
168:                try {
169:                    DocumentBuilder builder = factory.newDocumentBuilder();
170:                    doc = builder.parse(new InputSource(in));
171:                } catch (ParserConfigurationException pce) {
172:                    throw new RegistryException(pce);
173:                } catch (SAXException se) {
174:                    throw new RegistryException(se);
175:                }
176:
177:                Node c0 = doc.getDocumentElement();
178:                if (!("scheduler".equals(c0.getNodeName())))
179:                    throw new RegistryException("bad root element '"
180:                            + c0.getNodeName() + "'");
181:
182:                for (Node c1 = c0.getFirstChild(); c1 != null; c1 = c1
183:                        .getNextSibling()) {
184:                    if (c1.getNodeType() == Node.ELEMENT_NODE) {
185:                        if ("service".equals(c1.getNodeName())) {
186:                            Element ce = (Element) c1;
187:                            HashMap prms = null;
188:
189:                            /* read parameters */
190:                            for (Node c2 = c1.getFirstChild(); c2 != null; c2 = c2
191:                                    .getNextSibling()) {
192:                                if (c2.getNodeType() == Node.ELEMENT_NODE) {
193:                                    if ("param".equals(c2.getNodeName())) {
194:                                        Element c2e = (Element) c2;
195:
196:                                        String key = c2e.getAttribute("key");
197:                                        String value = c2e
198:                                                .getAttribute("value");
199:
200:                                        if (prms == null)
201:                                            prms = new HashMap();
202:
203:                                        prms.put(key, value);
204:                                    } else
205:                                        throw new RegistryException(
206:                                                "unknown element: '"
207:                                                        + c2.getNodeName()
208:                                                        + "'");
209:                                }
210:                            }
211:
212:                            setupSchedulerService(ce, prms);
213:                        } else
214:                            throw new RegistryException("unknown element: '"
215:                                    + c1.getNodeName() + "'");
216:                    }
217:                }
218:            }
219:
220:            /**
221:             * returns the first text element below a context node
222:             * @param cntx the context node
223:             **/
224:            private String getTextData(Node cntx) {
225:                cntx.normalize();
226:
227:                for (Node n = cntx.getFirstChild(); n != null; n = n
228:                        .getNextSibling()) {
229:                    if (n.getNodeType() == Node.TEXT_NODE) {
230:                        return n.getNodeValue();
231:                    } else if (n.getNodeType() == Node.CDATA_SECTION_NODE) {
232:                        return n.getNodeValue();
233:                    }
234:                }
235:                return null;
236:            }
237:
238:            /**
239:             * setup a specific scheduler service
240:             * @param ce the dom node to extract the parameters from
241:             * @param params the preparsed parameters found below the the domnode
242:             * @return <code>true</code> if the setup was successfull
243:             **/
244:            private boolean setupSchedulerService(Element ce, Map params)
245:                    throws RegistryException, SchedulerException {
246:                SchedulerServiceFactory sfact = null;
247:                Date start_at = null;
248:                Date stop_at = null;
249:                long frequency = 0;
250:                long delay = 0;
251:                boolean start_once = false;
252:                SchedulerService service_impl = null;
253:
254:                String id = ce.getAttribute("id").trim();
255:                String freq_s = ce.getAttribute("frequency").trim();
256:                String freq_unit_s = ce.getAttribute("freq-unit").trim();
257:                String delay_s = ce.getAttribute("delay").trim();
258:                String delay_unit = ce.getAttribute("delay-unit").trim();
259:                String start_date_s = ce.getAttribute("start-date").trim();
260:                String start_time_s = ce.getAttribute("start-time").trim();
261:                String stop_date_s = ce.getAttribute("stop-date").trim();
262:                String stop_time_s = ce.getAttribute("stop-time").trim();
263:                String fact_s = ce.getAttribute("factory-class").trim();
264:
265:                /* [1] load the factory class */
266:                try {
267:                    Class fact = Class.forName(fact_s.trim());
268:                    sfact = (SchedulerServiceFactory) fact.newInstance();
269:                } catch (Exception e) {
270:                    cat.error("Can't load scheduler service: '" + fact_s
271:                            + "' (" + e + ")");
272:                    return false;
273:                }
274:
275:                /* [2] parse the start information */
276:                start_at = parsePointOfTime(start_date_s, start_time_s,
277:                        new Date());
278:                if (start_at == null)
279:                    return false;
280:
281:                /* [2] parse the start information */
282:                stop_at = parsePointOfTime(stop_date_s, stop_time_s, null);
283:
284:                /* [3] parse the frequency information */
285:                start_once = "ONCE".equals(freq_s.toUpperCase());
286:                if (!start_once) {
287:                    try {
288:                        frequency = parseTimeWithUnit(freq_s, freq_unit_s);
289:                    } catch (NumberFormatException nfe) {
290:                        cat.error("Bad frequency setting: '" + freq_s + " "
291:                                + freq_unit_s + "' for scheduler service '"
292:                                + id + "' (" + nfe + ")");
293:                        return false;
294:                    }
295:
296:                    if (frequency <= 0) {
297:                        cat
298:                                .error("bad or no time setting for scheduler service '"
299:                                        + id + "'");
300:                        return false;
301:                    }
302:
303:                    try {
304:                        delay = parseTimeWithUnit(delay_s, delay_unit);
305:                    } catch (NumberFormatException nfe) {
306:                        cat.error("Bad delay setting: '" + delay_s + " "
307:                                + delay_unit + "' for scheduler service '" + id
308:                                + "' (" + nfe + ")");
309:                        return false;
310:                    }
311:                }
312:
313:                /* [4] set the params to the factory */
314:                if (params != null) {
315:                    for (Iterator it = params.keySet().iterator(); it.hasNext();) {
316:                        String key = (String) it.next();
317:                        sfact.setProperty(key, params.get(key));
318:                    }
319:                }
320:
321:                /* [5] register the service */
322:                if (start_once)
323:                    registerOneTimeService(id, start_at, sfact);
324:                else
325:                    registerFrequentService(id, start_at, stop_at, frequency,
326:                            delay, sfact);
327:
328:                return true;
329:            }
330:
331:            /**
332:             * parses a date (format: dd.mm.yyyy) and time (format: hh:mm:ss) string
333:             * @param at_date the date string properly trimmed
334:             * @param at_time the time string properly trimmed
335:             * @return the resulting date or <code>null</code> if a parse exception
336:             * (or similar) occured
337:             * @param def the default date to use if no valid date could be parsed
338:             * @return the date recognized
339:             **/
340:            private Date parsePointOfTime(String at_date, String at_time,
341:                    Date def) {
342:                Date start_at_date = null;
343:                Date start_at_time = null;
344:
345:                /* [2] parse the date and time information */
346:                if (at_date != null && at_date.length() > 0) {
347:                    try {
348:                        start_at_date = date_format.parse(at_date);
349:                    } catch (ParseException pe) {
350:                        cat.error("bad date setting: '" + pe + "'");
351:                        return null;
352:                    }
353:                }
354:
355:                if (at_time != null && at_time.length() > 0) {
356:                    try {
357:                        start_at_time = time_format.parse(at_time);
358:                    } catch (ParseException pe) {
359:                        cat.error("bad time setting: '" + pe + "'");
360:                        return null;
361:                    }
362:                }
363:
364:                if (start_at_date != null && start_at_time != null) {
365:                    Calendar dcal = Calendar.getInstance();
366:                    Calendar tcal = Calendar.getInstance();
367:                    dcal.setTime(start_at_date);
368:                    tcal.setTime(start_at_time);
369:
370:                    return new GregorianCalendar(dcal.get(Calendar.YEAR), dcal
371:                            .get(Calendar.MONTH), dcal
372:                            .get(Calendar.DAY_OF_MONTH), tcal
373:                            .get(Calendar.HOUR_OF_DAY), tcal
374:                            .get(Calendar.MINUTE), tcal.get(Calendar.SECOND))
375:                            .getTime();
376:                } else if (start_at_date != null) {
377:                    return start_at_date;
378:                } else if (start_at_time != null) {
379:                    Calendar dcal = Calendar.getInstance(); // relative to now!
380:                    Calendar tcal = Calendar.getInstance();
381:                    tcal.setTime(start_at_time);
382:                    return new GregorianCalendar(dcal.get(Calendar.YEAR), dcal
383:                            .get(Calendar.MONTH), dcal
384:                            .get(Calendar.DAY_OF_MONTH), tcal
385:                            .get(Calendar.HOUR_OF_DAY), tcal
386:                            .get(Calendar.MINUTE), tcal.get(Calendar.SECOND))
387:                            .getTime();
388:                }
389:
390:                return def;
391:            }
392:
393:            /**
394:             * parses a gap-of-time information according to a unit.  The units
395:             * known are: minutes, seconds, days, hours
396:             * @param tmstr the gap-of-time string
397:             * @param unit the unit string, if <code>null</code> or empty defaults to "minute"
398:             * @return the time computed to milliseconds
399:             *
400:             * @throws NumberFormatException if the timestring was bad or an
401:             * unknown unit was used.
402:             **/
403:            private long parseTimeWithUnit(String tmstr, String unit)
404:                    throws NumberFormatException {
405:                long tm = Long.parseLong(tmstr);
406:
407:                if (unit != null && unit.length() > 0) {
408:                    if ("SECONDS".equals(unit.toUpperCase()))
409:                        tm *= MILLISECONDS_PER_SEC;
410:                    else if ("MINUTES".equals(unit.toUpperCase()))
411:                        tm *= MILLISECONDS_PER_MIN;
412:                    else if ("HOURS".equals(unit.toUpperCase()))
413:                        tm *= MILLISECONDS_PER_HOUR;
414:                    else if ("DAYS".equals(unit.toUpperCase()))
415:                        tm *= MILLISECONDS_PER_DAY;
416:                    else
417:                        throw new NumberFormatException("unknown time unit: '"
418:                                + unit + "'");
419:                } else
420:                    tm *= MILLISECONDS_PER_MIN;
421:
422:                return tm;
423:            }
424:
425:            /* ----------------------------------------------------------------------
426:               the scheduler master thread stuff
427:               ---------------------------------------------------------------------- */
428:            /**
429:             * default sleep time
430:             **/
431:            private final static long DEFAULT_CHECK_TIME = 10 * 1000; // 5 second
432:
433:            /**
434:             * minimum check time
435:             **/
436:            private final static long MIN_CHECK_TIME = 1000; // 1 second
437:
438:            /**
439:             * the list of schedulers
440:             **/
441:            private ArrayList schedulers = new ArrayList();
442:
443:            /**
444:             * the iterator for the scheduler checking
445:             **/
446:            private Iterator checker = null;
447:
448:            /**
449:             * the scheduler thread
450:             **/
451:            private SchedulerThread thread = null;
452:
453:            /**
454:             * the time between two checks for due schedulers
455:             **/
456:            private long sleepTime = DEFAULT_CHECK_TIME;
457:
458:            /**
459:             * kicks off the scheduling check thread
460:             **/
461:            private void startThread() {
462:                if (thread == null && schedulers.size() > 0) {
463:                    thread = new SchedulerThread(this );
464:                    Thread t = new Thread(thread);
465:
466:                    /* the timer thread is a time daemon only. */
467:                    t.setDaemon(true);
468:                    t.start();
469:                }
470:            }
471:
472:            /**
473:             * checks the next scheduler in the scheduler list
474:             **/
475:            void checkNext() {
476:                cat.info("check next");
477:                synchronized (schedulers) {
478:                    if (checker == null || !checker.hasNext()) {
479:                        checker = schedulers.iterator();
480:                        if (!checker.hasNext()) {
481:                            thread.stop();
482:                            thread = null;
483:                            sleepTime = DEFAULT_CHECK_TIME;
484:                        }
485:                    }
486:
487:                    ServiceEntry srve = (ServiceEntry) checker.next();
488:                    Date now = new Date();
489:                    if (srve.isDue(now))
490:                        srve.executeNewService();
491:
492:                    if (srve.isOutdated(now)) {
493:                        cat
494:                                .debug("remove outdated service + '" + srve.id
495:                                        + "'");
496:                        checker.remove();
497:                    }
498:                }
499:            }
500:
501:            /**
502:             * returns the current sleep time for the timer thread
503:             **/
504:            long getSleepTime() {
505:                return sleepTime;
506:            }
507:
508:            /**
509:             * adds a service entry to the list of services.  
510:             * @param se the service entry to add, must not be <code>null</code>
511:             * @param _hint a time hint to use.  this is normaly the frequency, in
512:             * which the service should be used.
513:             **/
514:            private void addService(ServiceEntry se, long _hint) {
515:                synchronized (schedulers) {
516:                    cat.info("register scheduler service '" + se.id + "' ("
517:                            + se.factory.getClass().getName() + ") hint at: "
518:                            + _hint);
519:                    schedulers.add(se);
520:
521:                    /* if the hinted time frame is smalled than the actually sleep
522:                       time frame, use this one */
523:                    if (_hint < sleepTime) {
524:                        if (_hint > 0)
525:                            sleepTime = _hint + MIN_CHECK_TIME;
526:                        else
527:                            sleepTime = MIN_CHECK_TIME;
528:                    }
529:                    if (thread == null)
530:                        startThread();
531:
532:                    /* adding an object, makes the iterator unusable */
533:                    checker = null;
534:                }
535:            }
536:
537:            /**
538:             * registers a scheduler service, to be called on a regular base.  This
539:             * frequent repetition is characteristized by a start and stop point in
540:             * time, a start off delay and a repetition frequency.
541:             * @param _id a descriptive id of the service
542:             * @param _start_at start point
543:             * @param _stop_at stop point, if <code>null</code> stops never
544:             * @param _frequency the repetition frequency in milliseconds
545:             * @param _delay the start off delay in milliseconds, relative to _start_at
546:             * @param _sfact the scheduler services factory class
547:             **/
548:            public void registerFrequentService(String _id, Date _start_at,
549:                    Date _stop_at, long _frequency, long _delay,
550:                    SchedulerServiceFactory _sfact) {
551:                addService(new FrequentService(_id, _start_at, _stop_at,
552:                        _frequency, _delay, _sfact), _frequency);
553:            }
554:
555:            /**
556:             * registers a scheduler service, to be called excatly once, sometime
557:             * in the future.
558:             * @param _id a descriptive id of the service
559:             * @param _start_at the point in time to start the service
560:             * @param _sfact the scheduler services factory class
561:             **/
562:            public void registerOneTimeService(String _id, Date _start_at,
563:                    SchedulerServiceFactory _sfact) {
564:                Calendar cal = Calendar.getInstance();
565:                cal.setTime(_start_at);
566:                long check_time = System.currentTimeMillis()
567:                        - cal.getTime().getTime();
568:
569:                addService(new OneTimeService(_id, _start_at, _sfact),
570:                        check_time);
571:            }
572:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.