KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quartz > impl > StdSchedulerFactory


1 /*
2  * Copyright 2004-2005 OpenSymphony
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy
6  * of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  *
16  */

17
18 /*
19  * Previously Copyright (c) 2001-2004 James House
20  */

21 package org.quartz.impl;
22
23 import java.beans.BeanInfo JavaDoc;
24 import java.beans.IntrospectionException JavaDoc;
25 import java.beans.Introspector JavaDoc;
26 import java.beans.PropertyDescriptor JavaDoc;
27 import java.io.BufferedInputStream JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileInputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.lang.reflect.Method JavaDoc;
33 import java.security.AccessControlException JavaDoc;
34 import java.sql.SQLException JavaDoc;
35 import java.util.Collection JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Locale JavaDoc;
38 import java.util.Properties JavaDoc;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.quartz.JobListener;
43 import org.quartz.Scheduler;
44 import org.quartz.SchedulerConfigException;
45 import org.quartz.SchedulerException;
46 import org.quartz.SchedulerFactory;
47 import org.quartz.TriggerListener;
48 import org.quartz.core.JobRunShellFactory;
49 import org.quartz.core.QuartzScheduler;
50 import org.quartz.core.QuartzSchedulerResources;
51 import org.quartz.core.SchedulingContext;
52 import org.quartz.ee.jta.JTAJobRunShellFactory;
53 import org.quartz.ee.jta.UserTransactionHelper;
54 import org.quartz.impl.jdbcjobstore.JobStoreSupport;
55 import org.quartz.impl.jdbcjobstore.Semaphore;
56 import org.quartz.impl.jdbcjobstore.TablePrefixAware;
57 import org.quartz.simpl.RAMJobStore;
58 import org.quartz.simpl.SimpleThreadPool;
59 import org.quartz.spi.ClassLoadHelper;
60 import org.quartz.spi.InstanceIdGenerator;
61 import org.quartz.spi.JobFactory;
62 import org.quartz.spi.JobStore;
63 import org.quartz.spi.SchedulerPlugin;
64 import org.quartz.spi.ThreadPool;
65 import org.quartz.utils.ConnectionProvider;
66 import org.quartz.utils.DBConnectionManager;
67 import org.quartz.utils.JNDIConnectionProvider;
68 import org.quartz.utils.PoolingConnectionProvider;
69 import org.quartz.utils.PropertiesParser;
70
71 /**
72  * <p>
73  * An implementation of <code>{@link org.quartz.SchedulerFactory}</code> that
74  * does all of its work of creating a <code>QuartzScheduler</code> instance
75  * based on the contenents of a <code>Properties</code> file.
76  * </p>
77  *
78  * <p>
79  * By default a properties file named "quartz.properties" is loaded from the
80  * 'current working directory'. If that fails, then the "quartz.properties"
81  * file located (as a resource) in the org/quartz package is loaded. If you
82  * wish to use a file other than these defaults, you must define the system
83  * property 'org.quartz.properties' to point to the file you want.
84  * </p>
85  *
86  * <p>
87  * See the sample properties files that are distributed with Quartz for
88  * information about the various settings available within the file.
89  * </p>
90  *
91  * <p>
92  * Alternatively, you can explicitly initialize the factory by calling one of
93  * the <code>initialize(xx)</code> methods before calling <code>getScheduler()</code>.
94  * </p>
95  *
96  * <p>
97  * Instances of the specified <code>{@link org.quartz.spi.JobStore}</code>,
98  * <code>{@link org.quartz.spi.ThreadPool}</code>, classes will be created
99  * by name, and then any additional properties specified for them in the config
100  * file will be set on the instance by calling an equivalent 'set' method. For
101  * example if the properties file contains the property
102  * 'org.quartz.jobStore.myProp = 10' then after the JobStore class has been
103  * instantiated, the method 'setMyProp()' will be called on it. Type conversion
104  * to primitive Java types (int, long, float, double, boolean, and String) are
105  * performed before calling the property's setter method.
106  * </p>
107  *
108  * @author James House
109  * @author Anthony Eden
110  * @author Mohammad Rezaei
111  */

