merge of localization branch into HEAD. mh and zap
[mir.git] / source / mircoders / global / JobQueue.java
1 package mircoders.global;
2
3 import java.util.*;
4
5 // important: objects passed as data must not be altered once put into a job
6
7 public class JobQueue {
8   private Vector jobs;
9   private Map dataToJob;
10
11   public static final int STATUS_PENDING = 0;
12   public static final int STATUS_PROCESSING = 1;
13   public static final int STATUS_PROCESSED = 2;
14
15   public JobQueue() {
16     jobs = new Vector();
17     dataToJob = new HashMap();
18   }
19
20   public void appendJob(Object aData) {
21     synchronized (jobs) {
22       Job job = new Job(aData);
23       jobs.add(job);
24       dataToJob.put(aData, job);
25     }
26   }
27
28   public Object acquirePendingJob() {
29     synchronized (jobs) {
30       Iterator i = jobs.iterator();
31
32       while (i.hasNext()) {
33         Job job = (Job) i.next();
34
35         if (job.setProcessing()) {
36           return job.getData();
37         }
38       }
39     }
40
41     return null;
42   }
43
44   public void flagOffJob(Object aData) {
45     synchronized (jobs) {
46       Job job = (Job) dataToJob.get(aData);
47
48       if (job!=null) {
49         job.setProcessed();
50       }
51     }
52   }
53
54   public void cleanupJobs() {
55     synchronized (jobs) {
56       Iterator i = jobs.iterator();
57
58       while (i.hasNext()) {
59         Job job = (Job) i.next();
60
61         if (job.hasBeenProcessed()) {
62           i.remove();
63         }
64       }
65     }
66   }
67
68   public List makeJobListSnapshot() {
69     synchronized (jobs) {
70       return (List) jobs.clone();
71     }
72   }
73
74   public class Job implements Cloneable {
75     private Object data;
76     private int status;
77
78     public Job(Object aData, int aStatus) {
79       data = aData;
80       status = aStatus;
81     }
82
83     public Job(Object aData) {
84       this(aData, STATUS_PENDING);
85     }
86
87     public Object getData() {
88       return data;
89     }
90
91     public int getStatus() {
92       synchronized(this) {
93         return status;
94       }
95     }
96
97     protected boolean setProcessing() {
98       return setStatus(STATUS_PENDING, STATUS_PROCESSING);
99     }
100
101     protected void setProcessed() {
102       setStatus(STATUS_PROCESSING, STATUS_PROCESSED);
103     }
104
105     public boolean hasBeenProcessed() {
106       return getStatus() == STATUS_PROCESSED;
107     }
108
109     public boolean isProcessing() {
110       return getStatus() == STATUS_PROCESSING;
111     }
112
113     public boolean isPending() {
114       return getStatus() == STATUS_PENDING;
115     }
116
117     private boolean setStatus(int anOldStatus, int aNewStatus) {
118       synchronized(this) {
119         if (status == anOldStatus) {
120           status = aNewStatus;
121           return true;
122         }
123         else {
124           return false;
125         }
126       }
127     }
128
129     protected Object clone() {
130       synchronized(this) {
131         return new Job(data, status);
132       }
133     }
134   }
135 }
136