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