112 public class StdSchedulerFactory implements SchedulerFactory {
113
114     /*
115      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116      *
117      * Constants.
118      *
119      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120      */

121
122     public static final String JavaDoc PROPERTIES_FILE = "org.quartz.properties";
123
124     public static final String JavaDoc PROP_SCHED_INSTANCE_NAME = "org.quartz.scheduler.instanceName";
125
126     public static final String JavaDoc PROP_SCHED_INSTANCE_ID = "org.quartz.scheduler.instanceId";
127
128     public static final String JavaDoc PROP_SCHED_INSTANCE_ID_GENERATOR_PREFIX = "org.quartz.scheduler.instanceIdGenerator";
129     
130     public static final String JavaDoc PROP_SCHED_INSTANCE_ID_GENERATOR_CLASS =
131         PROP_SCHED_INSTANCE_ID_GENERATOR_PREFIX + ".class";
132     
133     public static final String JavaDoc PROP_SCHED_THREAD_NAME = "org.quartz.scheduler.threadName";
134
135     public static final String JavaDoc PROP_SCHED_JMX_EXPORT = "org.quartz.scheduler.jmx.export";
136     
137     public static final String JavaDoc PROP_SCHED_JMX_PROXY = "org.quartz.scheduler.jmx.proxy";
138
139     public static final String JavaDoc PROP_SCHED_JMX_PROXY_CLASS = "org.quartz.scheduler.jmx.proxy.class";
140
141     public static final String JavaDoc PROP_SCHED_JMX_OBJECT_NAME = "org.quartz.scheduler.jmx.objectName";
142
143     public static final String JavaDoc PROP_SCHED_RMI_EXPORT = "org.quartz.scheduler.rmi.export";
144
145     public static final String JavaDoc PROP_SCHED_RMI_PROXY = "org.quartz.scheduler.rmi.proxy";
146
147     public static final String JavaDoc PROP_SCHED_RMI_HOST = "org.quartz.scheduler.rmi.registryHost";
148
149     public static final String JavaDoc PROP_SCHED_RMI_PORT = "org.quartz.scheduler.rmi.registryPort";
150
151     public static final String JavaDoc PROP_SCHED_RMI_SERVER_PORT = "org.quartz.scheduler.rmi.serverPort";
152
153     public static final String JavaDoc PROP_SCHED_RMI_CREATE_REGISTRY = "org.quartz.scheduler.rmi.createRegistry";
154
155     public static final String JavaDoc PROP_SCHED_RMI_BIND_NAME = "org.quartz.scheduler.rmi.bindName";
156
157     public static final String JavaDoc PROP_SCHED_WRAP_JOB_IN_USER_TX = "org.quartz.scheduler.wrapJobExecutionInUserTransaction";
158
159     public static final String JavaDoc PROP_SCHED_USER_TX_URL = "org.quartz.scheduler.userTransactionURL";
160
161     public static final String JavaDoc PROP_SCHED_IDLE_WAIT_TIME = "org.quartz.scheduler.idleWaitTime";
162
163     public static final String JavaDoc PROP_SCHED_DB_FAILURE_RETRY_INTERVAL = "org.quartz.scheduler.dbFailureRetryInterval";
164
165     public static final String JavaDoc PROP_SCHED_MAKE_SCHEDULER_THREAD_DAEMON = "org.quartz.scheduler.makeSchedulerThreadDaemon";
166
167     public static final String JavaDoc PROP_SCHED_CLASS_LOAD_HELPER_CLASS = "org.quartz.scheduler.classLoadHelper.class";
168
169     public static final String JavaDoc PROP_SCHED_JOB_FACTORY_CLASS = "org.quartz.scheduler.jobFactory.class";
170
171     public static final String JavaDoc PROP_SCHED_JOB_FACTORY_PREFIX = "org.quartz.scheduler.jobFactory";
172
173     public static final String JavaDoc PROP_SCHED_CONTEXT_PREFIX = "org.quartz.context.key";
174
175     public static final String JavaDoc PROP_THREAD_POOL_PREFIX = "org.quartz.threadPool";
176
177     public static final String JavaDoc PROP_THREAD_POOL_CLASS = "org.quartz.threadPool.class";
178
179     public static final String JavaDoc PROP_JOB_STORE_PREFIX = "org.quartz.jobStore";
180
181     public static final String JavaDoc PROP_JOB_STORE_LOCK_HANDLER_PREFIX = PROP_JOB_STORE_PREFIX + ".lockHandler";
182     
183     public static final String JavaDoc PROP_JOB_STORE_LOCK_HANDLER_CLASS = PROP_JOB_STORE_LOCK_HANDLER_PREFIX + ".class";
184
185     public static final String JavaDoc PROP_TABLE_PREFIX = "tablePrefix";
186
187     public static final String JavaDoc PROP_JOB_STORE_CLASS = "org.quartz.jobStore.class";
188
189     public static final String JavaDoc PROP_JOB_STORE_USE_PROP = "org.quartz.jobStore.useProperties";
190
191     public static final String JavaDoc PROP_DATASOURCE_PREFIX = "org.quartz.dataSource";
192
193     public static final String JavaDoc PROP_CONNECTION_PROVIDER_CLASS = "connectionProvider.class";
194
195     public static final String JavaDoc PROP_DATASOURCE_DRIVER = "driver";
196
197     public static final String JavaDoc PROP_DATASOURCE_URL = "URL";
198
199     public static final String JavaDoc PROP_DATASOURCE_USER = "user";
200
201     public static final String JavaDoc PROP_DATASOURCE_PASSWORD = "password";
202
203     public static final String JavaDoc PROP_DATASOURCE_MAX_CONNECTIONS = "maxConnections";
204
205     public static final String JavaDoc PROP_DATASOURCE_VALIDATION_QUERY = "validationQuery";
206
207     public static final String JavaDoc PROP_DATASOURCE_JNDI_URL = "jndiURL";
208
209     public static final String JavaDoc PROP_DATASOURCE_JNDI_ALWAYS_LOOKUP = "jndiAlwaysLookup";
210
211     public static final String JavaDoc PROP_DATASOURCE_JNDI_INITIAL = "java.naming.factory.initial";
212
213     public static final String JavaDoc PROP_DATASOURCE_JNDI_PROVDER = "java.naming.provider.url";
214
215     public static final String JavaDoc PROP_DATASOURCE_JNDI_PRINCIPAL = "java.naming.security.principal";
216
217     public static final String JavaDoc PROP_DATASOURCE_JNDI_CREDENTIALS = "java.naming.security.credentials";
218
219     public static final String JavaDoc PROP_PLUGIN_PREFIX = "org.quartz.plugin";
220
221     public static final String JavaDoc PROP_PLUGIN_CLASS = "class";
222
223     public static final String JavaDoc PROP_JOB_LISTENER_PREFIX = "org.quartz.jobListener";
224
225     public static final String JavaDoc PROP_TRIGGER_LISTENER_PREFIX = "org.quartz.triggerListener";
226
227     public static final String JavaDoc PROP_LISTENER_CLASS = "class";
228
229     public static final String JavaDoc DEFAULT_INSTANCE_ID = "NON_CLUSTERED";
230
231     public static final String JavaDoc AUTO_GENERATE_INSTANCE_ID = "AUTO";
232
233     /*
234      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
235      *
236      * Data members.
237      *
238      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
239      */

240
241     private SchedulerException initException = null;
242
243     private String JavaDoc propSrc = null;
244
245     private PropertiesParser cfg;
246
247     private final Log log = LogFactory.getLog(getClass());
248
249     // private Scheduler scheduler;
250

251     /*
252      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
253      *
254      * Constructors.
255      *
256      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
257      */

258
259     /**
260      * Create an uninitialized StdSchedulerFactory.
261      */

262     public StdSchedulerFactory() {
263     }
264
265     /**
266      * Create a StdSchedulerFactory that has been initialized via
267      * <code>{@link #initialize(Properties)}</code>.
268      *
269      * @see #initialize(Properties)
270      */

271     public StdSchedulerFactory(Properties JavaDoc props) throws SchedulerException {
272         initialize(props);
273     }
274
275     /**
276      * Create a StdSchedulerFactory that has been initialized via
277      * <code>{@link #initialize(String)}</code>.
278      *
279      * @see #initialize(String)
280      */

281     public StdSchedulerFactory(String JavaDoc fileName) throws SchedulerException {
282         initialize(fileName);
283     }
284
285     /*
286      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
287      *
288      * Interface.
289      *
290      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291      */

292
293     public Log getLog() {
294         return log;
295     }
296
297     /**
298      * <p>
299      * Initialize the <code>{@link org.quartz.SchedulerFactory}</code> with
300      * the contents of a <code>Properties</code> file and overriding System
301      * properties.
302      * </p>
303      *
304      * <p>
305      * By default a properties file named "quartz.properties" is loaded from
306      * the 'current working directory'. If that fails, then the
307      * "quartz.properties" file located (as a resource) in the org/quartz
308      * package is loaded. If you wish to use a file other than these defaults,
309      * you must define the system property 'org.quartz.properties' to point to
310      * the file you want.
311      * </p>
312      *
313      * <p>
314      * System properties (environment variables, and -D definitions on the
315      * command-line when running the JVM) override any properties in the
316      * loaded file. For this reason, you may want to use a different initialize()
317      * method if your application security policy prohibits access to
318      * <code>{@link java.lang.System#getProperties()}</code>.
319      * </p>
320      */

321     public void initialize() throws SchedulerException {
322         // short-circuit if already initialized
323
if (cfg != null) {
324             return;
325         }
326         if (initException != null) {
327             throw initException;
328         }
329
330         String JavaDoc requestedFile = System.getProperty(PROPERTIES_FILE);
331         String JavaDoc propFileName = requestedFile != null ? requestedFile
332                 : "quartz.properties";
333         File JavaDoc propFile = new File JavaDoc(propFileName);
334
335         Properties JavaDoc props = new Properties JavaDoc();
336
337         if (propFile.exists()) {
338             try {
339                 if (requestedFile != null) {
340                     propSrc = "specified file: '" + requestedFile + "'";
341                 } else {
342                     propSrc = "default file in current working dir: 'quartz.properties'";
343                 }
344
345                 props.load(new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(
346                         propFileName)));
347
348             } catch (IOException JavaDoc ioe) {
349                 initException = new SchedulerException("Properties file: '"
350                         + propFileName + "' could not be read.", ioe);
351                 throw initException;
352             }
353         } else if (requestedFile != null) {
354             InputStream JavaDoc in =
355                 Thread.currentThread().getContextClassLoader().getResourceAsStream(requestedFile);
356
357             if(in == null) {
358                 initException = new SchedulerException("Properties file: '"
359                     + requestedFile + "' could not be found.");
360                 throw initException;
361             }
362             
363             propSrc = "specified file: '" + requestedFile + "' in the class resource path.";
364             
365             try {
366                 props.load(new BufferedInputStream JavaDoc(in));
367             } catch (IOException JavaDoc ioe) {
368                 initException = new SchedulerException("Properties file: '"
369                         + requestedFile + "' could not be read.", ioe);
370                 throw initException;
371             }
372             
373         } else {
374             propSrc = "default resource file in Quartz package: 'quartz.properties'";
375
376             InputStream JavaDoc in = getClass().getClassLoader().getResourceAsStream(
377                     "quartz.properties");
378
379             if (in == null) {
380                 in = getClass().getClassLoader().getResourceAsStream(
381                         "/quartz.properties");
382             }
383             if (in == null) {
384                 in = getClass().getClassLoader().getResourceAsStream(
385                         "org/quartz/quartz.properties");
386             }
387             if (in == null) {
388                 initException = new SchedulerException(
389                         "Default quartz.properties not found in class path");
390                 throw initException;
391             }
392             try {
393                 props.load(in);
394             } catch (IOException JavaDoc ioe) {
395                 initException = new SchedulerException(
396                         "Resource properties file: 'org/quartz/quartz.properties' "
397                                 + "could not be read from the classpath.", ioe);
398                 throw initException;
399             }
400         }
401         
402         initialize(overrideWithSysProps(props));
403     }
404
405     /**
406      * Add all System properties to the given <code>props</code>. Will override
407      * any properties that already exist in the given <code>props</code>.
408      */

