001package org.apache.maven.model.management;
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.Collections;
024import java.util.LinkedHashMap;
025import java.util.List;
026import java.util.Map;
027
028import org.apache.maven.model.Build;
029import org.apache.maven.model.Model;
030import org.apache.maven.model.Plugin;
031import org.apache.maven.model.PluginContainer;
032import org.apache.maven.model.PluginExecution;
033import org.apache.maven.model.PluginManagement;
034import org.apache.maven.model.building.ModelBuildingRequest;
035import org.apache.maven.model.building.ModelProblemCollector;
036import org.apache.maven.model.merge.MavenModelMerger;
037import org.codehaus.plexus.component.annotations.Component;
038
039/**
040 * Handles injection of plugin management into the model.
041 *
042 * @author Benjamin Bentmann
043 */
044@Component( role = PluginManagementInjector.class )
045public class DefaultPluginManagementInjector
046    implements PluginManagementInjector
047{
048
049    private ManagementModelMerger merger = new ManagementModelMerger();
050
051    @Override
052    public void injectManagement( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
053    {
054        merger.mergeManagedBuildPlugins( model );
055    }
056
057    protected static class ManagementModelMerger
058        extends MavenModelMerger
059    {
060
061        public void mergeManagedBuildPlugins( Model model )
062        {
063            Build build = model.getBuild();
064            if ( build != null )
065            {
066                PluginManagement pluginManagement = build.getPluginManagement();
067                if ( pluginManagement != null )
068                {
069                    mergePluginContainer_Plugins( build, pluginManagement );
070                }
071            }
072        }
073
074        private void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source )
075        {
076            List<Plugin> src = source.getPlugins();
077            if ( !src.isEmpty() )
078            {
079                List<Plugin> tgt = target.getPlugins();
080
081                Map<Object, Plugin> managedPlugins = new LinkedHashMap<>( src.size() * 2 );
082
083                Map<Object, Object> context = Collections.emptyMap();
084
085                for ( Plugin element : src )
086                {
087                    Object key = getPluginKey( element );
088                    managedPlugins.put( key, element );
089                }
090
091                for ( Plugin element : tgt )
092                {
093                    Object key = getPluginKey( element );
094                    Plugin managedPlugin = managedPlugins.get( key );
095                    if ( managedPlugin != null )
096                    {
097                        mergePlugin( element, managedPlugin, false, context );
098                    }
099                }
100            }
101        }
102
103        @Override
104        protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
105                                               Map<Object, Object> context )
106        {
107            List<PluginExecution> src = source.getExecutions();
108            if ( !src.isEmpty() )
109            {
110                List<PluginExecution> tgt = target.getExecutions();
111
112                Map<Object, PluginExecution> merged =
113                    new LinkedHashMap<>( ( src.size() + tgt.size() ) * 2 );
114
115                for ( PluginExecution element : src )
116                {
117                    Object key = getPluginExecutionKey( element );
118                    merged.put( key, element.clone() );
119                }
120
121                for ( PluginExecution element : tgt )
122                {
123                    Object key = getPluginExecutionKey( element );
124                    PluginExecution existing = merged.get( key );
125                    if ( existing != null )
126                    {
127                        mergePluginExecution( element, existing, sourceDominant, context );
128                    }
129                    merged.put( key, element );
130                }
131
132                target.setExecutions( new ArrayList<>( merged.values() ) );
133            }
134        }
135    }
136
137}