some deep down optimization
[mir.git] / source / mircoders / global / ProducerEngine.java
index f905bd0..33942e0 100755 (executable)
-/*\r
- * Copyright (C) 2001, 2002 The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with  any library licensed under the Apache Software License,\r
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
- * (or with modified versions of the above that use the same license as the above),\r
- * and distribute linked combinations including the two.  You must obey the\r
- * GNU General Public License in all respects for all of the code used other than\r
- * the above mentioned libraries.  If you modify this file, you may extend this\r
- * exception to your version of the file, but you are not obligated to do so.\r
- * If you do not wish to do so, delete this exception statement from your version.\r
- */\r
-package mircoders.global;\r
-\r
-import java.io.PrintWriter;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Vector;\r
-\r
-import mir.config.MirPropertiesConfiguration;\r
-import mir.log.LoggerToWriterAdapter;\r
-import mir.log.LoggerWrapper;\r
-import mir.producer.Producer;\r
-import mir.producer.ProducerFactory;\r
-import mir.util.GeneratorFormatAdapters;\r
-import mir.util.StringRoutines;\r
-import multex.Exc;\r
-import multex.Failure;\r
-\r
-public class ProducerEngine {\r
-//  private Map producers;\r
-  private JobQueue producerJobQueue;\r
-  private LoggerWrapper logger;\r
-\r
-\r
-  protected ProducerEngine() {\r
-    logger = new LoggerWrapper("Producer");\r
-    producerJobQueue = new JobQueue(new LoggerWrapper("Producer.Queue"));\r
-  }\r
-\r
-  public void addJob(String aProducerFactory, String aVerb) {\r
-    producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb);\r
-  }\r
-\r
-  public void cancelJobs(List aJobs) {\r
-    producerJobQueue.cancelJobs(aJobs);\r
-  };\r
-\r
-  public void cancelAllJobs() {\r
-    producerJobQueue.cancelAllJobs();\r
-  };\r
-\r
-  public void addTask(ProducerTask aTask) {\r
-    addJob(aTask.getProducer(), aTask.getVerb());\r
-  }\r
-\r
-  public void addTasks(List aTasks) {\r
-    Iterator i = aTasks.iterator();\r
-\r
-    while (i.hasNext()) {\r
-      addTask((ProducerTask) i.next());\r
-    }\r
-  }\r
-\r
-  private String convertStatus(JobQueue.JobInfo aJob) {\r
-    switch (aJob.getStatus()) {\r
-      case JobQueue.STATUS_ABORTED:\r
-        return "aborted";\r
-      case JobQueue.STATUS_CANCELLED:\r
-        return "cancelled";\r
-      case JobQueue.STATUS_CREATED:\r
-        return "created";\r
-      case JobQueue.STATUS_PENDING:\r
-        return "pending";\r
-      case JobQueue.STATUS_PROCESSED:\r
-        return "processed";\r
-      case JobQueue.STATUS_PROCESSING:\r
-        return "processing";\r
-    }\r
-    return "unknown";\r
-  }\r
-\r
-  private Map convertJob(JobQueue.JobInfo aJob) {\r
-    try {\r
-      Map result = new HashMap();\r
-      result.put("identifier", aJob.getIdentifier());\r
-      result.put("description", aJob.getDescription());\r
-      result.put("priority", new Integer(aJob.getPriority()));\r
-      result.put("runningtime", new Double( (double) aJob.getRunningTime() / 1000));\r
-      result.put("status", convertStatus(aJob));\r
-      result.put("lastchange", new GeneratorFormatAdapters.DateFormatAdapter(aJob.getLastChange(), MirPropertiesConfiguration.instance().getString("Mir.DefaultTimezone")));\r
-      result.put("finished", new Boolean(\r
-          aJob.getStatus() == JobQueue.STATUS_PROCESSED ||\r
-          aJob.getStatus() == JobQueue.STATUS_CANCELLED ||\r
-          aJob.getStatus() == JobQueue.STATUS_ABORTED));\r
-\r
-      return result;\r
-    }\r
-    catch (Throwable t) {\r
-      throw new RuntimeException(t.toString());\r
-    }\r
-  }\r
-\r
-  private List convertJobInfoList(List aJobInfoList) {\r
-    List result = new Vector();\r
-\r
-    Iterator i = aJobInfoList.iterator();\r
-\r
-    while (i.hasNext())\r
-      result.add(convertJob((JobQueue.JobInfo) i.next()));\r
-\r
-    return result;\r
-  }\r
-\r
-  public List getQueueStatus() {\r
-    return convertJobInfoList(producerJobQueue.getJobsInfo());\r
-  }\r
-\r
-  private class ProducerJob implements JobQueue.Job {\r
-    private String factoryName;\r
-    private String verb;\r
-    private Producer producer;\r
-\r
-    public ProducerJob(String aFactory, String aVerb) {\r
-      factoryName = aFactory;\r
-      verb = aVerb;\r
-      producer=null;\r
-    }\r
-\r
-    public String getFactoryName() {\r
-      return factoryName;\r
-    }\r
-\r
-    public String getVerb() {\r
-      return verb;\r
-    }\r
-\r
-    public void abort() {\r
-      if (producer!=null) {\r
-        producer.abort();\r
-      }\r
-    }\r
-\r
-    public boolean run() {\r
-      ProducerFactory factory;\r
-      long startTime;\r
-      long endTime;\r
-      boolean result = false;\r
-      Map startingMap = new HashMap();\r
-      Map mirMap = new HashMap();\r
-      mirMap.put("producer", factoryName);\r
-      mirMap.put("verb", verb);\r
-\r
-      startingMap.put("Mir", mirMap);\r
-\r
-      startTime = System.currentTimeMillis();\r
-      logger.info("Producing job: "+factoryName+"."+verb);\r
-\r
-      try {\r
-        factory = MirGlobal.localizer().producers().getFactoryForName( factoryName );\r
-\r
-        if (factory!=null) {\r
-          MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);\r
-\r
-          synchronized(factory) {\r
-            producer = factory.makeProducer(verb, startingMap);\r
-          }\r
-          if (producer!=null) {\r
-            result = producer.produce(logger);\r
-          }\r
-        }\r
-      }\r
-      catch (Throwable t) {\r
-        logger.error("Exception occurred while producing " + factoryName + "." + verb + t.getMessage());\r
-        t.printStackTrace(new PrintWriter(new LoggerToWriterAdapter(logger, LoggerWrapper.ERROR_MESSAGE)));\r
-      }\r
-      endTime = System.currentTimeMillis();\r
-      logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms");\r
-\r
-      return result;\r
-    }\r
-\r
-    boolean isAborted() {\r
-      return false;\r
-    }\r
-  }\r
-\r
-  public static class ProducerEngineExc extends Exc {\r
-    public ProducerEngineExc(String aMessage) {\r
-      super(aMessage);\r
-    }\r
-  }\r
-\r
-  public static class ProducerEngineRuntimeExc extends Failure {\r
-    public ProducerEngineRuntimeExc(String msg, Exception cause){\r
-      super(msg,cause);\r
-    }\r
-  }\r
-\r
-  public static class ProducerTask {\r
-    private String producer;\r
-    private String verb;\r
-\r
-    public ProducerTask(String aProducer, String aVerb) {\r
-      producer = aProducer;\r
-      verb = aVerb;\r
-    }\r
-\r
-    public String getVerb() {\r
-      return verb;\r
-    }\r
-\r
-    public String getProducer() {\r
-      return producer;\r
-    }\r
-\r
-    public static List parseProducerTaskList(String aList) throws ProducerEngineExc {\r
-      Iterator i;\r
-      List result = new Vector();\r
-\r
-      i = StringRoutines.splitString(aList, ";").iterator();\r
-      while (i.hasNext()) {\r
-        String taskExpression = ((String) i.next()).trim();\r
-\r
-        if (taskExpression.length()>0) {\r
-          List parts = StringRoutines.splitString(taskExpression, ".");\r
-\r
-          if (parts.size() != 2)\r
-            throw new ProducerEngineExc("Invalid producer expression: '" + taskExpression + "'");\r
-          else\r
-            result.add(new ProducerEngine.ProducerTask( (String) parts.get(0), (String) parts.get(1)));\r
-        }\r
-      }\r
-\r
-      return result;\r
-    }\r
-  }\r
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * 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  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.*;
+
+public class ProducerEngine {
+  private JobQueue producerJobQueue;
+  private LoggerWrapper logger;
+  private Map nameToFactory;
+  private List factories;
+
+  protected ProducerEngine() {
+    logger = new LoggerWrapper("Producer");
+    producerJobQueue = new JobQueue(new LoggerWrapper("Producer.Queue"));
+
+    factories = new ArrayList();
+    nameToFactory = new HashMap();
+
+    try {
+      reloadConfiguration();
+    }
+    catch (Throwable t) {
+    }
+  }
+
+  /**
+   * Reloads the producer configuration
+   */
+  public void reloadConfiguration()  throws MirGlobalExc, MirGlobalFailure {
+    try {
+      factories = MirGlobal.localizer().producers().loadFactories();
+
+      synchronized (nameToFactory) {
+        nameToFactory.clear();
+
+        Iterator i = factories.iterator();
+        while (i.hasNext()) {
+          ProducerFactory factory = (ProducerFactory) i.next();
+          nameToFactory.put(factory.getName(), factory);
+        }
+      }
+    }
+    catch (Throwable t) {
+      throw new MirGlobalFailure(t);
+    }
+  }
+
+  /**
+   * Looks up a producer factory by name
+   */
+  private ProducerFactory getFactoryForName(String aName) {
+    synchronized (nameToFactory) {
+      return (ProducerFactory) nameToFactory.get(aName);
+    }
+  }
+
+  /**
+   * 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;
+
+    factory = getFactoryForName( aProducerFactory );
+
+    if (factory==null)
+      throw new MirGlobalExc("Unknown producer: " + aProducerFactory);
+
+    if (!factory.allowVerb(aVerb))
+      throw new MirGlobalExc("illegal producer/verb combination: " + aProducerFactory+"::"+aVerb);
+
+    producerJobQueue.appendJob(
+        new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb);
+  }
+
+  /**
+   * 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());
+  }
+
+  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";
+  }
+
+  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 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 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();
+      logger.info("Producing job: "+factoryName+"."+verb);
+
+      try {
+        factory = getFactoryForName(factoryName);
+
+        if (factory!=null) {
+          MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
+
+          synchronized(factory) {
+            producer = factory.makeProducer(verb, startingMap);
+          }
+          if (producer!=null) {
+            result = producer.produce(logger);
+          }
+        }
+      }
+      catch (Throwable t) {
+        logger.error("Exception occurred while producing " + factoryName + "." + verb + t.getMessage());
+        t.printStackTrace(new PrintWriter(new LoggerToWriterAdapter(logger, LoggerWrapper.ERROR_MESSAGE)));
+      }
+      endTime = System.currentTimeMillis();
+      logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms");
+
+      return result;
+    }
+
+    boolean isAborted() {
+      return false;
+    }
+  }
+
+  public static class ProducerTask {
+    private String producer;
+    private String verb;
+
+    public ProducerTask(String aProducer, String aVerb) {
+      producer = aProducer;
+      verb = aVerb;
+    }
+
+    public String getVerb() {
+      return verb;
+    }
+
+    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