View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.management;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.LinkedHashMap;
24  import java.util.List;
25  import java.util.Map;
26  import javax.inject.Named;
27  import javax.inject.Singleton;
28  import org.apache.maven.api.model.Build;
29  import org.apache.maven.api.model.Model;
30  import org.apache.maven.api.model.Plugin;
31  import org.apache.maven.api.model.PluginContainer;
32  import org.apache.maven.api.model.PluginExecution;
33  import org.apache.maven.api.model.PluginManagement;
34  import org.apache.maven.model.building.ModelBuildingRequest;
35  import org.apache.maven.model.building.ModelProblemCollector;
36  import org.apache.maven.model.merge.MavenModelMerger;
37  
38  /**
39   * Handles injection of plugin management into the model.
40   *
41   * @author Benjamin Bentmann
42   */
43  @SuppressWarnings({"checkstyle:methodname"})
44  @Named
45  @Singleton
46  public class DefaultPluginManagementInjector implements PluginManagementInjector {
47  
48      private ManagementModelMerger merger = new ManagementModelMerger();
49  
50      @Override
51      public void injectManagement(
52              org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
53          model.update(merger.mergeManagedBuildPlugins(model.getDelegate()));
54      }
55  
56      /**
57       * ManagementModelMerger
58       */
59      protected static class ManagementModelMerger extends MavenModelMerger {
60  
61          public Model mergeManagedBuildPlugins(Model model) {
62              Build build = model.getBuild();
63              if (build != null) {
64                  PluginManagement pluginManagement = build.getPluginManagement();
65                  if (pluginManagement != null) {
66                      return model.withBuild(mergePluginContainerPlugins(build, pluginManagement));
67                  }
68              }
69              return model;
70          }
71  
72          private Build mergePluginContainerPlugins(Build target, PluginContainer source) {
73              List<Plugin> src = source.getPlugins();
74              if (!src.isEmpty()) {
75                  Map<Object, Plugin> managedPlugins = new LinkedHashMap<>(src.size() * 2);
76  
77                  Map<Object, Object> context = Collections.emptyMap();
78  
79                  for (Plugin element : src) {
80                      Object key = getPluginKey().apply(element);
81                      managedPlugins.put(key, element);
82                  }
83  
84                  List<Plugin> newPlugins = new ArrayList<>();
85                  for (Plugin element : target.getPlugins()) {
86                      Object key = getPluginKey().apply(element);
87                      Plugin managedPlugin = managedPlugins.get(key);
88                      if (managedPlugin != null) {
89                          element = mergePlugin(element, managedPlugin, false, context);
90                      }
91                      newPlugins.add(element);
92                  }
93                  return target.withPlugins(newPlugins);
94              }
95              return target;
96          }
97  
98          @Override
99          protected void mergePlugin_Executions(
100                 Plugin.Builder builder,
101                 Plugin target,
102                 Plugin source,
103                 boolean sourceDominant,
104                 Map<Object, Object> context) {
105             List<PluginExecution> src = source.getExecutions();
106             if (!src.isEmpty()) {
107                 List<PluginExecution> tgt = target.getExecutions();
108 
109                 Map<Object, PluginExecution> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
110 
111                 for (PluginExecution element : src) {
112                     Object key = getPluginExecutionKey().apply(element);
113                     merged.put(key, element);
114                 }
115 
116                 for (PluginExecution element : tgt) {
117                     Object key = getPluginExecutionKey().apply(element);
118                     PluginExecution existing = merged.get(key);
119                     if (existing != null) {
120                         element = mergePluginExecution(element, existing, sourceDominant, context);
121                     }
122                     merged.put(key, element);
123                 }
124 
125                 builder.executions(merged.values());
126             }
127         }
128     }
129 }