4748dae4089f3fd6fad64c383b6b7c751c0e7196
[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 the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mircoders.global;
33
34 import java.util.*;
35 import java.io.*;
36 import mir.producer.*;
37 import mir.util.*;
38 import multex.Exc;
39 import multex.Failure;
40
41 public class ProducerEngine {
42 //  private Map producers;
43   private JobQueue producerJobQueue;
44   private Thread queueThread;
45   private PrintWriter log;
46
47   protected ProducerEngine() {
48     producerJobQueue = new JobQueue();
49     try {
50       RandomAccessFile raFile = (new RandomAccessFile(MirGlobal.getConfigProperty("Home") + "/" + MirGlobal.getConfigProperty("Producer.Logfile"), "rw"));
51                         raFile.seek(raFile.length());
52                 log = new PrintWriter(new FileWriter( raFile.getFD()));
53     }
54     catch (Exception e) {
55       log = new PrintWriter(new NullWriter());
56     }
57     queueThread = new Thread(new ProducerJobQueueThread());
58     queueThread.start();
59   }
60
61   public void addJob(String aProducerFactory, String aVerb) {
62     producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb));
63   }
64
65   public void addTask(ProducerTask aTask) {
66     addJob(aTask.getProducer(), aTask.getVerb());
67   }
68
69   public void addTasks(List aTasks) {
70     Iterator i = aTasks.iterator();
71
72     while (i.hasNext()) {
73       addTask((ProducerTask) i.next());
74     }
75   }
76
77   private String convertStatus(JobQueue.Job aJob) {
78     if (aJob.hasBeenProcessed())
79       return "processed";
80     if (aJob.isProcessing())
81       return "processing";
82     if (aJob.isPending())
83       return "pending";
84     if (aJob.isCancelled())
85       return "cancelled";
86     if (aJob.hasBeenAborted())
87       return "aborted";
88
89     return "unknown";
90   }
91
92   private Map convertJob(JobQueue.Job aJob) {
93     Map result = new HashMap();
94     ProducerJob producerJob = (ProducerJob) aJob.getData();
95
96     result.put("identifier", aJob.getIdentifier());
97     result.put("factory", producerJob.getFactoryName());
98     result.put("verb", producerJob.getVerb());
99     result.put("priority", new Integer(aJob.getPriority()));
100     result.put("status", convertStatus(aJob));
101     result.put("lastchange", new DateToMapAdapter(aJob.getLastChange()));
102
103     return result;
104   }
105
106   private void convertJobList(List aSourceJobList, List aDestination) {
107     Iterator i = aSourceJobList.iterator();
108
109     while (i.hasNext())
110       aDestination.add(convertJob((JobQueue.Job) i.next()));
111   }
112
113   public List getQueueStatus() {
114     List result = new Vector();
115     List pendingJobs = new Vector();
116     List finishedJobs = new Vector();
117
118     producerJobQueue.makeJobListSnapshots(pendingJobs, finishedJobs);
119
120     convertJobList(pendingJobs, result);
121     convertJobList(finishedJobs, result);
122
123     return result;
124   }
125
126 private class ProducerJob {
127     private String factoryName;
128     private String verb;
129     private Producer producer;
130
131     public ProducerJob(String aFactory, String aVerb) {
132       factoryName = aFactory;
133       verb = aVerb;
134       producer=null;
135     }
136
137     public String getFactoryName() {
138       return factoryName;
139     }
140
141     public String getVerb() {
142       return verb;
143     }
144
145     public void abort() {
146       if (producer!=null) {
147         producer.abort();
148       }
149     }
150
151     public void execute() {
152       ProducerFactory factory;
153       long startTime;
154       long endTime;
155       Map startingMap = new HashMap();
156
157       startTime = System.currentTimeMillis();
158       log.println("Producing job: "+factoryName+"."+verb);
159
160       try {
161         factory = MirGlobal.localizer().producers().getFactoryForName( factoryName );
162
163         if (factory!=null) {
164           MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
165
166           synchronized(factory) {
167             producer = factory.makeProducer(verb, startingMap);
168           }
169           if (producer!=null) {
170             producer.produce(log);
171           }
172         }
173       }
174       catch (Throwable t) {
175         log.println("  exception "+t.getMessage());
176         t.printStackTrace(log);
177       }
178       log.println("Done producing job: "+factoryName+"."+verb);
179       endTime = System.currentTimeMillis();
180       log.println("Time: " + (endTime-startTime) + " ms");
181       log.flush();
182     }
183
184     boolean isAborted() {
185       return false;
186     }
187   }
188
189   private class ProducerJobQueueThread implements Runnable {
190     public void run() {
191       log.println("starting ProducerJobQueueThread");
192       log.flush();
193
194       while (true) {
195         ProducerJob job = (ProducerJob) producerJobQueue.acquirePendingJob();
196         if (job!=null) {
197           job.execute();
198           if (job.isAborted())
199             producerJobQueue.jobAborted(job);
200           else
201             producerJobQueue.jobProcessed(job);
202         }
203         else
204         {
205           try {
206             Thread.sleep(1500);
207           }
208           catch (InterruptedException e) {
209           }
210         }
211       }
212     }
213   }
214
215   public static class ProducerEngineExc extends Exc {
216     public ProducerEngineExc(String aMessage) {
217       super(aMessage);
218     }
219   }
220
221   public static class ProducerEngineRuntimeExc extends Failure {
222     public ProducerEngineRuntimeExc(String msg, Exception cause){
223       super(msg,cause);
224     }
225   }
226
227   public static class ProducerTask {
228     private String producer;
229     private String verb;
230
231     public ProducerTask(String aProducer, String aVerb) {
232       producer = aProducer;
233       verb = aVerb;
234     }
235
236     public String getVerb() {
237       return verb;
238     }
239
240     public String getProducer() {
241       return producer;
242     }
243
244     public static List parseProducerTaskList(String aList) throws ProducerEngineExc {
245       Iterator i;
246       List result = new Vector();
247
248       i = StringRoutines.splitString(aList, ";").iterator();
249       while (i.hasNext()) {
250         String taskExpression = (String) i.next();
251         List parts = StringRoutines.splitString(taskExpression, ".");
252
253         if (parts.size()!=2)
254           throw new ProducerEngineExc("Invalid producer expression: '" + taskExpression + "'");
255         else
256           result.add(new ProducerEngine.ProducerTask((String) parts.get(0), (String) parts.get(1)));
257       }
258
259       return result;
260     }
261   }
262 }