1   package org.apache.maven.lifecycle.internal;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import org.apache.maven.execution.MavenSession;
23  import org.apache.maven.project.MavenProject;
24  import org.codehaus.plexus.component.annotations.Component;
25  import org.codehaus.plexus.component.annotations.Requirement;
26  import org.codehaus.plexus.logging.Logger;
27  
28  import java.util.List;
29  import java.util.Map;
30  import java.util.concurrent.Callable;
31  import java.util.concurrent.CompletionService;
32  import java.util.concurrent.ExecutionException;
33  import java.util.concurrent.Future;
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  @Component( role = LifecycleThreadedBuilder.class )
45  public class LifecycleThreadedBuilder
46  {
47  
48      @Requirement
49      private Logger logger;
50  
51      @Requirement
52      private LifecycleModuleBuilder lifecycleModuleBuilder;
53  
54  
55      @SuppressWarnings( { "UnusedDeclaration" } )
56      public LifecycleThreadedBuilder()
57      {
58      }
59  
60      public void build( MavenSession session, ReactorContext reactorContext, ProjectBuildList projectBuilds,
61                         List<TaskSegment> currentTaskSegment, ConcurrencyDependencyGraph analyzer,
62                         CompletionService<ProjectSegment> service )
63      {
64  
65          
66          ThreadOutputMuxer muxer = null; 
67  
68          for ( TaskSegment taskSegment : currentTaskSegment )
69          {
70              Map<MavenProject, ProjectSegment> projectBuildMap = projectBuilds.selectSegment( taskSegment );
71                  try
72                  {
73                  multiThreadedProjectTaskSegmentBuild( analyzer, reactorContext, session, service, taskSegment,
74                                                        projectBuildMap, muxer );
75                      if ( reactorContext.getReactorBuildStatus().isHalted( ) )
76                      {
77                          break;
78                      }
79                  }
80                  catch ( Exception e )
81                  {
82                      break;  
83                  }
84  
85          }
86      }
87  
88      private void multiThreadedProjectTaskSegmentBuild( ConcurrencyDependencyGraph analyzer,
89                                                         ReactorContext reactorContext, MavenSession rootSession,
90                                                         CompletionService<ProjectSegment> service,
91                                                         TaskSegment taskSegment,
92                                                         Map<MavenProject, ProjectSegment> projectBuildList,
93                                                         ThreadOutputMuxer muxer )
94      {
95  
96          
97          for ( MavenProject mavenProject : analyzer.getRootSchedulableBuilds() )
98          {
99              ProjectSegment projectSegment = projectBuildList.get( mavenProject );
100             logger.debug( "Scheduling: " + projectSegment.getProject() );
101             Callable<ProjectSegment> cb =
102                 createBuildCallable( rootSession, projectSegment, reactorContext, taskSegment, muxer );
103             service.submit( cb );
104         }
105 
106         
107         for ( int i = 0; i < analyzer.getNumberOfBuilds(); i++ )
108         {
109             try
110             {
111                 ProjectSegment projectBuild = service.take().get();
112                 if ( reactorContext.getReactorBuildStatus().isHalted() )
113                 {
114                     break;
115                 }
116                 final List<MavenProject> newItemsThatCanBeBuilt =
117                     analyzer.markAsFinished( projectBuild.getProject() );
118                 for ( MavenProject mavenProject : newItemsThatCanBeBuilt )
119                 {
120                     ProjectSegment scheduledDependent = projectBuildList.get( mavenProject );
121                     logger.debug( "Scheduling: " + scheduledDependent );
122                     Callable<ProjectSegment> cb =
123                         createBuildCallable( rootSession, scheduledDependent, reactorContext, taskSegment, muxer );
124                     service.submit( cb );
125                 }
126             }
127             catch ( InterruptedException e )
128             {
129                 break;
130             }
131             catch ( ExecutionException e )
132             {
133                 break;
134             }
135         }
136 
137         
138 
139         Future<ProjectSegment> unprocessed;
140         while ( ( unprocessed = service.poll() ) != null )
141         {
142             try
143             {
144                 unprocessed.get();
145             }
146             catch ( InterruptedException e )
147             {
148                 throw new RuntimeException( e );
149             }
150             catch ( ExecutionException e )
151             {
152                 throw new RuntimeException( e );
153             }
154         }
155     }
156 
157     private Callable<ProjectSegment> createBuildCallable( final MavenSession rootSession,
158                                                           final ProjectSegment projectBuild,
159                                                           final ReactorContext reactorContext,
160                                                           final TaskSegment taskSegment, final ThreadOutputMuxer muxer )
161     {
162         return new Callable<ProjectSegment>()
163         {
164             public ProjectSegment call()
165             {
166                 
167                 lifecycleModuleBuilder.buildProject( projectBuild.getSession(), rootSession, reactorContext,
168                                                      projectBuild.getProject(), taskSegment );
169                 
170 
171                 return projectBuild;
172             }
173         };
174     }
175 }