001 package org.apache.maven.project;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.ArrayList;
023 import java.util.Iterator;
024 import java.util.LinkedHashMap;
025 import java.util.List;
026 import java.util.Map;
027 import java.util.TreeMap;
028
029 import org.apache.maven.model.Dependency;
030 import org.apache.maven.model.Plugin;
031 import org.apache.maven.model.PluginContainer;
032 import org.apache.maven.model.PluginExecution;
033 import org.apache.maven.model.Repository;
034 import org.codehaus.plexus.util.xml.Xpp3Dom;
035
036 /** @deprecated */
037 @Deprecated
038 public final class ModelUtils
039 {
040
041 /**
042 * This should be the resulting ordering of plugins after merging:
043 * <p/>
044 * Given:
045 * <p/>
046 * parent: X -> A -> B -> D -> E
047 * child: Y -> A -> C -> D -> F
048 * <p/>
049 * Result:
050 * <p/>
051 * X -> Y -> A -> B -> C -> D -> E -> F
052 */
053 public static void mergePluginLists( PluginContainer childContainer, PluginContainer parentContainer,
054 boolean handleAsInheritance )
055 {
056 if ( ( childContainer == null ) || ( parentContainer == null ) )
057 {
058 // nothing to do.
059 return;
060 }
061
062 List<Plugin> parentPlugins = parentContainer.getPlugins();
063
064 if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
065 {
066 parentPlugins = new ArrayList<Plugin>( parentPlugins );
067
068 // If we're processing this merge as an inheritance, we have to build up a list of
069 // plugins that were considered for inheritance.
070 if ( handleAsInheritance )
071 {
072 for ( Iterator<Plugin> it = parentPlugins.iterator(); it.hasNext(); )
073 {
074 Plugin plugin = it.next();
075
076 String inherited = plugin.getInherited();
077
078 if ( ( inherited != null ) && !Boolean.valueOf( inherited ) )
079 {
080 it.remove();
081 }
082 }
083 }
084
085 List<Plugin> assembledPlugins = new ArrayList<Plugin>();
086
087 Map<String, Plugin> childPlugins = childContainer.getPluginsAsMap();
088
089 for ( Plugin parentPlugin : parentPlugins )
090 {
091 String parentInherited = parentPlugin.getInherited();
092
093 // only merge plugin definition from the parent if at least one
094 // of these is true:
095 // 1. we're not processing the plugins in an inheritance-based merge
096 // 2. the parent's <inherited/> flag is not set
097 // 3. the parent's <inherited/> flag is set to true
098 if ( !handleAsInheritance || ( parentInherited == null )
099 || Boolean.valueOf( parentInherited ) )
100 {
101 Plugin childPlugin = (Plugin) 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 }