1 package org.andromda.maven.plugin.andromdapp;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.lang.reflect.Method;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.Iterator;
14 import java.util.LinkedHashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Properties;
18 import org.andromda.maven.plugin.andromdapp.utils.ProjectUtils;
19 import org.andromda.maven.plugin.andromdapp.utils.Projects;
20 import org.apache.commons.lang.ObjectUtils;
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.maven.BuildFailureException;
23 import org.apache.maven.execution.MavenSession;
24 import org.apache.maven.execution.ReactorManager;
25 import org.apache.maven.lifecycle.LifecycleExecutionException;
26 import org.apache.maven.lifecycle.LifecycleExecutor;
27 import org.apache.maven.plugin.AbstractMojo;
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.apache.maven.project.MavenProject;
30 import org.apache.maven.project.MavenProjectBuilder;
31 import org.apache.maven.project.ProjectBuildingException;
32 import org.codehaus.plexus.util.dag.CycleDetectedException;
33
34
35
36
37
38
39
40 public class BuildMojo
41 extends AbstractMojo
42 {
43
44
45
46 private LifecycleExecutor lifecycleExecutor;
47
48
49
50
51 private MavenSession session;
52
53
54
55
56 private File baseDirectory;
57
58
59
60
61
62
63
64
65
66 private String modules;
67
68
69
70
71
72
73 private MavenProject project;
74
75
76
77
78
79
80 private String startConsole;
81
82
83
84
85
86
87 private List<String> goals = new ArrayList<String>(Arrays.asList("install"));
88
89
90
91
92 private static final String EXIT = "exit";
93
94
95
96
97
98
99 private MavenProjectBuilder projectBuilder;
100
101
102
103
104
105
106 private Properties executionProperties = new Properties();
107
108
109
110
111 private static final String EXECUTION_PROPERTY_TOKEN = "-D";
112
113
114
115
116 private static final String LIST_PROPERTIES = "-list";
117
118
119
120
121 private static final String CLEAR_PROPERTIES = "-clear";
122
123
124
125
126 private static final String GARBAGE_COLLECT = "-gc";
127
128
129
130
131
132
133 private String environmentVariablePrefix;
134
135
136
137
138 public void execute()
139 throws MojoExecutionException
140 {
141 try
142 {
143 final Map environment = this.getEnvironment();
144 if (this.startConsole != null && !this.startConsole.equals(Boolean.FALSE.toString()))
145 {
146 boolean executed = false;
147 this.printLine();
148 while (true)
149 {
150 this.printConsolePrompt();
151 String input = StringUtils.trimToEmpty(this.readLine());
152 if (EXIT.equals(input))
153 {
154 break;
155 }
156 if (input.startsWith(EXECUTION_PROPERTY_TOKEN))
157 {
158 input = input.replaceFirst(
159 EXECUTION_PROPERTY_TOKEN,
160 "");
161 int index = input.indexOf('=');
162 String name;
163 String value;
164 if (index <= 0)
165 {
166 name = input.trim();
167 value = "true";
168 }
169 else
170 {
171 name = input.substring(
172 0,
173 index).trim();
174 value = input.substring(index + 1).trim();
175 }
176 if (value.startsWith(this.environmentVariablePrefix))
177 {
178 value = StringUtils.replace(
179 value,
180 this.environmentVariablePrefix,
181 "");
182 if (environment.containsKey(value))
183 {
184 value = ObjectUtils.toString(environment.get(value)).trim();
185 }
186 }
187 this.executionProperties.put(
188 name,
189 value);
190 System.setProperty(
191 name,
192 value);
193 this.printExecutionProperties();
194 }
195 else if (LIST_PROPERTIES.equals(input))
196 {
197 this.printExecutionProperties();
198 }
199 else if (CLEAR_PROPERTIES.equals(input))
200 {
201 this.executionProperties.clear();
202 this.printExecutionProperties();
203 }
204 else if (GARBAGE_COLLECT.equals(input))
205 {
206
207 System.gc();
208 }
209 else
210 {
211 try
212 {
213 executed = this.executeModules(input);
214
215
216 if (this.project != null && !executed && input.trim().length() > 0)
217 {
218 executed = true;
219 final List<String> goals = Arrays.asList(input.split("\\s+"));
220 this.executeModules(
221 StringUtils.join(
222 this.project.getModules().iterator(),
223 ","),
224 goals,
225 true);
226 }
227 }
228 catch (final Throwable throwable)
229 {
230 throwable.printStackTrace();
231 }
232 if (executed)
233 {
234 this.printLine();
235 }
236 Projects.instance().clear();
237 }
238 }
239 }
240 else
241 {
242 this.executionProperties.putAll(this.session.getExecutionProperties());
243 this.executeModules(this.modules);
244 }
245 }
246 catch (final Throwable throwable)
247 {
248 throw new MojoExecutionException("Error executing modules", throwable);
249 }
250 }
251
252 private static final String GET_ENVIRONMENT_METHOD = "getenv";
253
254
255
256
257
258
259 private Map<String, String> getEnvironment()
260 {
261 final Map<String, String> variables = new HashMap<String, String>();
262 try
263 {
264 final Method method = System.class.getMethod(
265 GET_ENVIRONMENT_METHOD);
266 final Object result = method.invoke(
267 System.class);
268 if (result instanceof Map)
269 {
270 variables.putAll((Map<String, String>)result);
271 }
272 }
273 catch (Exception exception)
274 {
275
276 }
277 return variables;
278 }
279
280 private void printExecutionProperties()
281 {
282 this.printLine();
283 this.printTextWithLine("| ------------- execution properties ------------- |");
284 for (final Iterator<Object> iterator = this.executionProperties.keySet().iterator(); iterator.hasNext();)
285 {
286 final String name = (String)iterator.next();
287 System.out.println(" " + name + " = " + this.executionProperties.getProperty(name));
288 }
289 this.printTextWithLine("| ------------------------------------------------ |");
290 this.printLine();
291 }
292
293
294
295
296 private void printConsolePrompt()
297 {
298 if (this.project != null)
299 {
300 this.printText("");
301 this.printText(this.project.getArtifactId() + ' ' + this.project.getVersion() + '>');
302 }
303 }
304
305
306
307
308
309
310 private void printText(final String text)
311 {
312 System.out.print(text);
313 System.out.flush();
314 }
315
316
317
318
319
320
321 private void printTextWithLine(final String text)
322 {
323 System.out.println(text);
324 System.out.flush();
325 }
326
327
328
329
330 private void printLine()
331 {
332 System.out.println();
333 System.out.flush();
334 }
335
336
337
338
339
340
341 @SuppressWarnings("null")
342 private String readLine()
343 {
344 final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
345 String inputString = null;
346 try
347 {
348 inputString = input.readLine();
349 }
350 catch (final IOException exception)
351 {
352 inputString = null;
353 }
354 return StringUtils.trimToNull(inputString);
355 }
356
357
358
359
360
361
362
363
364
365
366
367 private boolean executeModules(final String modules)
368 throws MojoExecutionException
369 {
370 return this.executeModules(
371 modules,
372 null,
373 false);
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389 private boolean executeModules(
390 final String modules,
391 final List<String> goals,
392 boolean sortProjects)
393 throws MojoExecutionException
394 {
395 final Map<MavenProject, List<String>> projects = this.collectProjects(modules);
396 boolean executed = !projects.isEmpty();
397
398
399 if (executed)
400 {
401 if (!sortProjects)
402 {
403 for (final MavenProject project : projects.keySet())
404 {
405 List<String> projectGoals;
406 if (goals == null)
407 {
408 projectGoals = projects.get(project);
409 if (projectGoals.isEmpty())
410 {
411 projectGoals.addAll(this.goals);
412 }
413 }
414 else
415 {
416 projectGoals = goals;
417 }
418 this.executeProjects(
419 Collections.singletonList(project),
420 projectGoals);
421 }
422 }
423 else
424 {
425 this.executeProjects(
426 projects.keySet(),
427 goals);
428 }
429 }
430 return executed;
431 }
432
433
434
435
436
437
438
439
440
441
442
443 private void executeProjects(
444 final Collection<MavenProject> projects,
445 final List<String> goals)
446 throws MojoExecutionException
447 {
448 try
449 {
450 if (goals.isEmpty())
451 {
452 goals.addAll(this.goals);
453 }
454 if (projects.size() > 1)
455 {
456 this.getLog().info("Reactor build order:");
457 }
458 final ReactorManager reactorManager = new ReactorManager(new ArrayList<MavenProject>(projects));
459 for (final MavenProject project : reactorManager.getSortedProjects())
460 {
461 this.getLog().info(" " + project.getName());
462 }
463
464 final MavenSession projectSession =
465 new MavenSession(
466 this.session.getContainer(),
467 this.session.getSettings(),
468 this.session.getLocalRepository(),
469 this.session.getEventDispatcher(),
470 reactorManager,
471 goals,
472 this.baseDirectory.toString(),
473 this.executionProperties,
474 this.session.getStartTime());
475
476 projectSession.setUsingPOMsFromFilesystem(true);
477 this.lifecycleExecutor.execute(
478 projectSession,
479 reactorManager,
480 projectSession.getEventDispatcher());
481 }
482 catch (final Throwable throwable)
483 {
484 throw new MojoExecutionException("An error occurred while attempting to execute projects", throwable);
485 }
486 }
487
488
489
490
491
492
493
494
495
496 private Map<MavenProject, List<String>> collectProjects(final String modules)
497 throws MojoExecutionException
498 {
499 final Map<MavenProject, List<String>> projects = new LinkedHashMap<MavenProject, List<String>>();
500 final Map<File, List<String>> poms = getModulePoms(modules);
501
502 if (!poms.isEmpty())
503 {
504 for (final File pom : poms.keySet())
505 {
506 try
507 {
508 final MavenProject project = ProjectUtils.getProject(
509 this.projectBuilder,
510 this.session,
511 pom,
512 this.getLog());
513 if (project != null)
514 {
515 if (this.getLog().isDebugEnabled())
516 {
517 this.getLog().debug("Adding project " + project.getId());
518 }
519 projects.put(
520 project,
521 poms.get(pom));
522 }
523 else
524 {
525 if (this.getLog().isWarnEnabled())
526 {
527 this.getLog().warn("Could not load project from pom: " + pom + " - ignoring");
528 }
529 }
530 }
531 catch (ProjectBuildingException exception)
532 {
533 throw new MojoExecutionException("Error loading POM --> '" + pom + '\'', exception);
534 }
535 }
536 }
537 return projects;
538 }
539
540
541
542
543
544
545
546 private Map<File, List<String>> getModulePoms(final String moduleList)
547 {
548 final Map<File, List<String>> poms = new LinkedHashMap<File, List<String>>();
549 final String[] modules = moduleList != null ? moduleList.split(",") : null;
550
551 final String goalPrefix = ":";
552 if (modules != null)
553 {
554 final int numberOfModules = modules.length;
555 for (int ctr = 0; ctr < numberOfModules; ctr++)
556 {
557 String module = modules[ctr].trim();
558 final List<String> goalsList = new ArrayList<String>();
559 if (module.contains(goalPrefix))
560 {
561 final String[] goals = module.replaceAll(
562 ".*(:\\[)|(\\])",
563 "").split("\\+");
564 if (goals != null)
565 {
566 final int numberOfGoals = goals.length;
567 for (int ctr2 = 0; ctr2 < numberOfGoals; ctr2++)
568 {
569 final String goal = goals[ctr2].trim();
570 goalsList.add(goal);
571 }
572 }
573 }
574 module = module.replaceAll(
575 goalPrefix + "\\[.*\\]",
576 "");
577 final File pom = new File(this.baseDirectory, module + "/pom.xml");
578 if (pom.isFile())
579 {
580 poms.put(
581 pom,
582 goalsList);
583 }
584 }
585 }
586 return poms;
587 }
588 }