409     private Properties JavaDoc overrideWithSysProps(Properties JavaDoc props) {
410         Properties JavaDoc sysProps = null;
411         try {
412             sysProps = System.getProperties();
413         } catch (AccessControlException JavaDoc e) {
414             getLog().warn(
415                 "Skipping overriding quartz properties with System properties " +
416                 "during initialization because of an AccessControlException. " +
417                 "This is likely due to not having read/write access for " +
418                 "java.util.PropertyPermission as required by java.lang.System.getProperties(). " +
419                 "To resolve this warning, either add this permission to your policy file or " +
420                 "use a non-default version of initialize().",
421                 e);
422         }
423         
424         if (sysProps != null) {
425             props.putAll(sysProps);
426         }
427
428         return props;
429     }
430
431     /**
432      * <p>
433      * Initialize the <code>{@link org.quartz.SchedulerFactory}</code> with
434      * the contenents of the <code>Properties</code> file with the given
435      * name.
436      * </p>
437      */

438     public void initialize(String JavaDoc filename) throws SchedulerException {
439         // short-circuit if already initialized
440
if (cfg != null) {
441             return;
442         }
443         
444         if (initException != null) {
445             throw initException;
446         }
447
448         InputStream JavaDoc is = null;
449         Properties JavaDoc props = new Properties JavaDoc();
450
451         is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
452          
453         try {
454             if(is != null) {
455                 is = new BufferedInputStream JavaDoc(is);
456                 propSrc = "the specified file : '" + filename + "' from the class resource path.";
457             } else {
458                 is = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(filename));
459                 propSrc = "the specified file : '" + filename + "'";
460             }
461             props.load(is);
462         } catch (IOException JavaDoc ioe) {
463             initException = new SchedulerException("Properties file: '"
464                     + filename + "' could not be read.", ioe);
465             throw initException;
466         }
467
468         initialize(props);
469     }
470
471     /**
472      * <p>
473      * Initialize the <code>{@link org.quartz.SchedulerFactory}</code> with
474      * the contenents of the <code>Properties</code> file opened with the
475      * given <code>InputStream</code>.
476      * </p>
477      */

478     public void initialize(InputStream JavaDoc propertiesStream)
479         throws SchedulerException {
480         // short-circuit if already initialized
481
if (cfg != null) {
482             return;
483         }
484         
485         if (initException != null) {
486             throw initException;
487         }
488
489         Properties JavaDoc props = new Properties JavaDoc();
490
491         if (propertiesStream != null) {
492             try {
493                 props.load(propertiesStream);
494                 propSrc = "an externally opened InputStream.";
495             } catch (IOException JavaDoc e) {
496                 initException = new SchedulerException(
497                         "Error loading property data from InputStream", e);
498                 throw initException;
499             }
500         } else {
501             initException = new SchedulerException(
502                     "Error loading property data from InputStream - InputStream is null.");
503             throw initException;
504         }
505
506         initialize(props);
507     }
508
509     /**
510      * <p>
511      * Initialize the <code>{@link org.quartz.SchedulerFactory}</code> with
512      * the contenents of the given <code>Properties</code> object.
513      * </p>
514      */

