View Javadoc
1   package org.apache.maven.project;
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.Iterator;
24  import java.util.LinkedHashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.TreeMap;
28  
29  import org.apache.maven.model.Dependency;
30  import org.apache.maven.model.Plugin;
31  import org.apache.maven.model.PluginContainer;
32  import org.apache.maven.model.PluginExecution;
33  import org.apache.maven.model.Repository;
34  import org.codehaus.plexus.util.xml.Xpp3Dom;
35  
36  /** @deprecated */
37  @Deprecated
38  public final class ModelUtils
39  {
40  
41      /**
42       * This should be the resulting ordering of plugins after merging:
43       * <p/>
44       * Given:
45       * <p/>
46       * parent: X -> A -> B -> D -> E
47       * child: Y -> A -> C -> D -> F
48       * <p/>
49       * Result:
50       * <p/>
51       * X -> Y -> A -> B -> C -> D -> E -> F
52       */
53      public static void mergePluginLists( PluginContainer childContainer, PluginContainer parentContainer,
54                                           boolean handleAsInheritance )
55      {
56          if ( ( childContainer == null ) || ( parentContainer == null ) )
57          {
58              // nothing to do.
59              return;
60          }
61  
62          List<Plugin> parentPlugins = parentContainer.getPlugins();
63  
64          if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
65          {
66              parentPlugins = new ArrayList<Plugin>( parentPlugins );
67  
68              // If we're processing this merge as an inheritance, we have to build up a list of
69              // plugins that were considered for inheritance.
70              if ( handleAsInheritance )
71              {
72                  for ( Iterator<Plugin> it = parentPlugins.iterator(); it.hasNext(); )
73                  {
74                      Plugin plugin = it.next();
75  
76                      String inherited = plugin.getInherited();
77  
78                      if ( ( inherited != null ) && !Boolean.valueOf( inherited ) )
79                      {
80                          it.remove();
81                      }
82                  }
83              }
84  
85              List<Plugin> assembledPlugins = new ArrayList<Plugin>();
86  
87              Map<String, Plugin> childPlugins = childContainer.getPluginsAsMap();
88  
89              for ( Plugin parentPlugin : parentPlugins )
90              {
91                  String parentInherited = parentPlugin.getInherited();
92  
93                  // only merge plugin definition from the parent if at least one
94                  // of these is true:
95                  // 1. we're not processing the plugins in an inheritance-based merge
96                  // 2. the parent's <inherited/> flag is not set
97                  // 3. the parent's <inherited/> flag is set to true
98                  if ( !handleAsInheritance || ( parentInherited == null )
99                      || Boolean.valueOf( parentInherited ) )
100                 {
101                     Plugin childPlugin = childPlugins.get( parentPlugin.getKey() );
102 
103                     if ( ( childPlugin != null ) && !assembledPlugins.contains( childPlugin ) )
104                     {
105                         Plugin assembledPlugin = childPlugin;
106 
107                         mergePluginDefinitions( childPlugin, parentPlugin, handleAsInheritance );
108 
109                         // fix for MNG-2221 (assembly cache was not being populated for later reference):
110                         assembledPlugins.add( assembledPlugin );
111                     }
112 
113                     // if we're processing this as an inheritance-based merge, and
114                     // the parent's <inherited/> flag is not set, then we need to
115                     // clear the inherited flag in the merge result.
116                     if ( handleAsInheritance && ( parentInherited == null ) )
117                     {
118                         parentPlugin.unsetInheritanceApplied();
119                     }
120                 }
121 
122                 // very important to use the parentPlugins List, rather than parentContainer.getPlugins()
123                 // since this list is a local one, and may have been modified during processing.
124                 List<Plugin> results =
125                     ModelUtils.orderAfterMerge( assembledPlugins, parentPlugins, childContainer.getPlugins() );
126 
127                 childContainer.setPlugins( results );
128 
129                 childContainer.flushPluginMap();
130             }
131         }
132     }
133 
134     public static List<Plugin> orderAfterMerge( List<Plugin> merged, List<Plugin> highPrioritySource,
135                                                 List<Plugin> lowPrioritySource )
136     {
137         List<Plugin> results = new ArrayList<Plugin>();
138 
139         if ( !merged.isEmpty() )
140         {
141             results.addAll( merged );
142         }
143 
144         List<Plugin> missingFromResults = new ArrayList<Plugin>();
145 
146         List<List<Plugin>> sources = new ArrayList<List<Plugin>>();
147 
148         sources.add( highPrioritySource );
149         sources.add( lowPrioritySource );
150 
151         for ( List<Plugin> source : sources )
152         {
153             for ( Plugin item : source )
154             {
155                 if ( results.contains( item ) )
156                 {
157                     if ( !missingFromResults.isEmpty() )
158                     {
159                         int idx = results.indexOf( item );
160 
161                         if ( idx < 0 )
162                         {
163                             idx = 0;
164                         }
165 
166                         results.addAll( idx, missingFromResults );
167 
168                         missingFromResults.clear();
169                     }
170                 }
171                 else
172                 {
173                     missingFromResults.add( item );
174                 }
175             }
176 
177             if ( !missingFromResults.isEmpty() )
178             {
179                 results.addAll( missingFromResults );
180 
181                 missingFromResults.clear();
182             }
183         }
184 
185         return results;
186     }
187 
188 
189     public static void mergePluginDefinitions( Plugin child, Plugin parent, boolean handleAsInheritance )
190     {
191         if ( ( child == null ) || ( parent == null ) )
192         {
193             // nothing to do.
194             return;
195         }
196 
197         if ( parent.isExtensions() )
198         {
199             child.setExtensions( true );
200         }
201 
202         if ( ( child.getVersion() == null ) && ( parent.getVersion() != null ) )
203         {
204             child.setVersion( parent.getVersion() );
205         }
206 
207         Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
208         Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
209 
210         childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
211 
212         child.setConfiguration( childConfiguration );
213 
214         child.setDependencies( mergeDependencyList( child.getDependencies(), parent.getDependencies() ) );
215 
216         // from here to the end of the method is dealing with merging of the <executions/> section.
217         String parentInherited = parent.getInherited();
218 
219         boolean parentIsInherited = ( parentInherited == null ) || Boolean.valueOf( parentInherited );
220 
221         List<PluginExecution> parentExecutions = parent.getExecutions();
222 
223         if ( ( parentExecutions != null ) && !parentExecutions.isEmpty() )
224         {
225             List<PluginExecution> mergedExecutions = new ArrayList<PluginExecution>();
226 
227             Map<String, PluginExecution> assembledExecutions = new TreeMap<String, PluginExecution>();
228 
229             Map<String, PluginExecution> childExecutions = child.getExecutionsAsMap();
230 
231             for ( PluginExecution parentExecution : parentExecutions )
232             {
233                 String inherited = parentExecution.getInherited();
234 
235                 boolean parentExecInherited =
236                     parentIsInherited && ( ( inherited == null ) || Boolean.valueOf( inherited ) );
237 
238                 if ( !handleAsInheritance || parentExecInherited )
239                 {
240                     PluginExecution assembled = parentExecution;
241 
242                     PluginExecution childExecution = childExecutions.get( parentExecution.getId() );
243 
244                     if ( childExecution != null )
245                     {
246                         mergePluginExecutionDefinitions( childExecution, parentExecution );
247 
248                         assembled = childExecution;
249                     }
250                     else if ( handleAsInheritance && ( parentInherited == null ) )
251                     {
252                         parentExecution.unsetInheritanceApplied();
253                     }
254 
255                     assembledExecutions.put( assembled.getId(), assembled );
256                     mergedExecutions.add( assembled );
257                 }
258             }
259 
260             for ( PluginExecution childExecution : child.getExecutions() )
261             {
262                 if ( !assembledExecutions.containsKey( childExecution.getId() ) )
263                 {
264                     mergedExecutions.add( childExecution );
265                 }
266             }
267 
268             child.setExecutions( mergedExecutions );
269 
270             child.flushExecutionMap();
271         }
272 
273     }
274 
275     private static void mergePluginExecutionDefinitions( PluginExecution child, PluginExecution parent )
276     {
277         if ( child.getPhase() == null )
278         {
279             child.setPhase( parent.getPhase() );
280         }
281 
282         List<String> parentGoals = parent.getGoals();
283         List<String> childGoals = child.getGoals();
284 
285         List<String> goals = new ArrayList<String>();
286 
287         if ( ( childGoals != null ) && !childGoals.isEmpty() )
288         {
289             goals.addAll( childGoals );
290         }
291 
292         if ( parentGoals != null )
293         {
294             for (  String goal : parentGoals )
295             {
296                 if ( !goals.contains( goal ) )
297                 {
298                     goals.add( goal );
299                 }
300             }
301         }
302 
303         child.setGoals( goals );
304 
305         Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
306         Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
307 
308         childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
309 
310         child.setConfiguration( childConfiguration );
311     }
312 
313     public static List<Repository> mergeRepositoryLists( List<Repository> dominant, List<Repository> recessive )
314     {
315         List<Repository> repositories = new ArrayList<Repository>();
316 
317         for ( Repository repository : dominant )
318         {
319             repositories.add( repository );
320         }
321 
322         for ( Repository repository : recessive )
323         {
324             if ( !repositories.contains( repository ) )
325             {
326                 repositories.add( repository );
327             }
328         }
329 
330         return repositories;
331     }
332 
333     public static void mergeFilterLists( List<String> childFilters, List<String> parentFilters )
334     {
335         for ( String f : parentFilters )
336         {
337             if ( !childFilters.contains( f ) )
338             {
339                 childFilters.add( f );
340             }
341         }
342     }
343 
344     private static List<Dependency> mergeDependencyList( List<Dependency> child, List<Dependency> parent )
345     {
346         Map<String, Dependency> depsMap = new LinkedHashMap<String, Dependency>();
347 
348         if ( parent != null )
349         {
350             for ( Dependency dependency : parent )
351             {
352                 depsMap.put( dependency.getManagementKey(), dependency );
353             }
354         }
355 
356         if ( child != null )
357         {
358             for ( Dependency dependency : child )
359             {
360                 depsMap.put( dependency.getManagementKey(), dependency );
361             }
362         }
363 
364         return new ArrayList<Dependency>( depsMap.values() );
365     }
366 
367 }