001/**
002 * Copyright 2005-2015 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    @Override
045    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
046        this.beanFactory = beanFactory;
047    }
048
049    /**
050     * Sets the Trigger for the message processing job
051     * @param messageProcessingTrigger the Trigger for the message processing job
052     */
053    @Required
054    public void setMessageProcessingTrigger(Trigger messageProcessingTrigger) {
055        this.messageProcessingTrigger = messageProcessingTrigger;
056    }
057    
058    /**
059     * Sets the JobDetail for the message processing job
060     * @param messageProcessingJobDetail the JobDetail for the message processing job
061     */
062    @Required
063    public void setMessageProcessingJobDetail(JobDetail messageProcessingJobDetail) {
064        this.messageProcessingJobDetail = messageProcessingJobDetail;
065    }
066
067
068    @Override
069    public void afterPropertiesSet() throws Exception {
070        GlobalKCBServiceLocator.init(beanFactory);
071        // kill the reference, our job is done
072        beanFactory = null;
073
074        Scheduler scheduler = getScheduler()==null?KSBServiceLocator.getScheduler():getScheduler();
075        scheduler.addJob(messageProcessingJobDetail, true);
076
077        addTriggerToScheduler(messageProcessingTrigger);
078    }
079    
080    private void addTriggerToScheduler(Trigger trigger) throws SchedulerException {
081                boolean triggerExists = (getScheduler().getTrigger(trigger.getName(), trigger.getGroup()) != null);
082                if (!triggerExists) {
083                        try {
084                                getScheduler().scheduleJob(trigger);
085                        } catch (ObjectAlreadyExistsException ex) {
086                                getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
087                        }
088                } else {
089                    getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
090                }
091        }
092
093    @Override
094    public void destroy() throws Exception {
095        // prevent anything from accessing our services after the module has been destroyed/shutdown
096        // our module's lifecycle is tied to the Spring context lifecycle for now
097        GlobalKCBServiceLocator.destroy();
098    }
099
100        /**
101         * @return the scheduler
102         */
103        public Scheduler getScheduler() {
104                return this.scheduler;
105        }
106
107        /**
108         * @param scheduler the scheduler to set
109         */
110        public void setScheduler(Scheduler scheduler) {
111                this.scheduler = scheduler;
112        }
113    
114}