View Javadoc

1   package org.apache.maven.lifecycle.internal;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * Builds the full lifecycle in weave-mode (phase by phase as opposed to project-by-project)
37   * 
38   * @since 3.0
39   * @author Kristian Rosenvold
40   *         Builds one or more lifecycles for a full module
41   *         <p/>
42   *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
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      public LifecycleThreadedBuilder()
56      {
57      }
58  
59      public void build( MavenSession session, ReactorContext reactorContext, ProjectBuildList projectBuilds,
60                         List<TaskSegment> currentTaskSegment, ConcurrencyDependencyGraph analyzer,
61                         CompletionService<ProjectSegment> service )
62      {
63  
64          // Currently disabled
65          ThreadOutputMuxer muxer = null; // new ThreadOutputMuxer( analyzer.getProjectBuilds(), System.out );
66  
67          for ( TaskSegment taskSegment : currentTaskSegment )
68          {
69              Map<MavenProject, ProjectSegment> projectBuildMap = projectBuilds.selectSegment( taskSegment );
70              try
71              {
72                  multiThreadedProjectTaskSegmentBuild( analyzer, reactorContext, session, service, taskSegment,
73                                                        projectBuildMap, muxer );
74                  if ( reactorContext.getReactorBuildStatus().isHalted() )
75                  {
76                      break;
77                  }
78              }
79              catch ( Exception e )
80              {
81                  session.getResult().addException( e );
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          // schedule independent projects
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         // for each finished project
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                 rootSession.getResult().addException( e );
130                 break;
131             }
132             catch ( ExecutionException e )
133             {
134                 rootSession.getResult().addException( e );
135                 break;
136             }
137         }
138 
139         // cancel outstanding builds (if any)  - this can happen if an exception is thrown in above block
140 
141         Future<ProjectSegment> unprocessed;
142         while ( ( unprocessed = service.poll() ) != null )
143         {
144             try
145             {
146                 unprocessed.get();
147             }
148             catch ( InterruptedException e )
149             {
150                 throw new RuntimeException( e );
151             }
152             catch ( ExecutionException e )
153             {
154                 throw new RuntimeException( e );
155             }
156         }
157     }
158 
159     private Callable<ProjectSegment> createBuildCallable( final MavenSession rootSession,
160                                                           final ProjectSegment projectBuild,
161                                                           final ReactorContext reactorContext,
162                                                           final TaskSegment taskSegment, final ThreadOutputMuxer muxer )
163     {
164         return new Callable<ProjectSegment>()
165         {
166             public ProjectSegment call()
167             {
168                 // muxer.associateThreadWithProjectSegment( projectBuild );
169                 lifecycleModuleBuilder.buildProject( projectBuild.getSession(), rootSession, reactorContext,
170                                                      projectBuild.getProject(), taskSegment );
171                 // muxer.setThisModuleComplete( projectBuild );
172 
173                 return projectBuild;
174             }
175         };
176     }
177 }