KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > rift > coad > daemon > timer > TimerImpl


1 /*
2  * Timer: The timer class
3  * Copyright (C) 2006-2007 Rift IT Contracting
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * TimerImpl.java
20  */

21
22 package com.rift.coad.daemon.timer;
23
24 // java imports
25
import java.io.Serializable JavaDoc;
26 import java.rmi.RemoteException JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Calendar JavaDoc;
29 import java.util.Date JavaDoc;
30 import java.util.List JavaDoc;
31 import javax.naming.NamingException JavaDoc;
32 import javax.rmi.PortableRemoteObject JavaDoc;
33 import javax.transaction.HeuristicMixedException JavaDoc;
34 import javax.transaction.HeuristicRollbackException JavaDoc;
35 import javax.transaction.NotSupportedException JavaDoc;
36 import javax.transaction.RollbackException JavaDoc;
37 import javax.transaction.SystemException JavaDoc;
38 import javax.naming.Context JavaDoc;
39 import javax.naming.InitialContext JavaDoc;
40 import javax.transaction.UserTransaction JavaDoc;
41 import javax.transaction.Status JavaDoc;
42
43 // logging import
44
import org.apache.log4j.Logger;
45
46 // coadunation imports
47
import com.rift.coad.lib.configuration.Configuration;
48 import com.rift.coad.lib.configuration.ConfigurationFactory;
49 import com.rift.coad.lib.common.CommonException;
50 import com.rift.coad.lib.common.ObjectSerializer;
51 import com.rift.coad.lib.bean.BeanRunnable;
52 //import com.rift.coad.daemon.timer.db.util.HibernateUtil;
53
import com.rift.coad.hibernate.util.HibernateUtil;
54 import com.rift.coad.daemon.timer.db.Schedule;
55 import com.rift.coad.lib.thread.ThreadStateMonitor;
56 import com.rift.coad.lib.thread.CoadunationThread;
57
58 // hibernate imports
59
import org.hibernate.Session;
60 import org.hibernate.Transaction;
61
62 /**
63  * The Timer implementation implements the Timer interface. All the logic
64  * involved in creating, processing, listing and deleting events is within the
65  * methods of this class.
66  *
67  * @author Glynn Chaldecott
68  */

