small fixes yet again
[mir.git] / source / mircoders / global / JobQueue.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mircoders.global;
33
34 import java.util.*;
35
36 // important: objects passed as data must not be altered once put into a job
37
38 public class JobQueue {
39   private Vector jobs;
40   private Vector finishedJobs;
41   private Map dataToJob;
42   private Map identifierToJob;
43   private int nrJobs;
44
45   public static final int STATUS_PENDING = 0;
46   public static final int STATUS_PROCESSING = 1;
47   public static final int STATUS_PROCESSED = 2;
48   public static final int STATUS_CANCELLED = 3;
49   public static final int STATUS_ABORTED = 4;
50
51   public static final int PRIORITY_NORMAL = 100;
52   public static final int PRIORITY_LOW = 10;
53   public static final int PRIORITY_HIGH = 1000;
54
55   public static final int FINISHEDJOBS_LOGSIZE = 10;
56
57   public JobQueue() {
58     finishedJobs = new Vector();
59     jobs = new Vector();
60     dataToJob = new HashMap();
61     identifierToJob = new HashMap();
62     nrJobs = 0;
63   }
64
65   public String appendJob(Object aData) {
66     synchronized (jobs) {
67       Job job = new Job(aData, Integer.toString(nrJobs));
68       nrJobs++;
69       jobs.add(job);
70       dataToJob.put(aData, job);
71       identifierToJob.put(job.getIdentifier(), job);
72       return job.getIdentifier();
73     }
74   }
75
76   public Object acquirePendingJob() {
77     synchronized (jobs) {
78       int priorityFound= 0;
79       Job jobFound;
80
81       do {
82         jobFound = null;
83         Iterator i = jobs.iterator();
84         while (i.hasNext()) {
85           Job job = (Job) i.next();
86
87           if (job.isPending() && (jobFound==null || priorityFound<job.getPriority())) {
88             jobFound = job;
89             priorityFound = job.getPriority();
90           }
91         }
92       }
93       while (jobFound!=null && !jobFound.setProcessing());
94
95       if (jobFound!=null)
96         return jobFound.getData();
97       else
98         return null;
99     }
100   }
101
102   private void finishJob(Job aJob) {
103     synchronized (jobs) {
104       identifierToJob.remove(aJob.identifier);
105       jobs.remove(aJob);
106       finishedJobs.insertElementAt(aJob, 0);
107       if (finishedJobs.size()>FINISHEDJOBS_LOGSIZE)
108         finishedJobs.remove(finishedJobs.size()-1);
109     }
110   }
111
112   public void jobProcessed(Object aData) {
113     synchronized (jobs) {
114       Job job = (Job) dataToJob.get(aData);
115
116       if (job!=null) {
117         job.setProcessed();
118         finishJob(job);
119       }
120     }
121   }
122
123   public void jobAborted(Object aData) {
124     synchronized (jobs) {
125       Job job = (Job) dataToJob.get(aData);
126
127       if (job!=null) {
128         job.setAborted();
129         finishJob(job);
130       }
131     }
132   }
133
134   public void cancelJob(Object aData) {
135     synchronized (jobs) {
136       Job job = (Job) dataToJob.get(aData);
137
138       if (job!=null && job.setCancelled()) {
139         finishJob(job);
140       }
141     }
142   }
143
144   public void makeJobListSnapshots(List aJobList, List aFinishedJobList) {
145     synchronized (jobs) {
146       aJobList.addAll(makeJobListSnapshot());
147       aFinishedJobList.addAll(makeFinishedJobListSnapshot());
148     }
149   }
150
151   public List makeJobListSnapshot() {
152     synchronized (jobs) {
153       return (List) jobs.clone();
154     }
155   }
156
157   public List makeFinishedJobListSnapshot() {
158     synchronized (jobs) {
159       return (List) finishedJobs.clone();
160     }
161   }
162
163   public class Job implements Cloneable {
164     private Object data;
165     private Date lastChange;
166     private String identifier;
167     private int status;
168     private int priority;
169
170     public Job(Object aData, String anIdentifier, int aStatus, int aPriority, Date aLastChange) {
171       data = aData;
172       status = aStatus;
173       identifier = anIdentifier;
174       priority = aPriority;
175       lastChange = aLastChange;
176     }
177
178     public Job(Object aData, String anIdentifier, int aStatus, int aPriority) {
179       this(aData, anIdentifier, aStatus, aPriority, (new GregorianCalendar()).getTime());
180     }
181
182     public Date getLastChange() {
183       return lastChange;
184     }
185
186     public String getIdentifier() {
187       return identifier;
188     }
189
190     public Job(Object aData, String anIdentifier) {
191       this(aData, anIdentifier, STATUS_PENDING, PRIORITY_NORMAL);
192     }
193
194     public Object getData() {
195       return data;
196     }
197
198     public int getStatus() {
199       synchronized(this) {
200         return status;
201       }
202     }
203
204     public int getPriority() {
205       return priority;
206     }
207
208     protected boolean setProcessing() {
209       return setStatus(STATUS_PENDING, STATUS_PROCESSING);
210     }
211
212     protected void setProcessed() {
213       setStatus(STATUS_PROCESSING, STATUS_PROCESSED);
214     }
215
216     protected void setAborted() {
217       setStatus(STATUS_PROCESSING, STATUS_ABORTED);
218     }
219
220     protected boolean setCancelled() {
221       return setStatus(STATUS_PENDING, STATUS_CANCELLED);
222     }
223
224     public boolean hasBeenProcessed() {
225       return getStatus() == STATUS_PROCESSED;
226     }
227
228     public boolean hasBeenAborted() {
229       return getStatus() == STATUS_ABORTED;
230     }
231
232     public boolean isCancelled() {
233       return getStatus() == STATUS_CANCELLED;
234     }
235
236     public boolean isFinished() {
237       return hasBeenProcessed() || hasBeenAborted() || isCancelled();
238     }
239
240     public boolean isProcessing() {
241       return getStatus() == STATUS_PROCESSING;
242     }
243
244     public boolean isPending() {
245       return getStatus() == STATUS_PENDING;
246     }
247
248     private boolean setStatus(int anOldStatus, int aNewStatus) {
249       synchronized(this) {
250         if (status == anOldStatus) {
251           status = aNewStatus;
252           lastChange = (new GregorianCalendar()).getTime();
253           return true;
254         }
255         else {
256           return false;
257         }
258       }
259     }
260
261     protected Object clone() {
262       synchronized(this) {
263         System.out.println("  blabla");
264         return new Job(data, identifier, status, priority, lastChange);
265       }
266     }
267   }
268 }
269