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