001: /*
002: * $Id: Worklist.java 1296 2007-08-09 13:25:14Z hengels $
003: * (c) Copyright 2004 con:cern development team.
004: *
005: * This file is part of con:cern (http://concern.org).
006: *
007: * con:cern is free software; you can redistribute it and/or modify
008: * it under the terms of the GNU Lesser General Public License
009: * as published by the Free Software Foundation; either version 2.1
010: * of the License, or (at your option) any later version.
011: *
012: * Please see COPYING for the complete licence.
013: */
014: package org.concern.controller;
015:
016: import org.concern.*;
017: import org.concern.Subject;
018: import org.concern.Assignment;
019: import org.hibernate.*;
020: import org.apache.commons.logging.LogFactory;
021:
022: import javax.transaction.TransactionManager;
023: import java.sql.Timestamp;
024: import java.util.*;
025:
026: /**
027: * @author hengels
028: * @version $Revision: 1296 $
029: */
030: public class Worklist implements org.concern.Worklist {
031: private static org.apache.commons.logging.Log LOG = LogFactory
032: .getLog(Worklist.class);
033:
034: private long timerInterval = 10000;
035: Sessions sessions = new DefaultSessions();
036: private Transactions transactions = new Transactions(
037: new NoTransactionManager(sessions));
038:
039: private java.util.Timer timer;
040: private TimeoutTask timeoutTask;
041: private List<AssignmentListener> eventListeners = new ArrayList<AssignmentListener>();
042:
043: public long getTimerInterval() {
044: return timerInterval;
045: }
046:
047: public void setTimerInterval(long timerInterval) {
048: this .timerInterval = timerInterval;
049: }
050:
051: public void setSessionFactory(SessionFactory sessionFactory) {
052: this .sessions.setSessionFactory(sessionFactory);
053: }
054:
055: public void setTransactionManager(
056: TransactionManager transactionManager) {
057: this .transactions.setTransactionManager(transactionManager);
058: SessionFactory sessionFactory = this .sessions
059: .getSessionFactory();
060: this .sessions = new JTASessions();
061: this .sessions.setSessionFactory(sessionFactory);
062: this .sessions.setTransactionManager(transactionManager);
063: }
064:
065: public List<Subject> listSubjects(String[] assignees,
066: String[] processes, String[] keywords,
067: String[] originators, int state, String[] orders,
068: String language, int maxResults) {
069: try {
070: StringBuffer buffer = new StringBuffer();
071: buffer
072: .append("select new org.concern.Subject(subject.process, subject.userValue, line.line, subject.originator, subject.created, subject.state)");
073: buffer
074: .append(" from Subject subject inner join subject.subjectLines line");
075: buffer.append(" where subject.state = :state");
076: buffer.append(" and :language = line.language");
077:
078: if (processes != null && processes.length != 0)
079: buffer.append(" and subject.process in (:processes)");
080:
081: if (keywords != null) {
082: for (int i = 0; i < keywords.length; i++) {
083: String keyword = keywords[i];
084: if ('-' == keyword.charAt(0))
085: buffer
086: .append(" and line.line not like :keyword"
087: + i);
088: else
089: buffer.append(" and line.line like :keyword"
090: + i);
091: }
092: }
093:
094: if (originators != null && originators.length != 0)
095: buffer
096: .append(" and subject.originator in (:originators)");
097:
098: if (orders != null && orders.length != 0) {
099: buffer.append(" order by ");
100: for (int i = 0; i < orders.length; i++) {
101: String order = orders[i];
102: if (i > 0)
103: buffer.append(", ");
104:
105: appendOrder(order, buffer);
106: }
107: } else
108: buffer.append(" order by subject.process, line.line");
109:
110: transactions.beginRequired();
111: Query query = sessions.getSession().createQuery(
112: buffer.toString()).setInteger("state", state)
113: .setParameter("language", language).setFetchSize(
114: maxResults);
115: if (processes != null && processes.length != 0)
116: query.setParameterList("processes", Arrays
117: .asList(processes));
118: if (keywords != null) {
119: for (int i = 0; i < keywords.length; i++) {
120: String keyword = keywords[i];
121: if ('-' == keyword.charAt(0)
122: || '+' == keyword.charAt(0))
123: query.setParameter("keyword" + i, "%"
124: + keyword.substring(1) + "%");
125: else
126: query.setParameter("keyword" + i, "%" + keyword
127: + "%");
128: }
129: }
130: if (originators != null && originators.length != 0)
131: query.setParameterList("originators", Arrays
132: .asList(originators));
133: List<Subject> list = query.list();
134:
135: if (list.size() != 0 && assignees != null
136: && assignees.length != 0) {
137: Map<String, Subject> byUserValue = new HashMap<String, Subject>();
138: for (Iterator iterator = list.iterator(); iterator
139: .hasNext();) {
140: Subject subject = (Subject) iterator.next();
141: byUserValue.put(subject.getProcess()
142: + subject.getSubjectId(), subject);
143: }
144: buffer = new StringBuffer();
145: buffer
146: .append("select subject.process || subject.userValue, enlistment.activity");
147: buffer.append(" from Subject subject");
148: buffer
149: .append(" inner join subject.enlistments enlistment");
150: buffer
151: .append(" inner join enlistment.assignments assignment");
152: buffer.append(" where enlistment.timeout = "
153: + Long.MAX_VALUE);
154: buffer
155: .append(" and subject.process || subject.userValue in (:userValues)");
156: buffer
157: .append(" and assignment.assignee in (:assignees)");
158: query = sessions.getSession().createQuery(
159: buffer.toString());
160: query.setParameterList("userValues", byUserValue
161: .keySet());
162: query.setParameterList("assignees", Arrays
163: .asList(assignees));
164: List options = query.list();
165: for (Iterator iterator = options.iterator(); iterator
166: .hasNext();) {
167: Object[] objects = (Object[]) iterator.next();
168: Subject subject = byUserValue.get(objects[0]);
169: subject.getOptions().add(objects[1]);
170: }
171:
172: for (Iterator<Subject> iterator = list.iterator(); iterator
173: .hasNext();) {
174: Subject subject = iterator.next();
175: if (subject.getOptions().size() == 0)
176: iterator.remove();
177: }
178: }
179:
180: return list;
181: } finally {
182: try {
183: transactions.endRequired();
184: } catch (ControllerException t) {
185: t.printStackTrace();
186: throw t;
187: }
188: }
189: }
190:
191: public List<Subject> listArchivedSubjects(String[] processes,
192: String[] keywords, String[] originators, String[] orders,
193: String language, int maxResults) {
194: try {
195: StringBuffer buffer = new StringBuffer();
196: buffer
197: .append("select new org.concern.Subject(subject.process, subject.userValue, line.line, subject.originator, subject.created, 5)");
198: buffer
199: .append(" from ArchiveSubject subject inner join subject.subjectLines line");
200: buffer.append(" where :language = line.language");
201:
202: if (processes != null && processes.length != 0)
203: buffer.append(" and subject.process in (:processes)");
204:
205: if (keywords != null) {
206: for (int i = 0; i < keywords.length; i++) {
207: String keyword = keywords[i];
208: if ('-' == keyword.charAt(0))
209: buffer
210: .append(" and line.line not like :keyword"
211: + i);
212: else
213: buffer.append(" and line.line like :keyword"
214: + i);
215: }
216: }
217:
218: if (originators != null && originators.length != 0)
219: buffer
220: .append(" and subject.originator in (:originators)");
221:
222: if (orders != null && orders.length != 0) {
223: buffer.append(" order by ");
224: for (int i = 0; i < orders.length; i++) {
225: String order = orders[i];
226: if (i > 0)
227: buffer.append(", ");
228:
229: appendOrder(order, buffer);
230: }
231: } else
232: buffer.append(" order by subject.process, line.line");
233:
234: transactions.beginRequired();
235: Query query = sessions.getSession().createQuery(
236: buffer.toString()).setParameter("language",
237: language).setFetchSize(maxResults);
238: if (processes != null && processes.length != 0)
239: query.setParameterList("processes", Arrays
240: .asList(processes));
241: if (keywords != null) {
242: for (int i = 0; i < keywords.length; i++) {
243: String keyword = keywords[i];
244: if ('-' == keyword.charAt(0)
245: || '+' == keyword.charAt(0))
246: query.setParameter("keyword" + i, "%"
247: + keyword.substring(1) + "%");
248: else
249: query.setParameter("keyword" + i, "%" + keyword
250: + "%");
251: }
252: }
253: if (originators != null && originators.length != 0)
254: query.setParameterList("originators", Arrays
255: .asList(originators));
256: List<Subject> list = query.list();
257:
258: return list;
259: } finally {
260: try {
261: transactions.endRequired();
262: } catch (ControllerException t) {
263: t.printStackTrace();
264: throw t;
265: }
266: }
267: }
268:
269: public List<Work> listWork(String[] userids, String language,
270: int maxResults) {
271: try {
272: StringBuffer buffer = new StringBuffer();
273: buffer
274: .append("select new org.concern.Work(subject.process, enlistment.activity, subject.userValue, line.line,");
275: buffer
276: .append(" subject.originator, enlistment.timeout, enlistment.trials, enlistment.lockedBy, enlistment.lockedUntil)");
277: buffer.append(" from Subject subject");
278: buffer.append(" inner join subject.subjectLines line");
279: buffer.append(" inner join subject.enlistments enlistment");
280: buffer
281: .append(" inner join enlistment.assignments assignment");
282: buffer.append(" where subject.state != 2");
283: buffer.append(" and assignment.assignee in (:assignees)");
284: buffer.append(" and :language = line.language");
285: buffer.append(" and enlistment.timeout != "
286: + Long.MAX_VALUE);
287: buffer
288: .append(" order by subject.process, enlistment.activity, enlistment.timeout");
289:
290: transactions.beginRequired();
291: Query query = sessions.getSession().createQuery(
292: buffer.toString()).setParameterList("assignees",
293: Arrays.asList(userids)).setParameter("language",
294: language).setFetchSize(maxResults);
295: List<Work> list = query.list();
296:
297: return list;
298: } finally {
299: try {
300: transactions.endRequired();
301: } catch (ControllerException t) {
302: t.printStackTrace();
303: throw t;
304: }
305: }
306: }
307:
308: public List<Work> listWork(String[] assignees, String[] processes,
309: String[] activities, String[] keywords, String[] orders,
310: String language, int maxResults) {
311: try {
312: StringBuffer buffer = new StringBuffer();
313: buffer
314: .append("select new org.concern.Work(subject.process, enlistment.activity, subject.userValue, line.line,");
315: buffer
316: .append(" subject.originator, enlistment.timeout, enlistment.trials, enlistment.lockedBy, enlistment.lockedUntil)");
317: buffer.append(" from Subject subject");
318: buffer.append(" inner join subject.subjectLines line");
319: buffer.append(" inner join subject.enlistments enlistment");
320: buffer
321: .append(" inner join enlistment.assignments assignment");
322: buffer.append(" where subject.state != 2");
323: buffer.append(" and :language = line.language");
324: buffer.append(" and enlistment.timeout != "
325: + Long.MAX_VALUE);
326:
327: if (processes != null && processes.length != 0)
328: buffer.append(" and subject.process in (:processes)");
329:
330: if (assignees != null && assignees.length != 0)
331: buffer
332: .append(" and assignment.assignee in (:assignees)");
333: if (activities != null && activities.length != 0)
334: buffer
335: .append(" and enlistment.activity in (:activities)");
336: if (keywords != null) {
337: for (int i = 0; i < keywords.length; i++) {
338: String keyword = keywords[i];
339: if ('-' == keyword.charAt(0))
340: buffer
341: .append(" and line.line not like :keyword"
342: + i);
343: else
344: buffer.append(" and line.line like :keyword"
345: + i);
346: }
347: }
348: if (orders != null && orders.length != 0) {
349: buffer.append(" order by ");
350: for (int i = 0; i < orders.length; i++) {
351: String order = orders[i];
352: if (i > 0)
353: buffer.append(", ");
354:
355: appendOrder(order, buffer);
356: }
357: } else
358: buffer
359: .append(" order by subject.process, enlistment.activity, enlistment.timeout");
360:
361: transactions.beginRequired();
362: Query query = sessions.getSession().createQuery(
363: buffer.toString()).setParameter("language",
364: language).setFetchSize(maxResults);
365: if (processes != null && processes.length != 0)
366: query.setParameterList("processes", Arrays
367: .asList(processes));
368: if (assignees != null && assignees.length != 0)
369: query.setParameterList("assignees", Arrays
370: .asList(assignees));
371: if (activities != null && activities.length != 0)
372: query.setParameterList("activities", Arrays
373: .asList(activities));
374: if (keywords != null) {
375: for (int i = 0; i < keywords.length; i++) {
376: String keyword = keywords[i];
377: if ('-' == keyword.charAt(0)
378: || '+' == keyword.charAt(0))
379: query.setParameter("keyword" + i, "%"
380: + keyword.substring(1) + "%");
381: else
382: query.setParameter("keyword" + i, "%" + keyword
383: + "%");
384: }
385: }
386:
387: List<Work> list = query.list();
388: return list;
389: } finally {
390: try {
391: transactions.endRequired();
392: } catch (ControllerException t) {
393: t.printStackTrace();
394: throw t;
395: }
396: }
397: }
398:
399: public List<Assignment> listAssignments(String subject,
400: String[] processes, String[] activities, String[] keywords,
401: String[] orders, String language, int maxResults) {
402: try {
403: StringBuffer buffer = new StringBuffer();
404: buffer
405: .append("select new org.concern.Assignment(subject.process, enlistment.activity, subject.userValue, line.line,");
406: buffer
407: .append(" subject.originator, enlistment.timeout, enlistment.trials, enlistment.lockedBy, enlistment.lockedUntil, assignment.assignee)");
408: buffer.append(" from Subject subject");
409: buffer.append(" inner join subject.subjectLines line");
410: buffer.append(" inner join subject.enlistments enlistment");
411: buffer
412: .append(" inner join enlistment.assignments assignment");
413: buffer.append(" where subject.state != 2");
414: buffer.append(" and :language = line.language");
415:
416: if (processes != null && processes.length != 0)
417: buffer.append(" and subject.process in (:processes)");
418: if (subject != null)
419: buffer.append(" and subject.userValue = :subject");
420:
421: if (activities != null && activities.length != 0)
422: buffer
423: .append(" and enlistment.activity in (:activities)");
424: if (keywords != null) {
425: for (int i = 0; i < keywords.length; i++) {
426: String keyword = keywords[i];
427: if ('-' == keyword.charAt(0))
428: buffer
429: .append(" and line.line not like :keyword"
430: + i);
431: else
432: buffer.append(" and line.line like :keyword"
433: + i);
434: }
435: }
436: if (orders != null && orders.length != 0) {
437: buffer.append(" order by ");
438: for (int i = 0; i < orders.length; i++) {
439: String order = orders[i];
440: if (i > 0)
441: buffer.append(", ");
442:
443: appendOrder(order, buffer);
444: }
445: } else
446: buffer
447: .append(" order by subject.process, enlistment.activity, enlistment.timeout");
448:
449: transactions.beginRequired();
450: Query query = sessions.getSession().createQuery(
451: buffer.toString()).setParameter("language",
452: language).setFetchSize(maxResults);
453: if (subject != null)
454: query.setParameter("subject", subject);
455: if (processes != null && processes.length != 0)
456: query.setParameterList("processes", Arrays
457: .asList(processes));
458: if (activities != null && activities.length != 0)
459: query.setParameterList("activities", Arrays
460: .asList(activities));
461: if (keywords != null) {
462: for (int i = 0; i < keywords.length; i++) {
463: String keyword = keywords[i];
464: if ('-' == keyword.charAt(0)
465: || '+' == keyword.charAt(0))
466: query.setParameter("keyword" + i, "%"
467: + keyword.substring(1) + "%");
468: else
469: query.setParameter("keyword" + i, "%" + keyword
470: + "%");
471: }
472: }
473:
474: List<Assignment> list = query.list();
475: return list;
476: } finally {
477: try {
478: transactions.endRequired();
479: } catch (ControllerException t) {
480: t.printStackTrace();
481: throw t;
482: }
483: }
484: }
485:
486: private void appendOrder(String order, StringBuffer buffer) {
487: if ('-' == order.charAt(0))
488: buffer.append(order.substring(1) + " desc");
489: else if ('+' == order.charAt(0))
490: buffer.append(order.substring(1));
491: else
492: buffer.append(order);
493: }
494:
495: public boolean lock(org.concern.Work work, String user,
496: Timestamp until) throws UnknownSubjectException {
497: try {
498: transactions.beginRequired();
499: Enlistment enlistment = (Enlistment) sessions
500: .getSession()
501: .createQuery(
502: "select enlistment from org.concern.controller.Subject subject"
503: + " inner join subject.enlistments enlistment"
504: + " where subject.userValue = :subject"
505: + " and enlistment.activity = :activity")
506: .setString("subject", work.getSubjectId())
507: .setString("activity", work.getActivity())
508: .uniqueResult();
509:
510: if (enlistment.getLockedUntil() != null
511: && enlistment.getLockedUntil().getTime() > System
512: .currentTimeMillis()
513: && !enlistment.getLockedBy().equals(user)) {
514: return false;
515: } else {
516: enlistment.setLockedBy(user);
517: enlistment.setLockedUntil(until);
518: return true;
519: }
520: } finally {
521: try {
522: transactions.endRequired();
523: } catch (ControllerException t) {
524: t.printStackTrace();
525: throw t;
526: }
527: }
528: }
529:
530: public boolean unlock(org.concern.Work work, String user)
531: throws UnknownSubjectException {
532: try {
533: transactions.beginRequired();
534: Enlistment enlistment = (Enlistment) sessions
535: .getSession()
536: .createQuery(
537: "select enlistment from org.concern.controller.Subject subject"
538: + " inner join subject.enlistments enlistment"
539: + " where subject.userValue = :subject"
540: + " and enlistment.activity = :activity")
541: .setString("subject", work.getSubjectId())
542: .setString("activity", work.getActivity())
543: .uniqueResult();
544:
545: if (enlistment != null
546: && user.equals(enlistment.getLockedBy())) {
547: enlistment.setLockedBy(null);
548: enlistment.setLockedUntil(null);
549: return true;
550: } else {
551: return false;
552: }
553: } finally {
554: try {
555: transactions.endRequired();
556: } catch (ControllerException t) {
557: t.printStackTrace();
558: throw t;
559: }
560: }
561: }
562:
563: public void addAssignmentListener(AssignmentListener listener) {
564: eventListeners.add(listener);
565: }
566:
567: public void removeAssignmentListener(AssignmentListener listener) {
568: eventListeners.remove(listener);
569: }
570:
571: public Subject getSubject(String process, String subjectId,
572: String language, String assignee) {
573: try {
574: StringBuffer buffer = new StringBuffer();
575: buffer
576: .append("select new org.concern.Subject(subject.process, subject.userValue, line.line, subject.originator, subject.created, subject.state)");
577: buffer
578: .append(" from Subject subject inner join subject.subjectLines line");
579: buffer.append(" where subject.userValue = :userValue");
580: buffer.append(" and subject.process = :process");
581: buffer.append(" and :language = line.language");
582:
583: transactions.beginRequired();
584: Query query = sessions.getSession().createQuery(
585: buffer.toString()).setParameter("userValue",
586: subjectId).setParameter("process", process)
587: .setParameter("language", language);
588: Subject subject = (Subject) query.uniqueResult();
589:
590: if (subject != null) {
591: buffer = new StringBuffer();
592: buffer.append("select enlistment.activity");
593: buffer.append(" from Subject subject");
594: buffer
595: .append(" inner join subject.enlistments enlistment");
596: buffer
597: .append(" inner join enlistment.assignments assignment");
598: buffer.append(" where enlistment.timeout = "
599: + Long.MAX_VALUE);
600: buffer.append(" and subject.process = :process");
601: buffer.append(" and subject.userValue = :userValue");
602: buffer.append(" and assignment.assignee = :assignee");
603: query = sessions.getSession().createQuery(
604: buffer.toString());
605: query.setParameter("process", process);
606: query.setParameter("userValue", subjectId);
607: query.setParameter("assignee", assignee);
608: List options = query.list();
609: subject.getOptions().addAll(options);
610: }
611:
612: return subject;
613: } finally {
614: try {
615: transactions.endRequired();
616: } catch (ControllerException t) {
617: t.printStackTrace();
618: throw t;
619: }
620: }
621: }
622:
623: public Work getWork(String process, String subjectId,
624: String activity, String locale) {
625: try {
626: StringBuffer buffer = new StringBuffer();
627: buffer
628: .append("select new org.concern.Work(subject.process, enlistment.activity, subject.userValue, line.line,");
629: buffer
630: .append(" subject.originator, enlistment.timeout, enlistment.trials, enlistment.lockedBy, enlistment.lockedUntil)");
631: buffer.append(" from Subject subject");
632: buffer.append(" inner join subject.subjectLines line");
633: buffer.append(" inner join subject.enlistments enlistment");
634: buffer.append(" where subject.userValue = :userValue");
635: buffer.append(" and subject.process = :process");
636: buffer.append(" and enlistment.activity = :activity");
637: buffer.append(" and line.language = :language");
638:
639: transactions.beginRequired();
640: Query query = sessions.getSession().createQuery(
641: buffer.toString()).setParameter("userValue",
642: subjectId).setParameter("process", process)
643: .setParameter("activity", activity).setParameter(
644: "language", locale);
645: Work work = (Work) query.uniqueResult();
646:
647: return work;
648: } finally {
649: try {
650: transactions.endRequired();
651: } catch (ControllerException t) {
652: t.printStackTrace();
653: throw t;
654: }
655: }
656: }
657:
658: void timeout() {
659: try {
660: transactions.begin();
661: Query query = sessions
662: .getSession()
663: .createQuery(
664: "from org.concern.controller.AssignmentNotification a"
665: + " where a.id not in (select id from org.concern.controller.Assignment)");
666: List<AssignmentNotification> remove = query.list();
667: for (AssignmentNotification assignmentNotification : remove) {
668: fireUnassignedWork(assignmentNotification);
669: sessions.getSession().delete(assignmentNotification);
670: }
671:
672: query = sessions
673: .getSession()
674: .createQuery(
675: "select new org.concern.controller.Ensignment("
676: + " a.id, s.userValue, s.process, e.activity, e.trials, a.assignee"
677: + ")"
678: + " from org.concern.controller.Subject s join s.enlistments e join e.assignments a"
679: + " where a.id not in (select id from org.concern.controller.AssignmentNotification)");
680: List<AssignmentNotification> add = query.list();
681: for (AssignmentNotification ensignment : add) {
682: fireAssignedWork(ensignment);
683: AssignmentNotification assignmentNotification = new AssignmentNotification();
684: assignmentNotification.setId(ensignment.getId());
685: assignmentNotification.setActivity(ensignment
686: .getActivity());
687: assignmentNotification.setAssignee(ensignment
688: .getAssignee());
689: assignmentNotification.setLevel(ensignment.getLevel());
690: assignmentNotification.setProcess(ensignment
691: .getProcess());
692: assignmentNotification.setSubjectId(ensignment
693: .getSubjectId());
694: sessions.getSession().save(assignmentNotification);
695: }
696: } catch (HibernateException e) {
697: LOG.error("timeout", e);
698: } finally {
699: try {
700: transactions.commit();
701: } catch (ControllerException t) {
702: t.printStackTrace();
703: throw t;
704: }
705: }
706: }
707:
708: private void fireAssignedWork(
709: AssignmentNotification assignmentNotification) {
710: AssignmentEvent event = new AssignmentEvent(this ,
711: assignmentNotification.getProcess(),
712: assignmentNotification.getActivity(),
713: assignmentNotification.getSubjectId(),
714: assignmentNotification.getAssignee(),
715: assignmentNotification.getLevel());
716:
717: for (Iterator<AssignmentListener> iterator = eventListeners
718: .iterator(); iterator.hasNext();) {
719: AssignmentListener listener = iterator.next();
720: listener.assigned(event);
721: }
722: }
723:
724: private void fireUnassignedWork(
725: AssignmentNotification assignmentNotification) {
726: AssignmentEvent event = new AssignmentEvent(this ,
727: assignmentNotification.getProcess(),
728: assignmentNotification.getActivity(),
729: assignmentNotification.getSubjectId(),
730: assignmentNotification.getAssignee(),
731: assignmentNotification.getLevel());
732:
733: for (Iterator<AssignmentListener> iterator = eventListeners
734: .iterator(); iterator.hasNext();) {
735: AssignmentListener listener = iterator.next();
736: listener.unassigned(event);
737: }
738: }
739:
740: public void start() {
741: if (timer != null)
742: throw new IllegalStateException("already started");
743: timer = new java.util.Timer(true);
744: timeoutTask = new TimeoutTask();
745: timer.schedule(timeoutTask, getTimerInterval(),
746: getTimerInterval());
747: }
748:
749: public void stop() {
750: if (timer != null) {
751: timer.cancel();
752: timer = null;
753: }
754: }
755:
756: private class TimeoutTask extends TimerTask {
757: public void run() {
758: if (System.currentTimeMillis() - scheduledExecutionTime() >= getTimerInterval())
759: return;
760:
761: try {
762: timeout();
763: } catch (Throwable e) {
764: LOG.error("timeout.run", e);
765: }
766: }
767: }
768: }
|