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 parentPlugins = parentContainer.getPlugins();
063    
064            if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
065            {
066                parentPlugins = new ArrayList( 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 it = parentPlugins.iterator(); it.hasNext(); )
073                    {
074                        Plugin plugin = (Plugin) it.next();
075    
076                        String inherited = plugin.getInherited();
077    
078                        if ( ( inherited != null ) && !Boolean.valueOf( inherited ).booleanValue() )
079                        {
080                            it.remove();
081                        }
082                    }
083                }
084    
085                List assembledPlugins = new ArrayList();
086    
087                Map childPlugins = childContainer.getPluginsAsMap();
088    
089                for ( Iterator it = parentPlugins.iterator(); it.hasNext(); )
090                {
091                    Plugin parentPlugin = (Plugin) it.next();
092    
093                    String parentInherited = parentPlugin.getInherited();
094    
095                    // only merge plugin definition from the parent if at least one
096                    // of these is true:
097                    // 1. we're not processing the plugins in an inheritance-based merge
098                    // 2. the parent's <inherited/> flag is not set
099                    // 3. the parent's <inherited/> flag is set to true
100                    if ( !handleAsInheritance || ( parentInherited == null )
101                        || Boolean.valueOf( parentInherited ).booleanValue() )
102                    {
103                        Plugin childPlugin = (Plugin) childPlugins.get( parentPlugin.getKey() );
104    
105                        if ( ( childPlugin != null ) && !assembledPlugins.contains( childPlugin ) )
106                        {
107                            Plugin assembledPlugin = childPlugin;
108    
109                            mergePluginDefinitions( childPlugin, parentPlugin, handleAsInheritance );
110    
111                            // fix for MNG-2221 (assembly cache was not being populated for later reference):
112                            assembledPlugins.add( assembledPlugin );
113                        }
114    
115                        // if we're processing this as an inheritance-based merge, and
116                        // the parent's <inherited/> flag is not set, then we need to
117                        // clear the inherited flag in the merge result.
118                        if ( handleAsInheritance && ( parentInherited == null ) )
119                        {
120                            parentPlugin.unsetInheritanceApplied();
121                        }
122                    }
123    
124                    // very important to use the parentPlugins List, rather than parentContainer.getPlugins()
125                    // since this list is a local one, and may have been modified during processing.
126                    List results =
127                        ModelUtils.orderAfterMerge( assembledPlugins, parentPlugins, childContainer.getPlugins() );
128    
129                    childContainer.setPlugins( results );
130    
131                    childContainer.flushPluginMap();
132                }
133            }
134        }
135    
136        public static List orderAfterMerge( List merged, List highPrioritySource, List lowPrioritySource )
137        {
138            List results = new ArrayList();
139    
140            if ( !merged.isEmpty() )
141            {
142                results.addAll( merged );
143            }
144    
145            List missingFromResults = new ArrayList();
146    
147            List sources = new ArrayList();
148    
149            sources.add( highPrioritySource );
150            sources.add( lowPrioritySource );
151    
152            for ( Iterator sourceIterator = sources.iterator(); sourceIterator.hasNext(); )
153            {
154                List source = (List) sourceIterator.next();
155    
156                for ( Iterator it = source.iterator(); it.hasNext(); )
157                {
158                    Object item = it.next();
159    
160                    if ( results.contains( item ) )
161                    {
162                        if ( !missingFromResults.isEmpty() )
163                        {
164                            int idx = results.indexOf( item );
165    
166                            if ( idx < 0 )
167                            {
168                                idx = 0;
169                            }
170    
171                            results.addAll( idx, missingFromResults );
172    
173                            missingFromResults.clear();
174                        }
175                    }
176                    else
177                    {
178                        missingFromResults.add( item );
179                    }
180                }
181    
182                if ( !missingFromResults.isEmpty() )
183                {
184                    results.addAll( missingFromResults );
185    
186                    missingFromResults.clear();
187                }
188            }
189    
190            return results;
191        }
192    
193    
194        public static void mergePluginDefinitions( Plugin child, Plugin parent, boolean handleAsInheritance )
195        {
196            if ( ( child == null ) || ( parent == null ) )
197            {
198                // nothing to do.
199                return;
200            }
201    
202            if ( parent.isExtensions() )
203            {
204                child.setExtensions( true );
205            }
206    
207            if ( ( child.getVersion() == null ) && ( parent.getVersion() != null ) )
208            {
209                child.setVersion( parent.getVersion() );
210            }
211    
212            Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
213            Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
214    
215            childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
216    
217            child.setConfiguration( childConfiguration );
218    
219            child.setDependencies( mergeDependencyList( child.getDependencies(), parent.getDependencies() ) );
220    
221            // from here to the end of the method is dealing with merging of the <executions/> section.
222            String parentInherited = parent.getInherited();
223    
224            boolean parentIsInherited = ( parentInherited == null ) || Boolean.valueOf( parentInherited ).booleanValue();
225    
226            List parentExecutions = parent.getExecutions();
227    
228            if ( ( parentExecutions != null ) && !parentExecutions.isEmpty() )
229            {
230                List mergedExecutions = new ArrayList();
231    
232                Map assembledExecutions = new TreeMap();
233    
234                Map childExecutions = child.getExecutionsAsMap();
235    
236                for ( Iterator it = parentExecutions.iterator(); it.hasNext(); )
237                {
238                    PluginExecution parentExecution = (PluginExecution) it.next();
239    
240                    String inherited = parentExecution.getInherited();
241    
242                    boolean parentExecInherited =
243                        parentIsInherited && ( ( inherited == null ) || Boolean.valueOf( inherited ).booleanValue() );
244    
245                    if ( !handleAsInheritance || parentExecInherited )
246                    {
247                        PluginExecution assembled = parentExecution;
248    
249                        PluginExecution childExecution = (PluginExecution) childExecutions.get( parentExecution.getId() );
250    
251                        if ( childExecution != null )
252                        {
253                            mergePluginExecutionDefinitions( childExecution, parentExecution );
254    
255                            assembled = childExecution;
256                        }
257                        else if ( handleAsInheritance && ( parentInherited == null ) )
258                        {
259                            parentExecution.unsetInheritanceApplied();
260                        }
261    
262                        assembledExecutions.put( assembled.getId(), assembled );
263                        mergedExecutions.add( assembled );
264                    }
265                }
266    
267                for ( Iterator it = child.getExecutions().iterator(); it.hasNext(); )
268                {
269                    PluginExecution childExecution = (PluginExecution) it.next();
270    
271                    if ( !assembledExecutions.containsKey( childExecution.getId() ) )
272                    {
273                        mergedExecutions.add( childExecution );
274                    }
275                }
276    
277                child.setExecutions( mergedExecutions );
278    
279                child.flushExecutionMap();
280            }
281    
282        }
283    
284        private static void mergePluginExecutionDefinitions( PluginExecution child, PluginExecution parent )
285        {
286            if ( child.getPhase() == null )
287            {
288                child.setPhase( parent.getPhase() );
289            }
290    
291            List parentGoals = parent.getGoals();
292            List childGoals = child.getGoals();
293    
294            List goals = new ArrayList();
295    
296            if ( ( childGoals != null ) && !childGoals.isEmpty() )
297            {
298                goals.addAll( childGoals );
299            }
300    
301            if ( parentGoals != null )
302            {
303                for ( Iterator goalIterator = parentGoals.iterator(); goalIterator.hasNext(); )
304                {
305                    String goal = (String) goalIterator.next();
306    
307                    if ( !goals.contains( goal ) )
308                    {
309                        goals.add( goal );
310                    }
311                }
312            }
313    
314            child.setGoals( goals );
315    
316            Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
317            Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
318    
319            childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
320    
321            child.setConfiguration( childConfiguration );
322        }
323    
324        public static List mergeRepositoryLists( List dominant, List recessive )
325        {
326            List repositories = new ArrayList();
327    
328            for ( Iterator it = dominant.iterator(); it.hasNext(); )
329            {
330                Repository repository = (Repository) it.next();
331    
332                repositories.add( repository );
333            }
334    
335            for ( Iterator it = recessive.iterator(); it.hasNext(); )
336            {
337                Repository repository = (Repository) it.next();
338    
339                if ( !repositories.contains( repository ) )
340                {
341                    repositories.add( repository );
342                }
343            }
344    
345            return repositories;
346        }
347    
348        public static void mergeFilterLists( List childFilters, List parentFilters )
349        {
350            for ( Iterator i = parentFilters.iterator(); i.hasNext(); )
351            {
352                String f = (String) i.next();
353                if ( !childFilters.contains( f ) )
354                {
355                    childFilters.add( f );
356                }
357            }
358        }
359    
360        private static List mergeDependencyList( List child, List parent )
361        {
362            Map depsMap = new LinkedHashMap();
363    
364            if ( parent != null )
365            {
366                for ( Iterator it = parent.iterator(); it.hasNext(); )
367                {
368                    Dependency dependency = (Dependency) it.next();
369                    depsMap.put( dependency.getManagementKey(), dependency );
370                }
371            }
372    
373            if ( child != null )
374            {
375                for ( Iterator it = child.iterator(); it.hasNext(); )
376                {
377                    Dependency dependency = (Dependency) it.next();
378                    depsMap.put( dependency.getManagementKey(), dependency );
379                }
380            }
381    
382            return new ArrayList( depsMap.values() );
383        }
384    
385    }