View Javadoc
1   package com.soebes.maven.extensions.deployer;
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 java.io.IOException;
23  import java.util.List;
24  
25  import javax.inject.Inject;
26  import javax.inject.Named;
27  import javax.inject.Singleton;
28  
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.eventspy.AbstractEventSpy;
31  import org.apache.maven.eventspy.EventSpy;
32  import org.apache.maven.execution.ExecutionEvent;
33  import org.apache.maven.execution.ExecutionEvent.Type;
34  import org.apache.maven.model.Plugin;
35  import org.apache.maven.model.PluginExecution;
36  import org.apache.maven.project.MavenProject;
37  import org.apache.maven.project.ProjectBuildingRequest;
38  import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
39  import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
40  import org.apache.maven.shared.transfer.project.NoFileAssignedException;
41  import org.apache.maven.shared.transfer.project.deploy.ProjectDeployer;
42  import org.apache.maven.shared.transfer.project.deploy.ProjectDeployerRequest;
43  import org.apache.maven.shared.transfer.project.install.ProjectInstaller;
44  import org.apache.maven.shared.transfer.project.install.ProjectInstallerRequest;
45  import org.slf4j.Logger;
46  import org.slf4j.LoggerFactory;
47  
48  /**
49   * This {@link EventSpy} implementation will handle the events of SessionEnd to identify the correct point in time to
50   * deploy all artifacts of the project into the given remote repository. This will also work if you are using plugins
51   * which define their own lifecycle.
52   * 
53   * @author Karl Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a>
54   */
55  @Singleton
56  @Named
57  public class MavenDeployer
58      extends AbstractEventSpy
59  {
60      private final Logger LOGGER = LoggerFactory.getLogger( getClass() );
61  
62      @Inject
63      private ProjectDeployer projectDeployer;
64  
65      @Inject
66      private ProjectInstaller projectInstaller;
67  
68      private boolean failure;
69  
70      public MavenDeployer()
71      {
72          this.failure = false;
73      }
74  
75      @Override
76      public void init( Context context )
77          throws Exception
78      {
79          super.init( context );
80          logDeployerVersion();
81      }
82  
83      private void logDeployerVersion()
84      {
85          LOGGER.info( "" );
86          LOGGER.info( " --- maven-deployer-extension:{} --- ", MavenDeployerExtensionVersion.getVersion() );
87      }
88  
89      @Override
90      public void onEvent( Object event )
91          throws Exception
92      {
93          try
94          {
95              // We are only interested in the ExecutionEvent.
96              if ( event instanceof ExecutionEvent )
97              {
98                  executionEventHandler( (ExecutionEvent) event );
99              }
100         }
101         catch ( Exception e )
102         {
103             LOGGER.error( "Exception", e );
104         }
105     }
106 
107     @Override
108     public void close()
109     {
110         // TODO: Check if we need to do something here?
111         LOGGER.debug( "Maven Deployer Extension." );
112     }
113 
114     private boolean goalsContain( ExecutionEvent executionEvent, String goal )
115     {
116         return executionEvent.getSession().getGoals().contains( goal );
117     }
118 
119     private void executionEventHandler( ExecutionEvent executionEvent )
120     {
121         Type type = executionEvent.getType();
122         switch ( type )
123         {
124             case ProjectDiscoveryStarted:
125                 break;
126             case SessionStarted:
127                 sessionStarted( executionEvent );
128                 break;
129             case SessionEnded:
130                 if ( this.failure )
131                 {
132                     LOGGER.warn( "The Maven Deployer Extension will not be called based on previous errors." );
133                 }
134                 else
135                 {
136                     sessionEnded( executionEvent );
137                 }
138                 break;
139             case ForkFailed:
140             case ForkedProjectFailed:
141             case MojoFailed:
142             case ProjectFailed:
143                 // TODO: Can we find out more about the cause of failure?
144                 LOGGER.debug( "Some failure has occured." );
145                 this.failure = true;
146                 break;
147 
148             case ForkStarted:
149             case ForkSucceeded:
150             case ForkedProjectStarted:
151             case ForkedProjectSucceeded:
152             case MojoStarted:
153             case MojoSucceeded:
154             case MojoSkipped:
155             case ProjectStarted:
156             case ProjectSucceeded:
157             case ProjectSkipped:
158                 break;
159 
160             default:
161                 LOGGER.error( "executionEventHandler: {}", type );
162                 break;
163         }
164 
165     }
166 
167     /**
168      * This will start to deploy all artifacts into remote repository if the goal {@code deploy} has been called.
169      * 
170      * @param executionEvent
171      */
172     private void sessionEnded( ExecutionEvent executionEvent )
173     {
174         logDeployerVersion();
175 
176         LOGGER.info( "" );
177         LOGGER.info( "Installing artifacts..." );
178         installProjects( executionEvent );
179 
180         if ( goalsContain( executionEvent, "deploy" ) )
181         {
182             LOGGER.info( "" );
183             LOGGER.info( "Deploying artifacts..." );
184             deployProjects( executionEvent );
185         }
186         else
187         {
188             LOGGER.info( " Deployment has been skipped." );
189         }
190     }
191 
192     private void sessionStarted( ExecutionEvent executionEvent )
193     {
194         if ( containsLifeCycleDeployPluginGoal( executionEvent, "deploy" ) )
195         {
196             removeDeployPluginFromLifeCycle( executionEvent );
197         }
198 
199         if ( containsLifeCycleInstallPluginGoal( executionEvent, "install" ) )
200         {
201             removeInstallPluginFromLifeCycle( executionEvent );
202         }
203     }
204 
205     private boolean containsLifeCycleDeployPluginGoal( ExecutionEvent executionEvent, String goal )
206     {
207         return containsLifeCyclePluginGoals( executionEvent, "org.apache.maven.plugins", "maven-deploy-plugin", goal );
208     }
209 
210     private boolean containsLifeCycleInstallPluginGoal( ExecutionEvent executionEvent, String goal )
211     {
212         return containsLifeCyclePluginGoals( executionEvent, "org.apache.maven.plugins", "maven-install-plugin", goal );
213     }
214 
215     private void removeDeployPluginFromLifeCycle( ExecutionEvent executionEvent )
216     {
217         removePluginFromLifeCycle( executionEvent, "org.apache.maven.plugins", "maven-deploy-plugin", "deploy" );
218     }
219 
220     private void removeInstallPluginFromLifeCycle( ExecutionEvent executionEvent )
221     {
222         removePluginFromLifeCycle( executionEvent, "org.apache.maven.plugins", "maven-install-plugin", "install" );
223     }
224 
225     private boolean containsLifeCyclePluginGoals( ExecutionEvent executionEvent, String groupId, String artifactId,
226                                                   String goal )
227     {
228 
229         boolean result = false;
230         List<MavenProject> sortedProjects = executionEvent.getSession().getProjectDependencyGraph().getSortedProjects();
231         for ( MavenProject mavenProject : sortedProjects )
232         {
233             List<Plugin> buildPlugins = mavenProject.getBuildPlugins();
234             for ( Plugin plugin : buildPlugins )
235             {
236                 if ( groupId.equals( plugin.getGroupId() ) && artifactId.equals( plugin.getArtifactId() ) )
237                 {
238                     List<PluginExecution> executions = plugin.getExecutions();
239                     for ( PluginExecution pluginExecution : executions )
240                     {
241                         if ( pluginExecution.getGoals().contains( goal ) )
242                         {
243                             result = true;
244                         }
245                     }
246                 }
247             }
248         }
249         return result;
250     }
251 
252     private void removePluginFromLifeCycle( ExecutionEvent executionEvent, String groupId, String artifactId,
253                                             String goal )
254     {
255 
256         boolean removed = false;
257 
258         List<MavenProject> sortedProjects = executionEvent.getSession().getProjectDependencyGraph().getSortedProjects();
259         for ( MavenProject mavenProject : sortedProjects )
260         {
261             List<Plugin> buildPlugins = mavenProject.getBuildPlugins();
262             for ( Plugin plugin : buildPlugins )
263             {
264                 LOGGER.debug( "Plugin: " + plugin.getId() );
265                 List<PluginExecution> printExecutions = plugin.getExecutions();
266                 for ( PluginExecution pluginExecution : printExecutions )
267                 {
268                     LOGGER.debug( "  -> " + pluginExecution.getGoals() );
269                 }
270 
271                 if ( groupId.equals( plugin.getGroupId() ) && artifactId.equals( plugin.getArtifactId() ) )
272                 {
273                     if ( !removed )
274                     {
275                         LOGGER.warn( groupId + ":" + artifactId + ":" + goal + " has been deactivated." );
276                     }
277                     List<PluginExecution> executions = plugin.getExecutions();
278                     for ( PluginExecution pluginExecution : executions )
279                     {
280                         pluginExecution.removeGoal( goal );
281                         removed = true;
282                     }
283                 }
284             }
285         }
286     }
287 
288     private void deployProjects( ExecutionEvent executionEvent )
289     {
290         // Assumption is to have the distributionManagement in the top level
291         // pom file located.
292         ArtifactRepository repository =
293             executionEvent.getSession().getTopLevelProject().getDistributionManagementArtifactRepository();
294 
295         List<MavenProject> sortedProjects = executionEvent.getSession().getProjectDependencyGraph().getSortedProjects();
296         for ( MavenProject mavenProject : sortedProjects )
297         {
298             ProjectDeployerRequest deployRequest =
299                 new ProjectDeployerRequest().setProject( mavenProject );
300 
301             deployProject( executionEvent.getSession().getProjectBuildingRequest(), deployRequest, repository );
302         }
303     }
304 
305     private void installProjects( ExecutionEvent exec )
306     {
307         List<MavenProject> sortedProjects = exec.getSession().getProjectDependencyGraph().getSortedProjects();
308         for ( MavenProject mavenProject : sortedProjects )
309         {
310             ProjectInstallerRequest pir =
311                 new ProjectInstallerRequest().setProject( mavenProject );
312 
313             installProject( exec.getSession().getProjectBuildingRequest(), pir );
314         }
315 
316     }
317 
318     private void deployProject( ProjectBuildingRequest projectBuildingRequest, ProjectDeployerRequest deployRequest,
319                                 ArtifactRepository repository )
320     {
321 
322         try
323         {
324             projectDeployer.deploy( projectBuildingRequest, deployRequest, repository );
325         }
326         catch ( IllegalArgumentException e )
327         {
328             LOGGER.error( "IllegalArgumentException", e );
329         }
330         catch ( NoFileAssignedException e )
331         {
332             LOGGER.error( "NoFileAssignedException", e );
333         }
334         catch ( ArtifactDeployerException e )
335         {
336             LOGGER.error( "ArtifactDeployerException", e );
337         }
338 
339     }
340 
341     private void installProject( ProjectBuildingRequest pbr, ProjectInstallerRequest pir )
342     {
343         try
344         {
345             projectInstaller.install( pbr, pir );
346         }
347         catch ( IOException e )
348         {
349             LOGGER.error( "IOException", e );
350         }
351         catch ( ArtifactInstallerException e )
352         {
353             LOGGER.error( "ArtifactInstallerException", e );
354         }
355         catch ( NoFileAssignedException e )
356         {
357             LOGGER.error( "NoFileAssignedException", e );
358         }
359     }
360 
361 }