1 package org.apache.maven;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.text.SimpleDateFormat;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.HashSet;
28 import java.util.LinkedHashMap;
29 import java.util.LinkedHashSet;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Properties;
33
34 import org.apache.maven.artifact.ArtifactUtils;
35 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
36 import org.apache.maven.execution.DefaultMavenExecutionResult;
37 import org.apache.maven.execution.ExecutionEvent;
38 import org.apache.maven.execution.MavenExecutionRequest;
39 import org.apache.maven.execution.MavenExecutionRequestPopulationException;
40 import org.apache.maven.execution.MavenExecutionRequestPopulator;
41 import org.apache.maven.execution.MavenExecutionResult;
42 import org.apache.maven.execution.MavenSession;
43 import org.apache.maven.execution.ProjectDependencyGraph;
44 import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
45 import org.apache.maven.lifecycle.internal.LifecycleStarter;
46 import org.apache.maven.model.building.ModelProblem;
47 import org.apache.maven.model.building.ModelProblemUtils;
48 import org.apache.maven.model.building.ModelSource;
49 import org.apache.maven.model.building.UrlModelSource;
50 import org.apache.maven.plugin.LegacySupport;
51 import org.apache.maven.project.DuplicateProjectException;
52 import org.apache.maven.project.MavenProject;
53 import org.apache.maven.project.ProjectBuilder;
54 import org.apache.maven.project.ProjectBuildingException;
55 import org.apache.maven.project.ProjectBuildingRequest;
56 import org.apache.maven.project.ProjectBuildingResult;
57 import org.apache.maven.project.ProjectSorter;
58 import org.apache.maven.repository.DelegatingLocalArtifactRepository;
59 import org.apache.maven.repository.LocalRepositoryNotAccessibleException;
60 import org.apache.maven.settings.Mirror;
61 import org.apache.maven.settings.Proxy;
62 import org.apache.maven.settings.Server;
63 import org.apache.maven.settings.building.SettingsProblem;
64 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
65 import org.apache.maven.settings.crypto.SettingsDecrypter;
66 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
67 import org.codehaus.plexus.PlexusContainer;
68 import org.codehaus.plexus.component.annotations.Component;
69 import org.codehaus.plexus.component.annotations.Requirement;
70 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
71 import org.codehaus.plexus.logging.Logger;
72 import org.codehaus.plexus.util.IOUtil;
73 import org.codehaus.plexus.util.StringUtils;
74 import org.codehaus.plexus.util.dag.CycleDetectedException;
75 import org.sonatype.aether.ConfigurationProperties;
76 import org.sonatype.aether.RepositoryEvent;
77 import org.sonatype.aether.RepositorySystem;
78 import org.sonatype.aether.RepositorySystemSession;
79 import org.sonatype.aether.collection.DependencyGraphTransformer;
80 import org.sonatype.aether.collection.DependencyManager;
81 import org.sonatype.aether.collection.DependencySelector;
82 import org.sonatype.aether.collection.DependencyTraverser;
83 import org.sonatype.aether.repository.Authentication;
84 import org.sonatype.aether.repository.LocalRepository;
85 import org.sonatype.aether.repository.RepositoryPolicy;
86 import org.sonatype.aether.repository.WorkspaceReader;
87 import org.sonatype.aether.util.DefaultRepositorySystemSession;
88 import org.sonatype.aether.util.graph.manager.ClassicDependencyManager;
89 import org.sonatype.aether.util.graph.selector.AndDependencySelector;
90 import org.sonatype.aether.util.graph.selector.ExclusionDependencySelector;
91 import org.sonatype.aether.util.graph.selector.OptionalDependencySelector;
92 import org.sonatype.aether.util.graph.selector.ScopeDependencySelector;
93 import org.sonatype.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
94 import org.sonatype.aether.util.graph.transformer.NearestVersionConflictResolver;
95 import org.sonatype.aether.util.graph.transformer.ConflictMarker;
96 import org.sonatype.aether.util.graph.transformer.JavaDependencyContextRefiner;
97 import org.sonatype.aether.util.graph.transformer.JavaEffectiveScopeCalculator;
98 import org.sonatype.aether.util.graph.traverser.FatArtifactTraverser;
99 import org.sonatype.aether.util.repository.ChainedWorkspaceReader;
100 import org.sonatype.aether.util.repository.DefaultAuthenticationSelector;
101 import org.sonatype.aether.util.repository.DefaultMirrorSelector;
102 import org.sonatype.aether.util.repository.DefaultProxySelector;
103
104
105
106
107 @Component(role = Maven.class)
108 public class DefaultMaven
109 implements Maven
110 {
111
112 @Requirement
113 private Logger logger;
114
115 @Requirement
116 protected ProjectBuilder projectBuilder;
117
118 @Requirement
119 private LifecycleStarter lifecycleStarter;
120
121 @Requirement
122 protected PlexusContainer container;
123
124 @Requirement
125 MavenExecutionRequestPopulator populator;
126
127 @Requirement
128 private ExecutionEventCatapult eventCatapult;
129
130 @Requirement
131 private ArtifactHandlerManager artifactHandlerManager;
132
133 @Requirement( optional = true, hint = "ide" )
134 private WorkspaceReader workspaceRepository;
135
136 @Requirement
137 private RepositorySystem repoSystem;
138
139 @Requirement
140 private SettingsDecrypter settingsDecrypter;
141
142 @Requirement
143 private LegacySupport legacySupport;
144
145 public MavenExecutionResult execute( MavenExecutionRequest request )
146 {
147 MavenExecutionResult result;
148
149 try
150 {
151 result = doExecute( populator.populateDefaults( request ) );
152 }
153 catch ( OutOfMemoryError e )
154 {
155 result = processResult( new DefaultMavenExecutionResult(), e );
156 }
157 catch ( MavenExecutionRequestPopulationException e )
158 {
159 result = processResult( new DefaultMavenExecutionResult(), e );
160 }
161 catch ( RuntimeException e )
162 {
163 result =
164 processResult( new DefaultMavenExecutionResult(),
165 new InternalErrorException( "Internal error: " + e, e ) );
166 }
167 finally
168 {
169 legacySupport.setSession( null );
170 }
171
172 return result;
173 }
174
175 @SuppressWarnings({"ThrowableInstanceNeverThrown", "ThrowableResultOfMethodCallIgnored"})
176 private MavenExecutionResult doExecute( MavenExecutionRequest request )
177 {
178
179 if ( request.getStartTime() != null )
180 {
181 request.getSystemProperties().put( "${build.timestamp}", new SimpleDateFormat( "yyyyMMdd-hhmm" ).format( request.getStartTime() ) );
182 }
183
184 request.setStartTime( new Date() );
185
186 MavenExecutionResult result = new DefaultMavenExecutionResult();
187
188 try
189 {
190 validateLocalRepository( request );
191 }
192 catch ( LocalRepositoryNotAccessibleException e )
193 {
194 return processResult( result, e );
195 }
196
197 DelegatingLocalArtifactRepository delegatingLocalArtifactRepository =
198 new DelegatingLocalArtifactRepository( request.getLocalRepository() );
199
200 request.setLocalRepository( delegatingLocalArtifactRepository );
201
202 DefaultRepositorySystemSession repoSession = (DefaultRepositorySystemSession) newRepositorySession( request );
203
204 MavenSession session = new MavenSession( container, repoSession, request, result );
205 legacySupport.setSession( session );
206
207 try
208 {
209 for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( Collections.<MavenProject> emptyList() ) )
210 {
211 listener.afterSessionStart( session );
212 }
213 }
214 catch ( MavenExecutionException e )
215 {
216 return processResult( result, e );
217 }
218
219 eventCatapult.fire( ExecutionEvent.Type.ProjectDiscoveryStarted, session, null );
220
221 request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() );
222
223
224
225 List<MavenProject> projects;
226 try
227 {
228 projects = getProjectsForMavenReactor( request );
229 }
230 catch ( ProjectBuildingException e )
231 {
232 return processResult( result, e );
233 }
234
235 session.setProjects( projects );
236
237 result.setTopologicallySortedProjects( session.getProjects() );
238
239 result.setProject( session.getTopLevelProject() );
240
241 try
242 {
243 Map<String, MavenProject> projectMap;
244 projectMap = getProjectMap( session.getProjects() );
245
246
247
248
249
250
251 ReactorReader reactorRepository = new ReactorReader( projectMap );
252
253 repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorRepository,
254 repoSession.getWorkspaceReader() ) );
255 }
256 catch ( org.apache.maven.DuplicateProjectException e )
257 {
258 return processResult( result, e );
259 }
260
261 ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
262 try
263 {
264 for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( projects ) )
265 {
266 Thread.currentThread().setContextClassLoader( listener.getClass().getClassLoader() );
267
268 listener.afterProjectsRead( session );
269 }
270 }
271 catch ( MavenExecutionException e )
272 {
273 return processResult( result, e );
274 }
275 finally
276 {
277 Thread.currentThread().setContextClassLoader( originalClassLoader );
278 }
279
280 try
281 {
282 ProjectSorter projectSorter = new ProjectSorter( session.getProjects() );
283
284 ProjectDependencyGraph projectDependencyGraph = createDependencyGraph( projectSorter, request );
285
286 session.setProjects( projectDependencyGraph.getSortedProjects() );
287
288 session.setProjectDependencyGraph( projectDependencyGraph );
289 }
290 catch ( CycleDetectedException e )
291 {
292 String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();
293
294 ProjectCycleException error = new ProjectCycleException( message, e );
295
296 return processResult( result, error );
297 }
298 catch ( DuplicateProjectException e )
299 {
300 return processResult( result, e );
301 }
302 catch ( MavenExecutionException e )
303 {
304 return processResult( result, e );
305 }
306
307 result.setTopologicallySortedProjects( session.getProjects() );
308
309 if ( result.hasExceptions() )
310 {
311 return result;
312 }
313
314 lifecycleStarter.execute( session );
315
316 validateActivatedProfiles( session.getProjects(), request.getActiveProfiles() );
317
318 if ( session.getResult().hasExceptions() )
319 {
320 return processResult( result, session.getResult().getExceptions().get( 0 ) );
321 }
322
323 return result;
324 }
325
326 public RepositorySystemSession newRepositorySession( MavenExecutionRequest request )
327 {
328 DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
329
330 session.setCache( request.getRepositoryCache() );
331
332 session.setIgnoreInvalidArtifactDescriptor( true ).setIgnoreMissingArtifactDescriptor( true );
333
334 session.setUserProps( request.getUserProperties() );
335 session.setSystemProps( request.getSystemProperties() );
336 Map<Object, Object> configProps = new LinkedHashMap<Object, Object>();
337 configProps.put( ConfigurationProperties.USER_AGENT, getUserAgent() );
338 configProps.put( ConfigurationProperties.INTERACTIVE, Boolean.valueOf( request.isInteractiveMode() ) );
339 configProps.putAll( request.getSystemProperties() );
340 configProps.putAll( request.getUserProperties() );
341 session.setConfigProps( configProps );
342
343 session.setOffline( request.isOffline() );
344 session.setChecksumPolicy( request.getGlobalChecksumPolicy() );
345 session.setUpdatePolicy( request.isUpdateSnapshots() ? RepositoryPolicy.UPDATE_POLICY_ALWAYS : null );
346
347 session.setNotFoundCachingEnabled( request.isCacheNotFound() );
348 session.setTransferErrorCachingEnabled( request.isCacheTransferError() );
349
350 session.setArtifactTypeRegistry( RepositoryUtils.newArtifactTypeRegistry( artifactHandlerManager ) );
351
352 LocalRepository localRepo = new LocalRepository( request.getLocalRepository().getBasedir() );
353 session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( localRepo ) );
354
355 if ( request.getWorkspaceReader() != null )
356 {
357 session.setWorkspaceReader( request.getWorkspaceReader() );
358 }
359 else
360 {
361 session.setWorkspaceReader( workspaceRepository );
362 }
363
364 DefaultSettingsDecryptionRequest decrypt = new DefaultSettingsDecryptionRequest();
365 decrypt.setProxies( request.getProxies() );
366 decrypt.setServers( request.getServers() );
367 SettingsDecryptionResult decrypted = settingsDecrypter.decrypt( decrypt );
368
369 if ( logger.isDebugEnabled() )
370 {
371 for ( SettingsProblem problem : decrypted.getProblems() )
372 {
373 logger.debug( problem.getMessage(), problem.getException() );
374 }
375 }
376
377 DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector();
378 for ( Mirror mirror : request.getMirrors() )
379 {
380 mirrorSelector.add( mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(),
381 mirror.getMirrorOfLayouts() );
382 }
383 session.setMirrorSelector( mirrorSelector );
384
385 DefaultProxySelector proxySelector = new DefaultProxySelector();
386 for ( Proxy proxy : decrypted.getProxies() )
387 {
388 Authentication proxyAuth = new Authentication( proxy.getUsername(), proxy.getPassword() );
389 proxySelector.add( new org.sonatype.aether.repository.Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(),
390 proxyAuth ), proxy.getNonProxyHosts() );
391 }
392 session.setProxySelector( proxySelector );
393
394 DefaultAuthenticationSelector authSelector = new DefaultAuthenticationSelector();
395 for ( Server server : decrypted.getServers() )
396 {
397 Authentication auth =
398 new Authentication( server.getUsername(), server.getPassword(), server.getPrivateKey(),
399 server.getPassphrase() );
400 authSelector.add( server.getId(), auth );
401 }
402 session.setAuthenticationSelector( authSelector );
403
404 DependencyTraverser depTraverser = new FatArtifactTraverser();
405 session.setDependencyTraverser( depTraverser );
406
407 DependencyManager depManager = new ClassicDependencyManager();
408 session.setDependencyManager( depManager );
409
410 DependencySelector depFilter =
411 new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ), new OptionalDependencySelector(),
412 new ExclusionDependencySelector() );
413 session.setDependencySelector( depFilter );
414
415 DependencyGraphTransformer transformer =
416 new ChainedDependencyGraphTransformer( new ConflictMarker(), new JavaEffectiveScopeCalculator(),
417 new NearestVersionConflictResolver(),
418 new JavaDependencyContextRefiner() );
419 session.setDependencyGraphTransformer( transformer );
420
421 session.setTransferListener( request.getTransferListener() );
422
423 session.setRepositoryListener( new LoggingRepositoryListener( logger ) );
424
425 return session;
426 }
427
428 private String getUserAgent()
429 {
430 StringBuilder buffer = new StringBuilder( 128 );
431
432 buffer.append( "Apache-Maven/" ).append( getMavenVersion() );
433 buffer.append( " (" );
434 buffer.append( "Java " ).append( System.getProperty( "java.version" ) );
435 buffer.append( "; " );
436 buffer.append( System.getProperty( "os.name" ) ).append( " " ).append( System.getProperty( "os.version" ) );
437 buffer.append( ")" );
438
439 return buffer.toString();
440 }
441
442 private String getMavenVersion()
443 {
444 Properties props = new Properties();
445
446 InputStream is = getClass().getResourceAsStream( "/META-INF/maven/org.apache.maven/maven-core/pom.properties" );
447 if ( is != null )
448 {
449 try
450 {
451 props.load( is );
452 }
453 catch ( IOException e )
454 {
455 logger.debug( "Failed to read Maven version", e );
456 }
457 IOUtil.close( is );
458 }
459
460 return props.getProperty( "version", "unknown-version" );
461 }
462
463 @SuppressWarnings({"ResultOfMethodCallIgnored"})
464 private void validateLocalRepository( MavenExecutionRequest request )
465 throws LocalRepositoryNotAccessibleException
466 {
467 File localRepoDir = request.getLocalRepositoryPath();
468
469 logger.debug( "Using local repository at " + localRepoDir );
470
471 localRepoDir.mkdirs();
472
473 if ( !localRepoDir.isDirectory() )
474 {
475 throw new LocalRepositoryNotAccessibleException( "Could not create local repository at " + localRepoDir );
476 }
477 }
478
479 private Collection<AbstractMavenLifecycleParticipant> getLifecycleParticipants( Collection<MavenProject> projects )
480 {
481 Collection<AbstractMavenLifecycleParticipant> lifecycleListeners =
482 new LinkedHashSet<AbstractMavenLifecycleParticipant>();
483
484 ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
485 try
486 {
487 try
488 {
489 lifecycleListeners.addAll( container.lookupList( AbstractMavenLifecycleParticipant.class ) );
490 }
491 catch ( ComponentLookupException e )
492 {
493
494 logger.warn( "Failed to lookup lifecycle participants: " + e.getMessage() );
495 }
496
497 Collection<ClassLoader> scannedRealms = new HashSet<ClassLoader>();
498
499 for ( MavenProject project : projects )
500 {
501 ClassLoader projectRealm = project.getClassRealm();
502
503 if ( projectRealm != null && scannedRealms.add( projectRealm ) )
504 {
505 Thread.currentThread().setContextClassLoader( projectRealm );
506
507 try
508 {
509 lifecycleListeners.addAll( container.lookupList( AbstractMavenLifecycleParticipant.class ) );
510 }
511 catch ( ComponentLookupException e )
512 {
513
514 logger.warn( "Failed to lookup lifecycle participants: " + e.getMessage() );
515 }
516 }
517 }
518 }
519 finally
520 {
521 Thread.currentThread().setContextClassLoader( originalClassLoader );
522 }
523
524 return lifecycleListeners;
525 }
526
527 private MavenExecutionResult processResult( MavenExecutionResult result, Throwable e )
528 {
529 if ( !result.getExceptions().contains( e ) )
530 {
531 result.addException( e );
532 }
533
534 return result;
535 }
536
537 private List<MavenProject> getProjectsForMavenReactor( MavenExecutionRequest request )
538 throws ProjectBuildingException
539 {
540 List<MavenProject> projects = new ArrayList<MavenProject>();
541
542
543
544 if ( request.getPom() == null )
545 {
546 ModelSource modelSource = new UrlModelSource( getClass().getResource( "project/standalone.xml" ) );
547 MavenProject project =
548 projectBuilder.build( modelSource, request.getProjectBuildingRequest() ).getProject();
549 project.setExecutionRoot( true );
550 projects.add( project );
551 request.setProjectPresent( false );
552 return projects;
553 }
554
555 List<File> files = Arrays.asList( request.getPom().getAbsoluteFile() );
556 collectProjects( projects, files, request );
557 return projects;
558 }
559
560 private Map<String, MavenProject> getProjectMap( List<MavenProject> projects )
561 throws org.apache.maven.DuplicateProjectException
562 {
563 Map<String, MavenProject> index = new LinkedHashMap<String, MavenProject>();
564 Map<String, List<File>> collisions = new LinkedHashMap<String, List<File>>();
565
566 for ( MavenProject project : projects )
567 {
568 String projectId = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
569
570 MavenProject collision = index.get( projectId );
571
572 if ( collision == null )
573 {
574 index.put( projectId, project );
575 }
576 else
577 {
578 List<File> pomFiles = collisions.get( projectId );
579
580 if ( pomFiles == null )
581 {
582 pomFiles = new ArrayList<File>( Arrays.asList( collision.getFile(), project.getFile() ) );
583 collisions.put( projectId, pomFiles );
584 }
585 else
586 {
587 pomFiles.add( project.getFile() );
588 }
589 }
590 }
591
592 if ( !collisions.isEmpty() )
593 {
594 throw new org.apache.maven.DuplicateProjectException( "Two or more projects in the reactor"
595 + " have the same identifier, please make sure that <groupId>:<artifactId>:<version>"
596 + " is unique for each project: " + collisions, collisions );
597 }
598
599 return index;
600 }
601
602 private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
603 throws ProjectBuildingException
604 {
605 ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
606
607 List<ProjectBuildingResult> results = projectBuilder.build( files, request.isRecursive(), projectBuildingRequest );
608
609 boolean problems = false;
610
611 for ( ProjectBuildingResult result : results )
612 {
613 projects.add( result.getProject() );
614
615 if ( !result.getProblems().isEmpty() && logger.isWarnEnabled() )
616 {
617 logger.warn( "" );
618 logger.warn( "Some problems were encountered while building the effective model for "
619 + result.getProject().getId() );
620
621 for ( ModelProblem problem : result.getProblems() )
622 {
623 String location = ModelProblemUtils.formatLocation( problem, result.getProjectId() );
624 logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( location ) ? " @ " + location : "" ) );
625 }
626
627 problems = true;
628 }
629 }
630
631 if ( problems )
632 {
633 logger.warn( "" );
634 logger.warn( "It is highly recommended to fix these problems"
635 + " because they threaten the stability of your build." );
636 logger.warn( "" );
637 logger.warn( "For this reason, future Maven versions might no"
638 + " longer support building such malformed projects." );
639 logger.warn( "" );
640 }
641 }
642
643 private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
644 {
645 Collection<String> notActivatedProfileIds = new LinkedHashSet<String>( activeProfileIds );
646
647 for ( MavenProject project : projects )
648 {
649 for ( List<String> profileIds : project.getInjectedProfileIds().values() )
650 {
651 notActivatedProfileIds.removeAll( profileIds );
652 }
653 }
654
655 for ( String notActivatedProfileId : notActivatedProfileIds )
656 {
657 logger.warn( "The requested profile \"" + notActivatedProfileId
658 + "\" could not be activated because it does not exist." );
659 }
660 }
661
662 protected Logger getLogger()
663 {
664 return logger;
665 }
666
667 private ProjectDependencyGraph createDependencyGraph( ProjectSorter sorter, MavenExecutionRequest request )
668 throws MavenExecutionException
669 {
670 ProjectDependencyGraph graph = new DefaultProjectDependencyGraph( sorter );
671
672 Collection<MavenProject> activeProjects = sorter.getSortedProjects();
673
674 File reactorDirectory;
675 if ( request.getBaseDirectory() != null )
676 {
677 reactorDirectory = new File( request.getBaseDirectory() );
678 }
679 else
680 {
681 reactorDirectory = null;
682 }
683
684 if ( !request.getSelectedProjects().isEmpty() )
685 {
686 List<MavenProject> selectedProjects = new ArrayList<MavenProject>( request.getSelectedProjects().size() );
687
688 for ( String selectedProject : request.getSelectedProjects() )
689 {
690 MavenProject project = null;
691
692 for ( MavenProject activeProject : activeProjects )
693 {
694 if ( isMatchingProject( activeProject, selectedProject, reactorDirectory ) )
695 {
696 project = activeProject;
697 break;
698 }
699 }
700
701 if ( project != null )
702 {
703 selectedProjects.add( project );
704 }
705 else
706 {
707 throw new MavenExecutionException( "Could not find the selected project in the reactor: "
708 + selectedProject, request.getPom() );
709 }
710 }
711
712 activeProjects = selectedProjects;
713
714 boolean makeUpstream = false;
715 boolean makeDownstream = false;
716
717 if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( request.getMakeBehavior() ) )
718 {
719 makeUpstream = true;
720 }
721 else if ( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM.equals( request.getMakeBehavior() ) )
722 {
723 makeDownstream = true;
724 }
725 else if ( MavenExecutionRequest.REACTOR_MAKE_BOTH.equals( request.getMakeBehavior() ) )
726 {
727 makeUpstream = true;
728 makeDownstream = true;
729 }
730 else if ( StringUtils.isNotEmpty( request.getMakeBehavior() ) )
731 {
732 throw new MavenExecutionException( "Invalid reactor make behavior: " + request.getMakeBehavior(),
733 request.getPom() );
734 }
735
736 if ( makeUpstream || makeDownstream )
737 {
738 activeProjects = new LinkedHashSet<MavenProject>( selectedProjects );
739
740 for ( MavenProject selectedProject : selectedProjects )
741 {
742 if ( makeUpstream )
743 {
744 activeProjects.addAll( graph.getUpstreamProjects( selectedProject, true ) );
745 }
746 if ( makeDownstream )
747 {
748 activeProjects.addAll( graph.getDownstreamProjects( selectedProject, true ) );
749 }
750 }
751 }
752 }
753
754 if ( StringUtils.isNotEmpty( request.getResumeFrom() ) )
755 {
756 String selectedProject = request.getResumeFrom();
757
758 List<MavenProject> projects = new ArrayList<MavenProject>( activeProjects.size() );
759
760 boolean resumed = false;
761
762 for ( MavenProject project : activeProjects )
763 {
764 if ( !resumed && isMatchingProject( project, selectedProject, reactorDirectory ) )
765 {
766 resumed = true;
767 }
768
769 if ( resumed )
770 {
771 projects.add( project );
772 }
773 }
774
775 if ( !resumed )
776 {
777 throw new MavenExecutionException( "Could not find project to resume reactor build from: "
778 + selectedProject + " vs " + activeProjects, request.getPom() );
779 }
780
781 activeProjects = projects;
782 }
783
784 if ( activeProjects.size() != sorter.getSortedProjects().size() )
785 {
786 graph = new FilteredProjectDependencyGraph( graph, activeProjects );
787 }
788
789 return graph;
790 }
791
792 private boolean isMatchingProject( MavenProject project, String selector, File reactorDirectory )
793 {
794
795 if ( selector.indexOf( ':' ) >= 0 )
796 {
797 String id = ':' + project.getArtifactId();
798
799 if ( id.equals( selector ) )
800 {
801 return true;
802 }
803
804 id = project.getGroupId() + id;
805
806 if ( id.equals( selector ) )
807 {
808 return true;
809 }
810 }
811
812
813 else if ( reactorDirectory != null )
814 {
815 File selectedProject = new File( new File( reactorDirectory, selector ).toURI().normalize() );
816
817 if ( selectedProject.isFile() )
818 {
819 return selectedProject.equals( project.getFile() );
820 }
821 else if ( selectedProject.isDirectory() )
822 {
823 return selectedProject.equals( project.getBasedir() );
824 }
825 }
826
827 return false;
828 }
829
830 }