1 package org.andromda.maven.plugin.andromdapp;
2
3 import java.io.File;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.LinkedHashMap;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12 import org.andromda.core.common.ResourceUtils;
13 import org.andromda.maven.plugin.andromdapp.eclipse.ClasspathWriter;
14 import org.andromda.maven.plugin.andromdapp.eclipse.ProjectWriter;
15 import org.andromda.maven.plugin.andromdapp.eclipse.Variable;
16 import org.andromda.maven.plugin.andromdapp.utils.ProjectUtils;
17 import org.apache.commons.lang.ObjectUtils;
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.maven.artifact.factory.ArtifactFactory;
20 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
21 import org.apache.maven.artifact.repository.ArtifactRepository;
22 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
23 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
24 import org.apache.maven.artifact.resolver.ArtifactResolver;
25 import org.apache.maven.execution.MavenSession;
26 import org.apache.maven.model.Build;
27 import org.apache.maven.model.Plugin;
28 import org.apache.maven.model.PluginExecution;
29 import org.apache.maven.model.PluginManagement;
30 import org.apache.maven.plugin.AbstractMojo;
31 import org.apache.maven.plugin.MojoExecutionException;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.project.MavenProjectBuilder;
34 import org.apache.maven.project.ProjectBuildingException;
35 import org.codehaus.plexus.util.DirectoryScanner;
36 import org.codehaus.plexus.util.xml.Xpp3Dom;
37
38
39
40
41
42
43
44
45
46 public class EclipseMojo
47 extends AbstractMojo
48 {
49
50
51
52 private MavenSession session;
53
54
55
56
57
58
59 private MavenProject project;
60
61 private static final String POM_FILE_NAME = "pom.xml";
62
63
64
65
66
67
68 private String[] includes = new String[] {"*/**/" + POM_FILE_NAME};
69
70
71
72
73
74
75 private String excludePoms;
76
77
78
79
80
81
82 private String[] excludes = new String[0];
83
84
85
86
87
88
89 private MavenProjectBuilder projectBuilder;
90
91
92
93
94
95
96 private String repositoryVariableName = "M2_REPO";
97
98
99
100
101
102
103
104
105 private ArtifactFactory artifactFactory;
106
107
108
109
110
111
112
113
114 private ArtifactResolver artifactResolver;
115
116
117
118
119
120
121 protected ArtifactRepository localRepository;
122
123
124
125
126 protected Variable[] variables;
127
128
129
130
131 private ArtifactMetadataSource artifactMetadataSource;
132
133
134
135
136
137
138 private Set<String> classpathArtifactTypes = new LinkedHashSet<String>(Arrays.asList("jar","ejb"));
139
140
141
142
143
144
145
146 private boolean resolveTransitiveDependencies = true;
147
148
149
150
151
152
153 private String classpathMerge;
154
155
156
157
158
159
160
161 private boolean skipProcessing = false;
162
163
164
165
166 public void execute()
167 throws MojoExecutionException
168 {
169 if (!this.skipProcessing)
170 {
171 try
172 {
173 final MavenProject rootProject = this.getRootProject();
174 final ProjectWriter projectWriter = new ProjectWriter(rootProject, this.getLog());
175 projectWriter.write();
176 final Map<MavenProject, Collection<String>> originalCompileSourceRoots = this.collectProjectCompileSourceRoots();
177 final List<MavenProject> projects = this.collectProjects();
178 this.processCompileSourceRoots(projects);
179 final ClasspathWriter classpathWriter = new ClasspathWriter(rootProject, this.getLog());
180 classpathWriter.write(
181 projects,
182 this.repositoryVariableName,
183 this.artifactFactory,
184 this.artifactResolver,
185 this.localRepository,
186 this.artifactMetadataSource,
187 this.classpathArtifactTypes,
188 this.project.getRemoteArtifactRepositories(),
189 this.resolveTransitiveDependencies,
190 this.variables,
191 this.classpathMerge);
192
193 for (final MavenProject project : projects)
194 {
195 project.getCompileSourceRoots().clear();
196 project.getCompileSourceRoots().addAll(originalCompileSourceRoots.get(project));
197 }
198 }
199 catch (Throwable throwable)
200 {
201 throw new MojoExecutionException("Error creating eclipse configuration", throwable);
202 }
203 }
204 }
205
206
207
208
209
210
211 private Map<MavenProject, Collection<String>> collectProjectCompileSourceRoots()
212 throws Exception
213 {
214 final Map<MavenProject, Collection<String>> sourceRoots = new LinkedHashMap<MavenProject, Collection<String>>();
215 for (final MavenProject project : this.collectProjects())
216 {
217 sourceRoots.put(project, new ArrayList<String>(project.getCompileSourceRoots()));
218 }
219 return sourceRoots;
220 }
221
222 private List<MavenProject> projects = new ArrayList<MavenProject>();
223
224
225
226
227
228
229
230
231 private List<MavenProject> collectProjects()
232 throws Exception
233 {
234 if (projects.isEmpty())
235 {
236 final List<File> poms = this.getPoms();
237 for (File pom : poms)
238 {
239 try
240 {
241
242 final MavenProject project = ProjectUtils.getProject(this.projectBuilder, this.session, pom, this.getLog());
243 if (project != null)
244 {
245 this.getLog().info("found project " + project.getId());
246 projects.add(project);
247 }
248 else
249 {
250 if (this.getLog().isWarnEnabled())
251 {
252 this.getLog().warn("Could not load project from pom: " + pom + " - ignoring");
253 }
254 }
255 }
256 catch (ProjectBuildingException exception)
257 {
258 throw new MojoExecutionException("Error loading " + pom, exception);
259 }
260 }
261 }
262 return projects;
263 }
264
265
266
267
268
269
270
271
272 private void processCompileSourceRoots(final List<MavenProject> projects)
273 throws Exception
274 {
275 for (final MavenProject project : projects)
276 {
277 final Set<String> compileSourceRoots = new LinkedHashSet<String>(project.getCompileSourceRoots());
278 compileSourceRoots.addAll(this.getExtraSourceDirectories(project));
279 final String testSourceDirectory = project.getBuild().getTestSourceDirectory();
280 if (StringUtils.isNotBlank(testSourceDirectory))
281 {
282 compileSourceRoots.add(testSourceDirectory);
283 }
284 project.getCompileSourceRoots().clear();
285 project.getCompileSourceRoots().addAll(compileSourceRoots);
286 }
287 }
288
289
290
291
292 private static final String MULTI_SOURCE_PLUGIN_ARTIFACT_ID = "build-helper-maven-plugin";
293
294
295
296
297
298
299
300 private List<String> getExtraSourceDirectories(final MavenProject project)
301 {
302 final List<String> sourceDirectories = new ArrayList<String>();
303 final Build build = project.getBuild();
304 if (build != null)
305 {
306 final PluginManagement pluginManagement = build.getPluginManagement();
307 if (pluginManagement != null && !pluginManagement.getPlugins().isEmpty())
308 {
309 Plugin multiSourcePlugin = null;
310 for (final Plugin plugin : pluginManagement.getPlugins())
311 {
312 if (MULTI_SOURCE_PLUGIN_ARTIFACT_ID.equals(plugin.getArtifactId()))
313 {
314 multiSourcePlugin = plugin;
315 break;
316 }
317 }
318 final Xpp3Dom configuration = this.getConfiguration(multiSourcePlugin);
319 if (configuration != null && configuration.getChildCount() > 0)
320 {
321 final Xpp3Dom directories = configuration.getChild(0);
322 if (directories != null)
323 {
324 final int childCount = directories.getChildCount();
325 if (childCount > 0)
326 {
327 final String baseDirectory =
328 ResourceUtils.normalizePath(ObjectUtils.toString(project.getBasedir()) + '/');
329 final Xpp3Dom[] children = directories.getChildren();
330 for (int ctr = 0; ctr < childCount; ctr++)
331 {
332 final Xpp3Dom child = children[ctr];
333 if (child != null)
334 {
335 String directoryValue = ResourceUtils.normalizePath(child.getValue());
336 if (directoryValue != null)
337 {
338 if (!directoryValue.startsWith(baseDirectory))
339 {
340 directoryValue =
341 ResourceUtils.normalizePath(baseDirectory + directoryValue.trim());
342 }
343 sourceDirectories.add(directoryValue);
344 }
345 }
346 }
347 }
348 }
349 }
350 }
351 }
352 return sourceDirectories;
353 }
354
355
356
357
358
359
360
361
362
363 private Xpp3Dom getConfiguration(final Plugin plugin)
364 {
365 Xpp3Dom configuration = null;
366 if (plugin != null)
367 {
368 if (plugin.getConfiguration() != null)
369 {
370 configuration = (Xpp3Dom)plugin.getConfiguration();
371 }
372 else
373 {
374 final List<PluginExecution> executions = plugin.getExecutions();
375 if (executions != null && !executions.isEmpty())
376 {
377
378 final PluginExecution execution = plugin.getExecutions().iterator().next();
379 configuration = (Xpp3Dom)execution.getConfiguration();
380 }
381 }
382 }
383 return configuration;
384 }
385
386
387
388
389 private MavenProject rootProject;
390
391
392
393
394
395
396
397
398 private MavenProject getRootProject()
399 throws MojoExecutionException, ArtifactResolutionException, ArtifactNotFoundException
400 {
401 if (this.rootProject == null)
402 {
403 final MavenProject firstParent = this.project.getParent();
404 File rootFile = this.project.getFile();
405 if (firstParent != null && firstParent.getFile() != null )
406 {
407 for (this.rootProject = firstParent, rootFile = new File(rootFile.getParentFile().getParentFile(), POM_FILE_NAME);
408 this.rootProject.getParent() != null && this.rootProject.getParent().getFile() != null;
409 this.rootProject = this.rootProject.getParent(), rootFile = new File(rootFile.getParentFile().getParentFile(), POM_FILE_NAME))
410 {
411 }
412
413 if (this.rootProject != null && this.rootProject.getFile() == null && rootFile.exists())
414 {
415 this.rootProject.setFile(rootFile);
416 }
417 }
418 else
419 {
420 this.rootProject = this.project;
421 }
422 }
423 return this.rootProject;
424 }
425
426
427
428
429
430
431
432 private List<File> getPoms()
433 throws Exception
434 {
435 final DirectoryScanner scanner = new DirectoryScanner();
436 scanner.setBasedir(this.getRootProject().getBasedir());
437 scanner.setIncludes(this.includes);
438
439 final List<String> excludes = new ArrayList<String>(Arrays.asList(this.excludes));
440 if (this.excludePoms != null)
441 {
442 excludes.addAll(Arrays.asList(excludePoms.split(",")));
443 }
444 scanner.setExcludes(excludes.toArray(new String[excludes.size()]));
445 scanner.scan();
446
447 List<File> poms = new ArrayList<File>();
448
449 for (int ctr = 0; ctr < scanner.getIncludedFiles().length; ctr++)
450 {
451 final File file = new File(
452 this.getRootProject().getBasedir(),
453 scanner.getIncludedFiles()[ctr]);
454 if (file.exists())
455 {
456 poms.add(file);
457 }
458 }
459
460 return poms;
461 }
462 }