+package mircoders.global;
+
+import java.util.*;
+
+// important: objects passed as data must not be altered once put into a job
+
+public class JobQueue {
+ private List jobs;
+ private Map dataToJob;
+
+ public static final int STATUS_PENDING = 0;
+ public static final int STATUS_PROCESSING = 1;
+ public static final int STATUS_PROCESSED = 2;
+
+ public JobQueue() {
+ jobs = new Vector();
+ dataToJob = new HashMap();
+ }
+
+ public void appendJob(Object aData) {
+ synchronized (jobs) {
+ Job job = new Job(aData);
+ jobs.add(job);
+ dataToJob.put(aData, job);
+ }
+ }
+
+ public Object acquirePendingJob() {
+ synchronized (jobs) {
+ Iterator i = jobs.iterator();
+
+ while (i.hasNext()) {
+ Job job = (Job) i.next();
+
+ if (job.setProcessing()) {
+ return job.getData();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void flagOffJob(Object aData) {
+ synchronized (jobs) {
+ Job job = (Job) dataToJob.get(aData);
+
+ if (job!=null) {
+ job.setProcessed();
+ }
+ }
+ }
+
+ public void cleanupJobs() {
+ synchronized (jobs) {
+ Iterator i = jobs.iterator();
+
+ while (i.hasNext()) {
+ Job job = (Job) i.next();
+
+ if (job.hasBeenProcessed()) {
+ i.remove();
+ }
+ }
+ }
+ }
+
+ public class Job {
+ private Object data;
+ private int status;
+ private int identifier;
+
+ public Job(Object aData) {
+ data = aData;
+ status = STATUS_PENDING;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public int getStatus() {
+ synchronized(this) {
+ return status;
+ }
+ }
+
+ public boolean setProcessing() {
+ return setStatus(STATUS_PENDING, STATUS_PROCESSING);
+ }
+
+ public void setProcessed() {
+ setStatus(STATUS_PROCESSING, STATUS_PROCESSED);
+ }
+
+ public boolean hasBeenProcessed() {
+ return getStatus() == STATUS_PROCESSED;
+ }
+
+ private boolean setStatus(int anOldStatus, int aNewStatus) {
+ synchronized(this) {
+ if (status == anOldStatus) {
+ status = aNewStatus;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+
+ }
+}
+