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.codehaus.plexus.util.FileUtils;
24 import org.codehaus.plexus.util.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 public void run( final String scriptDescription, final File basedir, final String relativeScriptPath,
156 final Map<String, ? extends Object> context, final ExecutionLogger logger, String stage,
157 boolean failOnException )
158 throws IOException, RunFailureException
159 {
160 if ( relativeScriptPath == null )
161 {
162 getLog().debug( "relativeScriptPath is null: not executing script" );
163 return;
164 }
165
166 final File scriptFile = resolveScript( new File( basedir, relativeScriptPath ) );
167
168 if ( !scriptFile.exists() )
169 {
170 getLog().debug( "no script found in directory: " + basedir.getAbsolutePath() );
171 return;
172 }
173
174 String path = scriptFile.getAbsolutePath();
175 getLog().info( "run script " + relativeScriptPath + path.substring( path.lastIndexOf( '.' ) ) );
176
177 executeRun( scriptDescription, scriptFile, context, logger, stage, failOnException );
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 public void run( final String scriptDescription, File scriptFile, final Map<String, ? extends Object> context,
194 final ExecutionLogger logger, String stage, boolean failOnException )
195 throws IOException, RunFailureException
196 {
197
198 if ( !scriptFile.exists() )
199 {
200 getLog().debug( "scriptFile not found in directory: " + scriptFile.getAbsolutePath() );
201 return;
202 }
203
204 getLog().info( "run script " + scriptFile.getAbsolutePath() );
205
206 executeRun( scriptDescription, scriptFile, context, logger, stage, failOnException );
207 }
208
209 private void executeRun( final String scriptDescription, File scriptFile,
210 final Map<String, ? extends Object> context, final ExecutionLogger logger, String stage,
211 boolean failOnException )
212 throws IOException, RunFailureException
213 {
214 Map<String, Object> globalVariables = new HashMap<String, Object>( this.globalVariables );
215 globalVariables.put( "basedir", scriptFile.getParentFile() );
216 globalVariables.put( "context", context );
217
218 PrintStream out = ( logger != null ) ? logger.getPrintStream() : null;
219
220 ScriptInterpreter interpreter = getInterpreter( scriptFile );
221 if ( getLog().isDebugEnabled() )
222 {
223 String name = interpreter.getClass().getName();
224 name = name.substring( name.lastIndexOf( '.' ) + 1 );
225 getLog().debug( "Running script with " + name + ": " + scriptFile );
226 }
227
228 String script;
229 try
230 {
231 script = FileUtils.fileRead( scriptFile, encoding );
232 }
233 catch ( IOException e )
234 {
235 String errorMessage =
236 "error reading " + scriptDescription + " " + scriptFile.getPath() + ", " + e.getMessage();
237 IOException ioException = new IOException( errorMessage );
238 ioException.initCause( e );
239 throw ioException;
240 }
241
242 Object result;
243 try
244 {
245 if ( logger != null )
246 {
247 logger.consumeLine( "Running " + scriptDescription + ": " + scriptFile );
248 }
249 result = interpreter.evaluateScript( script, classPath, globalVariables, out );
250 if ( logger != null )
251 {
252 logger.consumeLine( "Finished " + scriptDescription + ": " + scriptFile );
253 }
254 }
255 catch ( ScriptEvaluationException e )
256 {
257 Throwable t = ( e.getCause() != null ) ? e.getCause() : e;
258 String msg = ( t.getMessage() != null ) ? t.getMessage() : t.toString();
259 if ( getLog().isDebugEnabled() )
260 {
261 String errorMessage = "Error evaluating " + scriptDescription + " " + scriptFile.getPath() + ", " + t;
262 getLog().debug( errorMessage, t );
263 }
264 if ( logger != null )
265 {
266 t.printStackTrace( logger.getPrintStream() );
267 }
268 if ( failOnException )
269 {
270 throw new RunFailureException( "The " + scriptDescription + " did not succeed. " + msg, stage );
271 }
272 else
273 {
274 throw new RunErrorException( "The " + scriptDescription + " did not succeed. " + msg, stage, t );
275 }
276 }
277
278 if ( !( result == null || Boolean.TRUE.equals( result ) || "true".equals( result ) ) )
279 {
280 throw new RunFailureException( "The " + scriptDescription + " returned " + result + ".", stage );
281 }
282 }
283
284
285
286
287
288
289
290
291 private File resolveScript( File scriptFile )
292 {
293 if ( scriptFile != null && !scriptFile.exists() )
294 {
295 for ( String ext : this.scriptInterpreters.keySet() )
296 {
297 File candidateFile = new File( scriptFile.getPath() + '.' + ext );
298 if ( candidateFile.exists() )
299 {
300 scriptFile = candidateFile;
301 break;
302 }
303 }
304 }
305 return scriptFile;
306 }
307
308
309
310
311
312
313
314
315
316 private ScriptInterpreter getInterpreter( File scriptFile )
317 {
318 String ext = FileUtils.extension( scriptFile.getName() ).toLowerCase( Locale.ENGLISH );
319 ScriptInterpreter interpreter = scriptInterpreters.get( ext );
320 if ( interpreter == null )
321 {
322 interpreter = scriptInterpreters.get( "bsh" );
323 }
324 return interpreter;
325 }
326
327 }