001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kcb.config;
017
018import org.kuali.rice.kcb.service.GlobalKCBServiceLocator;
019import org.kuali.rice.ksb.service.KSBServiceLocator;
020import org.quartz.JobDetail;
021import org.quartz.ObjectAlreadyExistsException;
022import org.quartz.Scheduler;
023import org.quartz.SchedulerException;
024import org.quartz.Trigger;
025import org.springframework.beans.BeansException;
026import org.springframework.beans.factory.BeanFactory;
027import org.springframework.beans.factory.BeanFactoryAware;
028import org.springframework.beans.factory.DisposableBean;
029import org.springframework.beans.factory.InitializingBean;
030import org.springframework.beans.factory.annotation.Required;
031
032/**
033 * Initializing bean that initializes KCB (specifically the GlobalKCBServiceLocator)
034 * on Spring context initialization.  This bean should be eagerly initialized (not marked lazy) 
035 * 
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 */
038public class KCBInitializer implements BeanFactoryAware, InitializingBean, DisposableBean {
039    private BeanFactory beanFactory;
040    private Trigger messageProcessingTrigger;
041    private JobDetail messageProcessingJobDetail;
042    protected Scheduler scheduler;
043    
044        /**
045     * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
046     */
047    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
048        this.beanFactory = beanFactory;
049    }
050
051    /**
052     * Sets the Trigger for the message processing job
053     * @param messageProcessingTrigger the Trigger for the message processing job
054     */
055    @Required
056    public void setMessageProcessingTrigger(Trigger messageProcessingTrigger) {
057        this.messageProcessingTrigger = messageProcessingTrigger;
058    }
059    
060    /**
061     * Sets the JobDetail for the message processing job
062     * @param messageProcessingJobDetail the JobDetail for the message processing job
063     */
064    @Required
065    public void setMessageProcessingJobDetail(JobDetail messageProcessingJobDetail) {
066        this.messageProcessingJobDetail = messageProcessingJobDetail;
067    }
068
069    /**
070     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
071     */
072    public void afterPropertiesSet() throws Exception {
073        GlobalKCBServiceLocator.init(beanFactory);
074        // kill the reference, our job is done
075        beanFactory = null;
076
077        Scheduler scheduler = getScheduler()==null?KSBServiceLocator.getScheduler():getScheduler();
078        scheduler.addJob(messageProcessingJobDetail, true);
079
080        addTriggerToScheduler(messageProcessingTrigger);
081    }
082    
083    private void addTriggerToScheduler(Trigger trigger) throws SchedulerException {
084                boolean triggerExists = (getScheduler().getTrigger(trigger.getName(), trigger.getGroup()) != null);
085                if (!triggerExists) {
086                        try {
087                                getScheduler().scheduleJob(trigger);
088                        } catch (ObjectAlreadyExistsException ex) {
089                                getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
090                        }
091                } else {
092                    getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
093                }
094        }
095
096    public void destroy() throws Exception {
097        // prevent anything from accessing our services after the module has been destroyed/shutdown
098        // our module's lifecycle is tied to the Spring context lifecycle for now
099        GlobalKCBServiceLocator.destroy();
100    }
101
102        /**
103         * @return the scheduler
104         */
105        public Scheduler getScheduler() {
106                return this.scheduler;
107        }
108
109        /**
110         * @param scheduler the scheduler to set
111         */
112        public void setScheduler(Scheduler scheduler) {
113                this.scheduler = scheduler;
114        }
115    
116}