515     public void initialize(Properties JavaDoc props) throws SchedulerException {
516         if (propSrc == null) {
517             propSrc = "an externally provided properties instance.";
518         }
519
520         this.cfg = new PropertiesParser(props);
521     }
522
523     private Scheduler instantiate() throws SchedulerException {
524         if (cfg == null) {
525             initialize();
526         }
527
528         if (initException != null) {
529             throw initException;
530         }
531
532         JobStore js = null;
533         ThreadPool tp = null;
534         QuartzScheduler qs = null;
535         SchedulingContext schedCtxt = null;
536         DBConnectionManager dbMgr = null;
537         String JavaDoc instanceIdGeneratorClass = null;
538         Properties JavaDoc tProps = null;
539         String JavaDoc userTXLocation = null;
540         boolean wrapJobInTx = false;
541         boolean autoId = false;
542         long idleWaitTime = -1;
543         long dbFailureRetry = -1;
544         String JavaDoc classLoadHelperClass;
545         String JavaDoc jobFactoryClass;
546
547         SchedulerRepository schedRep = SchedulerRepository.getInstance();
548
549         // Get Scheduler Properties
550
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
551

552         String JavaDoc schedName = cfg.getStringProperty(PROP_SCHED_INSTANCE_NAME,
553                 "QuartzScheduler");
554
555         String JavaDoc threadName = cfg.getStringProperty(PROP_SCHED_THREAD_NAME,
556                 schedName + "_QuartzSchedulerThread");
557         
558         String JavaDoc schedInstId = cfg.getStringProperty(PROP_SCHED_INSTANCE_ID,
559                 DEFAULT_INSTANCE_ID);
560
561         if (schedInstId.equals(AUTO_GENERATE_INSTANCE_ID)) {
562             autoId = true;
563             instanceIdGeneratorClass = cfg.getStringProperty(
564                     PROP_SCHED_INSTANCE_ID_GENERATOR_CLASS,
565                     "org.quartz.simpl.SimpleInstanceIdGenerator");
566         }
567         
568         userTXLocation = cfg.getStringProperty(PROP_SCHED_USER_TX_URL,
569                 userTXLocation);
570         if (userTXLocation != null && userTXLocation.trim().length() == 0) {
571             userTXLocation = null;
572         }
573
574         classLoadHelperClass = cfg.getStringProperty(
575                 PROP_SCHED_CLASS_LOAD_HELPER_CLASS,
576                 "org.quartz.simpl.CascadingClassLoadHelper");
577         wrapJobInTx = cfg.getBooleanProperty(PROP_SCHED_WRAP_JOB_IN_USER_TX,
578                 wrapJobInTx);
579
580         jobFactoryClass = cfg.getStringProperty(
581                 PROP_SCHED_JOB_FACTORY_CLASS, null);
582
583         idleWaitTime = cfg.getLongProperty(PROP_SCHED_IDLE_WAIT_TIME,
584                 idleWaitTime);
585         dbFailureRetry = cfg.getLongProperty(
586                 PROP_SCHED_DB_FAILURE_RETRY_INTERVAL, dbFailureRetry);
587
588         boolean makeSchedulerThreadDaemon =
589             cfg.getBooleanProperty(PROP_SCHED_MAKE_SCHEDULER_THREAD_DAEMON);
590         
591         boolean jmxExport = cfg.getBooleanProperty(PROP_SCHED_JMX_EXPORT);
592         boolean jmxProxy = cfg.getBooleanProperty(PROP_SCHED_JMX_PROXY);
593         String JavaDoc jmxProxyClass = cfg.getStringProperty(PROP_SCHED_JMX_PROXY_CLASS);
594         String JavaDoc jmxObjectName = cfg.getStringProperty(PROP_SCHED_JMX_OBJECT_NAME);
595         
596         boolean rmiExport = cfg.getBooleanProperty(PROP_SCHED_RMI_EXPORT, false);
597         boolean rmiProxy = cfg.getBooleanProperty(PROP_SCHED_RMI_PROXY, false);
598         String JavaDoc rmiHost = cfg.getStringProperty(PROP_SCHED_RMI_HOST, "localhost");
599         int rmiPort = cfg.getIntProperty(PROP_SCHED_RMI_PORT, 1099);
600         int rmiServerPort = cfg.getIntProperty(PROP_SCHED_RMI_SERVER_PORT, -1);
601         String JavaDoc rmiCreateRegistry = cfg.getStringProperty(
602                 PROP_SCHED_RMI_CREATE_REGISTRY,
603                 QuartzSchedulerResources.CREATE_REGISTRY_NEVER);
604         String JavaDoc rmiBindName = cfg.getStringProperty(PROP_SCHED_RMI_BIND_NAME);
605
606         if (jmxProxy && rmiProxy) {
607             throw new SchedulerConfigException("Cannot proxy both RMI and JMX.");
608         }
609         
610         Properties JavaDoc schedCtxtProps = cfg.getPropertyGroup(PROP_SCHED_CONTEXT_PREFIX, true);
611
612         // If Proxying to remote scheduler, short-circuit here...
613
// ~~~~~~~~~~~~~~~~~~
614
if (rmiProxy) {
615
616             if (autoId) {
617                 schedInstId = DEFAULT_INSTANCE_ID;
618             }
619                 
620             schedCtxt = new SchedulingContext();
621             schedCtxt.setInstanceId(schedInstId);
622
623             String JavaDoc uid = (rmiBindName == null) ? QuartzSchedulerResources.getUniqueIdentifier(
624                     schedName, schedInstId) : rmiBindName;
625
626             RemoteScheduler remoteScheduler = new RemoteScheduler(schedCtxt,
627                     uid, rmiHost, rmiPort);
628
629             schedRep.bind(remoteScheduler);
630
631             return remoteScheduler;
632         }
633
634         
635         // Create class load helper
636
ClassLoadHelper loadHelper = null;
637         try {
638             loadHelper = (ClassLoadHelper) loadClass(classLoadHelperClass)
639                     .newInstance();
640         } catch (Exception JavaDoc e) {
641             throw new SchedulerConfigException(
642                     "Unable to instantiate class load helper class: "
643                             + e.getMessage(), e);
644         }
645         loadHelper.initialize();
646         
647         // If Proxying to remote JMX scheduler, short-circuit here...
648
// ~~~~~~~~~~~~~~~~~~
649
if (jmxProxy) {
650             if (autoId) {
651                 schedInstId = DEFAULT_INSTANCE_ID;
652             }
653
654             if (jmxProxyClass == null) {
655                 throw new SchedulerConfigException("No JMX Proxy Scheduler class provided");
656             }
657
658             RemoteMBeanScheduler jmxScheduler = null;
659             try {
660                 jmxScheduler = (RemoteMBeanScheduler)loadHelper.loadClass(jmxProxyClass)
661                         .newInstance();
662             } catch (Exception JavaDoc e) {
663                 throw new SchedulerConfigException(
664                         "Unable to instantiate RemoteMBeanScheduler class.", e);
665             }
666             
667             schedCtxt = new SchedulingContext();
668             schedCtxt.setInstanceId(schedInstId);
669             
670             if (jmxObjectName == null) {
671                 jmxObjectName = QuartzSchedulerResources.generateJMXObjectName(schedName, schedInstId);
672             }
673             
674             jmxScheduler.setSchedulingContext(schedCtxt);
675             jmxScheduler.setSchedulerObjectName(jmxObjectName);
676                         
677             tProps = cfg.getPropertyGroup(PROP_SCHED_JMX_PROXY, true);
678             try {
679                 setBeanProps(jmxScheduler, tProps);
680             } catch (Exception JavaDoc e) {
681                 initException = new SchedulerException("RemoteMBeanScheduler class '"
682                         + jmxProxyClass + "' props could not be configured.", e);
683                 initException.setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
684                 throw initException;
685             }
686             
687             jmxScheduler.initialize();
688             
689             schedRep.bind(jmxScheduler);
690
691             return jmxScheduler;
692         }
693         
694         JobFactory jobFactory = null;
695         if(jobFactoryClass != null) {
696             try {
697                 jobFactory = (JobFactory) loadHelper.loadClass(jobFactoryClass)
698                         .newInstance();
699             } catch (Exception JavaDoc e) {
700                 throw new SchedulerConfigException(
701                         "Unable to instantiate JobFactory class: "
702                                 + e.getMessage(), e);
703             }
704
705             tProps = cfg.getPropertyGroup(PROP_SCHED_JOB_FACTORY_PREFIX, true);
706             try {
707                 setBeanProps(jobFactory, tProps);
708             } catch (Exception JavaDoc e) {
709                 initException = new SchedulerException("JobFactory class '"
710                         + jobFactoryClass + "' props could not be configured.", e);
711                 initException
712                         .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
713                 throw initException;
714             }
715         }
716         
717         InstanceIdGenerator instanceIdGenerator = null;
718         if(instanceIdGeneratorClass != null) {
719             try {
720                 instanceIdGenerator = (InstanceIdGenerator) loadHelper.loadClass(instanceIdGeneratorClass)
721                     .newInstance();
722             } catch (Exception JavaDoc e) {
723                 throw new SchedulerConfigException(
724                         "Unable to instantiate InstanceIdGenerator class: "
725                         + e.getMessage(), e);
726             }
727             
728             tProps = cfg.getPropertyGroup(PROP_SCHED_INSTANCE_ID_GENERATOR_PREFIX, true);
729             try {
730                 setBeanProps(instanceIdGenerator, tProps);
731             } catch (Exception JavaDoc e) {
732                 initException = new SchedulerException("InstanceIdGenerator class '"
733                         + instanceIdGeneratorClass + "' props could not be configured.", e);
734                 initException
735                         .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
736                 throw initException;
737             }
738         }
739         
740         // Get ThreadPool Properties
741
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
742

743         String JavaDoc tpClass = cfg.getStringProperty(PROP_THREAD_POOL_CLASS, null);
744
745         if (tpClass == null) {
746             initException = new SchedulerException(
747                     "ThreadPool class not specified. ",
748                     SchedulerException.ERR_BAD_CONFIGURATION);
749             throw initException;
750         }
751
752         try {
753             tp = (ThreadPool) loadHelper.loadClass(tpClass).newInstance();
754         } catch (Exception JavaDoc e) {
755             initException = new SchedulerException("ThreadPool class '"
756                     + tpClass + "' could not be instantiated.", e);
757             initException
758                     .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
759             throw initException;
760         }
761         tProps = cfg.getPropertyGroup(PROP_THREAD_POOL_PREFIX, true);
762         try {
763             setBeanProps(tp, tProps);
764         } catch (Exception JavaDoc e) {
765             initException = new SchedulerException("ThreadPool class '"
766                     + tpClass + "' props could not be configured.", e);
767             initException
768                     .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
769             throw initException;
770         }
771
772         // Get JobStore Properties
773
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
774

775         String JavaDoc jsClass = cfg.getStringProperty(PROP_JOB_STORE_CLASS,
776                 RAMJobStore.class.getName());
777
778         if (jsClass == null) {
779             initException = new SchedulerException(
780                     "JobStore class not specified. ",
781                     SchedulerException.ERR_BAD_CONFIGURATION);
782             throw initException;
783         }
784
785         try {
786             js = (JobStore) loadHelper.loadClass(jsClass).newInstance();
787         } catch (Exception JavaDoc e) {
788             initException = new SchedulerException("JobStore class '" + jsClass
789                     + "' could not be instantiated.", e);
790             initException
791                     .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
792             throw initException;
793         }
794         tProps = cfg.getPropertyGroup(PROP_JOB_STORE_PREFIX, true, new String JavaDoc[] {PROP_JOB_STORE_LOCK_HANDLER_PREFIX});
795         try {
796             setBeanProps(js, tProps);
797         } catch (Exception JavaDoc e) {
798             initException = new SchedulerException("JobStore class '" + jsClass
799                     + "' props could not be configured.", e);
800             initException
801                     .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
802             throw initException;
803         }
804
805         if (js instanceof JobStoreSupport) {
806             ((JobStoreSupport)js).setInstanceId(schedInstId);
807             ((JobStoreSupport)js).setInstanceName(schedName);
808             
809             // Install custom lock handler (Semaphore)
810
String JavaDoc lockHandlerClass = cfg.getStringProperty(PROP_JOB_STORE_LOCK_HANDLER_CLASS);
811             if (lockHandlerClass != null) {
812                 try {
813                     Semaphore lockHandler = (Semaphore)loadHelper.loadClass(lockHandlerClass).newInstance();
814                     
815                     tProps = cfg.getPropertyGroup(PROP_JOB_STORE_LOCK_HANDLER_PREFIX, true);
816
817                     // If this lock handler requires the table prefix, add it to its properties.
818
if (lockHandler instanceof TablePrefixAware) {
819                         tProps.setProperty(
820                             PROP_TABLE_PREFIX, ((JobStoreSupport)js).getTablePrefix());
821                     }
822                     
823                     try {
824                         setBeanProps(lockHandler, tProps);
825                     } catch (Exception JavaDoc e) {
826                         initException = new SchedulerException("JobStore LockHandler class '" + lockHandlerClass
827                                 + "' props could not be configured.", e);
828                         initException.setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
829                         throw initException;
830                     }
831                     
832                     ((JobStoreSupport)js).setLockHandler(lockHandler);
833                     getLog().info("Using custom data access locking (synchronization): " + lockHandlerClass);
834                 } catch (Exception JavaDoc e) {
835                     initException = new SchedulerException("JobStore LockHandler class '" + lockHandlerClass
836                             + "' could not be instantiated.", e);
837                     initException.setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
838                     throw initException;
839                 }
840             }
841         }
842         
843         // Set up any DataSources
844
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
845

846         String JavaDoc[] dsNames = cfg.getPropertyGroups(PROP_DATASOURCE_PREFIX);
847         for (int i = 0; i < dsNames.length; i++) {
848             PropertiesParser pp = new PropertiesParser(cfg.getPropertyGroup(
849                     PROP_DATASOURCE_PREFIX + "." + dsNames[i], true));
850
851             String JavaDoc cpClass = pp.getStringProperty(PROP_CONNECTION_PROVIDER_CLASS, null);
852
853             // custom connectionProvider...
854
if(cpClass != null) {
855                 ConnectionProvider cp = null;
856                 try {
857                     cp = (ConnectionProvider) loadHelper.loadClass(cpClass).newInstance();
858                 } catch (Exception JavaDoc e) {
859                     initException = new SchedulerException("ConnectionProvider class '" + cpClass
860                             + "' could not be instantiated.", e);
861                     initException
862                             .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
863                     throw initException;
864                 }
865
866                 try {
867                     // remove the class name, so it isn't attempted to be set
868
pp.getUnderlyingProperties().remove(
869                             PROP_CONNECTION_PROVIDER_CLASS);
870                     
871                     setBeanProps(cp, pp.getUnderlyingProperties());
872                 } catch (Exception JavaDoc e) {
873                     initException = new SchedulerException("ConnectionProvider class '" + cpClass
874                             + "' props could not be configured.", e);
875                     initException
876                             .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
877                     throw initException;
878                 }
879
880                 dbMgr = DBConnectionManager.getInstance();
881                 dbMgr.addConnectionProvider(dsNames[i], cp);
882             } else {
883                 String JavaDoc dsJndi = pp.getStringProperty(PROP_DATASOURCE_JNDI_URL, null);
884         
885                 if (dsJndi != null) {
886                     boolean dsAlwaysLookup = pp.getBooleanProperty(
887                             PROP_DATASOURCE_JNDI_ALWAYS_LOOKUP);
888                     String JavaDoc dsJndiInitial = pp.getStringProperty(
889                             PROP_DATASOURCE_JNDI_INITIAL);
890                     String JavaDoc dsJndiProvider = pp.getStringProperty(
891                             PROP_DATASOURCE_JNDI_PROVDER);
892                     String JavaDoc dsJndiPrincipal = pp.getStringProperty(
893                             PROP_DATASOURCE_JNDI_PRINCIPAL);
894                     String JavaDoc dsJndiCredentials = pp.getStringProperty(
895                             PROP_DATASOURCE_JNDI_CREDENTIALS);
896                     Properties JavaDoc props = null;
897                     if (null != dsJndiInitial || null != dsJndiProvider
898                             || null != dsJndiPrincipal || null != dsJndiCredentials) {
899                         props = new Properties JavaDoc();
900                         if (dsJndiInitial != null) {
901                             props.put(PROP_DATASOURCE_JNDI_INITIAL,
902                                     dsJndiInitial);
903                         }
904                         if (dsJndiProvider != null) {
905                             props.put(PROP_DATASOURCE_JNDI_PROVDER,
906                                     dsJndiProvider);
907                         }
908                         if (dsJndiPrincipal != null) {
909                             props.put(PROP_DATASOURCE_JNDI_PRINCIPAL,
910                                     dsJndiPrincipal);
911                         }
912                         if (dsJndiCredentials != null) {
913                             props.put(PROP_DATASOURCE_JNDI_CREDENTIALS,
914                                     dsJndiCredentials);
915                         }
916                     }
917                     JNDIConnectionProvider cp = new JNDIConnectionProvider(dsJndi,
918                             props, dsAlwaysLookup);
919                     dbMgr = DBConnectionManager.getInstance();
920                     dbMgr.addConnectionProvider(dsNames[i], cp);
921                 } else {
922                     String JavaDoc dsDriver = pp.getStringProperty(PROP_DATASOURCE_DRIVER);
923                     String JavaDoc dsURL = pp.getStringProperty(PROP_DATASOURCE_URL);
924                     String JavaDoc dsUser = pp.getStringProperty(PROP_DATASOURCE_USER, "");
925                     String JavaDoc dsPass = pp.getStringProperty(PROP_DATASOURCE_PASSWORD, "");
926                     int dsCnt = pp.getIntProperty(PROP_DATASOURCE_MAX_CONNECTIONS, 10);
927                     String JavaDoc dsValidation = pp.getStringProperty(PROP_DATASOURCE_VALIDATION_QUERY);
928                     
929                     if (dsDriver == null) {
930                         initException = new SchedulerException(
931                                 "Driver not specified for DataSource: "
932                                         + dsNames[i]);
933                         throw initException;
934                     }
935                     if (dsURL == null) {
936                         initException = new SchedulerException(
937                                 "DB URL not specified for DataSource: "
938                                         + dsNames[i]);
939                         throw initException;
940                     }
941                     try {
942                         PoolingConnectionProvider cp = new PoolingConnectionProvider(
943                                 dsDriver, dsURL, dsUser, dsPass, dsCnt,
944                                 dsValidation);
945                         dbMgr = DBConnectionManager.getInstance();
946                         dbMgr.addConnectionProvider(dsNames[i], cp);
947                     } catch (SQLException JavaDoc sqle) {
948                         initException = new SchedulerException(
949                                 "Could not initialize DataSource: " + dsNames[i],
950                                 sqle);
951                         throw initException;
952                     }
953                 }
954                 
955             }
956             
957         }
958
959         // Set up any SchedulerPlugins
960
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
961

962         String JavaDoc[] pluginNames = cfg.getPropertyGroups(PROP_PLUGIN_PREFIX);
963         SchedulerPlugin[] plugins = new SchedulerPlugin[pluginNames.length];
964         for (int i = 0; i < pluginNames.length; i++) {
965             Properties JavaDoc pp = cfg.getPropertyGroup(PROP_PLUGIN_PREFIX + "."
966                     + pluginNames[i], true);
967
968             String JavaDoc plugInClass = pp.getProperty(PROP_PLUGIN_CLASS, null);
969
970             if (plugInClass == null) {
971                 initException = new SchedulerException(
972                         "SchedulerPlugin class not specified for plugin '"
973                                 + pluginNames[i] + "'",
974                         SchedulerException.ERR_BAD_CONFIGURATION);
975                 throw initException;
976             }
977             SchedulerPlugin plugin = null;
978             try {
979                 plugin = (SchedulerPlugin)
980                         loadHelper.loadClass(plugInClass).newInstance();
981             } catch (Exception JavaDoc e) {
982                 initException = new SchedulerException(
983                         "SchedulerPlugin class '" + plugInClass
984                                 + "' could not be instantiated.", e);
985                 initException
986                         .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
987                 throw initException;
988             }
989             try {
990                 setBeanProps(plugin, pp);
991             } catch (Exception JavaDoc e) {
992                 initException = new SchedulerException(
993                         "JobStore SchedulerPlugin '" + plugInClass
994                                 + "' props could not be configured.", e);
995                 initException
996                         .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
997                 throw initException;
998             }
999             
1000            plugins[i] = plugin;
1001        }
1002
1003        // Set up any JobListeners
1004
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1005

1006        Class JavaDoc[] strArg = new Class JavaDoc[] { String JavaDoc.class };
1007        String JavaDoc[] jobListenerNames = cfg.getPropertyGroups(PROP_JOB_LISTENER_PREFIX);
1008        JobListener[] jobListeners = new JobListener[jobListenerNames.length];
1009        for (int i = 0; i < jobListenerNames.length; i++) {
1010            Properties JavaDoc lp = cfg.getPropertyGroup(PROP_JOB_LISTENER_PREFIX + "."
1011                    + jobListenerNames[i], true);
1012            
1013            String JavaDoc listenerClass = lp.getProperty(PROP_LISTENER_CLASS, null);
1014
1015            if (listenerClass == null) {
1016                initException = new SchedulerException(
1017                        "JobListener class not specified for listener '"
1018                                + jobListenerNames[i] + "'",
1019                        SchedulerException.ERR_BAD_CONFIGURATION);
1020                throw initException;
1021            }
1022            JobListener listener = null;
1023            try {
1024                listener = (JobListener)
1025                       loadHelper.loadClass(listenerClass).newInstance();
1026            } catch (Exception JavaDoc e) {
1027                initException = new SchedulerException(
1028                        "JobListener class '" + listenerClass
1029                                + "' could not be instantiated.", e);
1030                initException
1031                        .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
1032                throw initException;
1033            }
1034            try {
1035                Method JavaDoc nameSetter = listener.getClass().getMethod("setName", strArg);
1036                if(nameSetter != null) {
1037                    nameSetter.invoke(listener, new Object JavaDoc[] {jobListenerNames[i] } );
1038                }
1039                setBeanProps(listener, lp);
1040            } catch (Exception JavaDoc e) {
1041                initException = new SchedulerException(
1042                        "JobListener '" + listenerClass
1043                                + "' props could not be configured.", e);
1044                initException
1045                        .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
1046                throw initException;
1047            }
1048            jobListeners[i] = listener;
1049        }
1050               
1051        // Set up any TriggerListeners
1052
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1053

1054        String JavaDoc[] triggerListenerNames = cfg.getPropertyGroups(PROP_TRIGGER_LISTENER_PREFIX);
1055        TriggerListener[] triggerListeners = new TriggerListener[triggerListenerNames.length];
1056        for (int i = 0; i < triggerListenerNames.length; i++) {
1057            Properties JavaDoc lp = cfg.getPropertyGroup(PROP_TRIGGER_LISTENER_PREFIX + "."
1058                    + triggerListenerNames[i], true);
1059            
1060            String JavaDoc listenerClass = lp.getProperty(PROP_LISTENER_CLASS, null);
1061
1062            if (listenerClass == null) {
1063                initException = new SchedulerException(
1064                        "TriggerListener class not specified for listener '"
1065                                + triggerListenerNames[i] + "'",
1066                        SchedulerException.ERR_BAD_CONFIGURATION);
1067                throw initException;
1068            }
1069            TriggerListener listener = null;
1070            try {
1071                listener = (TriggerListener)
1072                       loadHelper.loadClass(listenerClass).newInstance();
1073            } catch (Exception JavaDoc e) {
1074                initException = new SchedulerException(
1075                        "TriggerListener class '" + listenerClass
1076                                + "' could not be instantiated.", e);
1077                initException
1078                        .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
1079                throw initException;
1080            }
1081            try {
1082                Method JavaDoc nameSetter = listener.getClass().getMethod("setName", strArg);
1083                if(nameSetter != null) {
1084                    nameSetter.invoke(listener, new Object JavaDoc[] {triggerListenerNames[i] } );
1085                }
1086                setBeanProps(listener, lp);
1087            } catch (Exception JavaDoc e) {
1088                initException = new SchedulerException(
1089                        "TriggerListener '" + listenerClass
1090                                + "' props could not be configured.", e);
1091                initException
1092                        .setErrorCode(SchedulerException.ERR_BAD_CONFIGURATION);
1093                throw initException;
1094            }
1095            triggerListeners[i] = listener;
1096        }
1097                
1098        
1099        // Fire everything up
1100
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1101

1102        JobRunShellFactory jrsf = null; // Create correct run-shell factory...
1103

1104        UserTransactionHelper.setUserTxLocation(userTXLocation);
1105
1106        if (wrapJobInTx) {
1107            jrsf = new JTAJobRunShellFactory();
1108        } else {
1109            jrsf = new StdJobRunShellFactory();
1110        }
1111
1112        if (autoId) {
1113            try {
1114                schedInstId = DEFAULT_INSTANCE_ID;
1115                if (js instanceof JobStoreSupport) {
1116                    if(((JobStoreSupport)js).isClustered()) {
1117                        schedInstId = instanceIdGenerator.generateInstanceId();
1118                    }
1119                }
1120            } catch (Exception JavaDoc e) {
1121                getLog().error("Couldn't generate instance Id!", e);
1122                throw new IllegalStateException JavaDoc(
1123                        "Cannot run without an instance id.");
1124            }
1125        }
1126
1127        if (js instanceof JobStoreSupport) {
1128            JobStoreSupport jjs = (JobStoreSupport)js;
1129            jjs.setInstanceId(schedInstId);
1130            jjs.setDbRetryInterval(dbFailureRetry);
1131        }
1132        
1133        QuartzSchedulerResources rsrcs = new QuartzSchedulerResources();
1134        rsrcs.setName(schedName);
1135        rsrcs.setThreadName(threadName);
1136        rsrcs.setInstanceId(schedInstId);
1137        rsrcs.setJobRunShellFactory(jrsf);
1138        rsrcs.setMakeSchedulerThreadDaemon(makeSchedulerThreadDaemon);
1139        rsrcs.setJMXExport(jmxExport);
1140        rsrcs.setJMXObjectName(jmxObjectName);
1141
1142        if (rmiExport) {
1143            rsrcs.setRMIRegistryHost(rmiHost);
1144            rsrcs.setRMIRegistryPort(rmiPort);
1145            rsrcs.setRMIServerPort(rmiServerPort);
1146            rsrcs.setRMICreateRegistryStrategy(rmiCreateRegistry);
1147            rsrcs.setRMIBindName(rmiBindName);
1148        }
1149
1150        rsrcs.setThreadPool(tp);
1151        if(tp instanceof SimpleThreadPool) {
1152            ((SimpleThreadPool)tp).setThreadNamePrefix(schedName + "_Worker");
1153        }
1154        tp.initialize();
1155        
1156        rsrcs.setJobStore(js);
1157
1158        // add plugins
1159
for (int i = 0; i < plugins.length; i++) {
1160            rsrcs.addSchedulerPlugin(plugins[i]);
1161        }
1162
1163        schedCtxt = new SchedulingContext();
1164        schedCtxt.setInstanceId(rsrcs.getInstanceId());
1165
1166        qs = new QuartzScheduler(rsrcs, schedCtxt, idleWaitTime, dbFailureRetry);
1167
1168        // if(usingJSCMT)
1169
// qs.setSignalOnSchedulingChange(false); // TODO: fixed? (don't need
1170
// this any more?)
1171

1172        // Create Scheduler ref...
1173
Scheduler scheduler = instantiate(rsrcs, qs);
1174        
1175        // set job factory if specified
1176
if(jobFactory != null) {
1177            qs.setJobFactory(jobFactory);
1178        }
1179
1180        // Initialize plugins now that we have a Scheduler instance.
1181
for (int i = 0; i < plugins.length; i++) {
1182            plugins[i].initialize(pluginNames[i], scheduler);
1183        }
1184        
1185        // add listeners
1186
for (int i = 0; i < jobListeners.length; i++) {
1187            qs.addGlobalJobListener(jobListeners[i]);
1188        }
1189        for (int i = 0; i < triggerListeners.length; i++) {
1190            qs.addGlobalTriggerListener(triggerListeners[i]);
1191        }
1192        
1193        // set scheduler context data...
1194
Iterator JavaDoc itr = schedCtxtProps.keySet().iterator();
1195        while(itr.hasNext()) {
1196            String JavaDoc key = (String JavaDoc) itr.next();
1197            String JavaDoc val = schedCtxtProps.getProperty(key);
1198            
1199            scheduler.getContext().put(key, val);
1200        }
1201        
1202        // fire up job store, and runshell factory
1203

1204        js.initialize(loadHelper, qs.getSchedulerSignaler());
1205
1206        jrsf.initialize(scheduler, schedCtxt);
1207
1208        getLog().info(
1209                "Quartz scheduler '" + scheduler.getSchedulerName()
1210                        + "' initialized from " + propSrc);
1211
1212        getLog().info("Quartz scheduler version: " + qs.getVersion());
1213
1214        // prevents the repository from being garbage collected
1215
qs.addNoGCObject(schedRep);
1216        // prevents the db manager from being garbage collected
1217
if (dbMgr != null) {
1218            qs.addNoGCObject(dbMgr);
1219        }
1220
1221        schedRep.bind(scheduler);
1222
1223        return scheduler;
1224    }
1225
1226    protected Scheduler instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs) {
1227        SchedulingContext schedCtxt = new SchedulingContext();
1228        schedCtxt.setInstanceId(rsrcs.getInstanceId());
1229        
1230        Scheduler scheduler = new StdScheduler(qs, schedCtxt);
1231        return scheduler;
1232    }
1233    
1234
1235    private void setBeanProps(Object JavaDoc obj, Properties JavaDoc props)
1236        throws NoSuchMethodException JavaDoc, IllegalAccessException JavaDoc,
1237            java.lang.reflect.InvocationTargetException JavaDoc,
1238            IntrospectionException JavaDoc, SchedulerConfigException {
1239        props.remove("class");
1240
1241        BeanInfo JavaDoc bi = Introspector.getBeanInfo(obj.getClass());
1242        PropertyDescriptor JavaDoc[] propDescs = bi.getPropertyDescriptors();
1243        PropertiesParser pp = new PropertiesParser(props);
1244
1245        java.util.Enumeration JavaDoc keys = props.keys();
1246        while (keys.hasMoreElements()) {
1247            String JavaDoc name = (String JavaDoc) keys.nextElement();
1248            String JavaDoc c = name.substring(0, 1).toUpperCase(Locale.US);
1249            String JavaDoc methName = "set" + c + name.substring(1);
1250
1251            java.lang.reflect.Method JavaDoc setMeth = getSetMethod(methName, propDescs);
1252
1253            try {
1254                if (setMeth == null) {
1255                    throw new NoSuchMethodException JavaDoc(
1256                            "No setter for property '" + name + "'");
1257                }
1258
1259                Class JavaDoc[] params = setMeth.getParameterTypes();
1260                if (params.length != 1) {
1261                    throw new NoSuchMethodException JavaDoc(
1262                        "No 1-argument setter for property '" + name + "'");
1263                }
1264                if (params[0].equals(int.class)) {
1265                    setMeth.invoke(obj, new Object JavaDoc[]{new Integer JavaDoc(pp
1266                            .getIntProperty(name))});
1267                } else if (params[0].equals(long.class)) {
1268                    setMeth.invoke(obj, new Object JavaDoc[]{new Long JavaDoc(pp
1269                            .getLongProperty(name))});
1270                } else if (params[0].equals(float.class)) {
1271                    setMeth.invoke(obj, new Object JavaDoc[]{new Float JavaDoc(pp
1272                            .getFloatProperty(name))});
1273                } else if (params[0].equals(double.class)) {
1274                    setMeth.invoke(obj, new Object JavaDoc[]{new Double JavaDoc(pp
1275                            .getDoubleProperty(name))});
1276                } else if (params[0].equals(boolean.class)) {
1277                    setMeth.invoke(obj, new Object JavaDoc[]{new Boolean JavaDoc(pp
1278                            .getBooleanProperty(name))});
1279                } else if (params[0].equals(String JavaDoc.class)) {
1280                    setMeth.invoke(obj,
1281                            new Object JavaDoc[]{pp.getStringProperty(name)});
1282                } else {
1283                    throw new NoSuchMethodException JavaDoc(
1284                            "No primitive-type setter for property '" + name
1285                                    + "'");
1286                }
1287            } catch (NumberFormatException JavaDoc nfe) {
1288                throw new SchedulerConfigException("Could not parse property '"
1289                        + name + "' into correct data type: " + nfe.toString());
1290            }
1291        }
1292    }
1293
1294    private java.lang.reflect.Method JavaDoc getSetMethod(String JavaDoc name,
1295            PropertyDescriptor JavaDoc[] props) {
1296        for (int i = 0; i < props.length; i++) {
1297            java.lang.reflect.Method JavaDoc wMeth = props[i].getWriteMethod();
1298
1299            if (wMeth != null && wMeth.getName().equals(name)) {
1300                return wMeth;
1301            }
1302        }
1303
1304        return null;
1305    }
1306
1307    private Class JavaDoc loadClass(String JavaDoc className) throws ClassNotFoundException JavaDoc {
1308
1309        try {
1310            return Thread.currentThread().getContextClassLoader().loadClass(
1311                    className);
1312        } catch (ClassNotFoundException JavaDoc e) {
1313            return getClass().getClassLoader().loadClass(className);
1314        }
1315    }
1316    
1317    private String JavaDoc getSchedulerName() {
1318        return cfg.getStringProperty(PROP_SCHED_INSTANCE_NAME,
1319                "QuartzScheduler");
1320    }
1321
1322    private String JavaDoc getSchedulerInstId() {
1323        return cfg.getStringProperty(PROP_SCHED_INSTANCE_ID,
1324                DEFAULT_INSTANCE_ID);
1325    }
1326
1327    /**
1328     * <p>
1329     * Returns a handle to the Scheduler produced by this factory.
1330     * </p>
1331     *
1332     * <p>
1333     * If one of the <code>initialize</code> methods has not be previously
1334     * called, then the default (no-arg) <code>initialize()</code> method
1335     * will be called by this method.
1336     * </p>
1337     */

