Coverage Report - org.apache.maven.archiva.repository.project.ProjectModelMerge
 
Classes in this File Line Coverage Branch Coverage Complexity
ProjectModelMerge
0%
0/291
0%
0/116
0
 
 1  
 package org.apache.maven.archiva.repository.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.Enumeration;
 24  
 import java.util.HashMap;
 25  
 import java.util.HashSet;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 import java.util.Properties;
 30  
 import java.util.Set;
 31  
 
 32  
 import org.apache.commons.lang.StringUtils;
 33  
 import org.apache.maven.archiva.model.ArchivaModelCloner;
 34  
 import org.apache.maven.archiva.model.ArchivaProjectModel;
 35  
 import org.apache.maven.archiva.model.ArtifactReference;
 36  
 import org.apache.maven.archiva.model.CiManagement;
 37  
 import org.apache.maven.archiva.model.Dependency;
 38  
 import org.apache.maven.archiva.model.Exclusion;
 39  
 import org.apache.maven.archiva.model.Individual;
 40  
 import org.apache.maven.archiva.model.IssueManagement;
 41  
 import org.apache.maven.archiva.model.License;
 42  
 import org.apache.maven.archiva.model.Organization;
 43  
 import org.apache.maven.archiva.model.ProjectRepository;
 44  
 import org.apache.maven.archiva.model.Scm;
 45  
 
 46  
 /**
 47  
  * ProjectModelMerge
 48  
  *
 49  
  * TODO: Should call this ProjectModelAncestry as it deals with the current project and its parent.
 50  
  *
 51  
  * @version $Id: ProjectModelMerge.java 803840 2009-08-13 11:00:51Z jzurbano $
 52  
  */
 53  0
 public class ProjectModelMerge
 54  
 {
 55  
     /**
 56  
      * Merge the contents of a project with it's parent project.
 57  
      * 
 58  
      * @param mainProject the main project.
 59  
      * @param parentProject the parent project to merge.
 60  
      * @throws ProjectModelException if there was a problem merging the model.
 61  
      */
 62  
     public static ArchivaProjectModel merge( ArchivaProjectModel mainProject, ArchivaProjectModel parentProject )
 63  
         throws ProjectModelException
 64  
     {
 65  0
         if ( mainProject == null )
 66  
         {
 67  0
             throw new ProjectModelException( "Cannot merge with a null main project." );
 68  
         }
 69  
 
 70  0
         if ( parentProject == null )
 71  
         {
 72  0
             throw new ProjectModelException( "Cannot merge with a null parent project." );
 73  
         }
 74  
 
 75  0
         ArchivaProjectModel merged = new ArchivaProjectModel();
 76  
 
 77  
         // Unmerged.
 78  0
         merged.setParentProject(mainProject.getParentProject());
 79  0
         merged.setArtifactId( mainProject.getArtifactId() );
 80  0
         merged.setPackaging( StringUtils.defaultIfEmpty( mainProject.getPackaging(), "jar" ) );
 81  0
         merged.setRelocation( mainProject.getRelocation() );
 82  
 
 83  
         // Merged
 84  0
         merged.setGroupId( merge( mainProject.getGroupId(), parentProject.getGroupId() ) );
 85  0
         merged.setVersion( merge( mainProject.getVersion(), parentProject.getVersion() ) );
 86  0
         merged.setName( merge( mainProject.getName(), parentProject.getName() ) );
 87  0
         merged.setUrl( merge( mainProject.getUrl(), parentProject.getUrl() ) );
 88  0
         merged.setDescription( merge( mainProject.getDescription(), parentProject.getDescription() ) );
 89  
 
 90  0
         merged.setOrigin( "merged" );
 91  
 
 92  0
         merged.setCiManagement( merge( mainProject.getCiManagement(), parentProject.getCiManagement() ) );
 93  0
         merged.setIndividuals( mergeIndividuals( mainProject.getIndividuals(), parentProject.getIndividuals() ) );
 94  0
         merged.setIssueManagement( merge( mainProject.getIssueManagement(), parentProject.getIssueManagement() ) );
 95  0
         merged.setLicenses( mergeLicenses( mainProject.getLicenses(), parentProject.getLicenses() ) );
 96  0
         merged.setOrganization( merge( mainProject.getOrganization(), parentProject.getOrganization() ) );
 97  0
         merged.setScm( merge( mainProject.getScm(), parentProject.getScm() ) );
 98  0
         merged.setRepositories( mergeRepositories( mainProject.getRepositories(), parentProject.getRepositories() ) );
 99  0
         merged.setDependencies( mergeDependencies( mainProject.getDependencies(), parentProject.getDependencies() ) );
 100  0
         merged.setDependencyManagement( mergeDependencyManagement( mainProject.getDependencyManagement(), parentProject
 101  
             .getDependencyManagement() ) );
 102  0
         merged.setPlugins( mergePlugins( mainProject.getPlugins(), parentProject.getPlugins() ) );
 103  0
         merged.setReports( mergeReports( mainProject.getReports(), parentProject.getReports() ) );
 104  0
         merged.setProperties( merge( mainProject.getProperties(), parentProject.getProperties() ) );
 105  
         
 106  0
         return merged;
 107  
     }
 108  
 
 109  
     private static Map<String, ArtifactReference> createArtifactReferenceMap( List<ArtifactReference> artifactReferences )
 110  
     {
 111  0
         Map<String, ArtifactReference> ret = new HashMap<String, ArtifactReference>();
 112  
 
 113  0
         for ( ArtifactReference artifactReference : artifactReferences )
 114  
         {
 115  0
             String key = toVersionlessArtifactKey( artifactReference );
 116  0
             ret.put( key, artifactReference );
 117  0
         }
 118  
 
 119  0
         return ret;
 120  
     }
 121  
 
 122  
     private static Map<String, Dependency> createDependencyMap( List<Dependency> dependencies )
 123  
     {
 124  0
         Map<String, Dependency> ret = new HashMap<String, Dependency>();
 125  
 
 126  0
         Iterator<Dependency> it = dependencies.iterator();
 127  0
         while ( it.hasNext() )
 128  
         {
 129  0
             Dependency dep = it.next();
 130  0
             String key = toVersionlessDependencyKey( dep );
 131  0
             ret.put( key, dep );
 132  0
         }
 133  
 
 134  0
         return ret;
 135  
     }
 136  
 
 137  
     private static Map<String, Exclusion> createExclusionMap( List<Exclusion> exclusions )
 138  
     {
 139  0
         Map<String, Exclusion> ret = new HashMap<String, Exclusion>();
 140  
 
 141  0
         Iterator<Exclusion> it = exclusions.iterator();
 142  0
         while ( it.hasNext() )
 143  
         {
 144  0
             Exclusion exclusion = it.next();
 145  0
             String key = exclusion.getGroupId() + ":" + exclusion.getArtifactId();
 146  0
             ret.put( key, exclusion );
 147  0
         }
 148  
 
 149  0
         return ret;
 150  
     }
 151  
 
 152  
     private static Map<String, License> createLicensesMap( List<License> licenses )
 153  
     {
 154  0
         Map<String, License> ret = new HashMap<String, License>();
 155  
 
 156  0
         for ( License license : licenses )
 157  
         {
 158  
             // TODO: Change to 'id' when LicenseTypeMapper is created.
 159  0
             String key = license.getName();
 160  0
             ret.put( key, license );
 161  0
         }
 162  
 
 163  0
         return ret;
 164  
     }
 165  
 
 166  
     private static Map<String, ProjectRepository> createRepositoriesMap( List<ProjectRepository> repositories )
 167  
     {
 168  0
         Map<String, ProjectRepository> ret = new HashMap<String, ProjectRepository>();
 169  
 
 170  0
         for ( ProjectRepository repo : repositories )
 171  
         {
 172  
             // Should this really be using repo.id ?
 173  0
             String key = repo.getUrl();
 174  0
             ret.put( key, repo );
 175  0
         }
 176  
 
 177  0
         return ret;
 178  
     }
 179  
 
 180  
     private static boolean empty( String val )
 181  
     {
 182  0
         if ( val == null )
 183  
         {
 184  0
             return true;
 185  
         }
 186  
 
 187  0
         return ( val.trim().length() <= 0 );
 188  
     }
 189  
 
 190  
     private static ArtifactReference merge( ArtifactReference mainArtifactReference,
 191  
                                             ArtifactReference parentArtifactReference )
 192  
     {
 193  0
         if ( parentArtifactReference == null )
 194  
         {
 195  0
             return mainArtifactReference;
 196  
         }
 197  
 
 198  0
         if ( mainArtifactReference == null )
 199  
         {
 200  0
             return ArchivaModelCloner.clone( parentArtifactReference );
 201  
         }
 202  
 
 203  0
         ArtifactReference merged = new ArtifactReference();
 204  
 
 205  
         // Unmerged.
 206  0
         merged.setGroupId( mainArtifactReference.getGroupId() );
 207  0
         merged.setArtifactId( mainArtifactReference.getArtifactId() );
 208  
 
 209  
         // Merged.
 210  0
         merged.setVersion( merge( mainArtifactReference.getVersion(), parentArtifactReference.getVersion() ) );
 211  0
         merged.setClassifier( merge( mainArtifactReference.getClassifier(), parentArtifactReference.getClassifier() ) );
 212  0
         merged.setType( merge( mainArtifactReference.getType(), parentArtifactReference.getType() ) );
 213  
 
 214  0
         return merged;
 215  
     }
 216  
 
 217  
     private static CiManagement merge( CiManagement mainCim, CiManagement parentCim )
 218  
     {
 219  0
         if ( parentCim == null )
 220  
         {
 221  0
             return mainCim;
 222  
         }
 223  
 
 224  0
         if ( mainCim == null )
 225  
         {
 226  0
             return ArchivaModelCloner.clone( parentCim );
 227  
         }
 228  
 
 229  0
         CiManagement merged = new CiManagement();
 230  
 
 231  0
         merged.setSystem( merge( mainCim.getSystem(), parentCim.getSystem() ) );
 232  0
         merged.setUrl( merge( mainCim.getUrl(), parentCim.getUrl() ) );
 233  0
         merged.setCiUrl( merge( mainCim.getCiUrl(), parentCim.getCiUrl() ) );
 234  
 
 235  0
         return merged;
 236  
     }
 237  
 
 238  
     private static Dependency merge( Dependency mainDep, Dependency parentDep )
 239  
     {
 240  0
         if ( parentDep == null )
 241  
         {
 242  0
             return mainDep;
 243  
         }
 244  
 
 245  0
         if ( mainDep == null )
 246  
         {
 247  0
             Dependency dep = ArchivaModelCloner.clone( parentDep );
 248  0
             dep.setFromParent( true );
 249  0
             return dep;
 250  
         }
 251  
 
 252  0
         Dependency merged = new Dependency();
 253  
 
 254  0
         merged.setFromParent( true );
 255  
 
 256  
         // Unmerged.
 257  0
         merged.setGroupId( mainDep.getGroupId() );
 258  0
         merged.setArtifactId( mainDep.getArtifactId() );
 259  
 
 260  
         // Merged.
 261  0
         merged.setVersion( merge( mainDep.getVersion(), parentDep.getVersion() ) );
 262  0
         merged.setClassifier( merge( mainDep.getClassifier(), parentDep.getClassifier() ) );
 263  0
         merged.setType( merge( mainDep.getType(), parentDep.getType() ) );
 264  0
         merged.setScope( merge( mainDep.getScope(), parentDep.getScope() ) );
 265  0
         if ( parentDep.isOptional() )
 266  
         {
 267  0
             merged.setOptional( true );
 268  
         }
 269  
 
 270  0
         merged.setSystemPath( merge( mainDep.getSystemPath(), parentDep.getSystemPath() ) );
 271  0
         merged.setUrl( merge( mainDep.getUrl(), parentDep.getUrl() ) );
 272  0
         merged.setExclusions( mergeExclusions( mainDep.getExclusions(), parentDep.getExclusions() ) );
 273  
 
 274  0
         return merged;
 275  
     }
 276  
 
 277  
     private static IssueManagement merge( IssueManagement mainIssueManagement, IssueManagement parentIssueManagement )
 278  
     {
 279  0
         if ( parentIssueManagement == null )
 280  
         {
 281  0
             return mainIssueManagement;
 282  
         }
 283  
 
 284  0
         if ( mainIssueManagement == null )
 285  
         {
 286  0
             return ArchivaModelCloner.clone( parentIssueManagement );
 287  
         }
 288  
 
 289  0
         IssueManagement merged = new IssueManagement();
 290  
 
 291  0
         merged.setSystem( merge( mainIssueManagement.getSystem(), parentIssueManagement.getSystem() ) );
 292  0
         merged.setUrl( merge( mainIssueManagement.getUrl(), parentIssueManagement.getUrl() ) );
 293  0
         merged.setIssueManagementUrl( merge( mainIssueManagement.getIssueManagementUrl(), parentIssueManagement.getIssueManagementUrl() ) );
 294  
         
 295  0
         return merged;
 296  
     }
 297  
 
 298  
     private static Organization merge( Organization mainOrganization, Organization parentOrganization )
 299  
     {
 300  0
         if ( parentOrganization == null )
 301  
         {
 302  0
             return mainOrganization;
 303  
         }
 304  
 
 305  0
         if ( mainOrganization == null )
 306  
         {
 307  0
             return ArchivaModelCloner.clone( parentOrganization );
 308  
         }
 309  
 
 310  0
         Organization merged = new Organization();
 311  
 
 312  0
         merged.setFavicon( merge( mainOrganization.getFavicon(), parentOrganization.getFavicon() ) );
 313  0
         merged.setOrganizationName( merge( mainOrganization.getOrganizationName(), parentOrganization.getOrganizationName() ) );
 314  0
         merged.setName( merge( mainOrganization.getName(), parentOrganization.getName() ) );
 315  0
         merged.setUrl( merge( mainOrganization.getUrl(), parentOrganization.getUrl() ) );
 316  
 
 317  0
         return merged;
 318  
     }
 319  
 
 320  
     @SuppressWarnings("unchecked")
 321  
     private static Properties merge( Properties mainProperties, Properties parentProperties )
 322  
     {
 323  0
         if ( parentProperties == null )
 324  
         {
 325  0
             return mainProperties;
 326  
         }
 327  
 
 328  0
         if ( mainProperties == null )
 329  
         {
 330  0
             return ArchivaModelCloner.clone( parentProperties );
 331  
         }
 332  
 
 333  0
         Properties merged = new Properties();
 334  0
         merged.putAll(mainProperties);
 335  
 
 336  0
         Enumeration<String> keys = (Enumeration<String>) parentProperties.propertyNames();
 337  0
         while ( keys.hasMoreElements() )
 338  
         {
 339  0
             String key = (String) keys.nextElement();
 340  0
             String value = merge( mainProperties.getProperty( key ), parentProperties.getProperty( key ) );
 341  
             
 342  0
             if ( value != null )
 343  
             {
 344  0
                 merged.put( key, value );
 345  
             }
 346  0
         }
 347  
 
 348  0
         return merged;
 349  
     }
 350  
 
 351  
     private static Scm merge( Scm mainScm, Scm parentScm )
 352  
     {
 353  0
         if ( parentScm == null )
 354  
         {
 355  0
             return mainScm;
 356  
         }
 357  
 
 358  0
         if ( mainScm == null )
 359  
         {
 360  0
             return ArchivaModelCloner.clone( parentScm );
 361  
         }
 362  
 
 363  0
         Scm merged = new Scm();
 364  
 
 365  0
         merged.setConnection( merge( mainScm.getConnection(), parentScm.getConnection() ) );
 366  0
         merged.setDeveloperConnection( merge( mainScm.getDeveloperConnection(), parentScm.getDeveloperConnection() ) );
 367  0
         merged.setUrl( merge( mainScm.getUrl(), parentScm.getUrl() ) );
 368  
 
 369  0
         return merged;
 370  
     }
 371  
 
 372  
     private static String merge( String main, String parent )
 373  
     {
 374  0
         if ( empty( main ) && !empty( parent ) )
 375  
         {
 376  0
             return parent;
 377  
         }
 378  
 
 379  0
         return main;
 380  
     }
 381  
 
 382  
     private static List<ArtifactReference> mergeArtifactReferences( List<ArtifactReference> mainArtifactReferences, List<ArtifactReference> parentArtifactReferences )
 383  
     {
 384  0
         if ( parentArtifactReferences == null )
 385  
         {
 386  0
             return mainArtifactReferences;
 387  
         }
 388  
 
 389  0
         if ( mainArtifactReferences == null )
 390  
         {
 391  0
             return ArchivaModelCloner.cloneArtifactReferences( parentArtifactReferences );
 392  
         }
 393  
 
 394  0
         List<ArtifactReference> merged = new ArrayList<ArtifactReference>();
 395  
 
 396  0
         Map<String, ArtifactReference> mainArtifactReferenceMap = createArtifactReferenceMap( mainArtifactReferences );
 397  0
         Map<String, ArtifactReference> parentArtifactReferenceMap = createArtifactReferenceMap( parentArtifactReferences );
 398  
 
 399  0
         for ( Map.Entry<String,ArtifactReference> entry : mainArtifactReferenceMap.entrySet() )
 400  
         {
 401  0
             String key = entry.getKey();
 402  0
             ArtifactReference mainArtifactReference = (ArtifactReference) entry.getValue();
 403  0
             ArtifactReference parentArtifactReference = parentArtifactReferenceMap.get( key );
 404  
 
 405  0
             if ( parentArtifactReference == null )
 406  
             {
 407  0
                 merged.add( mainArtifactReference );
 408  
             }
 409  
             else
 410  
             {
 411  
                 // Not merging. Local wins.
 412  0
                 merged.add( merge( mainArtifactReference, parentArtifactReference ) );
 413  
             }
 414  0
         }
 415  
 
 416  0
         return merged;
 417  
     }
 418  
 
 419  
     private static List<Dependency> mergeDependencies( List<Dependency> mainDependencies, List<Dependency> parentDependencies )
 420  
     {
 421  0
         if ( parentDependencies == null )
 422  
         {
 423  0
             return mainDependencies;
 424  
         }
 425  
 
 426  0
         if ( mainDependencies == null )
 427  
         {
 428  0
             List<Dependency> merged = ArchivaModelCloner.cloneDependencies( parentDependencies );
 429  0
             Iterator<Dependency> it = merged.iterator();
 430  0
             while ( it.hasNext() )
 431  
             {
 432  0
                 Dependency dep = it.next();
 433  0
                 dep.setFromParent( true );
 434  0
             }
 435  0
             return merged;
 436  
         }
 437  
 
 438  0
         List<Dependency> merged = new ArrayList<Dependency>();
 439  
 
 440  0
         Map<String, Dependency> mainDepMap = createDependencyMap( mainDependencies );
 441  0
         Map<String, Dependency> parentDepMap = createDependencyMap( parentDependencies );
 442  0
         Set<String> uniqueKeys = new HashSet<String>();
 443  0
         uniqueKeys.addAll( mainDepMap.keySet() );
 444  0
         uniqueKeys.addAll( parentDepMap.keySet() );
 445  
 
 446  0
         Iterator<String> it = uniqueKeys.iterator();
 447  0
         while ( it.hasNext() )
 448  
         {
 449  0
             String key = it.next();
 450  0
             Dependency parentDep = parentDepMap.get( key );
 451  0
             Dependency mainDep = mainDepMap.get( key );
 452  
 
 453  0
             if ( parentDep == null )
 454  
             {
 455  
                 // Means there is no parent dep to override main dep.
 456  0
                 merged.add( mainDep );
 457  
             }
 458  
             else
 459  
             {
 460  
                 // Parent dep exists (main doesn't have to).
 461  
                 // Merge the parent over the main dep.
 462  0
                 merged.add( merge( mainDep, parentDep ) );
 463  
             }
 464  0
         }
 465  
 
 466  0
         return merged;
 467  
     }
 468  
 
 469  
     private static List<Dependency> mergeDependencyManagement( List<Dependency> mainDepMgmt, List<Dependency> parentDepMgmt )
 470  
     {
 471  0
         if ( parentDepMgmt == null )
 472  
         {
 473  0
             return mainDepMgmt;
 474  
         }
 475  
 
 476  0
         if ( mainDepMgmt == null )
 477  
         {
 478  0
             List<Dependency> merged = ArchivaModelCloner.cloneDependencies( parentDepMgmt );
 479  0
             Iterator<Dependency> it = merged.iterator();
 480  0
             while ( it.hasNext() )
 481  
             {
 482  0
                 Dependency dep = it.next();
 483  0
                 dep.setFromParent( true );
 484  0
             }
 485  0
             return merged;
 486  
         }
 487  
 
 488  0
         List<Dependency> merged = new ArrayList<Dependency>();
 489  
 
 490  0
         Map<String, Dependency> mainDepMap = createDependencyMap( mainDepMgmt );
 491  0
         Map<String, Dependency> parentDepMap = createDependencyMap( parentDepMgmt );
 492  0
         Set<String> uniqueKeys = new HashSet<String>();
 493  0
         uniqueKeys.addAll( mainDepMap.keySet() );
 494  0
         uniqueKeys.addAll( parentDepMap.keySet() );
 495  
 
 496  0
         Iterator<String> it = uniqueKeys.iterator();
 497  0
         while ( it.hasNext() )
 498  
         {
 499  0
             String key = it.next();
 500  0
             Dependency parentDep = parentDepMap.get( key );
 501  0
             Dependency mainDep = mainDepMap.get( key );
 502  
 
 503  0
             if ( parentDep == null )
 504  
             {
 505  
                 // Means there is no parent depMan entry to override main depMan.
 506  0
                 merged.add( mainDep );
 507  
             }
 508  
             else
 509  
             {
 510  
                 // Parent depMan entry exists (main doesn't have to).
 511  
                 // Merge the parent over the main depMan entry.
 512  0
                 merged.add( merge( mainDep, parentDep ) );
 513  
             }
 514  0
         }
 515  
 
 516  0
         return merged;
 517  
     }
 518  
 
 519  
     public static List<Exclusion> mergeExclusions( List<Exclusion> mainExclusions, List<Exclusion> parentExclusions )
 520  
     {
 521  0
         if ( parentExclusions == null )
 522  
         {
 523  0
             return mainExclusions;
 524  
         }
 525  
 
 526  0
         if ( mainExclusions == null )
 527  
         {
 528  0
             return ArchivaModelCloner.cloneExclusions( parentExclusions );
 529  
         }
 530  
 
 531  0
         List<Exclusion> merged = new ArrayList<Exclusion>();
 532  
 
 533  0
         Map<String, Exclusion> mainExclusionMap = createExclusionMap( mainExclusions );
 534  0
         Map<String, Exclusion> parentExclusionMap = createExclusionMap( parentExclusions );
 535  
 
 536  0
         for ( Map.Entry<String, Exclusion> entry : mainExclusionMap.entrySet() )
 537  
         {
 538  0
             String key = entry.getKey();
 539  0
             Exclusion mainExclusion = entry.getValue();
 540  0
             Exclusion parentExclusion = parentExclusionMap.get( key );
 541  
 
 542  0
             if ( parentExclusion == null )
 543  
             {
 544  0
                 merged.add( mainExclusion );
 545  
             }
 546  
             else
 547  
             {
 548  0
                 merged.add( parentExclusion );
 549  
             }
 550  0
         }
 551  
 
 552  0
         return merged;
 553  
     }
 554  
 
 555  
     private static List<Individual> mergeIndividuals( List<Individual> mainIndividuals, List<Individual> parentIndividuals )
 556  
     {
 557  0
         if ( parentIndividuals == null )
 558  
         {
 559  0
             return mainIndividuals;
 560  
         }
 561  
 
 562  0
         if ( mainIndividuals == null )
 563  
         {
 564  0
             return ArchivaModelCloner.cloneIndividuals( parentIndividuals );
 565  
         }
 566  
 
 567  0
         List<Individual> merged = ArchivaModelCloner.cloneIndividuals( mainIndividuals );
 568  
 
 569  0
         Iterator<Individual> it = parentIndividuals.iterator();
 570  0
         while ( it.hasNext() )
 571  
         {
 572  0
             Individual parentIndividual = it.next();
 573  
 
 574  0
             if ( !mainIndividuals.contains( parentIndividual ) )
 575  
             {
 576  0
                 merged.add( parentIndividual );
 577  
             }
 578  0
         }
 579  
 
 580  0
         return merged;
 581  
     }
 582  
 
 583  
     private static List<License> mergeLicenses( List<License> mainLicenses, List<License> parentLicenses )
 584  
     {
 585  0
         if ( parentLicenses == null )
 586  
         {
 587  0
             return mainLicenses;
 588  
         }
 589  
 
 590  0
         if ( mainLicenses == null )
 591  
         {
 592  0
             return ArchivaModelCloner.cloneLicenses( parentLicenses );
 593  
         }
 594  
 
 595  0
         List<License> merged = new ArrayList<License>();
 596  
 
 597  0
         Map<String, License> mainLicensesMap = createLicensesMap( mainLicenses );
 598  0
         Map<String, License> parentLicensesMap = createLicensesMap( parentLicenses );
 599  
 
 600  0
         for ( Map.Entry<String, License> entry : mainLicensesMap.entrySet() )
 601  
         {
 602  0
             String key = entry.getKey();
 603  0
             License mainLicense = entry.getValue();
 604  0
             License parentLicense = parentLicensesMap.get( key );
 605  
 
 606  0
             if ( parentLicense == null )
 607  
             {
 608  0
                 merged.add( mainLicense );
 609  
             }
 610  
             else
 611  
             {
 612  
                 // Not merging. Local wins.
 613  0
                 merged.add( parentLicense );
 614  
             }
 615  0
         }
 616  
 
 617  0
         return merged;
 618  
     }
 619  
 
 620  
     private static List<ArtifactReference> mergePlugins( List<ArtifactReference> mainPlugins, List<ArtifactReference> parentPlugins )
 621  
     {
 622  0
         return mergeArtifactReferences( mainPlugins, parentPlugins );
 623  
     }
 624  
 
 625  
     private static List<ArtifactReference> mergeReports( List<ArtifactReference> mainReports, List<ArtifactReference> parentReports )
 626  
     {
 627  0
         return mergeArtifactReferences( mainReports, parentReports );
 628  
     }
 629  
 
 630  
     private static List<ProjectRepository> mergeRepositories( List<ProjectRepository> mainRepositories, List<ProjectRepository> parentRepositories )
 631  
     {
 632  0
         if ( parentRepositories == null )
 633  
         {
 634  0
             return mainRepositories;
 635  
         }
 636  
 
 637  0
         if ( mainRepositories == null )
 638  
         {
 639  0
             return ArchivaModelCloner.cloneRepositories( parentRepositories );
 640  
         }
 641  
 
 642  0
         List<ProjectRepository> merged = new ArrayList<ProjectRepository>();
 643  
 
 644  0
         Map<String, ProjectRepository> mainRepositoriesMap = createRepositoriesMap( mainRepositories );
 645  0
         Map<String, ProjectRepository> parentRepositoriesMap = createRepositoriesMap( parentRepositories );
 646  
 
 647  0
         for ( Map.Entry<String, ProjectRepository> entry : mainRepositoriesMap.entrySet() )
 648  
         {
 649  0
             String key = entry.getKey();
 650  0
             ProjectRepository mainProjectRepository = entry.getValue();
 651  0
             ProjectRepository parentProjectRepository = parentRepositoriesMap.get( key );
 652  
 
 653  0
             if ( parentProjectRepository == null )
 654  
             {
 655  0
                 merged.add( mainProjectRepository );
 656  
             }
 657  
             else
 658  
             {
 659  
                 // Not merging. Local wins.
 660  0
                 merged.add( parentProjectRepository );
 661  
             }
 662  0
         }
 663  
 
 664  0
         return merged;
 665  
     }
 666  
 
 667  
     private static String toVersionlessArtifactKey( ArtifactReference artifactReference )
 668  
     {
 669  0
         StringBuffer key = new StringBuffer();
 670  
 
 671  0
         key.append( artifactReference.getGroupId() ).append( ":" ).append( artifactReference.getArtifactId() );
 672  0
         key.append( StringUtils.defaultString( artifactReference.getClassifier() ) ).append( ":" );
 673  0
         key.append( artifactReference.getType() );
 674  
 
 675  0
         return key.toString();
 676  
     }
 677  
 
 678  
     private static String toVersionlessDependencyKey( Dependency dep )
 679  
     {
 680  0
         StringBuffer key = new StringBuffer();
 681  
 
 682  0
         key.append( dep.getGroupId() ).append( ":" ).append( dep.getArtifactId() );
 683  0
         key.append( StringUtils.defaultString( dep.getClassifier() ) ).append( ":" );
 684  0
         key.append( dep.getType() );
 685  
 
 686  0
         return key.toString();
 687  
     }
 688  
 }