View Javadoc
1   package org.apache.maven.model.profile;
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.util.ArrayList;
23  import java.util.Collections;
24  import java.util.LinkedHashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.maven.model.Build;
29  import org.apache.maven.model.BuildBase;
30  import org.apache.maven.model.Model;
31  import org.apache.maven.model.ModelBase;
32  import org.apache.maven.model.Plugin;
33  import org.apache.maven.model.PluginContainer;
34  import org.apache.maven.model.PluginExecution;
35  import org.apache.maven.model.Profile;
36  import org.apache.maven.model.ReportPlugin;
37  import org.apache.maven.model.ReportSet;
38  import org.apache.maven.model.Reporting;
39  import org.apache.maven.model.building.ModelBuildingRequest;
40  import org.apache.maven.model.building.ModelProblemCollector;
41  import org.apache.maven.model.merge.MavenModelMerger;
42  import org.codehaus.plexus.component.annotations.Component;
43  
44  /**
45   * Handles profile injection into the model.
46   *
47   * @author Benjamin Bentmann
48   */
49  @Component( role = ProfileInjector.class )
50  @SuppressWarnings( { "checkstyle:methodname" } )
51  public class DefaultProfileInjector
52      implements ProfileInjector
53  {
54  
55      private ProfileModelMerger merger = new ProfileModelMerger();
56  
57      @Override
58      public void injectProfile( Model model, Profile profile, ModelBuildingRequest request,
59                                 ModelProblemCollector problems )
60      {
61          if ( profile != null )
62          {
63              merger.mergeModelBase( model, profile );
64  
65              if ( profile.getBuild() != null )
66              {
67                  if ( model.getBuild() == null )
68                  {
69                      model.setBuild( new Build() );
70                  }
71                  merger.mergeBuildBase( model.getBuild(), profile.getBuild() );
72              }
73          }
74      }
75  
76      /**
77       * ProfileModelMerger
78       */
79      protected static class ProfileModelMerger
80          extends MavenModelMerger
81      {
82  
83          public void mergeModelBase( ModelBase target, ModelBase source )
84          {
85              mergeModelBase( target, source, true, Collections.emptyMap() );
86          }
87  
88          public void mergeBuildBase( BuildBase target, BuildBase source )
89          {
90              mergeBuildBase( target, source, true, Collections.emptyMap() );
91          }
92  
93          @Override
94          protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
95                                                       boolean sourceDominant, Map<Object, Object> context )
96          {
97              List<Plugin> src = source.getPlugins();
98              if ( !src.isEmpty() )
99              {
100                 List<Plugin> tgt = target.getPlugins();
101                 Map<Object, Plugin> master = new LinkedHashMap<>( tgt.size() * 2 );
102 
103                 for ( Plugin element : tgt )
104                 {
105                     Object key = getPluginKey( element );
106                     master.put( key, element );
107                 }
108 
109                 Map<Object, List<Plugin>> predecessors = new LinkedHashMap<>();
110                 List<Plugin> pending = new ArrayList<>();
111                 for ( Plugin element : src )
112                 {
113                     Object key = getPluginKey( element );
114                     Plugin existing = master.get( key );
115                     if ( existing != null )
116                     {
117                         mergePlugin( existing, element, sourceDominant, context );
118 
119                         if ( !pending.isEmpty() )
120                         {
121                             predecessors.put( key, pending );
122                             pending = new ArrayList<>();
123                         }
124                     }
125                     else
126                     {
127                         pending.add( element );
128                     }
129                 }
130 
131                 List<Plugin> result = new ArrayList<>( src.size() + tgt.size() );
132                 for ( Map.Entry<Object, Plugin> entry : master.entrySet() )
133                 {
134                     List<Plugin> pre = predecessors.get( entry.getKey() );
135                     if ( pre != null )
136                     {
137                         result.addAll( pre );
138                     }
139                     result.add( entry.getValue() );
140                 }
141                 result.addAll( pending );
142 
143                 target.setPlugins( result );
144             }
145         }
146 
147         @Override
148         protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
149                                                Map<Object, Object> context )
150         {
151             List<PluginExecution> src = source.getExecutions();
152             if ( !src.isEmpty() )
153             {
154                 List<PluginExecution> tgt = target.getExecutions();
155                 Map<Object, PluginExecution> merged =
156                     new LinkedHashMap<>( ( src.size() + tgt.size() ) * 2 );
157 
158                 for ( PluginExecution element : tgt )
159                 {
160                     Object key = getPluginExecutionKey( element );
161                     merged.put( key, element );
162                 }
163 
164                 for ( PluginExecution element : src )
165                 {
166                     Object key = getPluginExecutionKey( element );
167                     PluginExecution existing = merged.get( key );
168                     if ( existing != null )
169                     {
170                         mergePluginExecution( existing, element, sourceDominant, context );
171                     }
172                     else
173                     {
174                         merged.put( key, element );
175                     }
176                 }
177 
178                 target.setExecutions( new ArrayList<>( merged.values() ) );
179             }
180         }
181 
182         @Override
183         protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
184                                                Map<Object, Object> context )
185         {
186             List<ReportPlugin> src = source.getPlugins();
187             if ( !src.isEmpty() )
188             {
189                 List<ReportPlugin> tgt = target.getPlugins();
190                 Map<Object, ReportPlugin> merged =
191                     new LinkedHashMap<>( ( src.size() + tgt.size() ) * 2 );
192 
193                 for ( ReportPlugin element : tgt )
194                 {
195                     Object key = getReportPluginKey( element );
196                     merged.put( key, element );
197                 }
198 
199                 for ( ReportPlugin element : src )
200                 {
201                     Object key = getReportPluginKey( element );
202                     ReportPlugin existing = merged.get( key );
203                     if ( existing == null )
204                     {
205                         merged.put( key, element );
206                     }
207                     else
208                     {
209                         mergeReportPlugin( existing, element, sourceDominant, context );
210                     }
211                 }
212 
213                 target.setPlugins( new ArrayList<>( merged.values() ) );
214             }
215         }
216 
217         @Override
218         protected void mergeReportPlugin_ReportSets( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
219                                                      Map<Object, Object> context )
220         {
221             List<ReportSet> src = source.getReportSets();
222             if ( !src.isEmpty() )
223             {
224                 List<ReportSet> tgt = target.getReportSets();
225                 Map<Object, ReportSet> merged = new LinkedHashMap<>( ( src.size() + tgt.size() ) * 2 );
226 
227                 for ( ReportSet element : tgt )
228                 {
229                     Object key = getReportSetKey( element );
230                     merged.put( key, element );
231                 }
232 
233                 for ( ReportSet element : src )
234                 {
235                     Object key = getReportSetKey( element );
236                     ReportSet existing = merged.get( key );
237                     if ( existing != null )
238                     {
239                         mergeReportSet( existing, element, sourceDominant, context );
240                     }
241                     else
242                     {
243                         merged.put( key, element );
244                     }
245                 }
246 
247                 target.setReportSets( new ArrayList<>( merged.values() ) );
248             }
249         }
250 
251     }
252 
253 }