KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > timerservice > quartz > QuartzTimerServiceFactory


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.ejb3.timerservice.quartz;
23
24 import java.sql.Connection JavaDoc;
25 import java.sql.PreparedStatement JavaDoc;
26 import java.sql.SQLException JavaDoc;
27 import java.util.Properties JavaDoc;
28
29 import javax.ejb.TimerService JavaDoc;
30 import javax.management.ObjectName JavaDoc;
31 import javax.naming.InitialContext JavaDoc;
32 import javax.transaction.HeuristicMixedException JavaDoc;
33 import javax.transaction.HeuristicRollbackException JavaDoc;
34 import javax.transaction.NotSupportedException JavaDoc;
35 import javax.transaction.RollbackException JavaDoc;
36 import javax.transaction.Status JavaDoc;
37 import javax.transaction.SystemException JavaDoc;
38 import javax.transaction.TransactionManager JavaDoc;
39
40 import org.jboss.ejb3.timerservice.TimedObjectInvoker;
41 import org.jboss.ejb3.timerservice.TimerServiceFactory;
42 import org.jboss.logging.Logger;
43 import org.jboss.tm.TransactionManagerService;
44 import org.quartz.Scheduler;
45 import org.quartz.SchedulerFactory;
46 import org.quartz.impl.StdSchedulerFactory;
47 import org.quartz.utils.DBConnectionManager;
48 import org.quartz.utils.JNDIConnectionProvider;
49
50 /**
51  * Creates timer service objects for use in EJB3 containers. For this
52  * two methods are provided: createTimerService and removeTimerService.
53  *
54  * The factory can be started and stopped within both an embedded and full stack.
55  *
56  * For now only one scheduler is supported. Each bean container has its own
57  * job and trigger group within Quartz.
58  *
59  * @author <a HREF="mailto:carlo@nerdnet.nl">Carlo de Wolf</a>
60  * @version $Revision: 56116 $
61  */