69 public class TimerImpl implements Timer, BeanRunnable {
70     
71     /**
72      * The timer thread is responsible for peforming the processing on the
73      * target.
74      */

75     public class TimerThread extends CoadunationThread {
76         
77         // private member variables
78
private Object JavaDoc[] row = null;
79         /**
80          * The constructor of the timer thread
81          */

82         public TimerThread(Object JavaDoc[] row) throws Exception JavaDoc {
83             this.row = row;
84         }
85         
86         /**
87          * This method is reponsible for performing the processing for this
88          * object.
89          */

90         public void process() {
91             String JavaDoc jndi = null;
92             UserTransaction JavaDoc ut = null;
93             try {
94                 ut = (UserTransaction JavaDoc)ctx.lookup("java:comp/UserTransaction");
95                 ut.begin();
96
97                 Session session = HibernateUtil
98                         .getInstance(com.rift.coad.daemon.timer.TimerImpl.class)
99                         .getSession();
100
101                 jndi = (String JavaDoc) row[0];
102                 byte[] b_event = (byte[]) row[1];
103                 byte recure = ((Byte JavaDoc) row[2]).byteValue();
104                 int id = Integer.parseInt(row[3].toString());
105                 if (recure == 0) {
106                     session.createQuery(
107                             "DELETE FROM Schedule as sche WHERE " +
108                             "sche.id = ?").
109                             setInteger(0,id).executeUpdate();
110                 }
111                 Object JavaDoc obj = ctx.lookup(jndi);
112                 com.rift.coad.daemon.timer.TimerEventHandler
113                         beanInterface =
114                         (com.rift.coad.daemon.timer.TimerEventHandler)
115                         PortableRemoteObject.narrow(obj,
116                         com.rift.coad.daemon.timer.
117
                        TimerEventHandler.class);
118                 Serializable JavaDoc event = (Serializable JavaDoc)
119                 ObjectSerializer.deserialize(b_event);
120                 beanInterface.processEvent(event);
121
122                 ut.commit();
123             } catch (Exception JavaDoc ex) {
124                 log.warn("Failed to process timer event for [" + jndi
125                         + "] because :" + ex.getMessage(), ex);
126                 try {
127                     ut.rollback();
128                 } catch (Exception JavaDoc ex2) {
129                     log.error("Failed to rollback the transaction " +
130                             "event :" + ex2.getMessage(), ex2);
131                 }
132             }
133         }
134         
135         
136         /**
137          * The terminate method
138          */

139         public void terminate() {
140             // ignore
141
}
142     }
143     
144     // class constants
145
private final static String JavaDoc TIMER_USERNAME = "timer_user";
146     
147     // the class log variable
148
protected Logger log =
149             Logger.getLogger(TimerImpl.class.getName());
150     
151     private Context JavaDoc ctx = null;
152     private ThreadStateMonitor state = null;
153     private String JavaDoc username = null;
154     
155     /** Creates a new instance of TimerImpl */
156     public TimerImpl() throws NamingException JavaDoc, TimerException {
157         ctx = new InitialContext JavaDoc();
158 // HibernateUtil.init();
159
state = new ThreadStateMonitor(60000);
160         try {
161             Configuration config = ConfigurationFactory.getInstance().
162                     getConfig(TimerImpl.class);
163             username = config.getString(TIMER_USERNAME);
164         } catch (Exception JavaDoc ex) {
165             log.error("Failed to instanciate the timer : " +
166                     ex.getMessage(),ex);
167             throw new TimerException("Failed to instanciate the timer : " +
168                     ex.getMessage());
169         }
170     }
171     
172     /**
173      * This method will register an event on the database.
174      *
175      * @param JNDI This is a string for the JNDI of the daemon that is to be
176      * called by the event.
177      * @param month The month of the event. -1 will occur monthly. (This
178      * parameter is zero indexed)
179      * @param day The day of the event. -1 will occur daily.
180      * @param hour The hour of the event. -1 will occur hourly.
181      * @param minute The minute of the event. -1 will occur every minute.
182      * @param event This is a serializable object used to identify an individual
183      * event.
184      * @param recure The value of this indicates whether an event will occur
185      * more then once of be deleted from the database after a single
186      * occurence. True will cause it to recure, false will result in it
187      * being deleted after a single occurence
188      */

189     public void register(String JavaDoc JNDI, int month, int day, int hour, int minute,
190             Serializable JavaDoc event, boolean recure) throws RemoteException JavaDoc,
191             TimerException {
192         try {
193             
194             Session session = HibernateUtil
195                         .getInstance(com.rift.coad.daemon.timer.TimerImpl.class)
196                         .getSession();
197             
198             byte[] b_event;
199             byte recure2 = 0;
200             if (recure == false) {
201                 recure2 = 0;
202             } else {
203                 recure2 = 1;
204             }
205             b_event = ObjectSerializer.serialize(event);
206             Schedule schedule = new Schedule(JNDI,month,day,hour,minute,b_event,
207                     recure2);
208             session.save(schedule);
209             
210             log.info("Registered a new event for : " + JNDI);
211             
212         } catch (Exception JavaDoc ex) {
213             log.error("Failed to register timer events :"
214                     + ex.getMessage(),ex);
215             throw new TimerException("Failed to register timer events :" +
216                     ex.getMessage());
217         }
218     }
219     
220     /**
221      * This method terminates the thread.
222      */

223     public void terminate() {
224         state.terminate(true);
225     }
226     
227     
228     /**
229      * This method is the thread. It loops once every minute checking the
230      * database for events assigned to that time. It then processes the event
231      * and deletes it from the database should recure be set to false.
232      */

233     public void process() {
234         while (!state.isTerminated()) {
235             // sleep so that other things can load
236
state.monitor();
237             if (state.isTerminated()) {
238                 // break out as this is terminated
239
break;
240             }
241             
242             UserTransaction JavaDoc ut = null;
243             try {
244                 
245                 ut = (UserTransaction JavaDoc)ctx.lookup("java:comp/UserTransaction");
246                 
247                 ut.begin();
248                 
249                 Session session = HibernateUtil
250                         .getInstance(com.rift.coad.daemon.timer.TimerImpl.class)
251                         .getSession();
252                 
253                 Calendar JavaDoc currentDate = Calendar.getInstance();
254                 
255                 List JavaDoc list = session.createSQLQuery("SELECT Schedule.jndi, " +
256                         "Schedule.event, Schedule.recure, Schedule.id FROM " +
257                         "Schedule WHERE " +
258                         "(month=? OR month=-1)" +
259                         " AND " +
260                         "(day=? OR day=-1)" +
261                         " AND " +
262                         "(hour=? OR hour=-1)" +
263                         " AND " +
264                         "(minute=? OR minute=-1)")
265                         .setInteger(0,currentDate.get(Calendar.MONTH))
266                         .setInteger(1,currentDate.get(Calendar.DAY_OF_MONTH))
267                         .setInteger(2,currentDate.get(Calendar.HOUR))
268                         .setInteger(3,currentDate.get(Calendar.MINUTE))
269                         .list();
270                 
271                 java.util.ArrayList JavaDoc copy = new java.util.ArrayList JavaDoc();
272                 copy.addAll(list);
273                 
274                 ut.commit();
275                 
276                 for (int index = 0; index < list.size() && !state.isTerminated();
277                         index++){
278                     TimerThread timerThread = new TimerThread((Object JavaDoc[])list.
279                             get(index));
280                     timerThread.start(username);
281                 }
282                 
283             } catch (Exception JavaDoc ex) {
284                 log.error("Failed to process timer events :" + ex.getMessage(),
285                         ex);
286                 try {
287                     ut.rollback();
288                 } catch (Exception JavaDoc ex2) {
289                     log.error("Rollback failed because :" + ex2.getMessage(),
290                             ex2);
291                 }
292             }
293         }
294     }
295     
296     
297     /**
298      * This method returns a list of all the events currently stored in the
299      * database.
300      *
301      * @return The method returns a List of TimerEvent objects. The TimerEvent
302      * object contains all the properties of an event from the
303      * database.
304      */

305     public TimerEvent[] listEvents() throws RemoteException JavaDoc, TimerException {
306         String JavaDoc returnString = "";
307         TimerEvent[] returnList = null;
308         try {
309             
310             Session session = HibernateUtil
311                         .getInstance(com.rift.coad.daemon.timer.TimerImpl.class)
312                         .getSession();
313             
314             List JavaDoc list = session.createSQLQuery("SELECT id,jndi,month,day," +
315                     "hour,minute,event,recure FROM Schedule ORDER BY id").list();
316             
317             returnList = new TimerEvent[list.size()];
318             for (int i = 0; i < list.size(); i ++) {
319                 Object JavaDoc[] row = (Object JavaDoc[]) list.get(i);
320                 TimerEvent tempEvent = new TimerEvent();
321                 tempEvent.setId(((Integer JavaDoc)row[0]).intValue());
322                 tempEvent.setJndi(row[1].toString());
323                 tempEvent.setMonth(((Integer JavaDoc)row[2]).intValue());
324                 tempEvent.setDay(((Integer JavaDoc)row[3]).intValue());
325                 tempEvent.setHour(((Integer JavaDoc)row[4]).intValue());
326                 tempEvent.setMinute(((Integer JavaDoc)row[5]).intValue());
327                 byte[] b_event = (byte[]) row[6];
328                 Serializable JavaDoc event = (Serializable JavaDoc)
329                         ObjectSerializer.deserialize(b_event);
330                 tempEvent.setEvent(event);
331                 if (((Byte JavaDoc)row[7]).byteValue() == 0) {
332                     tempEvent.setRecure(false);
333                 } else {
334                     tempEvent.setRecure(true);
335                 }
336                 returnList[i] = tempEvent;
337             }
338             
339         } catch (Exception JavaDoc ex) {
340             log.error("Failed to list timer events :" + ex.getMessage(),
341                     ex);
342             throw new TimerException("Failed to list timer events :" +
343                     ex.getMessage());
344         }
345         return returnList;
346     }
347     
348     /**
349      * This method deletes an event based on a supplied event ID which
350      * corresponds to the database ID.
351      *
352      * @param eventID The database ID of the event.
353      */

354     public void deleteEvent(int eventId) throws RemoteException JavaDoc,
355             TimerException {
356         try {
357             log.info("Remove event Event id : " + eventId);
358             
359             Session session = HibernateUtil
360                         .getInstance(com.rift.coad.daemon.timer.TimerImpl.class)
361                         .getSession();
362             
363             session.createQuery(
364                     "DELETE FROM Schedule as sche WHERE sche.id = ?")
365                     .setInteger(0,eventId)
366                     .executeUpdate();
367             
368         } catch (Exception JavaDoc ex) {
369             log.error("Failed to delete timer event :" + ex.getMessage(),
370                     ex);
371             throw new TimerException("Failed to delete timer event :" +
372                     ex.getMessage());
373         }
374     }
375     
376 }
377
Popular Tags