package se.idega.idegaweb.commune.accounting.invoice.business;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Logger;
import javax.ejb.FinderException;
import se.idega.idegaweb.commune.adulteducation.accounting.business.AdultEducationStarterThread;
import com.idega.block.school.data.School;
import com.idega.block.school.data.SchoolCategory;
import com.idega.block.school.data.SchoolCategoryHome;
import com.idega.data.IDOLookup;
import com.idega.data.IDOLookupException;
import com.idega.presentation.IWContext;
import com.idega.util.IWTimestamp;
/**
* Class to facilitate that batchruns can be executed one after another.
*
* @author Joakim
*/
public class BatchRunQueue {
// The queue holding the list of batch runs waiting to get executed. Holds
// objects of type BatchRunObject
private static ArrayList queue = new ArrayList();
private static BillingThread runningThread = null;
private static Logger log = Logger.getLogger("BatchRunQueue");
/**
* Call this funcion to add a batchrun to the queue of batchruns to be
* executed All batches are executed one at a time and in the order they
* were added.
*
* @param month
* @param readDate
* @param schoolCategory
* @param iwc
* @throws SchoolCategoryNotFoundException
*/
public static void addBatchRunToQueue(Date month, Date readDate,
String schoolCategory, School school, IWContext iwc, boolean testRun)
throws SchoolCategoryNotFoundException {
BatchRunObject batchRunObject = new BatchRunObject(month, readDate,
schoolCategory, school, iwc, testRun);
if (!isAlreadyInQueue(batchRunObject)) {
queue.add(batchRunObject);
log.info("Added " + batchRunObject + " to queue at place "
+ (queue.size() - 1));
if (queue.size() == 1) {
try {
log.info("About to start " + batchRunObject);
startBatch(batchRunObject);
} catch (IDOLookupException e) {
e.printStackTrace();
} catch (FinderException e) {
e.printStackTrace();
} catch (BatchAlreadyRunningException e) {
e.printStackTrace();
}
}
}
}
public static void addBatchRunToQueue(Date month, Date readDate,
String schoolCategory, IWContext iwc)
throws SchoolCategoryNotFoundException {
addBatchRunToQueue(month, readDate, schoolCategory, null, iwc, false);
}
/**
* Check to see if a batchrun of this type already is in the queue
*
* @param newBatchRun
* @return true if batch is in queue, else false.
*/
private static boolean isAlreadyInQueue(BatchRunObject newBatchRun) {
String s = newBatchRun.toString();
Iterator iter = queue.iterator();
while (iter.hasNext()) {
BatchRunObject batchRunObject = (BatchRunObject) iter.next();
if (batchRunObject.toString().equalsIgnoreCase(s)) {
return true;
}
}
return false;
}
/**
* Removes a batch from the queue according to the String parameter sent in
*
* @param s
*/
public static String removeBatchRunFromQueue(String s) {
boolean running = true;
Iterator iter = queue.iterator();
while (iter.hasNext()) {
BatchRunObject batchRunObject = (BatchRunObject) iter.next();
if (batchRunObject.toString().equalsIgnoreCase(s)) {
if (running) {
System.out.println("Removing current thread " + s);
if (runningThread != null) {
runningThread.terminate();
runningThread = null;
return "batchlist.Terminating_a_running_batch._It_will_take_a_few_seconds_before_it_is_terminated";
} else {
queue.remove(batchRunObject);
return "batchlist.Removed_batch_from_queue.";
}
} else {
System.out.println("Removing queue object " + s);
queue.remove(batchRunObject);
return "batchlist.Removed_batch_from_queue.";
}
}
running = false;
}
return null;
}
/**
* Calling this lets the queue know that it is possible to start another
* batch
*/
public static void BatchRunDone() {
queue.remove(0);
log.info("Done with one batchrun");
if (queue.size() > 0) {
try {
log.info("About to start " + queue.get(0));
startBatch((BatchRunObject) queue.get(0));
} catch (Exception e) {
e.printStackTrace();
}
} else {
log.info("No more batches to run.");
}
}
/**
* Starts a new batchrun
*
* @param batchRunObject
* @throws FinderException
* @throws BatchAlreadyRunningException
* @throws SchoolCategoryNotFoundException
* @throws IDOLookupException
*/
private static void startBatch(BatchRunObject batchRunObject)
throws FinderException, BatchAlreadyRunningException,
SchoolCategoryNotFoundException, IDOLookupException {
// Select correct thread to start
SchoolCategoryHome sch = (SchoolCategoryHome) IDOLookup
.getHome(SchoolCategory.class);
if (sch.findChildcareCategory().getCategory().equals(
batchRunObject.schoolCategory)) {
if (BatchRunSemaphore.getChildcareRunSemaphore()) {
runningThread = new InvoiceChildcareThread(
batchRunObject.month, batchRunObject.iwc,
batchRunObject.school, batchRunObject.testRun);
runningThread.start();
} else {
throw new BatchAlreadyRunningException("Childcare");
}
} else if (sch.findElementarySchoolCategory().getCategory().equals(
batchRunObject.schoolCategory)) {
if (BatchRunSemaphore.getElementaryRunSemaphore()) {
runningThread = new PaymentThreadElementarySchool(
batchRunObject.month, batchRunObject.iwc,
batchRunObject.school, batchRunObject.testRun);
runningThread.start();
} else {
throw new BatchAlreadyRunningException("ElementarySchool");
}
} else if (sch.findHighSchoolCategory().getCategory().equals(
batchRunObject.schoolCategory)) {
if (BatchRunSemaphore.getHighRunSemaphore()) {
runningThread = new PaymentThreadHighSchool(
batchRunObject.readDate, batchRunObject.iwc,
batchRunObject.school, batchRunObject.testRun);
runningThread.start();
} else {
throw new BatchAlreadyRunningException("HighSchool");
}
} else if (sch.findAdultEducationCategory().getCategory().equals(
batchRunObject.schoolCategory)) {
if (BatchRunSemaphore.getAdultRunSemaphore()) {
runningThread = new AdultEducationStarterThread(
batchRunObject.month, batchRunObject.iwc,
batchRunObject.school, batchRunObject.testRun);
runningThread.start();
} else {
throw new BatchAlreadyRunningException("Adult education");
}
} else {
log
.warning("Error: couldn't find any Schoolcategory for billing named "
+ batchRunObject.schoolCategory);
throw new SchoolCategoryNotFoundException(
"Couldn't find any Schoolcategory for billing named "
+ batchRunObject.schoolCategory);
}
}
public static Iterator iterator() {
return queue.iterator();
}
public static class BatchRunObject {
Date month;
Date readDate;
String schoolCategory;
IWContext iwc;
boolean testRun;
School school;
public BatchRunObject(Date month, Date readDate, String schoolCategory,
School school, IWContext iwc, boolean testRun) {
this.month = month;
this.readDate = readDate;
this.schoolCategory = schoolCategory;
this.iwc = iwc;
this.testRun = testRun;
this.school = school;
}
public BatchRunObject(Date month, Date readDate, String schoolCategory,
IWContext iwc) {
this(month, readDate, schoolCategory, null, iwc, false);
}
public String toString() {
IWTimestamp m = null;
if (month != null) {
m = new IWTimestamp(month);
} else if (readDate != null) {
m = new IWTimestamp(readDate);
}
String s = schoolCategory;
if (m != null) {
s += " " + m.getDateString("MMM yyyy");
}
if (school != null) {
s += " " + school;
}
if (testRun) {
s += " [TEST]";
}
return s;
}
}
}