View Javadoc
1   /**
2    * Copyright 2005-2016 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  package org.kuali.rice.ksb.messaging.quartz;
17  
18  import org.kuali.rice.core.api.config.ConfigurationException;
19  import org.kuali.rice.core.api.config.property.ConfigContext;
20  import org.kuali.rice.ksb.service.KSBServiceLocator;
21  import org.kuali.rice.ksb.util.KSBConstants;
22  import org.quartz.Scheduler;
23  import org.quartz.SchedulerException;
24  import org.quartz.SchedulerFactory;
25  import org.springframework.scheduling.quartz.SchedulerFactoryBean;
26  import org.springframework.transaction.PlatformTransactionManager;
27  
28  import javax.sql.DataSource;
29  import javax.transaction.TransactionManager;
30  
31  /**
32   * An implementation of the Quartz SchedulerFactoryBean which uses a database-backed quartz if the useQuartzDatabase property
33   * is set.
34   * 
35   * @author Kuali Rice Team (rice.collab@kuali.org)
36   */
37  public class KSBSchedulerFactoryBean extends SchedulerFactoryBean {
38  
39      private PlatformTransactionManager jtaTransactionManager;
40      private TransactionManager transactionManager;
41      private DataSource dataSource;
42      private DataSource nonTransactionalDataSource;
43      private boolean transactionManagerSet = false;
44      private boolean nonTransactionalDataSourceSet = false;
45      private boolean nonTransactionalDataSourceNull = true;
46      private boolean dataSourceSet = false;
47      private boolean schedulerInjected = false;
48      
49      @Override
50      protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName) throws SchedulerException {
51          if (ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY) != null) {
52              try {
53  	            schedulerInjected = true;
54                  Scheduler scheduler = (Scheduler) ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY);
55                  scheduler.addJobListener(new MessageServiceExecutorJobListener());
56                  return scheduler;
57              } catch (Exception e) {
58                  throw new ConfigurationException(e);
59              }
60          }
61          return super.createScheduler(schedulerFactory, schedulerName);
62      }
63  
64      @Override
65      public void afterPropertiesSet() throws Exception {
66  
67          boolean useQuartzDatabase = new Boolean(ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.Config.USE_QUARTZ_DATABASE));
68          if (useQuartzDatabase && !schedulerInjected) {
69              // require a transaction manager
70              if (jtaTransactionManager == null) {
71                  throw new ConfigurationException("No jta transaction manager was configured for the KSB Quartz Scheduler");
72              }
73              setTransactionManager(jtaTransactionManager);
74              if (!nonTransactionalDataSourceSet) {
75              	// since transaction manager is required... require a non transactional datasource
76              	nonTransactionalDataSource = KSBServiceLocator.getMessageNonTransactionalDataSource();
77              	if (nonTransactionalDataSource == null) {
78              		throw new ConfigurationException("No non-transactional data source was found but is required for the KSB Quartz Scheduler");
79              	}
80              	super.setNonTransactionalDataSource(nonTransactionalDataSource);
81              }
82              if (!dataSourceSet) {
83              	dataSource = KSBServiceLocator.getMessageDataSource();
84              }
85              super.setDataSource(dataSource);
86              if (transactionManagerSet && nonTransactionalDataSourceNull) {
87                  throw new ConfigurationException("A valid transaction manager was set but no non-transactional data source was found");
88              }
89          }
90          super.afterPropertiesSet();
91      }
92      
93      /**
94       * This overridden method is used simply to keep track of whether the transactionManager property has been set
95       * 
96       * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setTransactionManager(org.springframework.transaction.PlatformTransactionManager)
97       */
98      @Override
99      public void setTransactionManager(PlatformTransactionManager jtaTransactionManager) {
100         transactionManagerSet = jtaTransactionManager != null;
101         this.jtaTransactionManager = jtaTransactionManager;
102     }
103     
104     /**
105      * This overridden method is used to keep track of whether the non transactional data source is null
106      * 
107      * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setNonTransactionalDataSource(javax.sql.DataSource)
108      */
109     @Override
110     public void setNonTransactionalDataSource(DataSource nonTransactionalDataSource) {
111         nonTransactionalDataSourceSet = true;
112         nonTransactionalDataSourceNull = (nonTransactionalDataSource == null);
113         this.nonTransactionalDataSource = nonTransactionalDataSource;
114     }
115     
116     @Override
117     public void setDataSource(DataSource dataSource) {
118     	dataSourceSet = true;
119     	this.dataSource = dataSource;
120     }
121 }