001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: DatabaseTasks.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.scheduler.taskmanagers;
009:
010: import com.uwyn.rife.database.*;
011: import com.uwyn.rife.database.exceptions.DatabaseException;
012: import com.uwyn.rife.database.queries.*;
013: import com.uwyn.rife.scheduler.Scheduler;
014: import com.uwyn.rife.scheduler.Task;
015: import com.uwyn.rife.scheduler.TaskManager;
016: import com.uwyn.rife.scheduler.exceptions.FrequencyException;
017: import com.uwyn.rife.scheduler.exceptions.TaskManagerException;
018: import com.uwyn.rife.scheduler.taskmanagers.exceptions.*;
019:
020: import java.sql.ResultSet;
021: import java.sql.SQLException;
022: import java.util.ArrayList;
023: import java.util.Collection;
024:
025: public abstract class DatabaseTasks extends DbQueryManager implements
026: TaskManager {
027: private Scheduler mScheduler = null;
028:
029: protected DatabaseTasks(Datasource datasource) {
030: super (datasource);
031: }
032:
033: public void setScheduler(Scheduler scheduler) {
034: mScheduler = scheduler;
035: }
036:
037: public Scheduler getScheduler() {
038: return mScheduler;
039: }
040:
041: public abstract boolean install() throws TaskManagerException;
042:
043: public abstract boolean remove() throws TaskManagerException;
044:
045: protected boolean _install(final CreateSequence createSequenceTask,
046: final CreateTable createTableTask)
047: throws TaskManagerException {
048: assert createSequenceTask != null;
049: assert createTableTask != null;
050:
051: try {
052: executeUpdate(createSequenceTask);
053: executeUpdate(createTableTask);
054: } catch (DatabaseException e) {
055: throw new InstallTasksErrorException(e);
056: }
057:
058: return true;
059: }
060:
061: protected boolean _remove(final DropSequence dropSequenceTask,
062: final DropTable dropTableTask) throws TaskManagerException {
063: assert dropSequenceTask != null;
064: assert dropTableTask != null;
065:
066: try {
067: executeUpdate(dropTableTask);
068: executeUpdate(dropSequenceTask);
069: } catch (DatabaseException e) {
070: throw new RemoveTasksErrorException(e);
071: }
072:
073: return true;
074: }
075:
076: protected int _addTask(SequenceValue getTaskId, Insert insertTask,
077: DbPreparedStatementHandler handler, final Task task)
078: throws TaskManagerException {
079: assert getTaskId != null;
080: assert insertTask != null;
081:
082: if (null == task)
083: throw new IllegalArgumentException("task can't be null.");
084:
085: int result = -1;
086: int task_id = -1;
087: try {
088: task_id = executeGetFirstInt(getTaskId);
089: if (-1 == task_id) {
090: throw new GetTaskIdErrorException();
091: }
092: } catch (DatabaseException e) {
093: throw new GetTaskIdErrorException(e);
094: }
095:
096: if (task_id >= 0) {
097: task.setId(task_id);
098:
099: try {
100: if (0 == executeUpdate(insertTask, handler)) {
101: throw new AddTaskErrorException(task);
102: }
103:
104: result = task_id;
105: } catch (DatabaseException e) {
106: throw new AddTaskErrorException(task, e);
107: }
108: }
109:
110: assert result >= 0;
111:
112: return result;
113: }
114:
115: protected boolean _updateTask(Update updateTask,
116: DbPreparedStatementHandler handler, final Task task)
117: throws TaskManagerException {
118: assert updateTask != null;
119:
120: if (null == task)
121: throw new IllegalArgumentException("task can't be null.");
122:
123: boolean result = false;
124:
125: try {
126: if (0 == executeUpdate(updateTask, handler)) {
127: throw new UpdateTaskErrorException(task);
128: }
129:
130: result = true;
131: } catch (DatabaseException e) {
132: throw new UpdateTaskErrorException(task, e);
133: }
134:
135: return result;
136: }
137:
138: protected Task _getTask(Select getTask, ProcessTask processTask,
139: final int id) throws TaskManagerException {
140: assert getTask != null;
141:
142: if (id < 0)
143: throw new IllegalArgumentException(
144: "the task id can't be negative.");
145:
146: Task task = null;
147:
148: try {
149: executeFetchFirst(getTask, processTask,
150: new DbPreparedStatementHandler() {
151: public void setParameters(
152: DbPreparedStatement statement) {
153: statement.setInt("id", id);
154: }
155: });
156: task = processTask.getTask();
157: } catch (DatabaseException e) {
158: throw new GetTaskErrorException(id, e);
159: }
160:
161: return task;
162: }
163:
164: protected Collection<Task> _getTasksToProcess(
165: Select getTasksToProcess, ProcessTask processTask)
166: throws TaskManagerException {
167: assert getTasksToProcess != null;
168:
169: ArrayList<Task> tasks_to_process = new ArrayList<Task>();
170: processTask.setCollection(tasks_to_process);
171:
172: try {
173: executeFetchAll(getTasksToProcess, processTask,
174: new DbPreparedStatementHandler() {
175: public void setParameters(
176: DbPreparedStatement statement) {
177: statement.setLong("planned", System
178: .currentTimeMillis());
179: }
180: });
181: } catch (DatabaseException e) {
182: throw new GetTasksToProcessErrorException(e);
183: }
184:
185: assert tasks_to_process != null;
186:
187: return tasks_to_process;
188: }
189:
190: protected Collection<Task> _getScheduledTasks(
191: Select getScheduledTasks, ProcessTask processTask)
192: throws TaskManagerException {
193: ArrayList<Task> scheduled_tasks = new ArrayList<Task>();
194: processTask.setCollection(scheduled_tasks);
195:
196: try {
197: executeFetchAll(getScheduledTasks, processTask,
198: new DbPreparedStatementHandler() {
199: public void setParameters(
200: DbPreparedStatement statement) {
201: statement.setLong("planned", System
202: .currentTimeMillis());
203: }
204: });
205: } catch (DatabaseException e) {
206: throw new GetScheduledTasksErrorException(e);
207: }
208:
209: assert scheduled_tasks != null;
210:
211: return scheduled_tasks;
212: }
213:
214: protected boolean _removeTask(Delete removeTask, final int id)
215: throws TaskManagerException {
216: assert removeTask != null;
217:
218: if (id < 0)
219: throw new IllegalArgumentException(
220: "the task id can't be negative.");
221:
222: boolean result = false;
223:
224: try {
225: if (0 != executeUpdate(removeTask,
226: new DbPreparedStatementHandler() {
227: public void setParameters(
228: DbPreparedStatement statement) {
229: statement.setInt("id", id);
230: }
231: })) {
232: result = true;
233: }
234: } catch (DatabaseException e) {
235: throw new RemoveTaskErrorException(id, e);
236: }
237:
238: return result;
239: }
240:
241: protected boolean _rescheduleTask(Task task, long newPlanned,
242: String frequency) throws TaskManagerException {
243: if (null == task)
244: throw new IllegalArgumentException("task can't be null.");
245: if (newPlanned <= 0)
246: throw new IllegalArgumentException(
247: "newPlanned has to be bigger than 0.");
248:
249: boolean result = false;
250:
251: Task task_tmp = null;
252: try {
253: task_tmp = task.clone();
254: task_tmp.setPlanned(newPlanned);
255: task_tmp.setFrequency(frequency);
256: } catch (Throwable e) {
257: if (null == frequency) {
258: throw new RescheduleTaskErrorException(task.getId(),
259: newPlanned, e);
260: } else {
261: throw new RescheduleTaskErrorException(task.getId(),
262: newPlanned, frequency, e);
263: }
264: }
265: result = updateTask(task_tmp);
266:
267: assert result;
268:
269: return result;
270: }
271:
272: protected boolean _concludeTask(Task task)
273: throws TaskManagerException {
274: if (null == task)
275: throw new IllegalArgumentException("task can't be null.");
276:
277: if (task.getPlanned() <= System.currentTimeMillis()) {
278: if (null == task.getFrequency()) {
279: return removeTask(task.getId());
280: }
281:
282: try {
283: long next_date = task.getNextDate();
284: if (next_date >= 0
285: && rescheduleTask(task, next_date, task
286: .getFrequency())
287: && deactivateTask(task.getId())) {
288: return true;
289: }
290: } catch (FrequencyException e) {
291: throw new ConcludeTaskErrorException(task.getId(), e);
292: }
293: }
294:
295: return false;
296: }
297:
298: protected boolean _activateTask(Update activateTask, final int id)
299: throws TaskManagerException {
300: assert activateTask != null;
301:
302: if (id < 0)
303: throw new IllegalArgumentException(
304: "the task id can't be negative.");
305:
306: boolean result = false;
307:
308: try {
309: if (0 != executeUpdate(activateTask,
310: new DbPreparedStatementHandler() {
311: public void setParameters(
312: DbPreparedStatement statement) {
313: statement.setInt("id", id);
314: }
315: })) {
316: result = true;
317: }
318: } catch (DatabaseException e) {
319: throw new ActivateTaskErrorException(id);
320: }
321:
322: return result;
323: }
324:
325: protected boolean _desactivateTask(Update desactivateTask,
326: final int id) throws TaskManagerException {
327: assert desactivateTask != null;
328:
329: if (id < 0)
330: throw new IllegalArgumentException(
331: "the task id can't be negative.");
332:
333: boolean result = false;
334:
335: try {
336: if (0 != executeUpdate(desactivateTask,
337: new DbPreparedStatementHandler() {
338: public void setParameters(
339: DbPreparedStatement statement) {
340: statement.setInt("id", id);
341: }
342: })) {
343: result = true;
344: }
345: } catch (DatabaseException e) {
346: throw new DesactivateTaskErrorException(id, e);
347: }
348:
349: return result;
350: }
351:
352: protected class ProcessTask extends DbRowProcessor {
353: protected Collection<Task> mCollection = null;
354: protected Task mTask = null;
355:
356: public ProcessTask() {
357: }
358:
359: public void setCollection(Collection<Task> collection) {
360: mCollection = collection;
361: }
362:
363: public boolean processRow(ResultSet resultSet)
364: throws SQLException {
365: assert resultSet != null;
366:
367: mTask = new Task();
368:
369: mTask.setId(resultSet.getInt("id"));
370: mTask.setType(resultSet.getString("type"));
371: mTask.setPlanned(resultSet.getLong("planned"));
372: try {
373: mTask.setFrequency(resultSet.getString("frequency"));
374: } catch (FrequencyException e) {
375: throw new SQLException(e.getMessage());
376: }
377: mTask.setBusy(resultSet.getBoolean("busy"));
378: mTask.setTaskManager(DatabaseTasks.this );
379:
380: if (mCollection != null) {
381: mCollection.add(mTask);
382: }
383:
384: return true;
385: }
386:
387: Task getTask() {
388: return mTask;
389: }
390: }
391: }
|