blob: bf86d4ee12abe271c07cfb09f48c9cd08cc8f58e [file] [log] [blame]
package org.apache.maven.project;
/*
* 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 java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.maven.model.Activation;
import org.apache.maven.model.ActivationFile;
import org.apache.maven.model.ActivationOS;
import org.apache.maven.model.ActivationProperty;
import org.apache.maven.model.Build;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.CiManagement;
import org.apache.maven.model.Contributor;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.DeploymentRepository;
import org.apache.maven.model.Developer;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Exclusion;
import org.apache.maven.model.Extension;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.model.License;
import org.apache.maven.model.MailingList;
import org.apache.maven.model.Model;
import org.apache.maven.model.ModelBase;
import org.apache.maven.model.Notifier;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Parent;
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.Prerequisites;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Relocation;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.Repository;
import org.apache.maven.model.RepositoryBase;
import org.apache.maven.model.RepositoryPolicy;
import org.apache.maven.model.Resource;
import org.apache.maven.model.Scm;
import org.apache.maven.model.Site;
import org.codehaus.plexus.util.xml.Xpp3Dom;
public final class ModelUtils
{
private static final ModelPartCloner<Dependency> DEPENDENCY_CLONER = new ModelPartCloner<Dependency>()
{
public Dependency cloneModelPart( Dependency src )
{
return ModelUtils.cloneDependency( src );
}
};
private static final ModelPartCloner<Plugin> PLUGIN_CLONER = new ModelPartCloner<Plugin>()
{
public Plugin cloneModelPart( Plugin src )
{
return ModelUtils.clonePlugin( src );
}
};
private static final ModelPartCloner<Extension> EXTENSION_CLONER = new ModelPartCloner<Extension>()
{
public Extension cloneModelPart( Extension src )
{
return ModelUtils.cloneExtension( src );
}
};
private static final ModelPartCloner<Resource> RESOURCE_CLONER = new ModelPartCloner<Resource>()
{
public Resource cloneModelPart( Resource src )
{
return ModelUtils.cloneResource( src );
}
};
private static final ModelPartCloner<Notifier> NOTIFIER_CLONER = new ModelPartCloner<Notifier>()
{
public Notifier cloneModelPart( Notifier src )
{
return ModelUtils.cloneNotifier( src );
}
};
private static final ModelPartCloner<Contributor> CONTRIBUTOR_CLONER = new ModelPartCloner<Contributor>()
{
public Contributor cloneModelPart( Contributor src )
{
return ModelUtils.cloneContributor( src );
}
};
private static final ModelPartCloner<Developer> DEVELOPER_CLONER = new ModelPartCloner<Developer>()
{
public Developer cloneModelPart( Developer src )
{
return ModelUtils.cloneDeveloper( src );
}
};
private static final ModelPartCloner<License> LICENSE_CLONER = new ModelPartCloner<License>()
{
public License cloneModelPart( License src )
{
return ModelUtils.cloneLicense( src );
}
};
private static final ModelPartCloner<MailingList> MAILING_LIST_CLONER = new ModelPartCloner<MailingList>()
{
public MailingList cloneModelPart( MailingList src )
{
return ModelUtils.cloneMailingList( src );
}
};
private static final ModelPartCloner<Repository> REPOSITORY_CLONER = new ModelPartCloner<Repository>()
{
public Repository cloneModelPart( Repository src )
{
return ModelUtils.cloneRepository( src );
}
};
private static final ModelPartCloner<Profile> PROFILE_CLONER = new ModelPartCloner<Profile>()
{
public Profile cloneModelPart( Profile src )
{
return ModelUtils.cloneProfile( src );
}
};
private static final ModelPartCloner<ReportPlugin> REPORT_PLUGIN_CLONER = new ModelPartCloner<ReportPlugin>()
{
public ReportPlugin cloneModelPart( ReportPlugin src )
{
return ModelUtils.cloneReportPlugin( src );
}
};
private static final ModelPartCloner<ReportSet> REPORT_SET_CLONER = new ModelPartCloner<ReportSet>()
{
public ReportSet cloneModelPart( ReportSet src )
{
return ModelUtils.cloneReportSet( src );
}
};
private static final ModelPartCloner<Exclusion> DEPENDENCY_EXCLUSION_CLONER = new ModelPartCloner<Exclusion>()
{
public Exclusion cloneModelPart( Exclusion src )
{
return ModelUtils.cloneExclusion( src );
}
};
private static final ModelPartCloner<PluginExecution> PLUGIN_EXECUTION_CLONER = new ModelPartCloner<PluginExecution>()
{
public PluginExecution cloneModelPart( PluginExecution src )
{
return ModelUtils.clonePluginExecution( src );
}
};
/**
* Given this plugin list:
*
* A1 -> B -> C -> A2 -> D
*
* Rearrange it to this:
*
* A(A1 + A2) -> B -> C -> D
*
* In cases of overlapping definitions, A1 is overridden by A2
*
*/
public static void mergeDuplicatePluginDefinitions( PluginContainer pluginContainer )
{
if ( pluginContainer == null )
{
return;
}
List<Plugin> originalPlugins = pluginContainer.getPlugins();
if ( ( originalPlugins == null ) || originalPlugins.isEmpty() )
{
return;
}
List<Plugin> normalized = new ArrayList<Plugin>( originalPlugins.size() );
for ( Plugin currentPlugin : originalPlugins )
{
if ( normalized.contains( currentPlugin ) )
{
int idx = normalized.indexOf( currentPlugin );
Plugin firstPlugin = (Plugin) normalized.get( idx );
// MNG-3719: merge currentPlugin with firstPlugin as parent,
// then use updated currentPlugin as new parent
mergePluginDefinitions( currentPlugin, firstPlugin, false );
normalized.set( idx, currentPlugin );
}
else
{
normalized.add( currentPlugin );
}
}
pluginContainer.setPlugins( normalized );
}
public static ReportSet cloneReportSet( ReportSet src )
{
if ( src == null )
{
return null;
}
ReportSet result = new ReportSet();
result.setConfiguration( cloneConfiguration( src.getConfiguration() ) );
result.setId( src.getId() );
result.setInherited( src.getInherited() );
result.setReports( cloneListOfStrings( src.getReports() ) );
return result;
}
public static ReportPlugin cloneReportPlugin( ReportPlugin src )
{
if ( src == null )
{
return null;
}
ReportPlugin result = new ReportPlugin();
result.setArtifactId( src.getArtifactId() );
result.setConfiguration( cloneConfiguration( src.getConfiguration() ) );
result.setGroupId( src.getGroupId() );
result.setInherited( src.getInherited() );
result.setReportSets( cloneList( src.getReportSets(), REPORT_SET_CLONER ) );
result.setVersion( src.getVersion() );
return result;
}
public static Profile cloneProfile( Profile src )
{
if ( src == null )
{
return null;
}
Profile result = new Profile();
cloneModelBaseFields( src, result );
result.setActivation( cloneActivation( src.getActivation() ) );
BuildBase resultBuild = null;
if ( src.getBuild() != null )
{
resultBuild = new BuildBase();
cloneBuildBaseFields( src.getBuild(), resultBuild );
}
result.setBuild( resultBuild );
result.setId( src.getId() );
result.setSource( src.getSource() );
return result;
}
private static void cloneModelBaseFields( ModelBase src, ModelBase result )
{
result.setDependencies( cloneList( src.getDependencies(), DEPENDENCY_CLONER ) );
result.setDependencyManagement( cloneDependencyManagement( src.getDependencyManagement() ) );
result.setDistributionManagement( cloneDistributionManagement( src.getDistributionManagement() ) );
result.setModules( cloneListOfStrings( src.getModules() ) );
result.setPluginRepositories( cloneList( src.getPluginRepositories(), REPOSITORY_CLONER ) );
result.setProperties( cloneProperties( src.getProperties() ) );
result.setReporting( cloneReporting( src.getReporting() ) );
result.setRepositories( cloneList( src.getRepositories(), REPOSITORY_CLONER ) );
}
public static Reporting cloneReporting( Reporting src )
{
if ( src == null )
{
return null;
}
Reporting result = new Reporting();
result.setExcludeDefaults( src.isExcludeDefaults() );
result.setOutputDirectory( src.getOutputDirectory() );
result.setPlugins( cloneList( src.getPlugins(), REPORT_PLUGIN_CLONER ) );
return result;
}
public static Activation cloneActivation( Activation src )
{
if ( src == null )
{
return null;
}
Activation result = new Activation();
result.setActiveByDefault( src.isActiveByDefault() );
result.setFile( cloneActivationFile( src.getFile() ) );
result.setJdk( src.getJdk() );
result.setOs( cloneActivationOs( src.getOs() ) );
result.setProperty( cloneActivationProperty( src.getProperty() ) );
return result;
}
public static ActivationProperty cloneActivationProperty( ActivationProperty src )
{
if ( src == null )
{
return null;
}
ActivationProperty result = new ActivationProperty();
result.setName( src.getName() );
result.setValue( src.getValue() );
return result;
}
public static ActivationOS cloneActivationOs( ActivationOS src )
{
if ( src == null )
{
return null;
}
ActivationOS result = new ActivationOS();
result.setArch( src.getArch() );
result.setFamily( src.getFamily() );
result.setName( src.getName() );
result.setVersion( src.getVersion() );
return result;
}
public static ActivationFile cloneActivationFile( ActivationFile src )
{
if ( src == null )
{
return null;
}
ActivationFile result = new ActivationFile();
result.setExists( src.getExists() );
result.setMissing( src.getMissing() );
return result;
}
public static Repository cloneRepository( Repository src )
{
if ( src == null )
{
return null;
}
Repository result = new Repository();
result.setReleases( cloneRepositoryPolicy( src.getReleases() ) );
result.setSnapshots( cloneRepositoryPolicy( src.getSnapshots() ) );
cloneRepositoryBaseFields( src, result );
return result;
}
public static RepositoryPolicy cloneRepositoryPolicy( RepositoryPolicy src )
{
if ( src == null )
{
return null;
}
RepositoryPolicy result = new RepositoryPolicy();
result.setChecksumPolicy( src.getChecksumPolicy() );
result.setEnabled( src.isEnabled() );
result.setUpdatePolicy( src.getUpdatePolicy() );
return result;
}
public static MailingList cloneMailingList( MailingList src )
{
if ( src == null )
{
return null;
}
MailingList result = new MailingList();
result.setArchive( src.getArchive() );
result.setName( src.getName() );
result.setOtherArchives( src.getOtherArchives() );
result.setPost( src.getPost() );
result.setSubscribe( src.getSubscribe() );
result.setUnsubscribe( src.getUnsubscribe() );
return result;
}
/**
* This should be the resulting ordering of plugins after merging:
*
* Given:
*
* parent: X -> A -> B -> D -> E
* child: Y -> A -> C -> D -> F
*
* Result:
*
* X -> Y -> A -> B -> C -> D -> E -> F
*/
public static void mergePluginLists( PluginContainer child, PluginContainer parent,
boolean handleAsInheritance )
{
if ( ( child == null ) || ( parent == null ) )
{
// nothing to do.
return;
}
List<Plugin> parentPlugins = parent.getPlugins();
if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
{
parentPlugins = new ArrayList<Plugin>( parentPlugins );
// If we're processing this merge as an inheritance, we have to build up a list of
// plugins that were considered for inheritance.
if ( handleAsInheritance )
{
for ( Iterator<Plugin> it = parentPlugins.iterator(); it.hasNext(); )
{
Plugin plugin = it.next();
String inherited = plugin.getInherited();
if ( ( inherited != null ) && !Boolean.valueOf( inherited ).booleanValue() )
{
it.remove();
}
}
}
List<Plugin> assembledPlugins = new ArrayList<Plugin>();
Map<String, Plugin> childPlugins = child.getPluginsAsMap();
for ( Plugin parentPlugin : parentPlugins )
{
String parentInherited = parentPlugin.getInherited();
// only merge plugin definition from the parent if at least one
// of these is true:
// 1. we're not processing the plugins in an inheritance-based merge
// 2. the parent's <inherited/> flag is not set
// 3. the parent's <inherited/> flag is set to true
if ( !handleAsInheritance || ( parentInherited == null )
|| Boolean.valueOf( parentInherited ).booleanValue() )
{
Plugin childPlugin = (Plugin) childPlugins.get( parentPlugin.getKey() );
if ( ( childPlugin != null ) && !assembledPlugins.contains( childPlugin ) )
{
Plugin assembledPlugin = childPlugin;
mergePluginDefinitions( childPlugin, parentPlugin, handleAsInheritance );
// fix for MNG-2221 (assembly cache was not being populated for later reference):
assembledPlugins.add( assembledPlugin );
}
// if we're processing this as an inheritance-based merge, and
// the parent's <inherited/> flag is not set, then we need to
// clear the inherited flag in the merge result.
if ( handleAsInheritance && ( parentInherited == null ) )
{
parentPlugin.unsetInheritanceApplied();
}
}
// very important to use the parentPlugins List, rather than parentContainer.getPlugins()
// since this list is a local one, and may have been modified during processing.
List<Plugin> results = ModelUtils.orderAfterMerge( assembledPlugins, parentPlugins, child.getPlugins() );
child.setPlugins( results );
child.flushPluginMap();
}
}
}
public static <T> List<T> orderAfterMerge( List<T> merged, List<T> highPrioritySource, List<T> lowPrioritySource )
{
List<T> results = new ArrayList<T>();
if ( !merged.isEmpty() )
{
results.addAll( merged );
}
List<T> missingFromResults = new ArrayList<T>();
List<List<T>> sources = new ArrayList<List<T>>();
sources.add( highPrioritySource );
sources.add( lowPrioritySource );
for ( List<T> source : sources )
{
for ( T item : source )
{
if ( results.contains( item ) )
{
if ( !missingFromResults.isEmpty() )
{
int idx = results.indexOf( item );
if ( idx < 0 )
{
idx = 0;
}
results.addAll( idx, missingFromResults );
missingFromResults.clear();
}
}
else
{
missingFromResults.add( item );
}
}
if ( !missingFromResults.isEmpty() )
{
results.addAll( missingFromResults );
missingFromResults.clear();
}
}
return results;
}
/**
* Merge the list of reporting plugins from parent pom and child pom
* TODO it's pretty much a copy of {@link #mergePluginLists(PluginContainer, PluginContainer, boolean)}
*
* @param child
* @param parent
* @param handleAsInheritance
*/
public static void mergeReportPluginLists( Reporting child, Reporting parent, boolean handleAsInheritance )
{
if ( ( child == null ) || ( parent == null ) )
{
// nothing to do.
return;
}
List<ReportPlugin> parentPlugins = parent.getPlugins();
if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
{
parentPlugins = new ArrayList<ReportPlugin>( parentPlugins );
// If we're processing this merge as an inheritance, we have to build up a list of
// plugins that were considered for inheritance.
if ( handleAsInheritance )
{
for ( Iterator<ReportPlugin> it = parentPlugins.iterator(); it.hasNext(); )
{
ReportPlugin plugin = it.next();
String inherited = plugin.getInherited();
if ( ( inherited != null ) && !Boolean.valueOf( inherited ).booleanValue() )
{
it.remove();
}
}
}
List<ReportPlugin> assembledPlugins = new ArrayList<ReportPlugin>();
Map<String, ReportPlugin> childPlugins = child.getReportPluginsAsMap();
for ( ReportPlugin parentPlugin : parentPlugins )
{
String parentInherited = parentPlugin.getInherited();
// only merge plugin definition from the parent if at least one
// of these is true:
// 1. we're not processing the plugins in an inheritance-based merge
// 2. the parent's <inherited/> flag is not set
// 3. the parent's <inherited/> flag is set to true
if ( !handleAsInheritance || ( parentInherited == null )
|| Boolean.valueOf( parentInherited ).booleanValue() )
{
ReportPlugin childPlugin = childPlugins.get( parentPlugin.getKey() );
if ( ( childPlugin != null ) && !assembledPlugins.contains( childPlugin ) )
{
ReportPlugin assembledPlugin = childPlugin;
mergeReportPluginDefinitions( childPlugin, parentPlugin, handleAsInheritance );
// fix for MNG-2221 (assembly cache was not being populated for later reference):
assembledPlugins.add( assembledPlugin );
}
// if we're processing this as an inheritance-based merge, and
// the parent's <inherited/> flag is not set, then we need to
// clear the inherited flag in the merge result.
if ( handleAsInheritance && ( parentInherited == null ) )
{
parentPlugin.unsetInheritanceApplied();
}
}
// very important to use the parentPlugins List, rather than parentContainer.getPlugins()
// since this list is a local one, and may have been modified during processing.
List<ReportPlugin> results = ModelUtils.orderAfterMerge( assembledPlugins, parentPlugins,
child.getPlugins() );
child.setPlugins( results );
child.flushReportPluginMap();
}
}
}
public static void mergePluginDefinitions( Plugin child, Plugin parent, boolean handleAsInheritance )
{
if ( ( child == null ) || ( parent == null ) )
{
// nothing to do.
return;
}
if ( parent.isExtensions() )
{
child.setExtensions( true );
}
if ( ( child.getVersion() == null ) && ( parent.getVersion() != null ) )
{
child.setVersion( parent.getVersion() );
}
Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
child.setConfiguration( childConfiguration );
child.setDependencies( mergeDependencyList( child.getDependencies(), parent.getDependencies() ) );
// from here to the end of the method is dealing with merging of the <executions/> section.
String parentInherited = parent.getInherited();
boolean parentIsInherited = ( parentInherited == null ) || Boolean.valueOf( parentInherited ).booleanValue();
List<PluginExecution> parentExecutions = parent.getExecutions();
if ( ( parentExecutions != null ) && !parentExecutions.isEmpty() )
{
List<PluginExecution> mergedExecutions = new ArrayList<PluginExecution>();
Map<String, PluginExecution> assembledExecutions = new TreeMap<String, PluginExecution>();
Map<String, PluginExecution> childExecutions = child.getExecutionsAsMap();
for ( PluginExecution parentExecution : parentExecutions )
{
String inherited = parentExecution.getInherited();
boolean parentExecInherited = parentIsInherited && ( ( inherited == null ) || Boolean.valueOf( inherited ).booleanValue() );
if ( !handleAsInheritance || parentExecInherited )
{
PluginExecution assembled = parentExecution;
PluginExecution childExecution = (PluginExecution) childExecutions.get( parentExecution.getId() );
if ( childExecution != null )
{
mergePluginExecutionDefinitions( childExecution, parentExecution );
assembled = childExecution;
}
else if ( handleAsInheritance && ( parentInherited == null ) )
{
parentExecution.unsetInheritanceApplied();
}
assembledExecutions.put( assembled.getId(), assembled );
mergedExecutions.add( assembled );
}
}
for ( PluginExecution childExecution : child.getExecutions() )
{
if ( !assembledExecutions.containsKey( childExecution.getId() ) )
{
mergedExecutions.add( childExecution );
}
}
child.setExecutions( mergedExecutions );
child.flushExecutionMap();
}
}
public static void mergeReportPluginDefinitions( ReportPlugin child, ReportPlugin parent,
boolean handleAsInheritance )
{
if ( ( child == null ) || ( parent == null ) )
{
// nothing to do.
return;
}
if ( ( child.getVersion() == null ) && ( parent.getVersion() != null ) )
{
child.setVersion( parent.getVersion() );
}
String parentInherited = parent.getInherited();
boolean parentIsInherited = ( parentInherited == null ) || Boolean.valueOf( parentInherited ).booleanValue();
// merge configuration just like with build plugins
if ( parentIsInherited )
{
Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
child.setConfiguration( childConfiguration );
}
// from here to the end of the method is dealing with merging of the <executions/> section.
List<ReportSet> parentReportSets = parent.getReportSets();
if ( ( parentReportSets != null ) && !parentReportSets.isEmpty() )
{
Map<String, ReportSet> assembledReportSets = new TreeMap<String, ReportSet>();
Map<String, ReportSet> childReportSets = child.getReportSetsAsMap();
for ( ReportSet parentReportSet : parentReportSets )
{
if ( !handleAsInheritance || parentIsInherited )
{
ReportSet assembledReportSet = parentReportSet;
ReportSet childReportSet = childReportSets.get( parentReportSet.getId() );
if ( childReportSet != null )
{
mergeReportSetDefinitions( childReportSet, parentReportSet );
assembledReportSet = childReportSet;
}
else if ( handleAsInheritance && ( parentInherited == null ) )
{
parentReportSet.unsetInheritanceApplied();
}
assembledReportSets.put( assembledReportSet.getId(), assembledReportSet );
}
}
for ( Map.Entry<String, ReportSet> entry : childReportSets.entrySet() )
{
String id = entry.getKey();
if ( !assembledReportSets.containsKey( id ) )
{
assembledReportSets.put( id, entry.getValue() );
}
}
child.setReportSets( new ArrayList<ReportSet>( assembledReportSets.values() ) );
child.flushReportSetMap();
}
}
private static void mergePluginExecutionDefinitions( PluginExecution child, PluginExecution parent )
{
if ( child.getPhase() == null )
{
child.setPhase( parent.getPhase() );
}
List<String> parentGoals = parent.getGoals();
List<String> childGoals = child.getGoals();
List<String> goals = new ArrayList<String>();
if ( ( childGoals != null ) && !childGoals.isEmpty() )
{
goals.addAll( childGoals );
}
if ( parentGoals != null )
{
for ( String goal : parentGoals )
{
if ( !goals.contains( goal ) )
{
goals.add( goal );
}
}
}
child.setGoals( goals );
Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
child.setConfiguration( childConfiguration );
}
private static void mergeReportSetDefinitions( ReportSet child, ReportSet parent )
{
List<String> parentReports = parent.getReports();
List<String> childReports = child.getReports();
List<String> reports = new ArrayList<String>();
if ( ( childReports != null ) && !childReports.isEmpty() )
{
reports.addAll( childReports );
}
if ( parentReports != null )
{
for ( String report : parentReports )
{
if ( !reports.contains( report ) )
{
reports.add( report );
}
}
}
child.setReports( reports );
Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
child.setConfiguration( childConfiguration );
}
public static Model cloneModel( Model src )
{
if ( src == null )
{
return null;
}
Model result = new Model();
cloneModelBaseFields( src, result );
result.setArtifactId( src.getArtifactId() );
result.setBuild( cloneBuild( src.getBuild() ) );
result.setCiManagement( cloneCiManagement( src.getCiManagement() ) );
result.setContributors( cloneList( src.getContributors(), CONTRIBUTOR_CLONER ) );
result.setDescription( src.getDescription() );
result.setDevelopers( cloneList( src.getDevelopers(), DEVELOPER_CLONER ) );
result.setGroupId( src.getGroupId() );
result.setInceptionYear( src.getInceptionYear() );
result.setIssueManagement( cloneIssueManagement( src.getIssueManagement() ) );
result.setLicenses( cloneList( src.getLicenses(), LICENSE_CLONER ) );
result.setMailingLists( cloneList( src.getMailingLists(), MAILING_LIST_CLONER ) );
result.setModelVersion( src.getModelVersion() );
result.setName( src.getName() );
result.setOrganization( cloneOrganization( src.getOrganization() ) );
result.setPackaging( src.getPackaging() );
result.setParent( cloneParent( src.getParent() ) );
result.setPrerequisites( clonePrerequisites( src.getPrerequisites() ) );
result.setProfiles( cloneList( src.getProfiles(), PROFILE_CLONER ) );
result.setScm( cloneScm( src.getScm() ) );
result.setUrl( src.getUrl() );
result.setVersion( src.getVersion() );
return result;
}
public static Scm cloneScm( Scm src )
{
if ( src == null )
{
return null;
}
Scm result = new Scm();
result.setConnection( src.getConnection() );
result.setDeveloperConnection( src.getDeveloperConnection() );
result.setTag( src.getTag() );
result.setUrl( src.getUrl() );
return result;
}
public static Prerequisites clonePrerequisites( Prerequisites src )
{
if ( src == null )
{
return null;
}
Prerequisites result = new Prerequisites();
result.setMaven( src.getMaven() );
return result;
}
public static Organization cloneOrganization( Organization src )
{
if ( src == null )
{
return null;
}
Organization result = new Organization();
result.setName( src.getName() );
result.setUrl( src.getUrl() );
return result;
}
public static License cloneLicense( License src )
{
if ( src == null )
{
return null;
}
License result = new License();
result.setComments( src.getComments() );
result.setDistribution( src.getDistribution() );
result.setName( src.getName() );
result.setUrl( src.getUrl() );
return result;
}
public static IssueManagement cloneIssueManagement( IssueManagement src )
{
if ( src == null )
{
return null;
}
IssueManagement result = new IssueManagement();
result.setSystem( src.getSystem() );
result.setUrl( src.getUrl() );
return result;
}
public static DistributionManagement cloneDistributionManagement( DistributionManagement src )
{
if ( src == null )
{
return null;
}
DistributionManagement result = new DistributionManagement();
result.setDownloadUrl( src.getDownloadUrl() );
result.setRelocation( cloneRelocation( src.getRelocation() ) );
result.setRepository( cloneDeploymentRepository( src.getRepository() ) );
result.setSite( cloneSite( src.getSite() ) );
result.setSnapshotRepository( cloneDeploymentRepository( src.getSnapshotRepository() ) );
result.setStatus( src.getStatus() );
return result;
}
public static Site cloneSite( Site src )
{
if ( src == null )
{
return null;
}
Site result = new Site();
result.setId( src.getId() );
result.setName( src.getName() );
result.setUrl( src.getUrl() );
return result;
}
public static DeploymentRepository cloneDeploymentRepository( DeploymentRepository src )
{
if ( src == null )
{
return null;
}
DeploymentRepository result = new DeploymentRepository();
result.setUniqueVersion( src.isUniqueVersion() );
cloneRepositoryBaseFields( src, result );
return result;
}
private static void cloneRepositoryBaseFields( RepositoryBase src, RepositoryBase result )
{
result.setId( src.getId() );
result.setLayout( src.getLayout() );
result.setName( src.getName() );
result.setUrl( src.getUrl() );
}
public static Relocation cloneRelocation( Relocation src )
{
if ( src == null )
{
return null;
}
Relocation result = new Relocation();
result.setArtifactId( src.getArtifactId() );
result.setGroupId( src.getGroupId() );
result.setMessage( src.getMessage() );
result.setVersion( src.getVersion() );
return result;
}
public static DependencyManagement cloneDependencyManagement( DependencyManagement src )
{
if ( src == null )
{
return null;
}
DependencyManagement result = new DependencyManagement();
result.setDependencies( cloneList( src.getDependencies(), DEPENDENCY_CLONER ) );
return result;
}
private static <T> List<T> cloneList( List<T> src, ModelPartCloner<T> cloner )
{
List<T> result = null;
if ( src != null )
{
result = new ArrayList<T>( src.size() );
for ( T o : src )
{
result.add( cloner.cloneModelPart( o ) );
}
}
return result;
}
public static Contributor cloneContributor( Contributor src )
{
if ( src == null )
{
return null;
}
Contributor result = new Contributor();
cloneContributorFields( src, result );
return result;
}
public static Developer cloneDeveloper( Developer src )
{
if ( src == null )
{
return null;
}
Developer result = new Developer();
result.setId( src.getId() );
cloneContributorFields( src, result );
return result;
}
private static void cloneContributorFields( Contributor src, Contributor result )
{
result.setEmail( src.getEmail() );
result.setName( src.getName() );
result.setOrganization( src.getOrganization() );
result.setOrganizationUrl( src.getOrganizationUrl() );
result.setProperties( cloneProperties( src.getProperties() ) );
result.setRoles( cloneListOfStrings( src.getRoles() ) );
result.setTimezone( src.getTimezone() );
result.setUrl( src.getUrl() );
}
public static CiManagement cloneCiManagement( CiManagement src )
{
if ( src == null )
{
return null;
}
CiManagement result = new CiManagement();
List<Notifier> notifiers = null;
if ( src.getNotifiers() != null )
{
notifiers = new ArrayList<Notifier>( src.getNotifiers().size() );
for ( Notifier notifier : src.getNotifiers() )
{
notifiers.add( cloneNotifier( notifier ) );
}
}
result.setNotifiers( cloneList( src.getNotifiers(), NOTIFIER_CLONER ) );
result.setSystem( src.getSystem() );
result.setUrl( src.getUrl() );
return result;
}
public static Notifier cloneNotifier( Notifier src )
{
if ( src == null )
{
return null;
}
Notifier result = new Notifier();
result.setAddress( src.getAddress() );
result.setConfiguration( cloneProperties( src.getConfiguration() ) );
result.setSendOnError( src.isSendOnError() );
result.setSendOnFailure( result.isSendOnFailure() );
result.setSendOnSuccess( result.isSendOnSuccess() );
result.setSendOnWarning( result.isSendOnWarning() );
return result;
}
public static Properties cloneProperties( Properties src )
{
if ( src == null )
{
return null;
}
Properties result = new Properties();
for ( Enumeration<?> e = src.propertyNames(); e.hasMoreElements(); )
{
String key = (String) e.nextElement();
result.setProperty( key, src.getProperty( key ) );
}
return result;
}
public static Build cloneBuild( Build src )
{
if ( src == null )
{
return null;
}
Build result = new Build();
cloneBuildBaseFields( src, result );
result.setExtensions( cloneList( src.getExtensions(), EXTENSION_CLONER ) );
result.setOutputDirectory( src.getOutputDirectory() );
result.setScriptSourceDirectory( src.getScriptSourceDirectory() );
result.setSourceDirectory( src.getSourceDirectory() );
result.setTestOutputDirectory( src.getTestOutputDirectory() );
result.setTestSourceDirectory( src.getTestSourceDirectory() );
return result;
}
public static void cloneBuildBaseFields( BuildBase src, BuildBase result )
{
result.setDefaultGoal( src.getDefaultGoal() );
result.setDirectory( src.getDirectory() );
result.setFilters( cloneListOfStrings( src.getFilters() ) );
result.setFinalName( src.getFinalName() );
result.setPluginManagement( clonePluginManagement( src.getPluginManagement() ) );
result.setPlugins( cloneList( src.getPlugins(), PLUGIN_CLONER ) );
result.setResources( cloneList( src.getResources(), RESOURCE_CLONER ) );
result.setTestResources( cloneList( src.getTestResources(), RESOURCE_CLONER ) );
}
public static PluginManagement clonePluginManagement( PluginManagement src )
{
PluginManagement pMgmt = null;
if ( src != null )
{
pMgmt = new PluginManagement();
pMgmt.setPlugins( cloneList( src.getPlugins(), PLUGIN_CLONER ) );
}
return pMgmt;
}
public static Resource cloneResource( Resource src )
{
Resource result = null;
if ( src != null )
{
result = new Resource();
result.setDirectory( src.getDirectory() );
result.setExcludes( cloneListOfStrings( src.getExcludes() ) );
result.setFiltering( src.isFiltering() );
result.setIncludes( cloneListOfStrings( src.getIncludes() ) );
result.setMergeId( src.getMergeId() );
result.setTargetPath( src.getTargetPath() );
}
return result;
}
public static Plugin clonePlugin( Plugin src )
{
Plugin result = null;
if ( src != null )
{
result = new Plugin();
result.setArtifactId( src.getArtifactId() );
result.setConfiguration( cloneConfiguration( src.getConfiguration() ) );
result.setDependencies( cloneList( src.getDependencies(), DEPENDENCY_CLONER ) );
result.setExecutions( cloneList( src.getExecutions(), PLUGIN_EXECUTION_CLONER ) );
result.setExtensions( src.isExtensions() );
result.setGroupId( src.getGroupId() );
result.setInherited( src.getInherited() );
result.setVersion( src.getVersion() );
}
return result;
}
public static PluginExecution clonePluginExecution( PluginExecution src )
{
PluginExecution result = null;
if ( src != null )
{
result = new PluginExecution();
result.setId( src.getId() );
result.setGoals( cloneListOfStrings( src.getGoals() ) );
result.setConfiguration( cloneConfiguration( src.getConfiguration() ) );
result.setInherited( src.getInherited() );
result.setPhase( src.getPhase() );
}
return result;
}
// FIXME: We need something better than this for configurations!
public static Object cloneConfiguration( Object configuration )
{
if ( configuration == null )
{
return null;
}
return new Xpp3Dom( (Xpp3Dom) configuration );
}
public static Dependency cloneDependency( Dependency src )
{
Dependency result = null;
if ( src != null )
{
result = new Dependency();
result.setArtifactId( src.getArtifactId() );
result.setClassifier( src.getClassifier() );
result.setExclusions( cloneList( src.getExclusions(), DEPENDENCY_EXCLUSION_CLONER ) );
result.setGroupId( src.getGroupId() );
result.setOptional( src.isOptional() );
result.setScope( src.getScope() );
result.setSystemPath( src.getSystemPath() );
result.setType( src.getType() );
result.setVersion( src.getVersion() );
}
return result;
}
public static Exclusion cloneExclusion( Exclusion src )
{
Exclusion result = null;
if ( src != null )
{
result = new Exclusion();
result.setArtifactId( src.getArtifactId() );
result.setGroupId( src.getGroupId() );
}
return result;
}
public static List<String> cloneListOfStrings( List<String> src )
{
List<String> result = null;
if ( src != null )
{
result = new ArrayList<String>( src.size() );
for ( String item : src )
{
result.add( item );
}
}
return result;
}
public static Extension cloneExtension( Extension src )
{
Extension rExt = new Extension();
rExt.setArtifactId( src.getArtifactId() );
rExt.setGroupId( src.getGroupId() );
rExt.setVersion( src.getVersion() );
return rExt;
}
public static Exclusion cloneDependencyExclusion( Exclusion src )
{
if ( src == null )
{
return null;
}
Exclusion result = new Exclusion();
result.setArtifactId( src.getArtifactId() );
result.setGroupId( src.getGroupId() );
return result;
}
public static Parent cloneParent( Parent src )
{
if ( src == null )
{
return null;
}
Parent result = new Parent();
result.setArtifactId( src.getArtifactId() );
result.setGroupId( src.getGroupId() );
result.setRelativePath( src.getRelativePath() );
result.setVersion( src.getVersion() );
return result;
}
public static List<Repository> mergeRepositoryLists( List<Repository> dominant, List<Repository> recessive )
{
List<Repository> repositories = new ArrayList<Repository>();
for ( Repository repository : dominant )
{
repositories.add( repository );
}
for ( Repository repository : recessive )
{
if ( !repositories.contains( repository ) )
{
repositories.add( repository );
}
}
return repositories;
}
public static void mergeExtensionLists( Build childBuild, Build parentBuild )
{
Map<String, Extension> extMap = new LinkedHashMap<String, Extension>();
List<Extension> ext = childBuild.getExtensions();
if ( ext != null )
{
for ( Extension extension : ext )
{
extMap.put( extension.getKey(), extension );
}
}
ext = parentBuild.getExtensions();
if ( ext != null )
{
for ( Extension extension : ext )
{
if ( !extMap.containsKey( extension.getKey() ) )
{
extMap.put( extension.getKey(), extension );
}
}
}
childBuild.setExtensions( new ArrayList<Extension>( extMap.values() ) );
}
public static void mergeResourceLists( List<Resource> childResources, List<Resource> parentResources )
{
for ( Resource r : parentResources )
{
if ( !childResources.contains( r ) )
{
childResources.add( r );
}
}
}
public static void mergeFilterLists( List<String> childFilters, List<String> parentFilters )
{
for ( String f : parentFilters )
{
if ( !childFilters.contains( f ) )
{
childFilters.add( f );
}
}
}
public static List<Dependency> mergeDependencyList( List<Dependency> child, List<Dependency> parent )
{
Map<String, Dependency> depsMap = new LinkedHashMap<String, Dependency>();
if ( child != null )
{
for ( Dependency dependency : child )
{
depsMap.put( dependency.getManagementKey(), dependency );
}
}
if ( parent != null )
{
for ( Dependency dependency : parent )
{
if ( !depsMap.containsKey( dependency.getManagementKey() ) )
{
depsMap.put( dependency.getManagementKey(), dependency );
}
}
}
return new ArrayList<Dependency>( depsMap.values() );
}
public static interface ModelPartCloner<T>
{
T cloneModelPart( T src );
}
}