1 package org.apache.maven.shared.scriptinterpreter;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.plugin.logging.Log;
23 import org.apache.maven.shared.utils.io.FileUtils;
24 import org.apache.maven.shared.utils.StringUtils;
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.PrintStream;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.LinkedHashMap;
32 import java.util.List;
33 import java.util.Locale;
34 import java.util.Map;
35
36
37
38
39
40
41
42 public class ScriptRunner
43 {
44
45
46
47
48 private Log log;
49
50
51
52
53
54 private Map<String, ScriptInterpreter> scriptInterpreters;
55
56
57
58
59 private Map<String, Object> globalVariables;
60
61
62
63
64 private List<String> classPath;
65
66
67
68
69 private String encoding;
70
71
72
73
74
75
76 public ScriptRunner( Log log )
77 {
78 if ( log == null )
79 {
80 throw new IllegalArgumentException( "missing logger" );
81 }
82 this.log = log;
83 scriptInterpreters = new LinkedHashMap<String, ScriptInterpreter>();
84 scriptInterpreters.put( "bsh", new BeanShellScriptInterpreter() );
85 scriptInterpreters.put( "groovy", new GroovyScriptInterpreter() );
86 globalVariables = new HashMap<String, Object>();
87 classPath = new ArrayList<String>();
88 }
89
90 public void addScriptInterpreter( String id, ScriptInterpreter scriptInterpreter )
91 {
92 scriptInterpreters.put( id, scriptInterpreter );
93 }
94
95
96
97
98
99
100 private Log getLog()
101 {
102 return log;
103 }
104
105
106
107
108
109
110
111 public void setGlobalVariable( String name, Object value )
112 {
113 this.globalVariables.put( name, value );
114 }
115
116
117
118
119
120
121
122
123
124 public void setClassPath( List<String> classPath )
125 {
126 this.classPath = ( classPath != null ) ? new ArrayList<String>( classPath ) : new ArrayList<String>();
127 }
128
129
130
131
132
133
134
135 public void setScriptEncoding( String encoding )
136 {
137 this.encoding = StringUtils.isNotEmpty( encoding ) ? encoding : null;
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 public void run( final String scriptDescription, final File basedir, final String relativeScriptPath,
158 final Map<String, ? extends Object> context, final ExecutionLogger logger, String stage,
159 boolean failOnException )
160 throws IOException, RunFailureException
161 {
162 if ( relativeScriptPath == null )
163 {
164 getLog().debug( scriptDescription + ": relativeScriptPath is null, not executing script" );
165 return;
166 }
167
168 final File scriptFile = resolveScript( new File( basedir, relativeScriptPath ) );
169
170 if ( !scriptFile.exists() )
171 {
172 getLog().debug( scriptDescription + ": no script '" + relativeScriptPath + "' found in directory "
173 + basedir.getAbsolutePath() );
174 return;
175 }
176
177 getLog().info( "run " + scriptDescription + ' ' + relativeScriptPath + '.'
178 + FileUtils.extension( scriptFile.getAbsolutePath() ) );
179
180 executeRun( scriptDescription, scriptFile, context, logger, stage, failOnException );
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 public void run( final String scriptDescription, File scriptFile, final Map<String, ? extends Object> context,
199 final ExecutionLogger logger, String stage, boolean failOnException )
200 throws IOException, RunFailureException
201 {
202
203 if ( !scriptFile.exists() )
204 {
205 getLog().debug( scriptDescription + ": script file not found in directory "
206 + scriptFile.getAbsolutePath() );
207 return;
208 }
209
210 getLog().info( "run " + scriptDescription + ' ' + scriptFile.getAbsolutePath() );
211
212 executeRun( scriptDescription, scriptFile, context, logger, stage, failOnException );
213 }
214
215 private void executeRun( final String scriptDescription, File scriptFile,
216 final Map<String, ? extends Object> context, final ExecutionLogger logger, String stage,
217 boolean failOnException )
218 throws IOException, RunFailureException
219 {
220 Map<String, Object> globalVariables = new HashMap<String, Object>( this.globalVariables );
221 globalVariables.put( "basedir", scriptFile.getParentFile() );
222 globalVariables.put( "context", context );
223
224 ScriptInterpreter interpreter = getInterpreter( scriptFile );
225 if ( getLog().isDebugEnabled() )
226 {
227 String name = interpreter.getClass().getName();
228 name = name.substring( name.lastIndexOf( '.' ) + 1 );
229 getLog().debug( "Running script with " + name + ": " + scriptFile );
230 }
231
232 String script;
233 try
234 {
235 script = FileUtils.fileRead( scriptFile, encoding );
236 }
237 catch ( IOException e )
238 {
239 String errorMessage =
240 "error reading " + scriptDescription + " " + scriptFile.getPath() + ", " + e.getMessage();
241 IOException ioException = new IOException( errorMessage );
242 ioException.initCause( e );
243 throw ioException;
244 }
245
246 Object result;
247 try
248 {
249 if ( logger != null )
250 {
251 logger.consumeLine( "Running " + scriptDescription + ": " + scriptFile );
252 }
253
254 PrintStream out = ( logger != null ) ? logger.getPrintStream() : null;
255
256 result = interpreter.evaluateScript( script, classPath, globalVariables, out );
257 if ( logger != null )
258 {
259 logger.consumeLine( "Finished " + scriptDescription + ": " + scriptFile );
260 }
261 }
262 catch ( ScriptEvaluationException e )
263 {
264 Throwable t = ( e.getCause() != null ) ? e.getCause() : e;
265 String msg = ( t.getMessage() != null ) ? t.getMessage() : t.toString();
266 if ( getLog().isDebugEnabled() )
267 {
268 String errorMessage = "Error evaluating " + scriptDescription + " " + scriptFile.getPath() + ", " + t;
269 getLog().debug( errorMessage, t );
270 }
271 if ( logger != null )
272 {
273 t.printStackTrace( logger.getPrintStream() );
274 }
275 if ( failOnException )
276 {
277 throw new RunFailureException( "The " + scriptDescription + " did not succeed. " + msg, stage );
278 }
279 else
280 {
281 throw new RunErrorException( "The " + scriptDescription + " did not succeed. " + msg, stage, t );
282 }
283 }
284
285 if ( !( result == null || Boolean.TRUE.equals( result ) || "true".equals( result ) ) )
286 {
287 throw new RunFailureException( "The " + scriptDescription + " returned " + result + ".", stage );
288 }
289 }
290
291
292
293
294
295
296
297
298 private File resolveScript( File scriptFile )
299 {
300 if ( scriptFile != null && !scriptFile.exists() )
301 {
302 for ( String ext : this.scriptInterpreters.keySet() )
303 {
304 File candidateFile = new File( scriptFile.getPath() + '.' + ext );
305 if ( candidateFile.exists() )
306 {
307 scriptFile = candidateFile;
308 break;
309 }
310 }
311 }
312 return scriptFile;
313 }
314
315
316
317
318
319
320
321
322
323 private ScriptInterpreter getInterpreter( File scriptFile )
324 {
325 String ext = FileUtils.extension( scriptFile.getName() ).toLowerCase( Locale.ENGLISH );
326 ScriptInterpreter interpreter = scriptInterpreters.get( ext );
327 if ( interpreter == null )
328 {
329 interpreter = scriptInterpreters.get( "bsh" );
330 }
331 return interpreter;
332 }
333
334 }