1338    public Scheduler getScheduler() throws SchedulerException {
1339        if (cfg == null) {
1340            initialize();
1341        }
1342
1343        SchedulerRepository schedRep = SchedulerRepository.getInstance();
1344
1345        Scheduler sched = schedRep.lookup(getSchedulerName());
1346
1347        if (sched != null) {
1348            if (sched.isShutdown()) {
1349                schedRep.remove(getSchedulerName());
1350            } else {
1351                return sched;
1352            }
1353        }
1354
1355        sched = instantiate();
1356
1357        return sched;
1358    }
1359
1360    /**
1361     * <p>
1362     * Returns a handle to the default Scheduler, creating it if it does not
1363     * yet exist.
1364     * </p>
1365     *
1366     * @see #initialize()
1367     */

1368    public static Scheduler getDefaultScheduler() throws SchedulerException {
1369        StdSchedulerFactory fact = new StdSchedulerFactory();
1370
1371        return fact.getScheduler();
1372    }
1373
1374    /**
1375     * <p>
1376     * Returns a handle to the Scheduler with the given name, if it exists (if
1377     * it has already been instantiated).
1378     * </p>
1379     */

1380    public Scheduler getScheduler(String JavaDoc schedName) throws SchedulerException {
1381        return SchedulerRepository.getInstance().lookup(schedName);
1382    }
1383
1384    /**
1385     * <p>
1386     * Returns a handle to all known Schedulers (made by any
1387     * StdSchedulerFactory instance.).
1388     * </p>
1389     */

1390    public Collection JavaDoc getAllSchedulers() throws SchedulerException {
1391        return SchedulerRepository.getInstance().lookupAll();
1392    }
1393}
1394
Popular Tags