/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: DatabaseTasks.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.scheduler.taskmanagers; import com.uwyn.rife.database.*; import com.uwyn.rife.database.exceptions.DatabaseException; import com.uwyn.rife.database.queries.*; import com.uwyn.rife.scheduler.Scheduler; import com.uwyn.rife.scheduler.Task; import com.uwyn.rife.scheduler.TaskManager; import com.uwyn.rife.scheduler.exceptions.FrequencyException; import com.uwyn.rife.scheduler.exceptions.TaskManagerException; import com.uwyn.rife.scheduler.taskmanagers.exceptions.*; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; public abstract class DatabaseTasks extends DbQueryManager implements TaskManager { private Scheduler mScheduler = null; protected DatabaseTasks(Datasource datasource) { super(datasource); } public void setScheduler(Scheduler scheduler) { mScheduler = scheduler; } public Scheduler getScheduler() { return mScheduler; } public abstract boolean install() throws TaskManagerException; public abstract boolean remove() throws TaskManagerException; protected boolean _install(final CreateSequence createSequenceTask, final CreateTable createTableTask) throws TaskManagerException { assert createSequenceTask != null; assert createTableTask != null; try { executeUpdate(createSequenceTask); executeUpdate(createTableTask); } catch (DatabaseException e) { throw new InstallTasksErrorException(e); } return true; } protected boolean _remove(final DropSequence dropSequenceTask, final DropTable dropTableTask) throws TaskManagerException { assert dropSequenceTask != null; assert dropTableTask != null; try { executeUpdate(dropTableTask); executeUpdate(dropSequenceTask); } catch (DatabaseException e) { throw new RemoveTasksErrorException(e); } return true; } protected int _addTask(SequenceValue getTaskId, Insert insertTask, DbPreparedStatementHandler handler, final Task task) throws TaskManagerException { assert getTaskId != null; assert insertTask != null; if (null == task) throw new IllegalArgumentException("task can't be null."); int result = -1; int task_id = -1; try { task_id = executeGetFirstInt(getTaskId); if (-1 == task_id) { throw new GetTaskIdErrorException(); } } catch (DatabaseException e) { throw new GetTaskIdErrorException(e); } if (task_id >= 0) { task.setId(task_id); try { if (0 == executeUpdate(insertTask, handler)) { throw new AddTaskErrorException(task); } result = task_id; } catch (DatabaseException e) { throw new AddTaskErrorException(task, e); } } assert result >= 0; return result; } protected boolean _updateTask(Update updateTask, DbPreparedStatementHandler handler, final Task task) throws TaskManagerException { assert updateTask != null; if (null == task) throw new IllegalArgumentException("task can't be null."); boolean result = false; try { if (0 == executeUpdate(updateTask, handler)) { throw new UpdateTaskErrorException(task); } result = true; } catch (DatabaseException e) { throw new UpdateTaskErrorException(task, e); } return result; } protected Task _getTask(Select getTask, ProcessTask processTask, final int id) throws TaskManagerException { assert getTask != null; if (id < 0) throw new IllegalArgumentException("the task id can't be negative."); Task task = null; try { executeFetchFirst(getTask, processTask, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("id", id); } }); task = processTask.getTask(); } catch (DatabaseException e) { throw new GetTaskErrorException(id, e); } return task; } protected Collection<Task> _getTasksToProcess(Select getTasksToProcess, ProcessTask processTask) throws TaskManagerException { assert getTasksToProcess != null; ArrayList<Task> tasks_to_process = new ArrayList<Task>(); processTask.setCollection(tasks_to_process); try { executeFetchAll(getTasksToProcess, processTask, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("planned", System.currentTimeMillis()); } }); } catch (DatabaseException e) { throw new GetTasksToProcessErrorException(e); } assert tasks_to_process != null; return tasks_to_process; } protected Collection<Task> _getScheduledTasks(Select getScheduledTasks, ProcessTask processTask) throws TaskManagerException { ArrayList<Task> scheduled_tasks = new ArrayList<Task>(); processTask.setCollection(scheduled_tasks); try { executeFetchAll(getScheduledTasks, processTask, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("planned", System.currentTimeMillis()); } }); } catch (DatabaseException e) { throw new GetScheduledTasksErrorException(e); } assert scheduled_tasks != null; return scheduled_tasks; } protected boolean _removeTask(Delete removeTask, final int id) throws TaskManagerException { assert removeTask != null; if (id < 0) throw new IllegalArgumentException("the task id can't be negative."); boolean result = false; try { if (0 != executeUpdate(removeTask, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("id", id); } })) { result = true; } } catch (DatabaseException e) { throw new RemoveTaskErrorException(id, e); } return result; } protected boolean _rescheduleTask(Task task, long newPlanned, String frequency) throws TaskManagerException { if (null == task) throw new IllegalArgumentException("task can't be null."); if (newPlanned <= 0) throw new IllegalArgumentException("newPlanned has to be bigger than 0."); boolean result = false; Task task_tmp = null; try { task_tmp = task.clone(); task_tmp.setPlanned(newPlanned); task_tmp.setFrequency(frequency); } catch (Throwable e) { if (null == frequency) { throw new RescheduleTaskErrorException(task.getId(), newPlanned, e); } else { throw new RescheduleTaskErrorException(task.getId(), newPlanned, frequency, e); } } result = updateTask(task_tmp); assert result; return result; } protected boolean _concludeTask(Task task) throws TaskManagerException { if (null == task) throw new IllegalArgumentException("task can't be null."); if (task.getPlanned() <= System.currentTimeMillis()) { if (null == task.getFrequency()) { return removeTask(task.getId()); } try { long next_date = task.getNextDate(); if (next_date >= 0 && rescheduleTask(task, next_date, task.getFrequency()) && deactivateTask(task.getId())) { return true; } } catch (FrequencyException e) { throw new ConcludeTaskErrorException(task.getId(), e); } } return false; } protected boolean _activateTask(Update activateTask, final int id) throws TaskManagerException { assert activateTask != null; if (id < 0) throw new IllegalArgumentException("the task id can't be negative."); boolean result = false; try { if (0 != executeUpdate(activateTask, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("id", id); } })) { result = true; } } catch (DatabaseException e) { throw new ActivateTaskErrorException(id); } return result; } protected boolean _desactivateTask(Update desactivateTask, final int id) throws TaskManagerException { assert desactivateTask != null; if (id < 0) throw new IllegalArgumentException("the task id can't be negative."); boolean result = false; try { if (0 != executeUpdate(desactivateTask, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("id", id); } })) { result = true; } } catch (DatabaseException e) { throw new DesactivateTaskErrorException(id, e); } return result; } protected class ProcessTask extends DbRowProcessor { protected Collection<Task> mCollection = null; protected Task mTask = null; public ProcessTask() { } public void setCollection(Collection<Task> collection) { mCollection = collection; } public boolean processRow(ResultSet resultSet) throws SQLException { assert resultSet != null; mTask = new Task(); mTask.setId(resultSet.getInt("id")); mTask.setType(resultSet.getString("type")); mTask.setPlanned(resultSet.getLong("planned")); try { mTask.setFrequency(resultSet.getString("frequency")); } catch (FrequencyException e) { throw new SQLException(e.getMessage()); } mTask.setBusy(resultSet.getBoolean("busy")); mTask.setTaskManager(DatabaseTasks.this); if (mCollection != null) { mCollection.add(mTask); } return true; } Task getTask() { return mTask; } } }