public class JobQueue {
private Vector jobs;
+ private Vector finishedJobs;
private Map dataToJob;
+ private Map identifierToJob;
+ private int nrJobs;
public static final int STATUS_PENDING = 0;
public static final int STATUS_PROCESSING = 1;
public static final int STATUS_PROCESSED = 2;
+ public static final int STATUS_CANCELLED = 3;
+ public static final int STATUS_ABORTED = 4;
+
+ public static final int PRIORITY_NORMAL = 100;
+ public static final int PRIORITY_LOW = 10;
+ public static final int PRIORITY_HIGH = 1000;
+
+ public static final int FINISHEDJOBS_LOGSIZE = 10;
public JobQueue() {
+ finishedJobs = new Vector();
jobs = new Vector();
dataToJob = new HashMap();
+ identifierToJob = new HashMap();
+ nrJobs = 0;
}
- public void appendJob(Object aData) {
+ public String appendJob(Object aData) {
synchronized (jobs) {
- Job job = new Job(aData);
+ Job job = new Job(aData, Integer.toString(nrJobs));
+ nrJobs++;
jobs.add(job);
dataToJob.put(aData, job);
+ identifierToJob.put(job.getIdentifier(), job);
+ return job.getIdentifier();
}
}
public Object acquirePendingJob() {
synchronized (jobs) {
- Iterator i = jobs.iterator();
+ int priorityFound= 0;
+ Job jobFound;
- while (i.hasNext()) {
- Job job = (Job) i.next();
+ do {
+ jobFound = null;
+ Iterator i = jobs.iterator();
+ while (i.hasNext()) {
+ Job job = (Job) i.next();
- if (job.setProcessing()) {
- return job.getData();
+ if (job.isPending() && (jobFound==null || priorityFound<job.getPriority())) {
+ jobFound = job;
+ priorityFound = job.getPriority();
+ }
}
}
+ while (jobFound!=null && !jobFound.setProcessing());
+
+ if (jobFound!=null)
+ return jobFound.getData();
+ else
+ return null;
}
+ }
- return null;
+ private void finishJob(Job aJob) {
+ synchronized (jobs) {
+ identifierToJob.remove(aJob.identifier);
+ jobs.remove(aJob);
+ finishedJobs.insertElementAt(aJob, 0);
+ if (finishedJobs.size()>FINISHEDJOBS_LOGSIZE)
+ finishedJobs.remove(finishedJobs.size()-1);
+ }
}
- public void flagOffJob(Object aData) {
+ public void jobProcessed(Object aData) {
synchronized (jobs) {
Job job = (Job) dataToJob.get(aData);
if (job!=null) {
job.setProcessed();
+ finishJob(job);
}
}
}
- public void cleanupJobs() {
+ public void jobAborted(Object aData) {
synchronized (jobs) {
- Iterator i = jobs.iterator();
+ Job job = (Job) dataToJob.get(aData);
- while (i.hasNext()) {
- Job job = (Job) i.next();
+ if (job!=null) {
+ job.setAborted();
+ finishJob(job);
+ }
+ }
+ }
- if (job.hasBeenProcessed()) {
- i.remove();
- }
+ public void cancelJob(Object aData) {
+ synchronized (jobs) {
+ Job job = (Job) dataToJob.get(aData);
+
+ if (job!=null && job.setCancelled()) {
+ finishJob(job);
}
}
}
+ public void makeJobListSnapshots(List aJobList, List aFinishedJobList) {
+ synchronized (jobs) {
+ aJobList.addAll(makeJobListSnapshot());
+ aFinishedJobList.addAll(makeFinishedJobListSnapshot());
+ }
+ }
+
public List makeJobListSnapshot() {
synchronized (jobs) {
return (List) jobs.clone();
}
}
+ public List makeFinishedJobListSnapshot() {
+ synchronized (jobs) {
+ return (List) finishedJobs.clone();
+ }
+ }
+
public class Job implements Cloneable {
private Object data;
+ private Date lastChange;
+ private String identifier;
private int status;
+ private int priority;
- public Job(Object aData, int aStatus) {
+ public Job(Object aData, String anIdentifier, int aStatus, int aPriority, Date aLastChange) {
data = aData;
status = aStatus;
+ identifier = anIdentifier;
+ priority = aPriority;
+ lastChange = aLastChange;
+ }
+
+ public Job(Object aData, String anIdentifier, int aStatus, int aPriority) {
+ this(aData, anIdentifier, aStatus, aPriority, (new GregorianCalendar()).getTime());
+ }
+
+ public Date getLastChange() {
+ return lastChange;
+ }
+
+ public String getIdentifier() {
+ return identifier;
}
- public Job(Object aData) {
- this(aData, STATUS_PENDING);
+ public Job(Object aData, String anIdentifier) {
+ this(aData, anIdentifier, STATUS_PENDING, PRIORITY_NORMAL);
}
public Object getData() {
}
}
+ public int getPriority() {
+ return priority;
+ }
+
protected boolean setProcessing() {
return setStatus(STATUS_PENDING, STATUS_PROCESSING);
}
setStatus(STATUS_PROCESSING, STATUS_PROCESSED);
}
+ protected void setAborted() {
+ setStatus(STATUS_PROCESSING, STATUS_ABORTED);
+ }
+
+ protected boolean setCancelled() {
+ return setStatus(STATUS_PENDING, STATUS_CANCELLED);
+ }
+
public boolean hasBeenProcessed() {
return getStatus() == STATUS_PROCESSED;
}
+ public boolean hasBeenAborted() {
+ return getStatus() == STATUS_ABORTED;
+ }
+
+ public boolean isCancelled() {
+ return getStatus() == STATUS_CANCELLED;
+ }
+
+ public boolean isFinished() {
+ return hasBeenProcessed() || hasBeenAborted() || isCancelled();
+ }
+
public boolean isProcessing() {
return getStatus() == STATUS_PROCESSING;
}
synchronized(this) {
if (status == anOldStatus) {
status = aNewStatus;
+ lastChange = (new GregorianCalendar()).getTime();
return true;
}
else {
protected Object clone() {
synchronized(this) {
- return new Job(data, status);
+ System.out.println(" blabla");
+ return new Job(data, identifier, status, priority, lastChange);
}
}
}