Coverage Report - org.apache.maven.project.inheritance.DefaultModelInheritanceAssembler
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultModelInheritanceAssembler
98 %
194/197
84 %
118/140
5,643
 
 1  
 package org.apache.maven.project.inheritance;
 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 org.apache.maven.model.Build;
 23  
 import org.apache.maven.model.Dependency;
 24  
 import org.apache.maven.model.DependencyManagement;
 25  
 import org.apache.maven.model.DeploymentRepository;
 26  
 import org.apache.maven.model.DistributionManagement;
 27  
 import org.apache.maven.model.Model;
 28  
 import org.apache.maven.model.PluginManagement;
 29  
 import org.apache.maven.model.Reporting;
 30  
 import org.apache.maven.model.Scm;
 31  
 import org.apache.maven.model.Site;
 32  
 import org.apache.maven.project.ModelUtils;
 33  
 import org.codehaus.plexus.util.StringUtils;
 34  
 
 35  
 import java.util.ArrayList;
 36  
 import java.util.Iterator;
 37  
 import java.util.LinkedList;
 38  
 import java.util.List;
 39  
 import java.util.Map;
 40  
 import java.util.Properties;
 41  
 import java.util.StringTokenizer;
 42  
 import java.util.TreeMap;
 43  
 
 44  
 /**
 45  
  * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
 46  
  * @version $Id: DefaultModelInheritanceAssembler.java,v 1.4 2004/08/23 20:24:54
 47  
  *          jdcasey Exp $
 48  
  * @todo generate this with modello to keep it in sync with changes in the model.
 49  
  */
 50  116
 public class DefaultModelInheritanceAssembler
 51  
     implements ModelInheritanceAssembler
 52  
 {
 53  
     public void copyModel( Model dest, Model source )
 54  
     {
 55  0
         assembleModelInheritance( dest, source, null, false );
 56  0
     }
 57  
 
 58  
     public void assembleModelInheritance( Model child, Model parent, String childPathAdjustment )
 59  
     {
 60  147
         assembleModelInheritance( child, parent, childPathAdjustment, true );
 61  147
     }
 62  
 
 63  
     public void assembleModelInheritance( Model child, Model parent )
 64  
     {
 65  43
         assembleModelInheritance( child, parent, null, true );
 66  43
     }
 67  
 
 68  
     private void assembleModelInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
 69  
     {
 70  
         // cannot inherit from null parent.
 71  190
         if ( parent == null )
 72  
         {
 73  0
             return;
 74  
         }
 75  
 
 76  
         // Group id
 77  190
         if ( child.getGroupId() == null )
 78  
         {
 79  6
             child.setGroupId( parent.getGroupId() );
 80  
         }
 81  
 
 82  
         // version
 83  190
         if ( child.getVersion() == null )
 84  
         {
 85  
             // The parent version may have resolved to something different, so we take what we asked for...
 86  
             // instead of - child.setVersion( parent.getVersion() );
 87  
 
 88  6
             if ( child.getParent() != null )
 89  
             {
 90  6
                 child.setVersion( child.getParent().getVersion() );
 91  
             }
 92  
         }
 93  
 
 94  
         // inceptionYear
 95  190
         if ( child.getInceptionYear() == null )
 96  
         {
 97  185
             child.setInceptionYear( parent.getInceptionYear() );
 98  
         }
 99  
 
 100  
         // url
 101  190
         if ( child.getUrl() == null )
 102  
         {
 103  189
             if ( parent.getUrl() != null )
 104  
             {
 105  3
                 child.setUrl( appendPath( parent.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
 106  
             }
 107  
             else
 108  
             {
 109  186
                 child.setUrl( parent.getUrl() );
 110  
             }
 111  
         }
 112  
 
 113  190
         assembleDistributionInheritence( child, parent, childPathAdjustment, appendPaths );
 114  
 
 115  
         // issueManagement
 116  190
         if ( child.getIssueManagement() == null )
 117  
         {
 118  190
             child.setIssueManagement( parent.getIssueManagement() );
 119  
         }
 120  
 
 121  
         // description
 122  190
         if ( child.getDescription() == null )
 123  
         {
 124  189
             child.setDescription( parent.getDescription() );
 125  
         }
 126  
 
 127  
         // Organization
 128  190
         if ( child.getOrganization() == null )
 129  
         {
 130  143
             child.setOrganization( parent.getOrganization() );
 131  
         }
 132  
 
 133  
         // Scm
 134  190
         assembleScmInheritance( child, parent, childPathAdjustment, appendPaths );
 135  
 
 136  
         // ciManagement
 137  190
         if ( child.getCiManagement() == null )
 138  
         {
 139  190
             child.setCiManagement( parent.getCiManagement() );
 140  
         }
 141  
 
 142  
         // developers
 143  190
         if ( child.getDevelopers().size() == 0 )
 144  
         {
 145  189
             child.setDevelopers( parent.getDevelopers() );
 146  
         }
 147  
 
 148  
         // licenses
 149  190
         if ( child.getLicenses().size() == 0 )
 150  
         {
 151  190
             child.setLicenses( parent.getLicenses() );
 152  
         }
 153  
 
 154  
         // developers
 155  190
         if ( child.getContributors().size() == 0 )
 156  
         {
 157  189
             child.setContributors( parent.getContributors() );
 158  
         }
 159  
 
 160  
         // mailingLists
 161  190
         if ( child.getMailingLists().size() == 0 )
 162  
         {
 163  184
             child.setMailingLists( parent.getMailingLists() );
 164  
         }
 165  
 
 166  
         // Build
 167  190
         assembleBuildInheritance( child, parent );
 168  
 
 169  190
         assembleDependencyInheritance( child, parent );
 170  
 
 171  190
         child.setRepositories( ModelUtils.mergeRepositoryLists( child.getRepositories(), parent.getRepositories() ) );
 172  190
         child.setPluginRepositories(
 173  
             ModelUtils.mergeRepositoryLists( child.getPluginRepositories(), parent.getPluginRepositories() ) );
 174  
 
 175  190
         assembleReportingInheritance( child, parent );
 176  
 
 177  190
         assembleDependencyManagementInheritance( child, parent );
 178  
 
 179  190
         Properties props = new Properties();
 180  190
         props.putAll( parent.getProperties() );
 181  190
         props.putAll( child.getProperties() );
 182  
 
 183  190
         child.setProperties( props );
 184  190
     }
 185  
 
 186  
     private void assembleDependencyManagementInheritance( Model child, Model parent )
 187  
     {
 188  190
         DependencyManagement parentDepMgmt = parent.getDependencyManagement();
 189  
 
 190  190
         DependencyManagement childDepMgmt = child.getDependencyManagement();
 191  
 
 192  190
         if ( parentDepMgmt != null )
 193  
         {
 194  17
             if ( childDepMgmt == null )
 195  
             {
 196  6
                 child.setDependencyManagement( parentDepMgmt );
 197  
             }
 198  
             else
 199  
             {
 200  11
                 List childDeps = childDepMgmt.getDependencies();
 201  
 
 202  11
                 Map mappedChildDeps = new TreeMap();
 203  11
                 for ( Iterator it = childDeps.iterator(); it.hasNext(); )
 204  
                 {
 205  20
                     Dependency dep = (Dependency) it.next();
 206  20
                     mappedChildDeps.put( dep.getManagementKey(), dep );
 207  20
                 }
 208  
 
 209  11
                 for ( Iterator it = parentDepMgmt.getDependencies().iterator(); it.hasNext(); )
 210  
                 {
 211  24
                     Dependency dep = (Dependency) it.next();
 212  24
                     if ( !mappedChildDeps.containsKey( dep.getManagementKey() ) )
 213  
                     {
 214  15
                         childDepMgmt.addDependency( dep );
 215  
                     }
 216  24
                 }
 217  
             }
 218  
         }
 219  190
     }
 220  
 
 221  
     private void assembleReportingInheritance( Model child, Model parent )
 222  
     {
 223  
         // Reports :: aggregate
 224  190
         Reporting childReporting = child.getReporting();
 225  190
         Reporting parentReporting = parent.getReporting();
 226  
 
 227  190
         if ( parentReporting != null )
 228  
         {
 229  159
             if ( childReporting == null )
 230  
             {
 231  150
                 childReporting = new Reporting();
 232  150
                 child.setReporting( childReporting );
 233  
             }
 234  
 
 235  159
             if ( childReporting.isExcludeDefaultsValue() == null )
 236  
             {
 237  153
                 childReporting.setExcludeDefaultsValue( parentReporting.isExcludeDefaultsValue() );
 238  
             }
 239  
 
 240  159
             if ( StringUtils.isEmpty( childReporting.getOutputDirectory() ) )
 241  
             {
 242  159
                 childReporting.setOutputDirectory( parentReporting.getOutputDirectory() );
 243  
             }
 244  
 
 245  159
             ModelUtils.mergeReportPluginLists( childReporting, parentReporting, true );
 246  
         }
 247  190
     }
 248  
 
 249  
     private void assembleDependencyInheritance( Model child, Model parent )
 250  
     {
 251  190
         child.setDependencies( ModelUtils.mergeDependencyList( child.getDependencies(), parent.getDependencies() ) );
 252  190
     }
 253  
 
 254  
     private void assembleBuildInheritance( Model child, Model parent )
 255  
     {
 256  190
         Build childBuild = child.getBuild();
 257  190
         Build parentBuild = parent.getBuild();
 258  
 
 259  190
         if ( parentBuild != null )
 260  
         {
 261  150
             if ( childBuild == null )
 262  
             {
 263  110
                 childBuild = new Build();
 264  110
                 child.setBuild( childBuild );
 265  
             }
 266  
 
 267  150
             assembleBuildInheritance( childBuild, parentBuild, true );
 268  
         }
 269  190
     }
 270  
 
 271  
     public void assembleBuildInheritance( Build childBuild,
 272  
                                            Build parentBuild,
 273  
                                            boolean handleAsInheritance )
 274  
     {
 275  
         // The build has been set but we want to step in here and fill in
 276  
         // values that have not been set by the child.
 277  
 
 278  150
         if ( childBuild.getSourceDirectory() == null )
 279  
         {
 280  140
             childBuild.setSourceDirectory( parentBuild.getSourceDirectory() );
 281  
         }
 282  
 
 283  150
         if ( childBuild.getScriptSourceDirectory() == null )
 284  
         {
 285  142
             childBuild.setScriptSourceDirectory( parentBuild.getScriptSourceDirectory() );
 286  
         }
 287  
 
 288  150
         if ( childBuild.getTestSourceDirectory() == null )
 289  
         {
 290  141
             childBuild.setTestSourceDirectory( parentBuild.getTestSourceDirectory() );
 291  
         }
 292  
 
 293  150
         if ( childBuild.getOutputDirectory() == null )
 294  
         {
 295  144
             childBuild.setOutputDirectory( parentBuild.getOutputDirectory() );
 296  
         }
 297  
 
 298  150
         if ( childBuild.getTestOutputDirectory() == null )
 299  
         {
 300  144
             childBuild.setTestOutputDirectory( parentBuild.getTestOutputDirectory() );
 301  
         }
 302  
 
 303  
         // Extensions are accumlated
 304  150
         ModelUtils.mergeExtensionLists( childBuild, parentBuild );
 305  
 
 306  150
         if ( childBuild.getDirectory() == null )
 307  
         {
 308  144
             childBuild.setDirectory( parentBuild.getDirectory() );
 309  
         }
 310  
 
 311  150
         if ( childBuild.getDefaultGoal() == null )
 312  
         {
 313  150
             childBuild.setDefaultGoal( parentBuild.getDefaultGoal() );
 314  
         }
 315  
 
 316  150
         if ( childBuild.getFinalName() == null )
 317  
         {
 318  150
             childBuild.setFinalName( parentBuild.getFinalName() );
 319  
         }
 320  
 
 321  150
         ModelUtils.mergeFilterLists( childBuild.getFilters(), parentBuild.getFilters() );
 322  
 
 323  150
         List resources = childBuild.getResources();
 324  150
         if ( ( resources == null ) || resources.isEmpty() )
 325  
         {
 326  142
             childBuild.setResources( parentBuild.getResources() );
 327  
         }
 328  
 
 329  150
         resources = childBuild.getTestResources();
 330  150
         if ( ( resources == null ) || resources.isEmpty() )
 331  
         {
 332  149
             childBuild.setTestResources( parentBuild.getTestResources() );
 333  
         }
 334  
 
 335  
         // Plugins are aggregated if Plugin.inherit != false
 336  150
         ModelUtils.mergePluginLists( childBuild, parentBuild, handleAsInheritance );
 337  
 
 338  
         // Plugin management :: aggregate
 339  150
         PluginManagement dominantPM = childBuild.getPluginManagement();
 340  150
         PluginManagement recessivePM = parentBuild.getPluginManagement();
 341  
 
 342  150
         if ( ( dominantPM == null ) && ( recessivePM != null ) )
 343  
         {
 344  
             // FIXME: Filter out the inherited == false stuff!
 345  144
             childBuild.setPluginManagement( recessivePM );
 346  
         }
 347  
         else
 348  
         {
 349  6
             ModelUtils.mergePluginLists( childBuild.getPluginManagement(), parentBuild.getPluginManagement(),
 350  
                                          false );
 351  
         }
 352  150
     }
 353  
 
 354  
     private void assembleScmInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
 355  
     {
 356  190
         if ( parent.getScm() != null )
 357  
         {
 358  22
             Scm parentScm = parent.getScm();
 359  
 
 360  22
             Scm childScm = child.getScm();
 361  
 
 362  22
             if ( childScm == null )
 363  
             {
 364  18
                 childScm = new Scm();
 365  
 
 366  18
                 child.setScm( childScm );
 367  
             }
 368  
 
 369  22
             if ( StringUtils.isEmpty( childScm.getConnection() ) && !StringUtils.isEmpty( parentScm.getConnection() ) )
 370  
             {
 371  4
                 childScm.setConnection(
 372  
                     appendPath( parentScm.getConnection(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
 373  
             }
 374  
 
 375  22
             if ( StringUtils.isEmpty( childScm.getDeveloperConnection() ) &&
 376  
                 !StringUtils.isEmpty( parentScm.getDeveloperConnection() ) )
 377  
             {
 378  4
                 childScm
 379  
                     .setDeveloperConnection( appendPath( parentScm.getDeveloperConnection(), child.getArtifactId(),
 380  
                                                          childPathAdjustment, appendPaths ) );
 381  
             }
 382  
 
 383  22
             if ( StringUtils.isEmpty( childScm.getUrl() ) && !StringUtils.isEmpty( parentScm.getUrl() ) )
 384  
             {
 385  13
                 childScm.setUrl(
 386  
                     appendPath( parentScm.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
 387  
             }
 388  
         }
 389  190
     }
 390  
 
 391  
     private void assembleDistributionInheritence( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
 392  
     {
 393  190
         if ( parent.getDistributionManagement() != null )
 394  
         {
 395  1
             DistributionManagement parentDistMgmt = parent.getDistributionManagement();
 396  
 
 397  1
             DistributionManagement childDistMgmt = child.getDistributionManagement();
 398  
 
 399  1
             if ( childDistMgmt == null )
 400  
             {
 401  1
                 childDistMgmt = new DistributionManagement();
 402  
 
 403  1
                 child.setDistributionManagement( childDistMgmt );
 404  
             }
 405  
 
 406  1
             if ( childDistMgmt.getSite() == null )
 407  
             {
 408  1
                 if ( parentDistMgmt.getSite() != null )
 409  
                 {
 410  1
                     Site site = new Site();
 411  
 
 412  1
                     childDistMgmt.setSite( site );
 413  
 
 414  1
                     site.setId( parentDistMgmt.getSite().getId() );
 415  
 
 416  1
                     site.setName( parentDistMgmt.getSite().getName() );
 417  
 
 418  1
                     site.setUrl( parentDistMgmt.getSite().getUrl() );
 419  
 
 420  1
                     if ( site.getUrl() != null )
 421  
                     {
 422  1
                         site.setUrl(
 423  
                             appendPath( site.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
 424  
                     }
 425  
                 }
 426  
             }
 427  
 
 428  1
             if ( childDistMgmt.getRepository() == null )
 429  
             {
 430  1
                 if ( parentDistMgmt.getRepository() != null )
 431  
                 {
 432  1
                     DeploymentRepository repository = copyDistributionRepository( parentDistMgmt.getRepository() );
 433  1
                     childDistMgmt.setRepository( repository );
 434  
                 }
 435  
             }
 436  
 
 437  1
             if ( childDistMgmt.getSnapshotRepository() == null )
 438  
             {
 439  1
                 if ( parentDistMgmt.getSnapshotRepository() != null )
 440  
                 {
 441  1
                     DeploymentRepository repository =
 442  
                         copyDistributionRepository( parentDistMgmt.getSnapshotRepository() );
 443  1
                     childDistMgmt.setSnapshotRepository( repository );
 444  
                 }
 445  
             }
 446  
 
 447  1
             if ( StringUtils.isEmpty( childDistMgmt.getDownloadUrl() ) )
 448  
             {
 449  1
                 childDistMgmt.setDownloadUrl( parentDistMgmt.getDownloadUrl() );
 450  
             }
 451  
 
 452  
             // NOTE: We SHOULD NOT be inheriting status, since this is an assessment of the POM quality.
 453  
             // NOTE: We SHOULD NOT be inheriting relocation, since this relates to a single POM
 454  
         }
 455  190
     }
 456  
 
 457  
     private static DeploymentRepository copyDistributionRepository( DeploymentRepository parentRepository )
 458  
     {
 459  2
         DeploymentRepository repository = new DeploymentRepository();
 460  
 
 461  2
         repository.setId( parentRepository.getId() );
 462  
 
 463  2
         repository.setName( parentRepository.getName() );
 464  
 
 465  2
         repository.setUrl( parentRepository.getUrl() );
 466  
 
 467  2
         repository.setLayout( parentRepository.getLayout() );
 468  
 
 469  2
         repository.setUniqueVersion( parentRepository.isUniqueVersion() );
 470  
 
 471  2
         return repository;
 472  
     }
 473  
 
 474  
     // TODO: This should eventually be migrated to DefaultPathTranslator.
 475  
     protected String appendPath( String parentPath, String childPath, String pathAdjustment, boolean appendPaths )
 476  
     {
 477  29
         String uncleanPath = parentPath;
 478  
 
 479  29
         if ( appendPaths )
 480  
         {
 481  29
             if ( pathAdjustment != null )
 482  
             {
 483  6
                 uncleanPath += "/" + pathAdjustment;
 484  
             }
 485  
 
 486  29
             if ( childPath != null )
 487  
             {
 488  27
                 uncleanPath += "/" + childPath;
 489  
             }
 490  
         }
 491  
 
 492  29
         String cleanedPath = "";
 493  
 
 494  29
         int protocolIdx = uncleanPath.indexOf( "://" );
 495  
 
 496  29
         if ( protocolIdx > -1 )
 497  
         {
 498  8
             cleanedPath = uncleanPath.substring( 0, protocolIdx + 3 );
 499  8
             uncleanPath = uncleanPath.substring( protocolIdx + 3 );
 500  
         }
 501  
 
 502  29
         if ( uncleanPath.startsWith( "//" ) )
 503  
         {
 504  
             // preserve leading double slash for UNC paths like "file:////host/pom.xml"
 505  1
             cleanedPath += "//";
 506  
         }
 507  28
         else if ( uncleanPath.startsWith( "/" ) )
 508  
         {
 509  1
             cleanedPath += "/";
 510  
         }
 511  
 
 512  29
         return cleanedPath + resolvePath( uncleanPath );
 513  
     }
 514  
 
 515  
     // TODO: Move this to plexus-utils' PathTool.
 516  
     private static String resolvePath( String uncleanPath )
 517  
     {
 518  29
         LinkedList pathElements = new LinkedList();
 519  
 
 520  29
         StringTokenizer tokenizer = new StringTokenizer( uncleanPath, "/" );
 521  
 
 522  126
         while ( tokenizer.hasMoreTokens() )
 523  
         {
 524  97
             String token = tokenizer.nextToken();
 525  
 
 526  97
             if ( token.equals( "" ) )
 527  
             {
 528  
                 // Empty path entry ("...//.."), remove.
 529  
             }
 530  97
             else if ( token.equals( ".." ) )
 531  
             {
 532  6
                 if ( pathElements.isEmpty() )
 533  
                 {
 534  
                     // FIXME: somehow report to the user
 535  
                     // that there are too many '..' elements.
 536  
                     // For now, ignore the extra '..'.
 537  
                 }
 538  
                 else
 539  
                 {
 540  5
                     pathElements.removeLast();
 541  
                 }
 542  
             }
 543  
             else
 544  
             {
 545  91
                 pathElements.addLast( token );
 546  
             }
 547  97
         }
 548  
 
 549  
 
 550  29
         StringBuffer cleanedPath = new StringBuffer();
 551  
 
 552  115
         while ( !pathElements.isEmpty() )
 553  
         {
 554  86
             cleanedPath.append( pathElements.removeFirst() );
 555  86
             if ( !pathElements.isEmpty() )
 556  
             {
 557  57
                 cleanedPath.append( '/' );
 558  
             }
 559  
         }
 560  
 
 561  29
         return cleanedPath.toString();
 562  
     }
 563  
 
 564  
 }