001package org.apache.maven.lifecycle.internal; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.ArrayList; 023import java.util.LinkedHashMap; 024import java.util.List; 025import java.util.Map; 026import java.util.TreeMap; 027 028import org.apache.maven.execution.MavenSession; 029import org.apache.maven.lifecycle.Lifecycle; 030import org.apache.maven.lifecycle.LifecycleMappingDelegate; 031import org.apache.maven.model.Plugin; 032import org.apache.maven.model.PluginExecution; 033import org.apache.maven.plugin.BuildPluginManager; 034import org.apache.maven.plugin.InvalidPluginDescriptorException; 035import org.apache.maven.plugin.MojoExecution; 036import org.apache.maven.plugin.MojoNotFoundException; 037import org.apache.maven.plugin.PluginDescriptorParsingException; 038import org.apache.maven.plugin.PluginNotFoundException; 039import org.apache.maven.plugin.PluginResolutionException; 040import org.apache.maven.plugin.descriptor.MojoDescriptor; 041import org.apache.maven.project.MavenProject; 042import org.codehaus.plexus.component.annotations.Component; 043import org.codehaus.plexus.component.annotations.Requirement; 044 045@Component( role = LifecycleMappingDelegate.class, hint = DefaultLifecycleMappingDelegate.HINT ) 046public class DefaultLifecycleMappingDelegate 047 implements LifecycleMappingDelegate 048{ 049 public static final String HINT = "default"; 050 051 @Requirement 052 private BuildPluginManager pluginManager; 053 054 public Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project, 055 Lifecycle lifecycle, String lifecyclePhase ) 056 throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, 057 MojoNotFoundException, InvalidPluginDescriptorException 058 { 059 /* 060 * Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller 061 * is interested in, i.e. all phases up to and including the specified phase. 062 */ 063 064 Map<String, Map<Integer, List<MojoExecution>>> mappings = 065 new LinkedHashMap<>(); 066 067 for ( String phase : lifecycle.getPhases() ) 068 { 069 Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<>(); 070 071 mappings.put( phase, phaseBindings ); 072 073 if ( phase.equals( lifecyclePhase ) ) 074 { 075 break; 076 } 077 } 078 079 /* 080 * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of 081 * the project already contains the plugin executions induced by the project's packaging type. Remember, all 082 * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not 083 * interested in any of the executions bound to it. 084 */ 085 086 for ( Plugin plugin : project.getBuild().getPlugins() ) 087 { 088 for ( PluginExecution execution : plugin.getExecutions() ) 089 { 090 // if the phase is specified then I don't have to go fetch the plugin yet and pull it down 091 // to examine the phase it is associated to. 092 if ( execution.getPhase() != null ) 093 { 094 Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( execution.getPhase() ); 095 if ( phaseBindings != null ) 096 { 097 for ( String goal : execution.getGoals() ) 098 { 099 MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() ); 100 mojoExecution.setLifecyclePhase( execution.getPhase() ); 101 addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() ); 102 } 103 } 104 } 105 // if not then i need to grab the mojo descriptor and look at the phase that is specified 106 else 107 { 108 for ( String goal : execution.getGoals() ) 109 { 110 MojoDescriptor mojoDescriptor = 111 pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(), 112 session.getRepositorySession() ); 113 114 Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( mojoDescriptor.getPhase() ); 115 if ( phaseBindings != null ) 116 { 117 MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() ); 118 mojoExecution.setLifecyclePhase( mojoDescriptor.getPhase() ); 119 addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() ); 120 } 121 } 122 } 123 } 124 } 125 126 Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<>(); 127 128 for ( Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet() ) 129 { 130 List<MojoExecution> mojoExecutions = new ArrayList<>(); 131 132 for ( List<MojoExecution> executions : entry.getValue().values() ) 133 { 134 mojoExecutions.addAll( executions ); 135 } 136 137 lifecycleMappings.put( entry.getKey(), mojoExecutions ); 138 } 139 140 return lifecycleMappings; 141 142 } 143 144 private void addMojoExecution( Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution, 145 int priority ) 146 { 147 List<MojoExecution> mojoExecutions = phaseBindings.get( priority ); 148 149 if ( mojoExecutions == null ) 150 { 151 mojoExecutions = new ArrayList<>(); 152 phaseBindings.put( priority, mojoExecutions ); 153 } 154 155 mojoExecutions.add( mojoExecution ); 156 } 157 158}