1.1 restoration
[mir.git] / source / mircoders / global / ProducerEngine.java
index 20bbc5e..33a6267 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * 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 java.util.*;
-import java.io.*;
-import mir.producer.*;
-import mir.util.*;
-import multex.Exc;
-import multex.Failure;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+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;
 
 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() {
-    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) {
-      log = new PrintWriter(new NullWriter());
+    catch (Throwable t) {
     }
-    queueThread = new Thread(new ProducerJobQueueThread());
-    queueThread.start();
   }
 
-  public void addJob(String aProducerFactory, String aVerb) {
-    producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb));
-    log.println(aProducerFactory+"."+aVerb+" added to queue");
-    log.flush();
-  }
-
-  public void addTask(ProducerTask aTask) {
-    addJob(aTask.getProducer(), aTask.getVerb());
-  }
+  /**
+   * Reloads the producer configuration
+   */
+  public void reloadConfiguration()  throws MirGlobalExc, MirGlobalFailure {
+    try {
+      factories = MirGlobal.localizer().producers().loadFactories();
 
-  public void addTasks(List aTasks) {
-    Iterator i = aTasks.iterator();
+      synchronized (nameToFactory) {
+        nameToFactory.clear();
 
-    while (i.hasNext()) {
-      addTask((ProducerTask) i.next());
+        Iterator i = factories.iterator();
+        while (i.hasNext()) {
+          ProducerFactory factory = (ProducerFactory) i.next();
+          nameToFactory.put(factory.getName(), factory);
+        }
+      }
+    }
+    catch (Throwable t) {
+      throw new MirGlobalFailure(t);
     }
   }
 
-  private String convertStatus(JobQueue.Job aJob) {
-    if (aJob.hasBeenProcessed())
-      return "processed";
-    if (aJob.isProcessing())
-      return "processing";
-    if (aJob.isPending())
-      return "pending";
-    if (aJob.isCancelled())
-      return "cancelled";
-    if (aJob.hasBeenAborted())
-      return "aborted";
+  /**
+   * Looks up a producer factory by name
+   */
+  private ProducerFactory getFactoryForName(String aName) {
+    synchronized (nameToFactory) {
+      return (ProducerFactory) nameToFactory.get(aName);
+    }
+  }
 
-    return "unknown";
+  /**
+   * 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;
 
-  private Map convertJob(JobQueue.Job aJob) {
-    Map result = new HashMap();
-    ProducerJob producerJob = (ProducerJob) aJob.getData();
+    factory = getFactoryForName( aProducerFactory );
 
-    result.put("identifier", aJob.getIdentifier());
-    result.put("factory", producerJob.getFactoryName());
-    result.put("verb", producerJob.getVerb());
-    result.put("priority", new Integer(aJob.getPriority()));
-    result.put("status", convertStatus(aJob));
-    result.put("lastchange", new DateToMapAdapter(aJob.getLastChange()));
+    if (factory==null)
+      throw new MirGlobalExc("Unknown producer: " + aProducerFactory);
 
-    return result;
+    if (!factory.allowVerb(aVerb))
+      throw new MirGlobalExc("illegal producer/verb combination: " + aProducerFactory+"::"+aVerb);
+
+    producerJobQueue.appendJob(
+        new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb);
   }
 
-  private void convertJobList(List aSourceJobList, List aDestination) {
-    Iterator i = aSourceJobList.iterator();
+  /**
+   * Cancels a list of jobs by job identifier
+   */
+  public void cancelJobs(List aJobs) {
+    producerJobQueue.cancelJobs(aJobs);
+  };
+
+  /**
+   * Cancels all jobs in the queue
+   */
+  public void cancelAllJobs() {
+    producerJobQueue.cancelAllJobs();
+  };
+
+  public void addTask(ProducerTask aTask) throws MirGlobalExc, MirGlobalFailure {
+    addJob(aTask.getProducer(), aTask.getVerb());
+  }
 
-    while (i.hasNext())
-      aDestination.add(convertJob((JobQueue.Job) i.next()));
+  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";
+    }
+    return "unknown";
   }
 
-  public List getQueueStatus() {
+  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 List convertJobInfoList(List aJobInfoList) {
     List result = new Vector();
-    List pendingJobs = new Vector();
-    List finishedJobs = new Vector();
 
-    producerJobQueue.makeJobListSnapshots(pendingJobs, finishedJobs);
+    Iterator i = aJobInfoList.iterator();
 
-    convertJobList(pendingJobs, result);
-    convertJobList(finishedJobs, result);
+    while (i.hasNext())
+      result.add(convertJob((JobQueue.JobInfo) i.next()));
 
     return result;
   }
 
-private class ProducerJob {
+  public List getQueueStatus() {
+    return convertJobInfoList(producerJobQueue.getJobsInfo());
+  }
+
+  private class ProducerJob implements JobQueue.Job {
     private String factoryName;
     private String verb;
     private Producer producer;
@@ -150,17 +217,23 @@ private class ProducerJob {
       }
     }
 
-    public void execute() {
+    public boolean run() {
       ProducerFactory factory;
       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 = MirGlobal.localizer().producers().getFactoryForName( factoryName );
+        factory = getFactoryForName(factoryName);
 
         if (factory!=null) {
           MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
@@ -169,18 +242,18 @@ private class ProducerJob {
             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();
-      log.println("Time: " + (endTime-startTime) + " ms");
-      log.flush();
+      logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms");
+
+      return result;
     }
 
     boolean isAborted() {
@@ -188,44 +261,6 @@ private class ProducerJob {
     }
   }
 
-  private class ProducerJobQueueThread implements Runnable {
-    public void run() {
-      log.println("starting ProducerJobQueueThread");
-      log.flush();
-
-      while (true) {
-        ProducerJob job = (ProducerJob) producerJobQueue.acquirePendingJob();
-        if (job!=null) {
-          job.execute();
-          if (job.isAborted())
-            producerJobQueue.jobAborted(job);
-          else
-            producerJobQueue.jobProcessed(job);
-        }
-        else
-        {
-          try {
-            Thread.sleep(1500);
-          }
-          catch (InterruptedException e) {
-          }
-        }
-      }
-    }
-  }
-
-  public static class ProducerEngineExc extends Exc {
-    public ProducerEngineExc(String aMessage) {
-      super(aMessage);
-    }
-  }
-
-  public static class ProducerEngineRuntimeExc extends Failure {
-    public ProducerEngineRuntimeExc(String msg, Exception cause){
-      super(msg,cause);
-    }
-  }
-
   public static class ProducerTask {
     private String producer;
     private String verb;
@@ -243,19 +278,22 @@ private class ProducerJob {
       return producer;
     }
 
-    public static List parseProducerTaskList(String aList) throws ProducerEngineExc {
+    public static List parseProducerTaskList(String aList) throws MirGlobalExc {
       Iterator i;
       List result = new Vector();
 
       i = StringRoutines.splitString(aList, ";").iterator();
       while (i.hasNext()) {
-        String taskExpression = (String) i.next();
-        List parts = StringRoutines.splitString(taskExpression, ".");
+        String taskExpression = ((String) i.next()).trim();
 
-        if (parts.size()!=2)
-          throw new ProducerEngineExc("Invalid producer expression: '" + taskExpression + "'");
-        else
-          result.add(new ProducerEngine.ProducerTask((String) parts.get(0), (String) parts.get(1)));
+        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;