62 public class QuartzTimerServiceFactory extends TimerServiceFactory
63 {
64    @SuppressWarnings JavaDoc("unused")
65    private static final Logger log = Logger.getLogger(QuartzTimerServiceFactory.class);
66    
67    private TransactionManager JavaDoc tm;
68    
69    private static Scheduler scheduler;
70    
71    private Properties JavaDoc properties;
72    
73    /**
74     * Contains the sql statements to create the database schema.
75     */

76    private Properties JavaDoc sqlProperties;
77    
78    private void createSchema()
79    {
80       try
81       {
82          tm.begin();
83          try
84          {
85             Connection JavaDoc conn = getConnection();
86             try
87             {
88                boolean success = execute(conn, "CREATE_TABLE_JOB_DETAILS");
89                if(success)
90                {
91                   execute(conn, "CREATE_TABLE_JOB_LISTENERS");
92                   execute(conn, "CREATE_TABLE_TRIGGERS");
93                   execute(conn, "CREATE_TABLE_SIMPLE_TRIGGERS");
94                   execute(conn, "CREATE_TABLE_CRON_TRIGGERS");
95                   execute(conn, "CREATE_TABLE_BLOB_TRIGGERS");
96                   execute(conn, "CREATE_TABLE_TRIGGER_LISTENERS");
97                   execute(conn, "CREATE_TABLE_CALENDARS");
98                   execute(conn, "CREATE_TABLE_PAUSED_TRIGGER_GRPS");
99                   execute(conn, "CREATE_TABLE_FIRED_TRIGGERS");
100                   execute(conn, "CREATE_TABLE_SCHEDULER_STATE");
101                   execute(conn, "CREATE_TABLE_LOCKS");
102                   
103                   execute(conn, "INSERT_TRIGGER_ACCESS");
104                   execute(conn, "INSERT_JOB_ACCESS");
105                   execute(conn, "INSERT_CALENDAR_ACCESS");
106                   execute(conn, "INSERT_STATE_ACCESS");
107                   execute(conn, "INSERT_MISFIRE_ACCESS");
108                }
109             }
110             finally
111             {
112                conn.close();
113             }
114             tm.commit();
115          }
116          catch(SQLException JavaDoc e)
117          {
118             throw new RuntimeException JavaDoc(e);
119          }
120          catch (RollbackException JavaDoc e)
121          {
122             throw new RuntimeException JavaDoc(e);
123          }
124          catch (HeuristicMixedException JavaDoc e)
125          {
126             throw new RuntimeException JavaDoc(e);
127          }
128          catch (HeuristicRollbackException JavaDoc e)
129          {
130             throw new RuntimeException JavaDoc(e);
131          }
132          finally
133          {
134             if(tm.getStatus() == Status.STATUS_ACTIVE)
135                tm.rollback();
136          }
137       }
138       catch(SystemException JavaDoc e)
139       {
140          throw new RuntimeException JavaDoc(e);
141       }
142       catch (NotSupportedException JavaDoc e)
143       {
144          throw new RuntimeException JavaDoc(e);
145       }
146    }
147    
148    /**
149     * Create a TimerService for use in a bean container.
150     *
151     * @param objectName the name of the bean container
152     * @param invoker the invoker to call on timeouts
153     * @return an EJB TimerService
154     */

155    public TimerService JavaDoc createTimerService(ObjectName JavaDoc objectName, TimedObjectInvoker invoker)
156    {
157       Scheduler scheduler = getScheduler();
158       if (scheduler == null) return null;
159       
160       return new TimerServiceImpl(scheduler, objectName, invoker);
161    }
162    
163    private boolean execute(Connection JavaDoc conn, String JavaDoc stmtName) throws SQLException JavaDoc
164    {
165       String JavaDoc sql = sqlProperties.getProperty(stmtName);
166       if(sql == null)
167          throw new IllegalStateException JavaDoc("No sql set for '" + stmtName + "'");
168       
169       PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
170       try
171       {
172          stmt.execute();
173          return true;
174       }
175       catch(SQLException JavaDoc e)
176       {
177          log.warn("sql failed: " + sql);
178          if(log.isDebugEnabled())
179             log.debug("sql failed: " + sql, e);
180          return false;
181       }
182       finally
183       {
184          stmt.close();
185       }
186    }
187    
188    private Connection JavaDoc getConnection() throws SQLException JavaDoc
189    {
190       return DBConnectionManager.getInstance().getConnection("myDS");
191    }
192    
193    /**
194     * @return the scheduler for package use
195     */

196    protected static Scheduler getScheduler()
197    {
198       if(scheduler == null)
199       {
200          return null;
201          //throw new IllegalStateException("TimerServiceFactory hasn't been started yet");
202
}
203       
204       return scheduler;
205    }
206    
207    public void removeTimerService(TimerService JavaDoc aTimerService)
208    {
209       TimerServiceImpl timerService = (TimerServiceImpl) aTimerService;
210       timerService.shutdown();
211    }
212    
213    public void restoreTimerService(TimerService JavaDoc aTimerService)
214    {
215       // TODO: implement Quartz restore timer service
216
}
217    
218    public void setDataSource(String JavaDoc jndiName)
219    {
220       JNDIConnectionProvider connectionProvider = new JNDIConnectionProvider(jndiName, false);
221       // FIXME: remove hardcoding
222
DBConnectionManager.getInstance().addConnectionProvider("myDS", connectionProvider);
223    }
224    
225    public void setProperties(final Properties JavaDoc props)
226    {
227 // if(scheduler != null)
228
// throw new IllegalStateException("already started");
229

230       // TODO: precondition the prop
231
properties = props;
232    }
233    
234    public void setSqlProperties(Properties JavaDoc props)
235    {
236       this.sqlProperties = props;
237    }
238    
239    public synchronized void start() throws Exception JavaDoc
240    {
241       if(scheduler != null)
242          throw new IllegalStateException JavaDoc("already started");
243       
244       log.debug("properties = " + properties);
245       
246       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
247       tm = (TransactionManager JavaDoc) ctx.lookup(TransactionManagerService.JNDI_NAME);
248       
249       createSchema();
250       
251       // TODO: bind in JNDI, or is this done by the JMX bean?
252
SchedulerFactory factory;
253       if(properties == null)
254          factory = new StdSchedulerFactory();
255       else
256          factory = new StdSchedulerFactory(properties);
257       scheduler = factory.getScheduler();
258       // TODO: really start right away?
259
scheduler.start();
260    }
261    
262    public synchronized void stop() throws Exception JavaDoc
263    {
264       if(scheduler == null)
265          throw new IllegalStateException JavaDoc("already stopped");
266       
267       // TODO: unbind from JNDI
268

269       // TODO: standby or shutdown?
270
scheduler.shutdown();
271       
272       scheduler = null;
273    }
274 }
275
Popular Tags