1.1 restoration
[mir.git] / source / mir / producer / ExecuteProgramProducerNode.java
1 /*\r
2  * Copyright (C) 2001, 2002 The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\r
6  * Mir is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Mir is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with Mir; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  *\r
20  * In addition, as a special exception, The Mir-coders gives permission to link\r
21  * the code of this program with  any library licensed under the Apache Software License,\r
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
23  * (or with modified versions of the above that use the same license as the above),\r
24  * and distribute linked combinations including the two.  You must obey the\r
25  * GNU General Public License in all respects for all of the code used other than\r
26  * the above mentioned libraries.  If you modify this file, you may extend this\r
27  * exception to your version of the file, but you are not obligated to do so.\r
28  * If you do not wish to do so, delete this exception statement from your version.\r
29  */\r
30 package mir.producer;\r
31 \r
32 import java.util.Map;\r
33 \r
34 import mir.log.LoggerWrapper;\r
35 import mir.util.ParameterExpander;\r
36 \r
37 public class ExecuteProgramProducerNode implements ProducerNode  {\r
38   private String scriptExpression;\r
39   private String maxDurationExpression;\r
40   private String outputVariableExpression;\r
41   private String returnValueVariableExpression;\r
42 \r
43   public ExecuteProgramProducerNode(String aScriptExpression, String aMaxDurationExpression, String anOutputVariableExpression,\r
44                                     String aReturnValueVariableExpression) {\r
45     scriptExpression = aScriptExpression;\r
46     maxDurationExpression = aMaxDurationExpression;\r
47     outputVariableExpression = anOutputVariableExpression;\r
48     returnValueVariableExpression = aReturnValueVariableExpression;\r
49   }\r
50 \r
51   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {\r
52     String script;\r
53     long maxDuration;\r
54 \r
55     try {\r
56       script = ParameterExpander.expandExpression(aValueMap, scriptExpression);\r
57       maxDuration = ParameterExpander.evaluateIntegerExpressionWithDefault(aValueMap, maxDurationExpression, 0);\r
58 \r
59       ProcessRunner runner = new ProcessRunner(aLogger, script);\r
60       runner.start();\r
61 \r
62       synchronized (runner) {\r
63         runner.wait(maxDuration);\r
64       }\r
65       runner.interrupt();\r
66 \r
67       if (runner.getFinished()) {\r
68         aLogger.info(script + " terminated successfully, return value = " + runner.getReturnValue() + ".");\r
69 \r
70         if (returnValueVariableExpression != null) {\r
71           ParameterExpander.setValueForKey(aValueMap,\r
72               ParameterExpander.expandExpression(aValueMap, returnValueVariableExpression),\r
73               new Integer(runner.getReturnValue()));\r
74         }\r
75 \r
76       }\r
77       else {\r
78         aLogger.info(script + " interrupted prematurely after " + maxDuration + "ms.");\r
79       }\r
80     }\r
81     catch (Throwable e) {\r
82       aLogger.error("Error while executing " + scriptExpression + " : " + e.toString());\r
83     }\r
84   }\r
85 \r
86   private static class ProcessRunner extends Thread {\r
87     private String script;\r
88     private boolean finished = false;\r
89     private int returnValue = 0;\r
90     private LoggerWrapper logger;\r
91 \r
92     public ProcessRunner(LoggerWrapper aLogger, String aScript) {\r
93       script = aScript;\r
94       logger = aLogger;\r
95     }\r
96 \r
97     public boolean getFinished() {\r
98       return finished;\r
99     }\r
100 \r
101     public int getReturnValue() {\r
102       return returnValue;\r
103     }\r
104 \r
105     public void run() {\r
106       Process process = null;\r
107       try {\r
108         process = Runtime.getRuntime().exec(script);\r
109         returnValue = process.waitFor();\r
110 \r
111         finished = true;\r
112 \r
113         synchronized (this) {\r
114           this.notify();\r
115         }\r
116       }\r
117       catch (InterruptedException e) {\r
118         if (process!=null) {\r
119           process.destroy();\r
120         }\r
121       }\r
122       catch (Exception e) {\r
123         logger.error(script + " failed to execute: " + e.getMessage());\r
124       }\r
125     }\r
126   }\r
127 \r
128 }\r