1 //
2 //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
3 //All rights reserved.
4 //
5 //Redistribution and use in source and binary forms, with or without modification,
6 //are permitted provided that the following conditions are met:
7 //
8 //* Redistributions of source code must retain the above copyright notice,
9 //this list of conditions and the following disclaimer.
10 //* Redistributions in binary form must reproduce the above copyright notice,
11 //this list of conditions and the following disclaimer in the documentation
12 //and/or other materials provided with the distribution.
13 //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
14 //nor the names of its contributors may be used to endorse or promote products
15 //derived from this software without specific prior written permission.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 //POSSIBILITY OF SUCH DAMAGE.
27 //
28
29 package org.objectledge.scheduler.db;
30
31 import java.util.Iterator;
32 import java.util.List;
33
34 import org.jcontainer.dna.Configuration;
35 import org.jcontainer.dna.Logger;
36 import org.objectledge.ComponentInitializationError;
37 import org.objectledge.database.persistence.Persistence;
38 import org.objectledge.database.persistence.PersistenceException;
39 import org.objectledge.database.persistence.Persistent;
40 import org.objectledge.database.persistence.PersistentFactory;
41 import org.objectledge.scheduler.AbstractJobDescriptor;
42 import org.objectledge.scheduler.AbstractScheduler;
43 import org.objectledge.scheduler.JobModificationException;
44 import org.objectledge.scheduler.Schedule;
45 import org.objectledge.scheduler.ScheduleFactory;
46 import org.objectledge.threads.ThreadPool;
47 import org.picocontainer.MutablePicoContainer;
48
49 /**
50 * Scheduler base on database.
51 *
52 * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski</a>
53 */
54 public class DBScheduler extends AbstractScheduler
55 implements PersistentFactory
56 {
57 // instance variables ///////////////////////////////////////////////////
58
59 /*** The persistence service. */
60 protected Persistence persistence;
61
62 /***
63 * Component contructor.
64 *
65 * @param container the container to store loaded classes.
66 * @param config the configuration.
67 * @param logger the logger.
68 * @param threadPool the thread pool component.
69 * @param scheduleFactories the list of schedule factories.
70 * @param persistence the persistence component.
71 */
72 public DBScheduler(
73 MutablePicoContainer container,
74 Configuration config,
75 Logger logger,
76 ThreadPool threadPool,
77 ScheduleFactory[] scheduleFactories,
78 Persistence persistence)
79 {
80 super(container, config, logger, threadPool, scheduleFactories);
81 this.persistence = persistence;
82 }
83
84 // persitent factory implementation //////////////////////////////////////////////
85
86 /***
87 * {@inheritDoc}
88 */
89
90 public Persistent newInstance()
91 {
92 DBJobDescriptor job = new DBJobDescriptor(persistence, this);
93 return (Persistent)job;
94 }
95
96 // abstract scheduler impementation //////////////////////////////////////////////
97
98 /***
99 * {@inheritDoc}
100 */
101 public synchronized AbstractJobDescriptor createJobDescriptor(String name,
102 Schedule schedule, String jobClassName)
103 throws JobModificationException
104 {
105 if (jobs.get(name) != null)
106 {
107 throw new IllegalArgumentException("job " + name + " already exists");
108 }
109 DBJobDescriptor job = null;
110 try
111 {
112 job = (DBJobDescriptor)newInstance();
113 }
114 catch (Exception e)
115 {
116 throw new JobModificationException("failed to create instance", e);
117 }
118 job.init(name, schedule, jobClassName);
119 jobs.put(name, job);
120 try
121 {
122 persistence.save(job);
123 }
124 catch (PersistenceException e)
125 {
126 throw new JobModificationException("failed to save new job", e);
127 }
128 return job;
129 }
130
131 /***
132 * {@inheritDoc}
133 */
134 public synchronized void deleteJobDescriptor(AbstractJobDescriptor job)
135 throws JobModificationException
136 {
137 if (jobs.get(job.getName()) == null)
138 {
139 throw new IllegalArgumentException("unregistered job " + job.getName());
140 }
141 jobs.remove(job.getName());
142 try
143 {
144 persistence.delete((Persistent)job);
145 }
146 catch (PersistenceException e)
147 {
148 throw new JobModificationException("failed to delete job", e);
149 }
150 }
151
152 /***
153 * {@inheritDoc}
154 */
155 public boolean allowsModifications()
156 {
157 return true;
158 }
159
160 /***
161 * {@inheritDoc}
162 */
163 protected void loadJobs()
164 {
165 try
166 {
167 List jobList = persistence.load(null, this);
168 Iterator i = jobList.iterator();
169 while (i.hasNext())
170 {
171 AbstractJobDescriptor job = (AbstractJobDescriptor)i.next();
172 jobs.put(job.getName(), job);
173 }
174 }
175 catch (PersistenceException e)
176 {
177 ///CLOVER:OFF
178 throw new ComponentInitializationError("Failed to load jobs ", e);
179 ///CLOVER:ON
180 }
181 }
182 }