Organizing import, refresh the license (zapata deleted cos.jar)
[mir.git] / source / mircoders / global / ProducerEngine.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License, 
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
23  * (or with modified versions of the above that use the same license as the above), 
24  * and distribute linked combinations including the two.  You must obey the 
25  * GNU General Public License in all respects for all of the code used other than 
26  * the above mentioned libraries.  If you modify this file, you may extend this 
27  * exception to your version of the file, but you are not obligated to do so.  
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mircoders.global;
31
32 import java.io.PrintWriter;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Vector;
38
39 import mir.log.LoggerToWriterAdapter;
40 import mir.log.LoggerWrapper;
41 import mir.producer.Producer;
42 import mir.producer.ProducerFactory;
43 import mir.util.DateToMapAdapter;
44 import mir.util.StringRoutines;
45 import multex.Exc;
46 import multex.Failure;
47
48 public class ProducerEngine {
49 //  private Map producers;
50   private JobQueue producerJobQueue;
51   private Thread queueThread;
52   private LoggerWrapper logger;
53
54
55   protected ProducerEngine() {
56     producerJobQueue = new JobQueue();
57     logger = new LoggerWrapper("Producer");
58
59     queueThread = new Thread(new ProducerJobQueueThread());
60     queueThread.start();
61   }
62
63   public void addJob(String aProducerFactory, String aVerb) {
64     producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb));
65   }
66
67   public void addTask(ProducerTask aTask) {
68     addJob(aTask.getProducer(), aTask.getVerb());
69   }
70
71   public void addTasks(List aTasks) {
72     Iterator i = aTasks.iterator();
73
74     while (i.hasNext()) {
75       addTask((ProducerTask) i.next());
76     }
77   }
78
79   private String convertStatus(JobQueue.Job aJob) {
80     if (aJob.hasBeenProcessed())
81       return "processed";
82     if (aJob.isProcessing())
83       return "processing";
84     if (aJob.isPending())
85       return "pending";
86     if (aJob.isCancelled())
87       return "cancelled";
88     if (aJob.hasBeenAborted())
89       return "aborted";
90
91     return "unknown";
92   }
93
94   private Map convertJob(JobQueue.Job aJob) {
95     Map result = new HashMap();
96     ProducerJob producerJob = (ProducerJob) aJob.getData();
97
98     result.put("identifier", aJob.getIdentifier());
99     result.put("factory", producerJob.getFactoryName());
100     result.put("verb", producerJob.getVerb());
101     result.put("priority", new Integer(aJob.getPriority()));
102     result.put("status", convertStatus(aJob));
103     result.put("lastchange", new DateToMapAdapter(aJob.getLastChange()));
104
105     return result;
106   }
107
108   private void convertJobList(List aSourceJobList, List aDestination) {
109     Iterator i = aSourceJobList.iterator();
110
111     while (i.hasNext())
112       aDestination.add(convertJob((JobQueue.Job) i.next()));
113   }
114
115   public List getQueueStatus() {
116     List result = new Vector();
117     List pendingJobs = new Vector();
118     List finishedJobs = new Vector();
119
120     producerJobQueue.makeJobListSnapshots(pendingJobs, finishedJobs);
121
122     convertJobList(pendingJobs, result);
123     convertJobList(finishedJobs, result);
124
125     return result;
126   }
127
128 private class ProducerJob {
129     private String factoryName;
130     private String verb;
131     private Producer producer;
132
133     public ProducerJob(String aFactory, String aVerb) {
134       factoryName = aFactory;
135       verb = aVerb;
136       producer=null;
137     }
138
139     public String getFactoryName() {
140       return factoryName;
141     }
142
143     public String getVerb() {
144       return verb;
145     }
146
147     public void abort() {
148       if (producer!=null) {
149         producer.abort();
150       }
151     }
152
153     public void execute() {
154       ProducerFactory factory;
155       long startTime;
156       long endTime;
157       Map startingMap = new HashMap();
158
159       startTime = System.currentTimeMillis();
160       logger.info("Producing job: "+factoryName+"."+verb);
161
162       try {
163         factory = MirGlobal.localizer().producers().getFactoryForName( factoryName );
164
165         if (factory!=null) {
166           MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
167
168           synchronized(factory) {
169             producer = factory.makeProducer(verb, startingMap);
170           }
171           if (producer!=null) {
172             producer.produce(logger);
173           }
174         }
175       }
176       catch (Throwable t) {
177         logger.error("Exception occurred while producing " + factoryName + "." + verb + t.getMessage());
178         t.printStackTrace(new PrintWriter(new LoggerToWriterAdapter(logger, LoggerWrapper.ERROR_MESSAGE)));
179       }
180       endTime = System.currentTimeMillis();
181       logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms");
182     }
183
184     boolean isAborted() {
185       return false;
186     }
187   }
188
189   private class ProducerJobQueueThread implements Runnable {
190     public void run() {
191       logger.debug("starting ProducerJobQueueThread");
192
193       while (true) {
194         ProducerJob job = (ProducerJob) producerJobQueue.acquirePendingJob();
195         if (job!=null) {
196           job.execute();
197           if (job.isAborted())
198             producerJobQueue.jobAborted(job);
199           else
200             producerJobQueue.jobProcessed(job);
201         }
202         else
203         {
204           try {
205             Thread.sleep(1500);
206           }
207           catch (InterruptedException e) {
208           }
209         }
210       }
211     }
212   }
213
214   public static class ProducerEngineExc extends Exc {
215     public ProducerEngineExc(String aMessage) {
216       super(aMessage);
217     }
218   }
219
220   public static class ProducerEngineRuntimeExc extends Failure {
221     public ProducerEngineRuntimeExc(String msg, Exception cause){
222       super(msg,cause);
223     }
224   }
225
226   public static class ProducerTask {
227     private String producer;
228     private String verb;
229
230     public ProducerTask(String aProducer, String aVerb) {
231       producer = aProducer;
232       verb = aVerb;
233     }
234
235     public String getVerb() {
236       return verb;
237     }
238
239     public String getProducer() {
240       return producer;
241     }
242
243     public static List parseProducerTaskList(String aList) throws ProducerEngineExc {
244       Iterator i;
245       List result = new Vector();
246
247       i = StringRoutines.splitString(aList, ";").iterator();
248       while (i.hasNext()) {
249         String taskExpression = (String) i.next();
250         List parts = StringRoutines.splitString(taskExpression, ".");
251
252         if (parts.size()!=2)
253           throw new ProducerEngineExc("Invalid producer expression: '" + taskExpression + "'");
254         else
255           result.add(new ProducerEngine.ProducerTask((String) parts.get(0), (String) parts.get(1)));
256       }
257
258       return result;
259     }
260   }
261 }