All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.project.injection.DefaultProfileInjector Maven / Gradle / Ivy

Go to download

This library is used to not only read Maven project object model files, but to assemble inheritence and to retrieve remote models as required.

There is a newer version: 3.0-alpha-2
Show newest version
package org.apache.maven.project.injection;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.maven.model.Build;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.ConfigurationContainer;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginContainer;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.Profile;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.project.ModelUtils;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Inject profile data into a Model, using the profile as the dominant data source, and
 * persisting results of the injection in the Model.
 *
 * This will look similar to the ModelUtils/DefaultModelInheritanceAssembler code, but
 * they are distinct. In model inheritance, the child provides data dominance AND persists
 * the results of the merge...sort of a 'merge-out' system.
 *
 * In this system, the profile is dominant, but the model receives the merge result...sort
 * of a 'merge-in' system. The two pieces of code look like they could be combined with a
 * set of flags to determine which direction to merge 'to', but there are enough differences
 * in the code to justify the extra code involved with separating them, in order to simplify
 * the logic.
 */
public class DefaultProfileInjector
    implements ProfileInjector
{

    public void inject( Profile profile, Model model )
    {

        model.setDependencies( injectDependencies( profile.getDependencies(), model.getDependencies() ) );

        injectModules( profile, model );

        model.setRepositories( ModelUtils.mergeRepositoryLists( profile.getRepositories(), model.getRepositories() ) );
        model.setPluginRepositories( ModelUtils.mergeRepositoryLists( profile.getPluginRepositories(), model
            .getPluginRepositories() ) );

        injectReporting( profile, model );

        injectDependencyManagement( profile, model );

        injectDistributionManagement( profile, model );

        injectBuild( profile, model );

        Properties props = new Properties();
        props.putAll( model.getProperties() );
        props.putAll( profile.getProperties() );

        model.setProperties( props );
    }

    private void injectBuild( Profile profile, Model model )
    {
        BuildBase profileBuild = profile.getBuild();
        Build modelBuild = model.getBuild();

        // if the parent build is null, obviously we cannot inherit from it...
        if ( profileBuild != null )
        {
            if ( modelBuild == null )
            {
                modelBuild = new Build();
                model.setBuild( modelBuild );
            }

            if ( profileBuild.getDirectory() != null )
            {
                modelBuild.setDirectory( profileBuild.getDirectory() );
            }

            if ( profileBuild.getDefaultGoal() != null )
            {
                modelBuild.setDefaultGoal( profileBuild.getDefaultGoal() );
            }

            if ( profileBuild.getFinalName() != null )
            {
                modelBuild.setFinalName( profileBuild.getFinalName() );
            }

            ModelUtils.mergeFilterLists( modelBuild.getFilters(), profileBuild.getFilters() );
            ModelUtils.mergeResourceLists( modelBuild.getResources(), profileBuild.getResources() );
            ModelUtils.mergeResourceLists( modelBuild.getTestResources(), profileBuild.getTestResources() );

            injectPlugins( profileBuild, modelBuild );

            // Plugin management :: aggregate
            PluginManagement profilePM = profileBuild.getPluginManagement();
            PluginManagement modelPM = modelBuild.getPluginManagement();

            if ( modelPM == null )
            {
                modelBuild.setPluginManagement( profilePM );
            }
            else
            {
                injectPlugins( profilePM, modelPM );
            }
        }
    }

    /**
     * This should be the resulting ordering of plugins after injection:
     *
     * Given:
     *
     *   model: X -> A -> B -> D -> E
     *   profile: Y -> A -> C -> D -> F
     *
     * Result:
     *
     *   X -> Y -> A -> B -> C -> D -> E -> F
     */
    protected void injectPlugins( PluginContainer profileContainer, PluginContainer modelContainer )
    {
        if ( ( profileContainer == null ) || ( modelContainer == null ) )
        {
            // nothing to do...
            return;
        }

        List modelPlugins = modelContainer.getPlugins();

        if ( modelPlugins == null )
        {
            modelContainer.setPlugins( profileContainer.getPlugins() );
        }
        else if ( profileContainer.getPlugins() != null )
        {
            List mergedPlugins = new ArrayList();

            Map profilePlugins = profileContainer.getPluginsAsMap();

            for ( Iterator it = modelPlugins.iterator(); it.hasNext(); )
            {
                Plugin modelPlugin = (Plugin) it.next();

                Plugin profilePlugin = (Plugin) profilePlugins.get( modelPlugin.getKey() );

                if ( ( profilePlugin != null ) && !mergedPlugins.contains( profilePlugin ) )
                {
                    Plugin mergedPlugin = modelPlugin;

                    injectPluginDefinition( profilePlugin, modelPlugin );

                    mergedPlugins.add( mergedPlugin );
                }
            }

            List results = ModelUtils.orderAfterMerge( mergedPlugins, modelPlugins, profileContainer.getPlugins() );

            modelContainer.setPlugins( results );

            modelContainer.flushPluginMap();
        }
    }

    private void injectPluginDefinition( Plugin profilePlugin, Plugin modelPlugin )
    {
        if ( ( profilePlugin == null ) || ( modelPlugin == null ) )
        {
            // nothing to do.
            return;
        }

        if ( profilePlugin.isExtensions() )
        {
            modelPlugin.setExtensions( true );
        }

        if ( profilePlugin.getVersion() != null )
        {
            modelPlugin.setVersion( profilePlugin.getVersion() );
        }

        modelPlugin.setDependencies( injectDependencies( profilePlugin.getDependencies(), modelPlugin.getDependencies() ) );

        // merge the lists of goals that are not attached to an 
        injectConfigurationContainer( profilePlugin, modelPlugin );

        // from here to the end of the method is dealing with merging of the  section.
        List modelExecutions = modelPlugin.getExecutions();

        if ( ( modelExecutions == null ) || modelExecutions.isEmpty() )
        {
            modelPlugin.setExecutions( profilePlugin.getExecutions() );
        }
        else
        {
            Map executions = new LinkedHashMap();

            Map profileExecutions = profilePlugin.getExecutionsAsMap();

            for ( Iterator it = modelExecutions.iterator(); it.hasNext(); )
            {
                PluginExecution modelExecution = (PluginExecution) it.next();

                PluginExecution profileExecution = (PluginExecution) profileExecutions.get( modelExecution.getId() );

                if ( profileExecution != null )
                {
                    injectConfigurationContainer( profileExecution, modelExecution );

                    if ( profileExecution.getPhase() != null )
                    {
                        modelExecution.setPhase( profileExecution.getPhase() );
                    }

                    List profileGoals = profileExecution.getGoals();
                    List modelGoals = modelExecution.getGoals();

                    List goals = new ArrayList();

                    if ( ( modelGoals != null ) && !modelGoals.isEmpty() )
                    {
                        goals.addAll( modelGoals );
                    }

                    if ( profileGoals != null )
                    {
                        for ( Iterator goalIterator = profileGoals.iterator(); goalIterator.hasNext(); )
                        {
                            String goal = (String) goalIterator.next();

                            if ( !goals.contains( goal ) )
                            {
                                goals.add( goal );
                            }
                        }
                    }

                    modelExecution.setGoals( goals );
                }

                executions.put( modelExecution.getId(), modelExecution );
            }

            for ( Iterator it = profileExecutions.entrySet().iterator(); it.hasNext(); )
            {
                Map.Entry entry = (Map.Entry) it.next();

                String id = (String) entry.getKey();

                if ( !executions.containsKey( id ) )
                {
                    executions.put( id, entry.getValue() );
                }
            }

            modelPlugin.setExecutions( new ArrayList( executions.values() ) );

            modelPlugin.flushExecutionMap();
        }

    }

    /**
     * Merge two DOMs. Copy the dominant DOM so the original one is left unchanged.
     * 

* Use this method instead of a direct call to {@link Xpp3Dom#mergeXpp3Dom(Xpp3Dom, Xpp3Dom)}. * Profiles are dominant, thus they are merge targets, but they may be merged in several times * (e.g. if they are inherited). So with the second merge, you don't get the profile's original * DOM, but an already merged one. * * @param dominant Dominant DOM * @param recessive Recessive DOM * @return Merged DOM */ private Xpp3Dom merge( Xpp3Dom dominant, Xpp3Dom recessive ) { Xpp3Dom dominantCopy = ( dominant == null ) ? null : new Xpp3Dom( dominant ); return Xpp3Dom.mergeXpp3Dom( dominantCopy, recessive ); } private void injectConfigurationContainer( ConfigurationContainer profileContainer, ConfigurationContainer modelContainer ) { Xpp3Dom configuration = (Xpp3Dom) profileContainer.getConfiguration(); Xpp3Dom parentConfiguration = (Xpp3Dom) modelContainer.getConfiguration(); configuration = merge( configuration, parentConfiguration ); modelContainer.setConfiguration( configuration ); } /** * Append modules specified in the profile to the end of the list supplied by the model, if * they don't already exist. */ private void injectModules( Profile profile, Model model ) { List modules = new ArrayList(); List modelModules = model.getModules(); if ( ( modelModules != null ) && !modelModules.isEmpty() ) { modules.addAll( modelModules ); } List profileModules = profile.getModules(); if ( profileModules != null ) { for ( Iterator it = profileModules.iterator(); it.hasNext(); ) { String module = (String) it.next(); if ( !modules.contains( module ) ) { modules.add( module ); } } } model.setModules( modules ); } private void injectDistributionManagement( Profile profile, Model model ) { DistributionManagement pDistMgmt = profile.getDistributionManagement(); DistributionManagement mDistMgmt = model.getDistributionManagement(); if ( mDistMgmt == null ) { model.setDistributionManagement( pDistMgmt ); } else if ( pDistMgmt != null ) { if ( pDistMgmt.getRepository() != null ) { mDistMgmt.setRepository( pDistMgmt.getRepository() ); } if ( pDistMgmt.getSnapshotRepository() != null ) { mDistMgmt.setSnapshotRepository( pDistMgmt.getSnapshotRepository() ); } if ( StringUtils.isNotEmpty( pDistMgmt.getDownloadUrl() ) ) { mDistMgmt.setDownloadUrl( pDistMgmt.getDownloadUrl() ); } if ( pDistMgmt.getRelocation() != null ) { mDistMgmt.setRelocation( pDistMgmt.getRelocation() ); } if ( pDistMgmt.getSite() != null ) { mDistMgmt.setSite( pDistMgmt.getSite() ); } // NOTE: We SHOULD NOT be inheriting status, since this is an assessment of the POM quality. } } private void injectDependencyManagement( Profile profile, Model model ) { DependencyManagement modelDepMgmt = model.getDependencyManagement(); DependencyManagement profileDepMgmt = profile.getDependencyManagement(); if ( profileDepMgmt != null ) { if ( modelDepMgmt == null ) { model.setDependencyManagement( profileDepMgmt ); } else { Map depsMap = new LinkedHashMap(); List deps = modelDepMgmt.getDependencies(); if ( deps != null ) { for ( Iterator it = deps.iterator(); it.hasNext(); ) { Dependency dependency = (Dependency) it.next(); depsMap.put( dependency.getManagementKey(), dependency ); } } deps = profileDepMgmt.getDependencies(); if ( deps != null ) { for ( Iterator it = deps.iterator(); it.hasNext(); ) { Dependency dependency = (Dependency) it.next(); depsMap.put( dependency.getManagementKey(), dependency ); } } modelDepMgmt.setDependencies( new ArrayList( depsMap.values() ) ); } } } private void injectReporting( Profile profile, Model model ) { // Reports :: aggregate Reporting profileReporting = profile.getReporting(); Reporting modelReporting = model.getReporting(); if ( profileReporting != null ) { if ( modelReporting == null ) { model.setReporting( profileReporting ); } else { if ( StringUtils.isEmpty( modelReporting.getOutputDirectory() ) ) { modelReporting.setOutputDirectory( profileReporting.getOutputDirectory() ); } Map mergedReportPlugins = new LinkedHashMap(); Map profileReportersByKey = profileReporting.getReportPluginsAsMap(); List modelReportPlugins = modelReporting.getPlugins(); if ( modelReportPlugins != null ) { for ( Iterator it = modelReportPlugins.iterator(); it.hasNext(); ) { ReportPlugin modelReportPlugin = (ReportPlugin) it.next(); String inherited = modelReportPlugin.getInherited(); if ( StringUtils.isEmpty( inherited ) || Boolean.valueOf( inherited ).booleanValue() ) { ReportPlugin profileReportPlugin = (ReportPlugin) profileReportersByKey .get( modelReportPlugin.getKey() ); ReportPlugin mergedReportPlugin = modelReportPlugin; if ( profileReportPlugin != null ) { mergedReportPlugin = profileReportPlugin; mergeReportPlugins( profileReportPlugin, modelReportPlugin ); } else if ( StringUtils.isEmpty( inherited ) ) { mergedReportPlugin.unsetInheritanceApplied(); } mergedReportPlugins.put( mergedReportPlugin.getKey(), mergedReportPlugin ); } } } for ( Iterator it = profileReportersByKey.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); if ( !mergedReportPlugins.containsKey( key ) ) { mergedReportPlugins.put( key, entry.getValue() ); } } modelReporting.setPlugins( new ArrayList( mergedReportPlugins.values() ) ); modelReporting.flushReportPluginMap(); } } } private void mergeReportPlugins( ReportPlugin dominant, ReportPlugin recessive ) { if ( StringUtils.isEmpty( recessive.getVersion() ) ) { recessive.setVersion( dominant.getVersion() ); } Xpp3Dom dominantConfig = (Xpp3Dom) dominant.getConfiguration(); Xpp3Dom recessiveConfig = (Xpp3Dom) recessive.getConfiguration(); recessive.setConfiguration( merge( dominantConfig, recessiveConfig ) ); Map mergedReportSets = new LinkedHashMap(); Map dominantReportSetsById = dominant.getReportSetsAsMap(); for ( Iterator it = recessive.getReportSets().iterator(); it.hasNext(); ) { ReportSet recessiveReportSet = (ReportSet) it.next(); ReportSet dominantReportSet = (ReportSet) dominantReportSetsById.get( recessiveReportSet.getId() ); ReportSet merged = recessiveReportSet; if ( dominantReportSet != null ) { merged = recessiveReportSet; Xpp3Dom dominantRSConfig = (Xpp3Dom) dominantReportSet.getConfiguration(); Xpp3Dom mergedRSConfig = (Xpp3Dom) merged.getConfiguration(); merged.setConfiguration( merge( dominantRSConfig, mergedRSConfig ) ); List mergedReports = merged.getReports(); if ( mergedReports == null ) { mergedReports = new ArrayList(); merged.setReports( mergedReports ); } List dominantRSReports = dominantReportSet.getReports(); if ( dominantRSReports != null ) { for ( Iterator reportIterator = dominantRSReports.iterator(); reportIterator.hasNext(); ) { String report = (String) reportIterator.next(); if ( !mergedReports.contains( report ) ) { mergedReports.add( report ); } } } mergedReportSets.put( merged.getId(), merged ); } } for ( Iterator rsIterator = dominantReportSetsById.entrySet().iterator(); rsIterator.hasNext(); ) { Map.Entry entry = (Map.Entry) rsIterator.next(); String key = (String) entry.getKey(); if ( !mergedReportSets.containsKey( key ) ) { mergedReportSets.put( key, entry.getValue() ); } } recessive.setReportSets( new ArrayList( mergedReportSets.values() ) ); recessive.flushReportSetMap(); } private List injectDependencies( List profileDeps, List modelDeps ) { Map depsMap = new LinkedHashMap(); if ( modelDeps != null ) { for ( Iterator it = modelDeps.iterator(); it.hasNext(); ) { Dependency dependency = (Dependency) it.next(); depsMap.put( dependency.getManagementKey(), dependency ); } } if ( profileDeps != null ) { for ( Iterator it = profileDeps.iterator(); it.hasNext(); ) { Dependency dependency = (Dependency) it.next(); depsMap.put( dependency.getManagementKey(), dependency ); } } return new ArrayList( depsMap.values() ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy