1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package net.israfil.mojo.flex2;
35
36 import java.io.File;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Iterator;
42 import java.util.List;
43
44 import org.apache.maven.artifact.Artifact;
45 import org.apache.maven.plugin.AbstractMojo;
46 import org.apache.maven.plugin.MojoExecutionException;
47 import org.apache.maven.plugin.MojoFailureException;
48 import org.apache.maven.project.MavenProject;
49 import org.apache.maven.project.MavenProjectHelper;
50 import org.codehaus.plexus.util.cli.CommandLineException;
51 import org.codehaus.plexus.util.cli.CommandLineUtils;
52 import org.codehaus.plexus.util.cli.Commandline;
53 import org.codehaus.plexus.util.cli.StreamConsumer;
54
55 /***
56 * Base class for flex2/actionscript3 plugin
57 *
58 * @author <a href="cgruber@israfil.net">Christian Edward Gruber</a>
59 * @author <a href="tspurway@gmail.com">Tim Spurway</a>
60 * @version $Id: AbstractFlexMojo.java 610 2008-01-15 16:49:22Z christianedwardgruber $
61 */
62 public abstract class AbstractFlexMojo extends AbstractMojo {
63
64 /***
65 * The directory in which Flex (command-line or builder) is installed.
66 *
67 * @parameter expression="${flex.home}"
68 * @required
69 *
70 */
71 protected File flexHome;
72
73 /***
74 * The location of the flex configuration file.
75 *
76 * @parameter expression="${flex.config}"
77 */
78 protected File flexConfig;
79
80 /***
81 * Location of the flex sources.
82 *
83 * @parameter expression="${flex.compiler.source}" default="src/main/flex"
84 */
85 protected File source;
86
87 /***
88 * The directory into which to place the resulting artifact. note that this is a read-only
89 * parameter, satisfied from the build directory. Attempts to configure this should use the
90 * standard <build><directory/></build> approach.
91 *
92 * @parameter expression="${project.build.directory}"
93 * @required
94 * @readonly
95 */
96 protected File outputDirectory;
97
98 /***
99 * Name of the generated compiled binary file.
100 *
101 * @parameter expression="${project.build.finalName}"
102 * @required
103 */
104 protected String finalName;
105
106
107 /***
108 * The maven project.
109 *
110 * @parameter expression="${project}"
111 * @required
112 * @readonly
113 */
114 protected MavenProject project;
115
116 /***
117 * @component
118 */
119 protected MavenProjectHelper projectHelper;
120
121 /***
122 * @parameter expression="${plugin.artifacts}"
123 * @required
124 * @readonly
125 */
126 protected List pluginArtifacts;
127
128 /***
129 * These are additional JVM options used when invoking the Flex compiler
130 *
131 * @parameter expression="${flex.java.options}"
132 */
133 protected String[] javaOpts;
134
135 /***
136 * @parameter expression="${flex.extraParameters}"
137 */
138 protected Parameter[] extraParameters;
139
140 /***
141 * Classifier to add to the artifact generated. If given, the artifact will
142 * be an attachment instead.
143 *
144 * @parameter
145 */
146 protected String classifier;
147
148 protected abstract File getOutputFile();
149
150 protected abstract String getCompilerClass();
151
152 protected abstract String getFileExtension();
153
154 protected File getFile( File basedir, String finalName, String classifier ) {
155 if ( classifier != null && !classifier.equals("") ) {
156 if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" )){
157 classifier = "-" + classifier;
158 }
159 return new File( basedir, finalName + classifier + ".jar" );
160 } else {
161 return new File( basedir, finalName + "." + getFileExtension() );
162 }
163 }
164
165 /***
166 * Override and implement this method to take the existing java parameters
167 * and add any final information requried to provide source files to the
168 * compiler.
169 * @param parameterList
170 */
171 protected List prepareParameters() throws MojoFailureException, MojoExecutionException {
172 List parameters = new ArrayList();
173
174 try {
175 parameters.add("+flexlib=" + new File(flexHome,"frameworks").getCanonicalPath());
176 } catch (IOException e) {
177 throw new MojoExecutionException("Config file does not exist.", e);
178 }
179
180 if (flexConfig != null) {
181 parameters.add("-load-config");
182 try {
183 parameters.add(flexConfig.getCanonicalFile().getAbsolutePath());
184 } catch (IOException e) {
185 throw new MojoExecutionException("Config file does not exist.", e);
186 }
187 }
188
189 parameters.add( "-source-path" );
190
191 try {
192 parameters.add( source.getCanonicalPath());
193 } catch (IOException e) {
194 throw new MojoExecutionException("Source path doesn't exist.", e);
195 }
196
197
198 return parameters;
199 }
200
201 protected void finalizeParameters(List parameters) throws MojoExecutionException, MojoFailureException {
202 getLog().info("Adding Extra Parameters: " + Arrays.asList(extraParameters));
203 Iterator extraParmsIter = Arrays.asList(extraParameters).iterator();
204 while (extraParmsIter.hasNext()) {
205 Parameter p = (Parameter)extraParmsIter.next();
206 getLog().debug("Adding parameter " + p.getName());
207 parameters.add("-" + p.getName());
208 if (p.getValues() != null) {
209 Iterator values = Arrays.asList(p.getValues()).iterator();
210 while (values.hasNext()) {
211 String value = (String)values.next();
212 getLog().debug("Adding parameter value" + value);
213 parameters.add(value);
214 }
215 }
216 }
217 }
218
219
220 protected abstract String getExecutableJar();
221
222 protected String getCommandClassPath() throws MojoExecutionException, MojoFailureException {
223 StringBuffer compilerClasspath = new StringBuffer();
224 try {
225 addClasspathEntry(compilerClasspath,new File(new File(flexHome,"lib"),getExecutableJar()).getCanonicalPath());
226
227
228 for (Iterator i = pluginArtifacts.iterator(); i.hasNext() ;) {
229 Artifact artifact = (Artifact)i.next();
230 getLog().debug("Trying artifact to add to classpath: " + artifact);
231 if (artifact.getGroupId().equals("net.israfil.mojo") && artifact.getArtifactId().equals("maven-flex2-plugin-support")) {
232 addClasspathEntry(compilerClasspath, artifact.getFile().getCanonicalFile().getAbsolutePath());
233 break;
234 }
235 }
236 } catch (IOException e) {
237 throw new MojoExecutionException("Could not generate a canonical path for library.",e);
238 }
239
240 return compilerClasspath.toString();
241 }
242
243 public void execute() throws MojoExecutionException, MojoFailureException {
244
245 if (!flexHome.exists())
246 throw new MojoExecutionException(flexHome + " does not exist. flex.home property must be set.");
247
248
249 this.getLog().debug("Creating output directory: " + outputDirectory);
250 outputDirectory.mkdirs();
251
252
253
254 if (source == null) source = new File(project.getBasedir(),"src/main/flex");
255 if ( !source.exists() )
256 throw new MojoExecutionException("Source directory " + source + " does not exist.");
257
258
259
260
261 List commandLineArgs = new ArrayList();
262
263
264
265
266
267 boolean maxMemIsSet = false;
268 boolean sunIoCachesIsSet = false;
269 for( int i = 0; i < javaOpts.length; i++ ) {
270 commandLineArgs.add( javaOpts[i] );
271 if (javaOpts[i].startsWith("-Xmx")) maxMemIsSet = true;
272 else if (javaOpts[i].startsWith("-Dsun.io.useCanonCaches")) sunIoCachesIsSet = true;
273 }
274 if (!maxMemIsSet) commandLineArgs.add("-Xmx384m");
275 if (!sunIoCachesIsSet) commandLineArgs.add("-Dsun.io.useCanonCaches=false");
276
277 commandLineArgs.add("-classpath");
278 commandLineArgs.add(getCommandClassPath());
279
280
281
282
283
284 List parameters = prepareParameters();
285 finalizeParameters(parameters);
286
287
288 int result = -1;
289
290 try {
291 source = source.getCanonicalFile();
292 } catch (IOException e) {}
293
294 try {
295 result = executeJavaCommand("java", source.getAbsolutePath(), commandLineArgs, getCompilerClass(), parameters);
296 if ( result != 0 )
297 throw new MojoExecutionException( "Result of " + getCompilerClass() + " execution is: '" + result + "'." );
298 } catch ( CommandLineException e ) {
299 throw new MojoExecutionException( "Command execution failed.", e );
300 }
301
302 postProcess();
303
304 }
305
306 /***
307 * Executed near the end of execute().
308 */
309 protected void postProcess() {
310
311 File outFile = getOutputFile();
312 if (classifier != null) {
313 projectHelper.attachArtifact(project, classifier, outFile);
314 } else {
315 project.getArtifact().setFile(outFile);
316 }
317 };
318
319 protected void addClasspathEntry(StringBuffer compilerClasspath, String path) {
320 getLog().debug("Adding " + path + " to path.");
321 if (compilerClasspath.length() != 0) {
322 compilerClasspath.append(System.getProperty("path.separator"));
323 }
324 compilerClasspath.append(path);
325 }
326
327 protected int executeJavaCommand(String cmd, String cwd, List commandLineArgs, String className, List programArgs) throws CommandLineException {
328
329
330
331
332 getLog().debug("Invoking " + className + " with parameters: " + programArgs);
333
334 Commandline cl = new Commandline();
335 cl.setExecutable( cmd );
336 Iterator clargsIterator = commandLineArgs.iterator();
337 while ( clargsIterator.hasNext() )
338 cl.createArgument().setValue( (String)clargsIterator.next() );
339
340 cl.createArgument().setValue( StreamedParameterExecutableWrapper.class.getCanonicalName() );
341
342 cl.createArgument().setValue( className );
343
344 InputStream argIs = StringStreamUtil.prepareInputStreamFromStrings(programArgs);
345
346 cl.setWorkingDirectory( cwd );
347
348 StreamConsumer consumer = new StreamConsumer() {
349 public void consumeLine( String line ) { getLog().info( line ); }
350 };
351
352 getLog().debug("Command line: " + cl);
353
354 return CommandLineUtils.executeCommandLine( cl, argIs, consumer, consumer );
355
356 }
357
358 }