001: package org.andromda.maven.plugin.andromdapp;
002:
003: import java.io.File;
004: import java.util.ArrayList;
005: import java.util.Collections;
006: import java.util.Iterator;
007: import java.util.List;
008:
009: import org.andromda.maven.plugin.andromdapp.utils.ProjectUtils;
010: import org.andromda.maven.plugin.andromdapp.utils.Projects;
011: import org.apache.maven.execution.MavenSession;
012: import org.apache.maven.execution.ReactorManager;
013: import org.apache.maven.lifecycle.LifecycleExecutor;
014: import org.apache.maven.plugin.AbstractMojo;
015: import org.apache.maven.plugin.MojoExecutionException;
016: import org.apache.maven.plugin.MojoFailureException;
017: import org.apache.maven.project.MavenProject;
018: import org.apache.maven.project.MavenProjectBuilder;
019: import org.apache.maven.project.ProjectBuildingException;
020: import org.codehaus.plexus.util.DirectoryScanner;
021:
022: /**
023: * Allows the execution of maven from a given project (searches
024: * for nested pom.xml files and executes Maven)
025: *
026: * @author Chad Brandon
027: * @goal maven
028: */
029: public class MavenExecuteMojo extends AbstractMojo {
030: /**
031: * @parameter expression="${session}"
032: */
033: private MavenSession session;
034:
035: /**
036: * @parameter expression="${project.basedir}"
037: */
038: private File baseDirectory;
039:
040: /**
041: * @parameter expression="${component.org.apache.maven.lifecycle.LifecycleExecutor}"
042: */
043: private LifecycleExecutor lifecycleExecutor;
044:
045: /**
046: * @parameter expression="${project}"
047: * @required
048: * @readonly
049: */
050: private MavenProject project;
051:
052: /**
053: * Used to contruct Maven project instances from POMs.
054: *
055: * @component
056: */
057: private MavenProjectBuilder projectBuilder;
058:
059: /**
060: * @parameter
061: */
062: private String[] includes = new String[] { "*/**/pom.xml" };
063:
064: /**
065: * Whether or not goals should be aggregated when executing the projects
066: * (i.e. whether goals should be executed together per project or seperate for
067: * each project).
068: *
069: * @parameter
070: */
071: private boolean aggregateGoals = false;
072:
073: /**
074: * @parameter
075: */
076: private String[] excludes = new String[] { "pom.xml" };
077:
078: /**
079: * This is used to remove the 'version' property from the system
080: * properties as it ends up being used in the POM interpolation (in other
081: * words is a hack until they fix this Maven2 bug).
082: */
083: private static final String VERSION_PROPERTY = "version";
084:
085: /**
086: * @see org.apache.maven.plugin.AbstractMojo#execute()
087: */
088: public void execute() throws MojoExecutionException,
089: MojoFailureException {
090: // - remove any "version" property as it seems to be picked up and used
091: // in maven2's POM interpolation (remove this when this issue is fixed).
092: System.getProperties().remove(VERSION_PROPERTY);
093: if (!Projects.instance().isPresent(this .project.getId())) {
094: try {
095: final List projects = this .collectProjects();
096:
097: // - only execute if we have some projects
098: if (!projects.isEmpty()) {
099: final List goals = this .session.getGoals();
100: if (goals.isEmpty()) {
101: if (this .project != null) {
102: final String defaultGoal = this .project
103: .getDefaultGoal();
104: if (defaultGoal != null
105: && defaultGoal.trim().length() > 0) {
106: goals.add(defaultGoal);
107: }
108: }
109: }
110: if (this .aggregateGoals) {
111: final ReactorManager reactorManager = new ReactorManager(
112: projects);
113: if (projects.size() > 1) {
114: this .getLog().info("Reactor build order:");
115: }
116: for (final Iterator iterator = reactorManager
117: .getSortedProjects().iterator(); iterator
118: .hasNext();) {
119: final MavenProject project = (MavenProject) iterator
120: .next();
121: this .getLog()
122: .info(" " + project.getName());
123: }
124: final MavenSession projectSession = new MavenSession(
125: this .session.getContainer(),
126: this .session.getSettings(),
127: this .session.getLocalRepository(),
128: this .session.getEventDispatcher(),
129: reactorManager, goals,
130: this .baseDirectory.toString(),
131: this .session.getExecutionProperties(),
132: this .session.getStartTime());
133:
134: projectSession.setUsingPOMsFromFilesystem(true);
135: this .lifecycleExecutor.execute(projectSession,
136: reactorManager, projectSession
137: .getEventDispatcher());
138: } else {
139: for (final Iterator iterator = this .session
140: .getGoals().iterator(); iterator
141: .hasNext();) {
142: final String goal = (String) iterator
143: .next();
144: final ReactorManager reactorManager = new ReactorManager(
145: projects);
146: if (projects.size() > 1) {
147: this .getLog().info(
148: "Reactor build order:");
149: }
150: for (final Iterator projectIterator = reactorManager
151: .getSortedProjects().iterator(); projectIterator
152: .hasNext();) {
153: final MavenProject project = (MavenProject) projectIterator
154: .next();
155: this .getLog().info(
156: " " + project.getName());
157: }
158:
159: final MavenSession projectSession = new MavenSession(
160: this .session.getContainer(),
161: this .session.getSettings(),
162: this .session.getLocalRepository(),
163: this .session.getEventDispatcher(),
164: reactorManager, Collections
165: .singletonList(goal),
166: this .baseDirectory.toString(),
167: this .session
168: .getExecutionProperties(),
169: this .session.getStartTime());
170:
171: projectSession
172: .setUsingPOMsFromFilesystem(true);
173:
174: this .lifecycleExecutor
175: .execute(
176: projectSession,
177: reactorManager,
178: projectSession
179: .getEventDispatcher());
180: }
181: }
182: }
183: } catch (final Throwable throwable) {
184: throw new MojoExecutionException("Execution failed",
185: throwable);
186: }
187: Projects.instance().add(this .project.getId());
188: }
189: }
190:
191: /**
192: * Collects all project modules to execute.
193: *
194: * @return the Map of collected projects (the key is the project, the value
195: * the goals).
196: * @throws MojoExecutionException
197: */
198: private List collectProjects() throws MojoExecutionException {
199: final List projects = new ArrayList();
200: final List poms = this .getPoms();
201: if (!poms.isEmpty()) {
202: for (final Iterator iterator = poms.iterator(); iterator
203: .hasNext();) {
204: final File pom = (File) iterator.next();
205:
206: // - first attempt to get the existing project from the session
207: try {
208: final MavenProject project = ProjectUtils
209: .getProject(this .projectBuilder,
210: this .session, pom);
211: if (this .getLog().isDebugEnabled()) {
212: getLog().debug(
213: "Adding project " + project.getId());
214: }
215: projects.add(project);
216: } catch (ProjectBuildingException exception) {
217: throw new MojoExecutionException(
218: "Error loading POM --> '" + pom + "'",
219: exception);
220: }
221: }
222: }
223: return projects;
224: }
225:
226: /**
227: * Gets all POMs for the modules specified.
228: *
229: * @return the list of module poms
230: */
231: private List getPoms() {
232: final DirectoryScanner scanner = new DirectoryScanner();
233: scanner.setBasedir(this .baseDirectory);
234: scanner.setIncludes(includes);
235: scanner.setExcludes(excludes);
236: scanner.scan();
237: final List poms = new ArrayList();
238: for (int ctr = 0; ctr < scanner.getIncludedFiles().length; ctr++) {
239: poms.add(new File(this.baseDirectory, scanner
240: .getIncludedFiles()[ctr]));
241: }
242: return poms;
243: }
244: }
|