/*
- * Copyright (C) 2001, 2002 The Mir-coders group
+ * Copyright (C) 2001, 2002 The Mir-coders group
*
* This file is part of Mir.
*
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with the com.oreilly.servlet library, any library
- * licensed under the Apache Software License, The Sun (tm) Java Advanced
- * Imaging library (JAI), The Sun JIMI library (or with modified versions of
- * the above that use the same license as the above), and distribute linked
- * combinations including the two. You must obey the GNU General Public
- * License in all respects for all of the code used other than the above
- * mentioned libraries. If you modify this file, you may extend this exception
- * to your version of the file, but you are not obligated to do so. If you do
- * not wish to do so, delete this exception statement from your version.
+ * the code of this program with any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two. You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries. If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
*/
-
package mircoders.global;
+import mir.config.MirPropertiesConfiguration;
+import mir.log.LoggerToWriterAdapter;
+import mir.log.LoggerWrapper;
+import mir.producer.Producer;
+import mir.producer.ProducerFactory;
+import mir.util.GeneratorFormatAdapters;
+import mir.util.StringRoutines;
+
+import java.io.PrintWriter;
import java.util.*;
-import java.io.*;
-import mir.producer.*;
-import mir.util.*;
-import multex.Exc;
-import multex.Failure;
public class ProducerEngine {
-// private Map producers;
private JobQueue producerJobQueue;
- private Thread queueThread;
- private PrintWriter log;
+ private LoggerWrapper logger;
+ private Map nameToFactory;
+ private List factories;
protected ProducerEngine() {
-// producers = MirGlobal.localizer().producers().factories();
- producerJobQueue = new JobQueue();
+ logger = new LoggerWrapper("Producer");
+ producerJobQueue = new JobQueue(new LoggerWrapper("Producer.Queue"));
+
+ factories = new ArrayList();
+ nameToFactory = new HashMap();
+
try {
- RandomAccessFile raFile = (new RandomAccessFile(MirGlobal.getConfigProperty("Home") + "/" + MirGlobal.getConfigProperty("Producer.Logfile"), "rw"));
- raFile.seek(raFile.length());
- log = new PrintWriter(new FileWriter( raFile.getFD()));
+ reloadConfiguration();
}
- catch (Exception e) {
-// throw new ProducerEngineRuntimeExc("Creating PrintWriter log failed",e);
- log = new PrintWriter(new NullWriter());
+ catch (Throwable t) {
}
- queueThread = new Thread(new ProducerJobQueueThread());
- queueThread.start();
}
- public void addJob(String aProducerFactory, String aVerb) {
-// ML: TODO: should check if a similar job is already pending
- producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb));
- log.println(aProducerFactory+"."+aVerb+" added to queue");
- log.flush();
- }
-
- public void printQueueStatus(PrintWriter aWriter) {
- Iterator iterator = producerJobQueue.makeJobListSnapshot().iterator();
- producerJobQueue.cleanupJobs();
- JobQueue.Job job;
+ /**
+ * Reloads the producer configuration
+ */
+ public void reloadConfiguration() throws MirGlobalExc, MirGlobalFailure {
+ try {
+ factories = MirGlobal.localizer().producers().loadFactories();
- while (iterator.hasNext()) {
- job = (JobQueue.Job) iterator.next();
- ProducerJob producerJob = (ProducerJob) job.getData();
+ synchronized (nameToFactory) {
+ nameToFactory.clear();
- aWriter.print(producerJob.factoryName + "." + producerJob.verb);
- if (job.hasBeenProcessed())
- aWriter.print(" processed");
- else if (job.isProcessing())
- aWriter.print(" processing");
- else if (job.isPending())
- aWriter.print(" pending");
- else
- aWriter.print(" unknown status");
+ Iterator i = factories.iterator();
+ while (i.hasNext()) {
+ ProducerFactory factory = (ProducerFactory) i.next();
+ nameToFactory.put(factory.getName(), factory);
+ }
+ }
+ }
+ catch (Throwable t) {
+ throw new MirGlobalFailure(t);
+ }
+ }
- aWriter.println("<br/>");
+ /**
+ * Looks up a producer factory by name
+ */
+ private ProducerFactory getFactoryForName(String aName) {
+ synchronized (nameToFactory) {
+ return (ProducerFactory) nameToFactory.get(aName);
}
}
- private void produceNow(String aProducerFactory, String aVerb, PrintWriter aLogger) {
- try {
- long startTime;
- long endTime;
- Map startingMap = new HashMap();
+ /**
+ * Returns all factories
+ */
+ public List getFactories() {
+ return factories;
+ }
+ /**
+ * Adds a producer job to the queue
+ */
+ public void addJob(String aProducerFactory, String aVerb) throws MirGlobalExc, MirGlobalFailure {
+ ProducerFactory factory;
- startTime = System.currentTimeMillis();
+ factory = getFactoryForName( aProducerFactory );
- aLogger.println("Producing (" + aProducerFactory + "," + aVerb + ")");
+ if (factory==null)
+ throw new MirGlobalExc("Unknown producer: " + aProducerFactory);
- ProducerFactory factory = (ProducerFactory) MirGlobal.localizer().producers().factories().get(aProducerFactory);
+ if (!factory.allowVerb(aVerb))
+ throw new MirGlobalExc("illegal producer/verb combination: " + aProducerFactory+"::"+aVerb);
- if (factory == null )
- throw new Exception("No producer factory '"+aProducerFactory+"' present.");
+ producerJobQueue.appendJob(
+ new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb);
+ }
- MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
- Producer producer = factory.makeProducer(aVerb, startingMap);
+ /**
+ * Cancels a list of jobs by job identifier
+ */
+ public void cancelJobs(List aJobs) {
+ producerJobQueue.cancelJobs(aJobs);
+ };
- producer.produce(aLogger);
+ /**
+ * Cancels all jobs in the queue
+ */
+ public void cancelAllJobs() {
+ producerJobQueue.cancelAllJobs();
+ };
- endTime = System.currentTimeMillis();
+ public void addTask(ProducerTask aTask) throws MirGlobalExc, MirGlobalFailure {
+ addJob(aTask.getProducer(), aTask.getVerb());
+ }
- aLogger.println("Time: " + (endTime-startTime) + " ms<br>");
+ private String convertStatus(JobQueue.JobInfo aJob) {
+ switch (aJob.getStatus()) {
+ case JobQueue.STATUS_ABORTED:
+ return "aborted";
+ case JobQueue.STATUS_CANCELLED:
+ return "cancelled";
+ case JobQueue.STATUS_CREATED:
+ return "created";
+ case JobQueue.STATUS_PENDING:
+ return "pending";
+ case JobQueue.STATUS_PROCESSED:
+ return "processed";
+ case JobQueue.STATUS_PROCESSING:
+ return "processing";
}
- catch (Throwable e) {
- try {
- aLogger.println("exception occurred:<br>");
- aLogger.println(e.getMessage());
- e.printStackTrace(aLogger);
- }
- catch (Throwable f) {
- }
+ return "unknown";
+ }
+
+ private Map convertJob(JobQueue.JobInfo aJob) {
+ try {
+ Map result = new HashMap();
+ result.put("identifier", aJob.getIdentifier());
+ result.put("description", aJob.getDescription());
+ result.put("priority", new Integer(aJob.getPriority()));
+ result.put("runningtime", new Double( (double) aJob.getRunningTime() / 1000));
+ result.put("status", convertStatus(aJob));
+ result.put("lastchange", new GeneratorFormatAdapters.DateFormatAdapter(aJob.getLastChange(), MirPropertiesConfiguration.instance().getString("Mir.DefaultTimezone")));
+ result.put("finished", new Boolean(
+ aJob.getStatus() == JobQueue.STATUS_PROCESSED ||
+ aJob.getStatus() == JobQueue.STATUS_CANCELLED ||
+ aJob.getStatus() == JobQueue.STATUS_ABORTED));
+
+ return result;
+ }
+ catch (Throwable t) {
+ throw new RuntimeException(t.toString());
}
}
- private class ProducerJob {
+ private List convertJobInfoList(List aJobInfoList) {
+ List result = new ArrayList();
+
+ Iterator i = aJobInfoList.iterator();
+
+ while (i.hasNext())
+ result.add(convertJob((JobQueue.JobInfo) i.next()));
+
+ return result;
+ }
+
+ public List getQueueStatus() {
+ return convertJobInfoList(producerJobQueue.getJobsInfo());
+ }
+
+ private class ProducerJob implements JobQueue.Job {
private String factoryName;
private String verb;
+ private Producer producer;
public ProducerJob(String aFactory, String aVerb) {
factoryName = aFactory;
verb = aVerb;
+ producer=null;
+ }
+
+ public String getFactoryName() {
+ return factoryName;
+ }
+
+ public String getVerb() {
+ return verb;
+ }
+
+ public void abort() {
+ if (producer!=null) {
+ producer.abort();
+ }
}
- public void execute() {
+ public boolean run() {
ProducerFactory factory;
- Producer producer;
long startTime;
long endTime;
+ boolean result = false;
Map startingMap = new HashMap();
+ Map mirMap = new HashMap();
+ mirMap.put("producer", factoryName);
+ mirMap.put("verb", verb);
+
+ startingMap.put("Mir", mirMap);
startTime = System.currentTimeMillis();
- log.println("Producing job: "+factoryName+"."+verb);
+ logger.info("Producing job: "+factoryName+"."+verb);
try {
- factory = (ProducerFactory) MirGlobal.localizer().producers().factories().get( factoryName );
+ factory = getFactoryForName(factoryName);
if (factory!=null) {
MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
producer = factory.makeProducer(verb, startingMap);
}
if (producer!=null) {
- producer.produce(log);
+ result = producer.produce(logger);
}
}
}
catch (Throwable t) {
- log.println(" exception "+t.getMessage());
- t.printStackTrace(log);
+ logger.error("Exception occurred while producing " + factoryName + "." + verb + t.getMessage());
+ t.printStackTrace(new PrintWriter(new LoggerToWriterAdapter(logger, LoggerWrapper.ERROR_MESSAGE)));
}
- log.println("Done producing job: "+factoryName+"."+verb);
- endTime = System.currentTimeMillis();
+ endTime = System.currentTimeMillis();
+ logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms");
- log.println("Time: " + (endTime-startTime) + " ms");
- log.flush();
+ return result;
+ }
+
+ boolean isAborted() {
+ return false;
}
}
- private class ProducerJobQueueThread implements Runnable {
- public void run() {
- log.println("starting ProducerJobQueueThread");
- log.flush();
+ public static class ProducerTask {
+ private String producer;
+ private String verb;
- while (true) {
- ProducerJob job = (ProducerJob) producerJobQueue.acquirePendingJob();
- if (job!=null) {
- job.execute();
- producerJobQueue.flagOffJob(job);
- }
- else
- {
- try {
- Thread.sleep(1500);
- }
- catch (InterruptedException e) {
- }
- }
- }
+ public ProducerTask(String aProducer, String aVerb) {
+ producer = aProducer;
+ verb = aVerb;
}
- }
+ public String getVerb() {
+ return verb;
+ }
- public static class ProducerEngineRuntimeExc extends Failure {
- public ProducerEngineRuntimeExc(String msg, Exception cause){
- super(msg,cause);
+ public String getProducer() {
+ return producer;
}
- }
+ public static List parseProducerTaskList(String aList) throws MirGlobalExc {
+ Iterator i;
+ List result = new ArrayList();
+
+ i = StringRoutines.splitString(aList, ";").iterator();
+ while (i.hasNext()) {
+ String taskExpression = ((String) i.next()).trim();
+
+ if (taskExpression.length()>0) {
+ List parts = StringRoutines.splitString(taskExpression, ".");
+
+ if (parts.size() != 2)
+ throw new MirGlobalExc("Invalid producer expression: '" + taskExpression + "'");
+ else
+ result.add(new ProducerEngine.ProducerTask( (String) parts.get(0), (String) parts.get(1)));
+ }
+ }
+
+ return result;
+ }
+ }
}
\ No newline at end of file