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    public void injectManagement( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
052    {
053        merger.mergeManagedBuildPlugins( model );
054    }
055
056    protected static class ManagementModelMerger
057        extends MavenModelMerger
058    {
059
060        public void mergeManagedBuildPlugins( Model model )
061        {
062            Build build = model.getBuild();
063            if ( build != null )
064            {
065                PluginManagement pluginManagement = build.getPluginManagement();
066                if ( pluginManagement != null )
067                {
068                    mergePluginContainer_Plugins( build, pluginManagement );
069                }
070            }
071        }
072
073        private void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source )
074        {
075            List<Plugin> src = source.getPlugins();
076            if ( !src.isEmpty() )
077            {
078                List<Plugin> tgt = target.getPlugins();
079
080                Map<Object, Plugin> managedPlugins = new LinkedHashMap<Object, Plugin>( src.size() * 2 );
081
082                Map<Object, Object> context = Collections.emptyMap();
083
084                for ( Plugin element : src )
085                {
086                    Object key = getPluginKey( element );
087                    managedPlugins.put( key, element );
088                }
089
090                for ( Plugin element : tgt )
091                {
092                    Object key = getPluginKey( element );
093                    Plugin managedPlugin = managedPlugins.get( key );
094                    if ( managedPlugin != null )
095                    {
096                        mergePlugin( element, managedPlugin, false, context );
097                    }
098                }
099            }
100        }
101
102        @Override
103        protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
104                                               Map<Object, Object> context )
105        {
106            List<PluginExecution> src = source.getExecutions();
107            if ( !src.isEmpty() )
108            {
109                List<PluginExecution> tgt = target.getExecutions();
110
111                Map<Object, PluginExecution> merged =
112                    new LinkedHashMap<Object, PluginExecution>( ( src.size() + tgt.size() ) * 2 );
113
114                for ( PluginExecution element : src )
115                {
116                    Object key = getPluginExecutionKey( element );
117                    merged.put( key, element.clone() );
118                }
119
120                for ( PluginExecution element : tgt )
121                {
122                    Object key = getPluginExecutionKey( element );
123                    PluginExecution existing = merged.get( key );
124                    if ( existing != null )
125                    {
126                        mergePluginExecution( element, existing, sourceDominant, context );
127                    }
128                    merged.put( key, element );
129                }
130
131                target.setExecutions( new ArrayList<PluginExecution>( merged.values() ) );
132            }
133        }
134    }
135
136}