View Javadoc

1   /*
2    * Copyright 2006-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.kuali.rice.ksb.messaging.quartz;
18  
19  import org.kuali.rice.core.api.config.ConfigurationException;
20  import org.kuali.rice.core.api.config.property.ConfigContext;
21  import org.kuali.rice.ksb.service.KSBServiceLocator;
22  import org.kuali.rice.ksb.util.KSBConstants;
23  import org.quartz.Scheduler;
24  import org.quartz.SchedulerException;
25  import org.quartz.SchedulerFactory;
26  import org.springframework.scheduling.quartz.SchedulerFactoryBean;
27  import org.springframework.transaction.PlatformTransactionManager;
28  
29  import javax.sql.DataSource;
30  import javax.transaction.TransactionManager;
31  
32  /**
33   * An implementation of the Quartz SchedulerFactoryBean which uses a database-backed quartz if the useQuartzDatabase property
34   * is set.
35   * 
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   */
38  public class KSBSchedulerFactoryBean extends SchedulerFactoryBean {
39  
40      private PlatformTransactionManager jtaTransactionManager;
41      private TransactionManager transactionManager;
42      private DataSource dataSource;
43      private DataSource nonTransactionalDataSource;
44      private boolean transactionManagerSet = false;
45      private boolean nonTransactionalDataSourceSet = false;
46      private boolean nonTransactionalDataSourceNull = true;
47      private boolean dataSourceSet = false;
48      private boolean schedulerInjected = false;
49      
50      @Override
51      protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName) throws SchedulerException {
52          if (ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY) != null) {
53              try {
54  	            schedulerInjected = true;
55                  Scheduler scheduler = (Scheduler) ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY);
56                  scheduler.addJobListener(new MessageServiceExecutorJobListener());
57                  return scheduler;
58              } catch (Exception e) {
59                  throw new ConfigurationException(e);
60              }
61          }
62          return super.createScheduler(schedulerFactory, schedulerName);
63      }
64  
65      @Override
66      public void afterPropertiesSet() throws Exception {
67  
68          boolean useQuartzDatabase = new Boolean(ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.Config.USE_QUARTZ_DATABASE));
69          if (useQuartzDatabase && !schedulerInjected) {
70              // require a transaction manager
71              if (jtaTransactionManager == null) {
72                  throw new ConfigurationException("No jta transaction manager was configured for the KSB Quartz Scheduler");
73              }
74              setTransactionManager(jtaTransactionManager);
75              if (!nonTransactionalDataSourceSet) {
76              	// since transaction manager is required... require a non transactional datasource
77              	nonTransactionalDataSource = KSBServiceLocator.getMessageNonTransactionalDataSource();
78              	if (nonTransactionalDataSource == null) {
79              		throw new ConfigurationException("No non-transactional data source was found but is required for the KSB Quartz Scheduler");
80              	}
81              	super.setNonTransactionalDataSource(nonTransactionalDataSource);
82              }
83              if (!dataSourceSet) {
84              	dataSource = KSBServiceLocator.getMessageDataSource();
85              }
86              super.setDataSource(dataSource);
87              if (transactionManagerSet && nonTransactionalDataSourceNull) {
88                  throw new ConfigurationException("A valid transaction manager was set but no non-transactional data source was found");
89              }
90          }
91          super.afterPropertiesSet();
92      }
93      
94      /**
95       * This overridden method is used simply to keep track of whether the transactionManager property has been set
96       * 
97       * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setTransactionManager(org.springframework.transaction.PlatformTransactionManager)
98       */
99      @Override
100     public void setTransactionManager(PlatformTransactionManager jtaTransactionManager) {
101         transactionManagerSet = jtaTransactionManager != null;
102         this.jtaTransactionManager = jtaTransactionManager;
103     }
104     
105     /**
106      * This overridden method is used to keep track of whether the non transactional data source is null
107      * 
108      * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setNonTransactionalDataSource(javax.sql.DataSource)
109      */
110     @Override
111     public void setNonTransactionalDataSource(DataSource nonTransactionalDataSource) {
112         nonTransactionalDataSourceSet = true;
113         nonTransactionalDataSourceNull = (nonTransactionalDataSource == null);
114         this.nonTransactionalDataSource = nonTransactionalDataSource;
115     }
116     
117     @Override
118     public void setDataSource(DataSource dataSource) {
119     	dataSourceSet = true;
120     	this.dataSource = dataSource;
121     }
122 }