001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.quartz;
016    
017    import java.io.IOException;
018    import java.net.URL;
019    import java.util.List;
020    import java.util.Properties;
021    
022    import org.apache.tapestry5.ioc.annotations.EagerLoad;
023    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
024    import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
025    import org.apache.tapestry5.ioc.services.RegistryShutdownListener;
026    
027    import org.chenillekit.quartz.services.JobSchedulingBundle;
028    import org.chenillekit.quartz.services.QuartzSchedulerManager;
029    import org.chenillekit.quartz.services.impl.QuartzSchedulerManagerImpl;
030    import org.quartz.Scheduler;
031    import org.quartz.SchedulerException;
032    import org.quartz.SchedulerFactory;
033    import org.quartz.impl.StdSchedulerFactory;
034    import org.slf4j.Logger;
035    
036    /**
037     * @version $Id: ChenilleKitQuartzModule.java 618 2010-02-23 23:30:31Z homburgs $
038     */
039    public class ChenilleKitQuartzModule
040    {
041        /**
042         * bind the <a href="http://www.opensymphony.com/quartz/">Quartz</a> scheduler factory.
043         * <p/>
044         * first we look for configuration contribution. if not exists (is null) we try to access
045         * the quartz.properties in classpath.
046         *
047         * @param shutdownHub the shutdown hub
048         *
049         * @return scheduler factory
050         */
051        public SchedulerFactory buildSchedulerFactory(Logger logger,
052                                                             RegistryShutdownHub shutdownHub,
053                                                             List<URL> contributions)
054        {
055            if (logger.isInfoEnabled())
056                logger.info("initialize scheduler factory");
057    
058            try
059            {
060                    
061                    if (contributions.isEmpty())
062                            throw new RuntimeException("Configuration to SchedulerFactory services needed");
063                    
064                    Properties prop = new Properties();
065                    
066                    for (URL contibutionURL: contributions)
067                    {
068                            prop.load(contibutionURL.openStream());
069                            }
070                    
071                final SchedulerFactory factory = new StdSchedulerFactory(prop);
072    
073                shutdownHub.addRegistryShutdownListener(new RegistryShutdownListener()
074                {
075                    /**
076                     * Invoked when the registry shuts down, giving services a chance to perform any final operations. Service
077                     * implementations should not attempt to invoke methods on other services (via proxies) as the service proxies may
078                     * themselves be shutdown.
079                     */
080                    public void registryDidShutdown()
081                    {
082                        try
083                        {
084                            List<Scheduler> schedulers = CollectionFactory.newList(factory.getAllSchedulers());
085                            for (Scheduler scheduler : schedulers)
086                                scheduler.shutdown();
087                        }
088                        catch (SchedulerException e)
089                        {
090                            throw new RuntimeException(e);
091                        }
092                    }
093                });
094    
095                return factory;
096            }
097            catch (IOException ioe)
098            {
099                throw new RuntimeException(ioe);
100            }
101            catch (SchedulerException se)
102            {
103                throw new RuntimeException(se);
104            }
105        }
106    
107        /**
108         * bind the <a href="http://www.opensymphony.com/quartz/">Quartz</a> based scheduler manager.
109         *
110         * @param schedulerFactory     the scheduler factory
111         * @param jobSchedulingBundles list of job detail and trigger bundles
112         *
113         * @return scheduler manager
114         */
115        @EagerLoad
116        public QuartzSchedulerManager buildQuartzSchedulerManager(Logger logger, final SchedulerFactory schedulerFactory,
117                                                                         final List<JobSchedulingBundle> jobSchedulingBundles)
118        {
119            return new QuartzSchedulerManagerImpl(logger, schedulerFactory, jobSchedulingBundles);
120        }
121    }