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: MemoryTasks.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.scheduler.taskmanagers;
009:
010: import com.uwyn.rife.pcj.map.IntKeyOpenHashMap;
011: import com.uwyn.rife.scheduler.Scheduler;
012: import com.uwyn.rife.scheduler.Task;
013: import com.uwyn.rife.scheduler.TaskManager;
014: import com.uwyn.rife.scheduler.exceptions.FrequencyException;
015: import com.uwyn.rife.scheduler.exceptions.TaskManagerException;
016: import com.uwyn.rife.scheduler.taskmanagers.exceptions.ConcludeTaskErrorException;
017: import com.uwyn.rife.scheduler.taskmanagers.exceptions.RescheduleTaskErrorException;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021:
022: public class MemoryTasks implements TaskManager {
023: private Scheduler mScheduler = null;
024: private IntKeyOpenHashMap<Task> mTaskMapping = null;
025: private int mTaskIdSequence = 0;
026:
027: public MemoryTasks() {
028: mTaskMapping = new IntKeyOpenHashMap<Task>();
029: }
030:
031: public void setScheduler(Scheduler scheduler) {
032: mScheduler = scheduler;
033: }
034:
035: public Scheduler getScheduler() {
036: return mScheduler;
037: }
038:
039: public int addTask(Task task) throws TaskManagerException {
040: if (null == task)
041: throw new IllegalArgumentException("task can't be null.");
042:
043: synchronized (this ) {
044: // FIXME: check for integer overflow
045: int task_id = mTaskIdSequence++;
046:
047: task.setId(task_id);
048: mTaskMapping.put(task_id, task);
049: task.setTaskManager(this );
050:
051: return task_id;
052: }
053: }
054:
055: public boolean updateTask(Task task) throws TaskManagerException {
056: if (null == task)
057: throw new IllegalArgumentException("task can't be null.");
058: if (task.getId() < 0)
059: throw new IllegalArgumentException(
060: "the task id is required.");
061:
062: synchronized (this ) {
063: int task_id = task.getId();
064:
065: if (!mTaskMapping.containsKey(task_id)) {
066: return false;
067: }
068:
069: mTaskMapping.put(task_id, task);
070: task.setTaskManager(this );
071:
072: return true;
073: }
074: }
075:
076: public Task getTask(int id) throws TaskManagerException {
077: if (id < 0)
078: throw new IllegalArgumentException(
079: "the task id can't be negative.");
080:
081: return mTaskMapping.get(id);
082: }
083:
084: public Collection<Task> getTasksToProcess()
085: throws TaskManagerException {
086: ArrayList<Task> tasks_to_process = new ArrayList<Task>();
087:
088: synchronized (this ) {
089: for (Task task : mTaskMapping.values()) {
090: if (!task.isBusy()
091: && task.getPlanned() < System
092: .currentTimeMillis()) {
093: tasks_to_process.add(task);
094: }
095: }
096: }
097:
098: return tasks_to_process;
099: }
100:
101: public Collection<Task> getScheduledTasks()
102: throws TaskManagerException {
103: ArrayList<Task> scheduled_tasks = new ArrayList<Task>();
104:
105: synchronized (this ) {
106: for (Task task : mTaskMapping.values()) {
107: if (!task.isBusy()
108: && task.getPlanned() >= System
109: .currentTimeMillis()) {
110: scheduled_tasks.add(task);
111: }
112: }
113: }
114:
115: return scheduled_tasks;
116: }
117:
118: public boolean removeTask(int id) throws TaskManagerException {
119: if (id < 0)
120: throw new IllegalArgumentException(
121: "the task id can't be negative.");
122:
123: synchronized (this ) {
124: if (null == mTaskMapping.remove(id)) {
125: return false;
126: }
127:
128: return true;
129: }
130: }
131:
132: public boolean rescheduleTask(Task task, long newPlanned,
133: String frequency) throws TaskManagerException {
134: if (null == task)
135: throw new IllegalArgumentException("task can't be null.");
136: if (newPlanned <= 0)
137: throw new IllegalArgumentException(
138: "newPlanned has to be bigger than 0.");
139:
140: boolean result = false;
141:
142: Task task_tmp = null;
143: try {
144: task_tmp = task.clone();
145: task_tmp.setPlanned(newPlanned);
146: task_tmp.setFrequency(frequency);
147: } catch (Throwable e) {
148: if (null == frequency) {
149: throw new RescheduleTaskErrorException(task.getId(),
150: newPlanned, e);
151: } else {
152: throw new RescheduleTaskErrorException(task.getId(),
153: newPlanned, frequency, e);
154: }
155: }
156: result = updateTask(task_tmp);
157:
158: assert result;
159:
160: return result;
161: }
162:
163: public boolean concludeTask(Task task) throws TaskManagerException {
164: if (null == task)
165: throw new IllegalArgumentException("task can't be null.");
166:
167: if (task.getPlanned() <= System.currentTimeMillis()) {
168: if (null == task.getFrequency()) {
169: return removeTask(task.getId());
170: }
171:
172: try {
173: long next_date = task.getNextDate();
174: if (next_date >= 0
175: && rescheduleTask(task, next_date, task
176: .getFrequency())
177: && deactivateTask(task.getId())) {
178: return true;
179: }
180: } catch (FrequencyException e) {
181: throw new ConcludeTaskErrorException(task.getId(), e);
182: }
183: }
184:
185: return false;
186: }
187:
188: public boolean activateTask(int id) throws TaskManagerException {
189: if (id < 0)
190: throw new IllegalArgumentException(
191: "the task id can't be negative.");
192:
193: synchronized (this ) {
194: Task task = mTaskMapping.get(id);
195: if (null == task) {
196: return false;
197: }
198: task.setBusy(true);
199: return true;
200: }
201: }
202:
203: public boolean deactivateTask(int id) throws TaskManagerException {
204: if (id < 0)
205: throw new IllegalArgumentException(
206: "the task id can't be negative.");
207:
208: synchronized (this ) {
209: Task task = mTaskMapping.get(id);
210: if (null == task) {
211: return false;
212: }
213: task.setBusy(false);
214: return true;
215: }
216: }
217: }
|