Coverage Report - org.apache.maven.plugin.resources.remote.ProcessRemoteResourcesMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
ProcessRemoteResourcesMojo
39%
147/375
31%
51/166
0
ProcessRemoteResourcesMojo$OrganizationComparator
8%
1/13
0%
0/16
0
ProcessRemoteResourcesMojo$ProjectComparator
33%
1/3
N/A
0
 
 1  
 package org.apache.maven.plugin.resources.remote;
 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.ProjectDependenciesResolver;
 23  
 import org.apache.maven.artifact.Artifact;
 24  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 25  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 26  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 27  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 28  
 import org.apache.maven.artifact.versioning.VersionRange;
 29  
 import org.apache.maven.execution.MavenSession;
 30  
 import org.apache.maven.model.Model;
 31  
 import org.apache.maven.model.Organization;
 32  
 import org.apache.maven.model.Resource;
 33  
 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 34  
 import org.apache.maven.plugin.AbstractMojo;
 35  
 import org.apache.maven.plugin.MojoExecutionException;
 36  
 import org.apache.maven.plugin.logging.Log;
 37  
 import org.apache.maven.plugin.resources.remote.io.xpp3.RemoteResourcesBundleXpp3Reader;
 38  
 import org.apache.maven.plugin.resources.remote.io.xpp3.SupplementalDataModelXpp3Reader;
 39  
 import org.apache.maven.project.InvalidProjectModelException;
 40  
 import org.apache.maven.project.MavenProject;
 41  
 import org.apache.maven.project.MavenProjectBuilder;
 42  
 import org.apache.maven.project.ProjectBuildingException;
 43  
 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
 44  
 import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
 45  
 import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
 46  
 import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
 47  
 import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
 48  
 import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
 49  
 import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
 50  
 import org.apache.maven.shared.artifact.filter.collection.TransitivityFilter;
 51  
 import org.apache.maven.shared.downloader.DownloadException;
 52  
 import org.apache.maven.shared.downloader.DownloadNotFoundException;
 53  
 import org.apache.maven.shared.downloader.Downloader;
 54  
 import org.apache.maven.shared.filtering.MavenFileFilter;
 55  
 import org.apache.maven.shared.filtering.MavenFileFilterRequest;
 56  
 import org.apache.maven.shared.filtering.MavenFilteringException;
 57  
 import org.apache.velocity.VelocityContext;
 58  
 import org.apache.velocity.app.Velocity;
 59  
 import org.apache.velocity.exception.MethodInvocationException;
 60  
 import org.apache.velocity.exception.ParseErrorException;
 61  
 import org.apache.velocity.exception.ResourceNotFoundException;
 62  
 import org.codehaus.plexus.resource.ResourceManager;
 63  
 import org.codehaus.plexus.resource.loader.FileResourceLoader;
 64  
 import org.codehaus.plexus.util.FileUtils;
 65  
 import org.codehaus.plexus.util.IOUtil;
 66  
 import org.codehaus.plexus.util.ReaderFactory;
 67  
 import org.codehaus.plexus.util.StringUtils;
 68  
 import org.codehaus.plexus.util.WriterFactory;
 69  
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 70  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 71  
 import org.codehaus.plexus.velocity.VelocityComponent;
 72  
 
 73  
 import java.io.File;
 74  
 import java.io.FileInputStream;
 75  
 import java.io.FileOutputStream;
 76  
 import java.io.FileReader;
 77  
 import java.io.FileWriter;
 78  
 import java.io.IOException;
 79  
 import java.io.InputStream;
 80  
 import java.io.InputStreamReader;
 81  
 import java.io.OutputStream;
 82  
 import java.io.OutputStreamWriter;
 83  
 import java.io.PrintWriter;
 84  
 import java.io.Reader;
 85  
 import java.io.StringReader;
 86  
 import java.io.Writer;
 87  
 import java.net.MalformedURLException;
 88  
 import java.net.URL;
 89  
 import java.text.SimpleDateFormat;
 90  
 import java.util.ArrayList;
 91  
 import java.util.Collections;
 92  
 import java.util.Comparator;
 93  
 import java.util.Date;
 94  
 import java.util.Enumeration;
 95  
 import java.util.HashMap;
 96  
 import java.util.LinkedHashSet;
 97  
 import java.util.List;
 98  
 import java.util.Map;
 99  
 import java.util.Set;
 100  
 import java.util.TreeMap;
 101  
 
 102  
 /**
 103  
  * <p>
 104  
  * Pull down resourceBundles containing remote resources and process the
 105  
  * resources contained inside. When that is done the resources are injected
 106  
  * into the current (in-memory) Maven project, making them available to the
 107  
  * process-resources phase.
 108  
  * </p>
 109  
  * <p>
 110  
  * Resources that end in ".vm" are treated as velocity templates.  For those, the ".vm" is
 111  
  * stripped off for the final artifact name and it's  fed through velocity to have properties
 112  
  * expanded, conditions processed, etc...
 113  
  * </p>
 114  
  * <p>
 115  
  * Resources that don't end in ".vm" are copied "as is".
 116  
  * </p>
 117  
  *
 118  
  * @goal process
 119  
  * @phase generate-resources
 120  
  */
 121  
 // NOTE: Removed the following in favor of maven-artifact-resolver library, for MRRESOURCES-41
 122  
 // If I leave this intact, interdependent projects within the reactor that haven't been built
 123  
 // (remember, this runs in the generate-resources phase) will cause the build to fail.
 124  
 //
 125  
 // @requiresDependencyResolution test
 126  18
 public class ProcessRemoteResourcesMojo
 127  
     extends AbstractMojo
 128  
 {
 129  
     
 130  
     private static final String TEMPLATE_SUFFIX = ".vm";
 131  
     
 132  
     /**
 133  
      * <p>
 134  
      * In cases where a local resource overrides one from a remote resource bundle, that resource
 135  
      * should be filtered if the resource set specifies it. In those cases, this parameter defines
 136  
      * the list of delimiters for filterable expressions. These delimiters are specified in the
 137  
      * form 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end.
 138  
      * </p>
 139  
      * <p>
 140  
      * So, the default filtering delimiters might be specified as:
 141  
      * </p>
 142  
      * <pre>
 143  
      * &lt;delimiters&gt;
 144  
      *   &lt;delimiter&gt;${*}&lt/delimiter&gt;
 145  
      *   &lt;delimiter&gt;@&lt/delimiter&gt;
 146  
      * &lt;/delimiters&gt;
 147  
      * </pre>
 148  
      * <p>
 149  
      * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
 150  
      * </p>
 151  
      * @parameter
 152  
      * @since 1.1
 153  
      */
 154  
     protected List<String> filterDelimiters;
 155  
 
 156  
     /**
 157  
      * @parameter default-value="true"
 158  
      * @since 1.1
 159  
      */
 160  
     protected boolean useDefaultFilterDelimiters;
 161  
     
 162  
     /**
 163  
      * If true, only generate resources in the directory of the root project in a multimodule build.
 164  
      * Dependencies from all modules will be aggregated before resource-generation takes place.
 165  
      * 
 166  
      * @parameter default-value="false"
 167  
      * @since 1.1
 168  
      */
 169  
     protected boolean runOnlyAtExecutionRoot;
 170  
     
 171  
     /**
 172  
      * Used for calculation of execution-root for {@link ProcessRemoteResourcesMojo#runOnlyAtExecutionRoot}.
 173  
      * 
 174  
      * @parameter default-value="${basedir}"
 175  
      * @readonly
 176  
      * @required
 177  
      */
 178  
     protected File basedir;
 179  
     
 180  
     /**
 181  
      * The character encoding scheme to be applied when filtering resources.
 182  
      *
 183  
      * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
 184  
      */
 185  
     protected String encoding;
 186  
 
 187  
     /**
 188  
      * The local repository taken from Maven's runtime. Typically $HOME/.m2/repository.
 189  
      *
 190  
      * @parameter expression="${localRepository}"
 191  
      * @readonly
 192  
      * @required
 193  
      */
 194  
     private ArtifactRepository localRepository;
 195  
 
 196  
     /**
 197  
      * List of Remote Repositories used by the resolver
 198  
      *
 199  
      * @parameter expression="${project.remoteArtifactRepositories}"
 200  
      * @readonly
 201  
      * @required
 202  
      */
 203  
     private List<ArtifactRepository> remoteArtifactRepositories;
 204  
 
 205  
     /**
 206  
      * The current Maven project.
 207  
      *
 208  
      * @parameter expression="${project}"
 209  
      * @readonly
 210  
      * @required
 211  
      */
 212  
     private MavenProject project;
 213  
 
 214  
     /**
 215  
      * The directory where processed resources will be placed for packaging.
 216  
      *
 217  
      * @parameter expression="${project.build.directory}/maven-shared-archive-resources"
 218  
      */
 219  
     private File outputDirectory;
 220  
 
 221  
     /**
 222  
      * The directory containing extra information appended to the generated resources.
 223  
      *
 224  
      * @parameter expression="${basedir}/src/main/appended-resources"
 225  
      */
 226  
     private File appendedResourcesDirectory;
 227  
 
 228  
     /**
 229  
      * Supplemental model data.  Useful when processing
 230  
      * artifacts with incomplete POM metadata.
 231  
      * <p/>
 232  
      * By default, this Mojo looks for supplemental model
 233  
      * data in the file "${appendedResourcesDirectory}/supplemental-models.xml".
 234  
      *
 235  
      * @parameter
 236  
      * @since 1.0-alpha-5
 237  
      */
 238  
     private String[] supplementalModels;
 239  
 
 240  
     /**
 241  
      * List of artifacts that are added to the search path when looking 
 242  
      * for supplementalModels
 243  
      * @parameter
 244  
      * @since 1.1 
 245  
      */
 246  
     private List<String> supplementalModelArtifacts;
 247  
 
 248  
     /**
 249  
      * Map of artifacts to supplemental project object models.
 250  
      */
 251  
     private Map<String, Model> supplementModels;
 252  
     
 253  
     /**
 254  
      * Merges supplemental data model with artifact
 255  
      * metadata.  Useful when processing artifacts with
 256  
      * incomplete POM metadata.
 257  
      *
 258  
      * @component
 259  
      * @readonly
 260  
      * @required
 261  
      */
 262  
     private ModelInheritanceAssembler inheritanceAssembler;
 263  
 
 264  
     /**
 265  
      * The resource bundles that will be retrieved and processed.
 266  
      *
 267  
      * @parameter
 268  
      * @required
 269  
      */
 270  
     private List<String> resourceBundles;
 271  
 
 272  
     /**
 273  
      * Skip remote-resource processing
 274  
      *
 275  
      * @parameter expression="${remoteresources.skip}" default-value="false"
 276  
      * @since 1.0-alpha-5
 277  
      */
 278  
     private boolean skip;
 279  
 
 280  
     /**
 281  
      * Attaches the resource to the project as a resource directory
 282  
      *
 283  
      * @parameter default-value="true"
 284  
      * @since 1.0-beta-1
 285  
      */
 286  18
     private boolean attached = true;
 287  
 
 288  
     /**
 289  
      * Additional properties to be passed to velocity.
 290  
      * <p/>
 291  
      * Several properties are automatically added:<br/>
 292  
      * project - the current MavenProject <br/>
 293  
      * projects - the list of dependency projects<br/>
 294  
      * projectTimespan - the timespan of the current project (requires inceptionYear in pom)<br/>
 295  
      * <p/>
 296  
      * See <a href="http://maven.apache.org/ref/current/maven-project/apidocs/org/apache/maven/project/MavenProject.html">
 297  
      * the javadoc for MavenProject</a> for information about the properties on the MavenProject.
 298  
      *
 299  
      * @parameter
 300  
      */
 301  18
     private Map<String, String> properties = new HashMap<String, String>();
 302  
 
 303  
     /**
 304  
      * The list of resources defined for the project.
 305  
      *
 306  
      * @parameter expression="${project.resources}"
 307  
      * @readonly
 308  
      * @required
 309  
      */
 310  
     private List<Resource> resources;
 311  
 
 312  
     /**
 313  
      * Artifact downloader.
 314  
      *
 315  
      * @component
 316  
      * @readonly
 317  
      * @required
 318  
      */
 319  
     private Downloader downloader;
 320  
 
 321  
     /**
 322  
      * Velocity component.
 323  
      *
 324  
      * @component
 325  
      * @readonly
 326  
      * @required
 327  
      */
 328  
     private VelocityComponent velocity;
 329  
     
 330  
     /**
 331  
      * Filtering support, for local resources that override those in the remote bundle.
 332  
      * 
 333  
      * @component
 334  
      */
 335  
     private MavenFileFilter fileFilter;
 336  
 
 337  
     /**
 338  
      * Artifact factory, needed to create artifacts.
 339  
      *
 340  
      * @component
 341  
      * @readonly
 342  
      * @required
 343  
      */
 344  
     private ArtifactFactory artifactFactory;
 345  
 
 346  
     /**
 347  
      * The Maven session.
 348  
      *
 349  
      * @parameter expression="${session}"
 350  
      * @readonly
 351  
      * @required
 352  
      */
 353  
     private MavenSession mavenSession;
 354  
 
 355  
     /**
 356  
      * ProjectBuilder, needed to create projects from the artifacts.
 357  
      *
 358  
      * @component role="org.apache.maven.project.MavenProjectBuilder"
 359  
      * @required
 360  
      * @readonly
 361  
      */
 362  
     private MavenProjectBuilder mavenProjectBuilder;
 363  
 
 364  
     /**
 365  
      * @component
 366  
      * @required
 367  
      * @readonly
 368  
      */
 369  
     private ResourceManager locator;
 370  
 
 371  
 
 372  
     /**
 373  
      * Scope to include. An Empty string indicates all scopes (default).
 374  
      *
 375  
      * @since 1.0
 376  
      * @parameter expression="${includeScope}" default-value="runtime"
 377  
      * @optional
 378  
      */
 379  
     protected String includeScope;
 380  
 
 381  
     /**
 382  
      * Scope to exclude. An Empty string indicates no scopes (default).
 383  
      *
 384  
      * @since 1.0
 385  
      * @parameter expression="${excludeScope}" default-value=""
 386  
      * @optional
 387  
      */
 388  
     protected String excludeScope;
 389  
 
 390  
     /**
 391  
      * Comma separated list of Artifact names too exclude.
 392  
      *
 393  
      * @since 1.0
 394  
      * @optional
 395  
      * @parameter expression="${excludeArtifactIds}" default-value=""
 396  
      */
 397  
     protected String excludeArtifactIds;
 398  
 
 399  
     /**
 400  
      * Comma separated list of Artifact names to include.
 401  
      *
 402  
      * @since 1.0
 403  
      * @optional
 404  
      * @parameter expression="${includeArtifactIds}" default-value=""
 405  
      */
 406  
     protected String includeArtifactIds;
 407  
 
 408  
     /**
 409  
      * Comma separated list of GroupId Names to exclude.
 410  
      *
 411  
      * @since 1.0
 412  
      * @optional
 413  
      * @parameter expression="${excludeGroupIds}" default-value=""
 414  
      */
 415  
     protected String excludeGroupIds;
 416  
 
 417  
     /**
 418  
      * Comma separated list of GroupIds to include.
 419  
      *
 420  
      * @since 1.0
 421  
      * @optional
 422  
      * @parameter expression="${includeGroupIds}" default-value=""
 423  
      */
 424  
     protected String includeGroupIds;
 425  
 
 426  
     /**
 427  
      * If we should exclude transitive dependencies
 428  
      *
 429  
      * @since 1.0
 430  
      * @optional
 431  
      * @parameter expression="${excludeTransitive}" default-value="false"
 432  
      */
 433  
     protected boolean excludeTransitive;
 434  
     
 435  
     /**
 436  
      * @component role-hint="default"
 437  
      */
 438  
     protected ProjectDependenciesResolver dependencyResolver;
 439  
 
 440  
     @SuppressWarnings( "unchecked" )
 441  
     public void execute()
 442  
         throws MojoExecutionException
 443  
     {
 444  18
         if ( skip )
 445  
         {
 446  0
             return;
 447  
         }
 448  
         
 449  18
         if ( runOnlyAtExecutionRoot && !isExecutionRoot() )
 450  
         {
 451  0
             getLog().info( "Skipping remote-resource generation in this project because it's not the Execution Root" );
 452  0
             return;
 453  
         }
 454  
         
 455  18
         if ( supplementalModels == null )
 456  
         {
 457  18
             File sups = new File( appendedResourcesDirectory, "supplemental-models.xml" );
 458  18
             if ( sups.exists() )
 459  
             {
 460  
                 try
 461  
                 {
 462  0
                     supplementalModels = new String[]{sups.toURL().toString()};
 463  
                 }
 464  0
                 catch ( MalformedURLException e )
 465  
                 {
 466  
                     //ignore
 467  0
                     getLog().debug( "URL issue with supplemental-models.xml: " + e.toString() );
 468  0
                 }
 469  
             }
 470  
         }
 471  
 
 472  18
         addSupplementalModelArtifacts();
 473  18
         locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
 474  18
         if ( appendedResourcesDirectory != null )
 475  
         {
 476  0
             locator.addSearchPath( FileResourceLoader.ID, appendedResourcesDirectory.getAbsolutePath() );
 477  
         }
 478  18
         locator.addSearchPath( "url", "" );
 479  18
         locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
 480  
 
 481  18
         ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
 482  
         try
 483  
         {
 484  18
             Thread.currentThread().setContextClassLoader( this.getClass().getClassLoader() );
 485  
 
 486  18
             validate();
 487  
 
 488  18
             List<File> resourceBundleArtifacts = downloadBundles( resourceBundles );
 489  18
             supplementModels = loadSupplements( supplementalModels );
 490  
 
 491  18
             VelocityContext context = new VelocityContext( properties );
 492  18
             configureVelocityContext( context );
 493  
 
 494  18
             RemoteResourcesClassLoader classLoader
 495  
                 = new RemoteResourcesClassLoader( null );
 496  
             
 497  18
             initalizeClassloader( classLoader, resourceBundleArtifacts );
 498  18
             Thread.currentThread().setContextClassLoader( classLoader );
 499  
             
 500  18
             processResourceBundles( classLoader, context );
 501  
 
 502  
             try
 503  
             {
 504  18
                 if ( outputDirectory.exists() )
 505  
                 {
 506  
                     // ----------------------------------------------------------------------------
 507  
                     // Push our newly generated resources directory into the MavenProject so that
 508  
                     // these resources can be picked up by the process-resources phase.
 509  
                     // ----------------------------------------------------------------------------
 510  18
                     if ( attached )
 511  
                     {
 512  18
                         Resource resource = new Resource();
 513  18
                         resource.setDirectory( outputDirectory.getAbsolutePath() );
 514  
 
 515  18
                         project.getResources().add( resource );
 516  18
                         project.getTestResources().add( resource );
 517  
                     }
 518  
 
 519  
                     // ----------------------------------------------------------------------------
 520  
                     // Write out archiver dot file
 521  
                     // ----------------------------------------------------------------------------
 522  18
                     File dotFile = new File( project.getBuild().getDirectory(), ".plxarc" );
 523  18
                     FileUtils.mkdir( dotFile.getParentFile().getAbsolutePath() );
 524  18
                     FileUtils.fileWrite( dotFile.getAbsolutePath(), outputDirectory.getName() );
 525  
                 }
 526  
             }
 527  0
             catch ( IOException e )
 528  
             {
 529  0
                 throw new MojoExecutionException( "Error creating dot file for archiving instructions.", e );
 530  18
             }
 531  
         }
 532  
         finally
 533  
         {
 534  18
             Thread.currentThread().setContextClassLoader( origLoader );
 535  18
         }
 536  18
     }
 537  
 
 538  
     private boolean isExecutionRoot()
 539  
     {
 540  0
         Log log = this.getLog();
 541  
         
 542  0
         boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase( basedir.toString() );
 543  
         
 544  0
         if ( log.isDebugEnabled() )
 545  
         {
 546  0
             log.debug("Root Folder:" + mavenSession.getExecutionRootDirectory());
 547  0
             log.debug("Current Folder:"+ basedir );
 548  
             
 549  0
             if ( result )
 550  
             {
 551  0
                 log.debug( "This is the execution root." );
 552  
             }
 553  
             else
 554  
             {
 555  0
                 log.debug( "This is NOT the execution root." );
 556  
             }
 557  
         }
 558  
         
 559  0
         return result;
 560  
     }
 561  
 
 562  
     private void addSupplementalModelArtifacts() throws MojoExecutionException
 563  
     {
 564  18
         if ( supplementalModelArtifacts != null && !supplementalModelArtifacts.isEmpty() )
 565  
         {
 566  0
             List<File> artifacts = downloadBundles( supplementalModelArtifacts );
 567  
             
 568  0
             for ( File artifact : artifacts )
 569  
             {
 570  0
                 if ( artifact.isDirectory() ) 
 571  
                 {
 572  0
                     locator.addSearchPath( FileResourceLoader.ID, artifact.getAbsolutePath() );
 573  
                 }
 574  
                 else
 575  
                 {
 576  
                     try 
 577  
                     {
 578  0
                         locator.addSearchPath( "jar", "jar:" + artifact.toURL().toExternalForm() );
 579  
                     } 
 580  0
                     catch (MalformedURLException e) 
 581  
                     {
 582  0
                         throw new MojoExecutionException( "Could not use jar " 
 583  
                                                           + artifact.getAbsolutePath(), e );
 584  0
                     }
 585  
                 }
 586  
             }
 587  
 
 588  
             
 589  
         }
 590  18
     }
 591  
 
 592  
     @SuppressWarnings( "unchecked" )
 593  
     protected List<MavenProject> getProjects()
 594  
         throws MojoExecutionException
 595  
     {
 596  18
         List<MavenProject> projects = new ArrayList<MavenProject>();
 597  
 
 598  
         // add filters in well known order, least specific to most specific
 599  18
         FilterArtifacts filter = new FilterArtifacts();
 600  
         
 601  
         Set<Artifact> depArtifacts;
 602  18
         Set<Artifact> artifacts = resolveProjectArtifacts();
 603  18
         if ( runOnlyAtExecutionRoot )
 604  
         {
 605  0
             depArtifacts = aggregateProjectDependencyArtifacts();
 606  
         }
 607  
         else
 608  
         {
 609  18
             depArtifacts = project.getDependencyArtifacts();
 610  
         }
 611  
 
 612  18
         filter.addFilter( new TransitivityFilter( depArtifacts, this.excludeTransitive ) );
 613  18
         filter.addFilter( new ScopeFilter( this.includeScope, this.excludeScope ) );
 614  18
         filter.addFilter( new GroupIdFilter( this.includeGroupIds, this.excludeGroupIds ) );
 615  18
         filter.addFilter( new ArtifactIdFilter( this.includeArtifactIds, this.excludeArtifactIds ) );
 616  
 
 617  
         // perform filtering
 618  
         try
 619  
         {
 620  18
             artifacts = filter.filter( artifacts );
 621  
         }
 622  0
         catch ( ArtifactFilterException e )
 623  
         {
 624  0
             throw new MojoExecutionException(e.getMessage(),e);
 625  18
         }
 626  
 
 627  
 
 628  18
         for ( Artifact artifact : artifacts )
 629  
         {
 630  
             try
 631  
             {
 632  0
                 List<ArtifactRepository> remoteRepo = remoteArtifactRepositories;
 633  0
                 if ( artifact.isSnapshot() )
 634  
                 {
 635  0
                     VersionRange rng = VersionRange.createFromVersion( artifact.getBaseVersion() );
 636  0
                     artifact = artifactFactory.createDependencyArtifact( artifact.getGroupId(),
 637  
                                                                          artifact.getArtifactId(), rng,
 638  
                                                                          artifact.getType(), artifact.getClassifier(),
 639  
                                                                          artifact.getScope(), null,
 640  
                                                                          artifact.isOptional() );
 641  
                 }
 642  
 
 643  0
                 getLog().debug( "Building project for " + artifact );
 644  0
                 MavenProject p = null;
 645  
                 try
 646  
                 {
 647  0
                     p = mavenProjectBuilder.buildFromRepository( artifact, remoteRepo, localRepository );
 648  
                 }
 649  0
                 catch ( InvalidProjectModelException e )
 650  
                 {
 651  0
                     getLog().warn( "Invalid project model for artifact [" + artifact.getArtifactId() + ":" +
 652  
                         artifact.getGroupId() + ":" + artifact.getVersion() + "]. " +
 653  
                         "It will be ignored by the remote resources Mojo." );
 654  0
                     continue;
 655  0
                 }
 656  
 
 657  0
                 String supplementKey =
 658  
                     generateSupplementMapKey( p.getModel().getGroupId(), p.getModel().getArtifactId() );
 659  
 
 660  0
                 if ( supplementModels.containsKey( supplementKey ) )
 661  
                 {
 662  0
                     Model mergedModel = mergeModels( p.getModel(), (Model) supplementModels.get( supplementKey ) );
 663  0
                     MavenProject mergedProject = new MavenProject( mergedModel );
 664  0
                     projects.add( mergedProject );
 665  0
                     mergedProject.setArtifact( artifact );
 666  0
                     mergedProject.setVersion( artifact.getVersion() );
 667  0
                     getLog().debug( "Adding project with groupId [" + mergedProject.getGroupId() + "] (supplemented)" );
 668  0
                 }
 669  
                 else
 670  
                 {
 671  0
                     projects.add( p );
 672  0
                     getLog().debug( "Adding project with groupId [" + p.getGroupId() + "]" );
 673  
                 }
 674  
             }
 675  0
             catch ( ProjectBuildingException e )
 676  
             {
 677  0
                 throw new MojoExecutionException( e.getMessage(), e );
 678  0
             }
 679  
         }
 680  18
         Collections.sort( projects, new ProjectComparator() );
 681  18
         return projects;
 682  
     }
 683  
 
 684  
     @SuppressWarnings( "unchecked" )
 685  
     private Set<Artifact> resolveProjectArtifacts()
 686  
         throws MojoExecutionException
 687  
     {
 688  
         try
 689  
         {
 690  18
             if ( runOnlyAtExecutionRoot )
 691  
             {
 692  0
                 List<MavenProject> projects = mavenSession.getSortedProjects();
 693  0
                 return dependencyResolver.resolve( projects, Collections.singleton( Artifact.SCOPE_TEST ), mavenSession );
 694  
             }
 695  
             else
 696  
             {
 697  18
                 return dependencyResolver.resolve( project, Collections.singleton( Artifact.SCOPE_TEST ), mavenSession );
 698  
             }
 699  
         }
 700  0
         catch ( ArtifactResolutionException e )
 701  
         {
 702  0
             throw new MojoExecutionException( "Failed to resolve dependencies for one or more projects in the reactor. Reason: "
 703  
                 + e.getMessage(), e );
 704  
         }
 705  0
         catch ( ArtifactNotFoundException e )
 706  
         {
 707  0
             throw new MojoExecutionException( "Failed to resolve dependencies for one or more projects in the reactor. Reason: "
 708  
                 + e.getMessage(), e );
 709  
         }
 710  
     }
 711  
 
 712  
     @SuppressWarnings( "unchecked" )
 713  
     private Set<Artifact> aggregateProjectDependencyArtifacts()
 714  
         throws MojoExecutionException
 715  
     {
 716  0
         Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
 717  
         
 718  0
         List<MavenProject> projects = mavenSession.getSortedProjects();
 719  0
         for ( MavenProject p : projects )
 720  
         {
 721  0
             if ( p.getDependencyArtifacts() == null )
 722  
             {
 723  
                 try
 724  
                 {
 725  0
                     Set<Artifact> depArtifacts = p.createArtifacts( artifactFactory, null, null );
 726  0
                     p.setDependencyArtifacts( depArtifacts );
 727  
                     
 728  0
                     if ( depArtifacts != null && !depArtifacts.isEmpty() )
 729  
                     {
 730  0
                         artifacts.addAll( depArtifacts );
 731  
                     }
 732  
                 }
 733  0
                 catch ( InvalidDependencyVersionException e )
 734  
                 {
 735  0
                     throw new MojoExecutionException( "Failed to create dependency artifacts for: " + p.getId() + ". Reason: "
 736  
                         + e.getMessage(), e );
 737  0
                 }
 738  
             }
 739  
         }
 740  
         
 741  0
         return artifacts;
 742  
     }
 743  
 
 744  
     protected Map<Organization, List<MavenProject>> getProjectsSortedByOrganization( List<MavenProject> projects )
 745  
         throws MojoExecutionException
 746  
     {
 747  18
         Map<Organization, List<MavenProject>> organizations = new TreeMap<Organization, List<MavenProject>>( new OrganizationComparator() );
 748  18
         List<MavenProject> unknownOrganization = new ArrayList<MavenProject>();
 749  
 
 750  18
         for ( MavenProject p : projects )
 751  
         {
 752  0
             if ( p.getOrganization() != null && StringUtils.isNotEmpty( p.getOrganization().getName() ) )
 753  
             {
 754  0
                 List<MavenProject> sortedProjects = (List<MavenProject>) organizations.get( p.getOrganization() );
 755  0
                 if ( sortedProjects == null )
 756  
                 {
 757  0
                     sortedProjects = new ArrayList<MavenProject>();
 758  
                 }
 759  0
                 sortedProjects.add( p );
 760  
 
 761  0
                 organizations.put( p.getOrganization(), sortedProjects );
 762  0
             }
 763  
             else
 764  
             {
 765  0
                 unknownOrganization.add( p );
 766  
             }
 767  
         }
 768  18
         if ( !unknownOrganization.isEmpty() )
 769  
         {
 770  0
             Organization unknownOrg = new Organization();
 771  0
             unknownOrg.setName( "an unknown organization" );
 772  0
             organizations.put( unknownOrg, unknownOrganization );
 773  
         }
 774  
 
 775  18
         return organizations;
 776  
     }
 777  
 
 778  
     protected boolean copyResourceIfExists( File file, String relFileName, VelocityContext context )
 779  
         throws IOException, MojoExecutionException
 780  
     {
 781  15
         for ( Resource resource : resources )
 782  
         {
 783  18
             File resourceDirectory = new File( resource.getDirectory() );
 784  
 
 785  18
             if ( !resourceDirectory.exists() )
 786  
             {
 787  0
                 continue;
 788  
             }
 789  
             
 790  
             //TODO - really should use the resource includes/excludes and name mapping
 791  18
             File source = new File( resourceDirectory, relFileName );
 792  18
             File templateSource = new File( resourceDirectory, relFileName + TEMPLATE_SUFFIX );
 793  
             
 794  18
             if ( !source.exists() && templateSource.exists() )
 795  
             {
 796  0
                 source = templateSource;
 797  
             }
 798  
 
 799  18
             if ( source.exists() && !source.equals( file ) )
 800  
             {
 801  0
                 if ( source == templateSource )
 802  
                 {
 803  0
                     Reader reader = null;
 804  0
                     Writer writer = null;
 805  
                     try
 806  
                     {
 807  0
                         if ( encoding != null )
 808  
                         {
 809  0
                             reader = new InputStreamReader( new FileInputStream( source ), encoding );
 810  0
                             writer = new OutputStreamWriter( new FileOutputStream( file ), encoding );
 811  
                         }
 812  
                         else
 813  
                         {
 814  0
                             reader = ReaderFactory.newPlatformReader( source );
 815  0
                             writer = WriterFactory.newPlatformWriter( file );
 816  
                         }
 817  
                         
 818  0
                         velocity.getEngine().evaluate( context, writer, "", reader );
 819  0
                         velocity.getEngine().evaluate( context, writer, "", reader );
 820  
                     }
 821  0
                     catch ( ParseErrorException e )
 822  
                     {
 823  0
                         throw new MojoExecutionException( "Error rendering velocity resource.", e );
 824  
                     }
 825  0
                     catch ( MethodInvocationException e )
 826  
                     {
 827  0
                         throw new MojoExecutionException( "Error rendering velocity resource.", e );
 828  
                     }
 829  0
                     catch ( ResourceNotFoundException e )
 830  
                     {
 831  0
                         throw new MojoExecutionException( "Error rendering velocity resource.", e );
 832  
                     }
 833  
                     finally
 834  
                     {
 835  0
                         IOUtil.close( writer );
 836  0
                         IOUtil.close( reader );
 837  0
                     }
 838  0
                 }
 839  0
                 else if ( resource.isFiltering() )
 840  
                 {
 841  
                     
 842  0
                     MavenFileFilterRequest req = setupRequest( resource, source, file );
 843  
                     
 844  
                     try
 845  
                     {
 846  0
                         fileFilter.copyFile( req );
 847  
                     }
 848  0
                     catch ( MavenFilteringException e )
 849  
                     {
 850  0
                         throw new MojoExecutionException( "Error filtering resource: " + source, e );
 851  0
                     }
 852  0
                 }
 853  
                 else
 854  
                 {
 855  0
                     FileUtils.copyFile( source, file );
 856  
                 }
 857  
 
 858  
                 //exclude the original (so eclipse doesn't complain about duplicate resources)
 859  0
                 resource.addExclude( relFileName );
 860  
 
 861  0
                 return true;
 862  
             }
 863  
 
 864  18
         }
 865  15
         return false;
 866  
     }
 867  
 
 868  
     @SuppressWarnings( "unchecked" )
 869  
     private MavenFileFilterRequest setupRequest( Resource resource, File source, File file )
 870  
     {
 871  0
         MavenFileFilterRequest req = new MavenFileFilterRequest();
 872  0
         req.setFrom( source );
 873  0
         req.setTo( file );
 874  0
         req.setFiltering( resource.isFiltering() );
 875  
         
 876  0
         req.setMavenProject( project );
 877  0
         req.setMavenSession( mavenSession );
 878  0
         req.setInjectProjectBuildFilters( true );
 879  
         
 880  0
         if ( encoding != null )
 881  
         {
 882  0
             req.setEncoding( encoding );
 883  
         }
 884  
         
 885  0
         if ( filterDelimiters != null && !filterDelimiters.isEmpty() )
 886  
         {
 887  0
             LinkedHashSet<String> delims = new LinkedHashSet<String>();
 888  0
             if ( useDefaultFilterDelimiters )
 889  
             {
 890  0
                 delims.addAll( req.getDelimiters() );
 891  
             }
 892  
             
 893  0
             for ( String delim : filterDelimiters )
 894  
             {
 895  0
                 if ( delim == null )
 896  
                 {
 897  0
                     delims.add( "${*}" );
 898  
                 }
 899  
                 else
 900  
                 {
 901  0
                     delims.add( delim );
 902  
                 }
 903  
             }
 904  
             
 905  0
             req.setDelimiters( delims );
 906  
         }
 907  
         
 908  0
         return req;
 909  
     }
 910  
 
 911  
     protected void validate()
 912  
         throws MojoExecutionException
 913  
     {
 914  18
         int bundleCount = 1;
 915  
 
 916  18
         for ( String artifactDescriptor : resourceBundles )
 917  
         {
 918  
             // groupId:artifactId:version
 919  15
             String[] s = StringUtils.split( artifactDescriptor, ":" );
 920  
 
 921  15
             if ( s.length != 3 )
 922  
             {
 923  
                 String position;
 924  
 
 925  0
                 if ( bundleCount == 1 )
 926  
                 {
 927  0
                     position = "1st";
 928  
                 }
 929  0
                 else if ( bundleCount == 2 )
 930  
                 {
 931  0
                     position = "2nd";
 932  
                 }
 933  0
                 else if ( bundleCount == 3 )
 934  
                 {
 935  0
                     position = "3rd";
 936  
                 }
 937  
                 else
 938  
                 {
 939  0
                     position = bundleCount + "th";
 940  
                 }
 941  
 
 942  0
                 throw new MojoExecutionException( "The " + position +
 943  
                     " resource bundle configured must specify a groupId, artifactId, and" +
 944  
                     " version for a remote resource bundle. " +
 945  
                     "Must be of the form <resourceBundle>groupId:artifactId:version</resourceBundle>" );
 946  
             }
 947  
 
 948  15
             bundleCount++;
 949  15
         }
 950  
 
 951  18
     }
 952  
 
 953  
     protected void configureVelocityContext( VelocityContext context )
 954  
         throws MojoExecutionException
 955  
     {
 956  18
         String inceptionYear = project.getInceptionYear();
 957  18
         String year = new SimpleDateFormat( "yyyy" ).format( new Date() );
 958  
 
 959  18
         if ( StringUtils.isEmpty( inceptionYear ) )
 960  
         {
 961  0
             if ( getLog().isDebugEnabled() )
 962  
             {
 963  0
                 getLog().debug( "inceptionYear not specified, defaulting to " + year );
 964  
             }
 965  
             
 966  0
             inceptionYear = year;
 967  
         }
 968  18
         context.put( "project", project );
 969  18
         List<MavenProject> projects = getProjects();
 970  18
         context.put( "projects", projects );
 971  18
         context.put( "projectsSortedByOrganization", getProjectsSortedByOrganization( projects ) );
 972  
 
 973  18
         context.put( "presentYear", year );
 974  
 
 975  18
         if ( inceptionYear.equals( year ) )
 976  
         {
 977  0
             context.put( "projectTimespan", year );
 978  
         }
 979  
         else
 980  
         {
 981  18
             context.put( "projectTimespan", inceptionYear + "-" + year );
 982  
         }
 983  18
     }
 984  
 
 985  
     @SuppressWarnings( "unchecked" )
 986  
     private List<File> downloadBundles( List<String> bundles )
 987  
         throws MojoExecutionException
 988  
     {
 989  18
         List<File> bundleArtifacts = new ArrayList<File>();
 990  
 
 991  
         try
 992  
         {
 993  18
             for ( String artifactDescriptor : bundles )
 994  
             {
 995  
                 // groupId:artifactId:version
 996  15
                 String[] s = artifactDescriptor.split( ":" );
 997  15
                 File artifact = null;
 998  
                 //check if the artifact is part of the reactor
 999  15
                 if ( mavenSession != null ) 
 1000  
                 {
 1001  15
                     List<MavenProject> list = mavenSession.getSortedProjects();
 1002  15
                     for ( MavenProject p : list )
 1003  
                     {
 1004  0
                         if ( s[0].equals( p.getGroupId() )
 1005  
                             && s[1].equals( p.getArtifactId() ) 
 1006  
                             && s[2].equals( p.getVersion() ) ) 
 1007  
                         {
 1008  0
                             artifact = new File( p.getBuild().getOutputDirectory() );
 1009  
                         }
 1010  
                     }
 1011  
                 }
 1012  15
                 if ( artifact == null || !artifact.exists() )
 1013  
                 {
 1014  15
                     artifact = downloader.download( s[0], s[1], s[2], localRepository, remoteArtifactRepositories );
 1015  
                 }
 1016  
 
 1017  15
                 bundleArtifacts.add( artifact );
 1018  15
             }
 1019  
         }
 1020  0
         catch ( DownloadException e )
 1021  
         {
 1022  0
             throw new MojoExecutionException( "Error downloading resources JAR.", e );
 1023  
         }
 1024  0
         catch ( DownloadNotFoundException e )
 1025  
         {
 1026  0
             throw new MojoExecutionException( "Resources JAR cannot be found.", e );
 1027  18
         }
 1028  
 
 1029  18
         return bundleArtifacts;
 1030  
     }
 1031  
 
 1032  
     private void initalizeClassloader( RemoteResourcesClassLoader cl, List<File> artifacts )
 1033  
         throws MojoExecutionException
 1034  
     {
 1035  
         try
 1036  
         {
 1037  18
             for ( File artifact : artifacts )
 1038  
             {
 1039  15
                 cl.addURL( artifact.toURI().toURL() );
 1040  
             }
 1041  
         }
 1042  0
         catch ( MalformedURLException e )
 1043  
         {
 1044  0
             throw new MojoExecutionException( "Unable to configure resources classloader: " + e.getMessage(), e );
 1045  18
         }
 1046  18
     }
 1047  
 
 1048  
     protected void processResourceBundles( RemoteResourcesClassLoader classLoader, VelocityContext context )
 1049  
         throws MojoExecutionException
 1050  
     {
 1051  18
         InputStreamReader reader = null;
 1052  
         
 1053  
         try
 1054  
         {
 1055  
 
 1056  18
             for ( Enumeration<URL> e = classLoader.getResources( BundleRemoteResourcesMojo.RESOURCES_MANIFEST );
 1057  33
                   e.hasMoreElements(); )
 1058  
             {
 1059  15
                 URL url = (URL) e.nextElement();
 1060  
 
 1061  
                 try
 1062  
                 {
 1063  15
                     reader = new InputStreamReader( url.openStream() );
 1064  
 
 1065  15
                     RemoteResourcesBundleXpp3Reader bundleReader = new RemoteResourcesBundleXpp3Reader();
 1066  
 
 1067  15
                     RemoteResourcesBundle bundle = bundleReader.read( reader );
 1068  
 
 1069  15
                     for ( String bundleResource : (List<String>) bundle.getRemoteResources() )
 1070  
                     {
 1071  15
                         String projectResource = bundleResource;
 1072  
 
 1073  15
                         boolean doVelocity = false;
 1074  15
                         if ( projectResource.endsWith( TEMPLATE_SUFFIX ) )
 1075  
                         {
 1076  12
                             projectResource = projectResource.substring( 0, projectResource.length() - 3 );
 1077  12
                             doVelocity = true;
 1078  
                         }
 1079  
 
 1080  
                         // Don't overwrite resource that are already being provided.
 1081  
 
 1082  15
                         File f = new File( outputDirectory, projectResource );
 1083  
 
 1084  15
                         FileUtils.mkdir( f.getParentFile().getAbsolutePath() );
 1085  
 
 1086  15
                         if ( !copyResourceIfExists( f, projectResource, context ) )
 1087  
                         {
 1088  15
                             if ( doVelocity )
 1089  
                             {
 1090  
                                 PrintWriter writer;
 1091  12
                                 if ( bundle.getSourceEncoding() == null )
 1092  
                                 {
 1093  6
                                     writer = new PrintWriter( new FileWriter( f ) );
 1094  
                                 }
 1095  
                                 else
 1096  
                                 {
 1097  6
                                     writer = new PrintWriter( new OutputStreamWriter( new FileOutputStream( f ),
 1098  
                                                                                       bundle.getSourceEncoding() ) );
 1099  
 
 1100  
                                 }
 1101  
 
 1102  
                                 try
 1103  
                                 {
 1104  12
                                     if ( bundle.getSourceEncoding() == null )
 1105  
                                     {
 1106  6
                                         velocity.getEngine().mergeTemplate( bundleResource, context, writer );
 1107  
                                     }
 1108  
                                     else
 1109  
                                     {
 1110  6
                                         velocity.getEngine().mergeTemplate( bundleResource, bundle.getSourceEncoding(),
 1111  
                                                                             context, writer );
 1112  
 
 1113  
                                     }
 1114  
                                 }
 1115  
                                 finally
 1116  
                                 {
 1117  12
                                     IOUtil.close(writer);
 1118  12
                                 }
 1119  12
                             }
 1120  
                             else
 1121  
                             {
 1122  3
                                 URL resUrl = classLoader.getResource( bundleResource );
 1123  3
                                 if ( resUrl != null )
 1124  
                                 {
 1125  3
                                     FileUtils.copyURLToFile( resUrl, f );
 1126  
                                 }
 1127  
                             }
 1128  15
                             File appendedResourceFile = new File( appendedResourcesDirectory, projectResource );
 1129  15
                             File appendedVmResourceFile = new File( appendedResourcesDirectory,
 1130  
                                                                     projectResource + ".vm" );
 1131  15
                             if ( appendedResourceFile.exists() )
 1132  
                             {
 1133  0
                                 final InputStream in = new FileInputStream( appendedResourceFile );
 1134  0
                                 final OutputStream append = new FileOutputStream( f, true );
 1135  
 
 1136  
                                 try
 1137  
                                 {
 1138  0
                                     IOUtil.copy( in, append );
 1139  
                                 }
 1140  
                                 finally
 1141  
                                 {
 1142  0
                                     IOUtil.close( in );
 1143  0
                                     IOUtil.close( append );
 1144  0
                                 }
 1145  0
                             }
 1146  15
                             else if ( appendedVmResourceFile.exists() )
 1147  
                             {
 1148  
                                 PrintWriter writer;
 1149  0
                                 FileReader freader = new FileReader( appendedVmResourceFile );
 1150  
 
 1151  0
                                 if ( bundle.getSourceEncoding() == null )
 1152  
                                 {
 1153  0
                                     writer = new PrintWriter( new FileWriter( f, true ) );
 1154  
                                 }
 1155  
                                 else
 1156  
                                 {
 1157  0
                                     writer = new PrintWriter( new OutputStreamWriter( new FileOutputStream( f, true ),
 1158  
                                                                                       bundle.getSourceEncoding() ) );
 1159  
 
 1160  
                                 }
 1161  
 
 1162  
                                 try
 1163  
                                 {
 1164  0
                                     Velocity.init();
 1165  0
                                     Velocity.evaluate( context, writer, "remote-resources", freader );
 1166  
                                 }
 1167  
                                 finally
 1168  
                                 {
 1169  0
                                     IOUtil.close(writer);
 1170  0
                                     IOUtil.close(freader);
 1171  0
                                 }
 1172  
                             }
 1173  
 
 1174  
                         }
 1175  15
                     }
 1176  
                 }
 1177  
                 finally
 1178  
                 {
 1179  15
                     reader.close();
 1180  15
                 }
 1181  15
             }
 1182  
         }
 1183  0
         catch ( IOException e )
 1184  
         {
 1185  0
             throw new MojoExecutionException( "Error finding remote resources manifests", e );
 1186  
         }
 1187  0
         catch ( XmlPullParserException e )
 1188  
         {
 1189  0
             throw new MojoExecutionException( "Error parsing remote resource bundle descriptor.", e );
 1190  
         }
 1191  0
         catch ( Exception e )
 1192  
         {
 1193  0
             throw new MojoExecutionException( "Error rendering velocity resource.", e );
 1194  18
         }
 1195  18
     }
 1196  
 
 1197  
     protected Model getSupplement( Xpp3Dom supplementModelXml )
 1198  
         throws MojoExecutionException
 1199  
     {
 1200  0
         MavenXpp3Reader modelReader = new MavenXpp3Reader();
 1201  0
         Model model = null;
 1202  
 
 1203  
         try
 1204  
         {
 1205  0
             model = modelReader.read( new StringReader( supplementModelXml.toString() ) );
 1206  0
             String groupId = model.getGroupId();
 1207  0
             String artifactId = model.getArtifactId();
 1208  
 
 1209  0
             if ( groupId == null || groupId.trim().equals( "" ) )
 1210  
             {
 1211  0
                 throw new MojoExecutionException(
 1212  
                     "Supplemental project XML " + "requires that a <groupId> element be present." );
 1213  
             }
 1214  
 
 1215  0
             if ( artifactId == null || artifactId.trim().equals( "" ) )
 1216  
             {
 1217  0
                 throw new MojoExecutionException(
 1218  
                     "Supplemental project XML " + "requires that a <artifactId> element be present." );
 1219  
             }
 1220  
         }
 1221  0
         catch ( IOException e )
 1222  
         {
 1223  0
             getLog().warn( "Unable to read supplemental XML: " + e.getMessage(), e );
 1224  
         }
 1225  0
         catch ( XmlPullParserException e )
 1226  
         {
 1227  0
             getLog().warn( "Unable to parse supplemental XML: " + e.getMessage(), e );
 1228  0
         }
 1229  
 
 1230  0
         return model;
 1231  
     }
 1232  
 
 1233  
     protected Model mergeModels( Model parent, Model child )
 1234  
     {
 1235  0
         inheritanceAssembler.assembleModelInheritance( child, parent );
 1236  0
         return child;
 1237  
     }
 1238  
 
 1239  
     private static String generateSupplementMapKey( String groupId, String artifactId )
 1240  
     {
 1241  0
         return groupId.trim() + ":" + artifactId.trim();
 1242  
     }
 1243  
 
 1244  
     private Map<String, Model> loadSupplements( String models[] )
 1245  
         throws MojoExecutionException
 1246  
     {
 1247  18
         if ( models == null )
 1248  
         {
 1249  18
             getLog().debug( "Supplemental data models won't be loaded.  " + "No models specified." );
 1250  18
             return Collections.emptyMap();
 1251  
         }
 1252  
 
 1253  0
         List<Supplement> supplements = new ArrayList<Supplement>();
 1254  0
         for ( int idx = 0; idx < models.length; idx++ )
 1255  
         {
 1256  0
             String set = models[idx];
 1257  0
             getLog().debug( "Preparing ruleset: " + set );
 1258  
             try
 1259  
             {
 1260  0
                 File f = locator.getResourceAsFile( set, getLocationTemp( set ) );
 1261  
 
 1262  0
                 if ( null == f || !f.exists() )
 1263  
                 {
 1264  0
                     throw new MojoExecutionException( "Cold not resolve " + set );
 1265  
                 }
 1266  0
                 if ( !f.canRead() )
 1267  
                 {
 1268  0
                     throw new MojoExecutionException( "Supplemental data models won't be loaded. " + "File " +
 1269  
                         f.getAbsolutePath() + " cannot be read, check permissions on the file." );
 1270  
                 }
 1271  
 
 1272  0
                 getLog().debug( "Loading supplemental models from " + f.getAbsolutePath() );
 1273  
 
 1274  0
                 SupplementalDataModelXpp3Reader reader = new SupplementalDataModelXpp3Reader();
 1275  0
                 SupplementalDataModel supplementalModel = reader.read( new FileReader( f ) );
 1276  0
                 supplements.addAll( supplementalModel.getSupplement() );
 1277  
             }
 1278  0
             catch ( Exception e )
 1279  
             {
 1280  0
                 String msg = "Error loading supplemental data models: " + e.getMessage();
 1281  0
                 getLog().error( msg, e );
 1282  0
                 throw new MojoExecutionException( msg, e );
 1283  0
             }
 1284  
         }
 1285  
 
 1286  0
         getLog().debug( "Loading supplements complete." );
 1287  
 
 1288  0
         Map<String, Model> supplementMap = new HashMap<String, Model>();
 1289  0
         for ( Supplement sd : supplements )
 1290  
         {
 1291  0
             Xpp3Dom dom = (Xpp3Dom) sd.getProject();
 1292  
 
 1293  0
             Model m = getSupplement( dom );
 1294  0
             supplementMap.put( generateSupplementMapKey( m.getGroupId(), m.getArtifactId() ), m );
 1295  0
         }
 1296  
 
 1297  0
         return supplementMap;
 1298  
     }
 1299  
 
 1300  
     /**
 1301  
      * Convenience method to get the location of the specified file name.
 1302  
      *
 1303  
      * @param name the name of the file whose location is to be resolved
 1304  
      * @return a String that contains the absolute file name of the file
 1305  
      */
 1306  
     private String getLocationTemp( String name )
 1307  
     {
 1308  0
         String loc = name;
 1309  0
         if ( loc.indexOf( '/' ) != -1 )
 1310  
         {
 1311  0
             loc = loc.substring( loc.lastIndexOf( '/' ) + 1 );
 1312  
         }
 1313  0
         if ( loc.indexOf( '\\' ) != -1 )
 1314  
         {
 1315  0
             loc = loc.substring( loc.lastIndexOf( '\\' ) + 1 );
 1316  
         }
 1317  0
         getLog().debug( "Before: " + name + " After: " + loc );
 1318  0
         return loc;
 1319  
     }
 1320  
 
 1321  18
     class OrganizationComparator
 1322  
         implements Comparator<Organization>
 1323  
     {
 1324  
         public int compare( Organization org1, Organization org2 )
 1325  
         {
 1326  0
             int i = compareStrings( org1.getName(), org2.getName() );
 1327  0
             if (i == 0)
 1328  
             {
 1329  0
                 i = compareStrings( org1.getUrl(), org2.getUrl() );
 1330  
             }
 1331  0
             return i;
 1332  
         }
 1333  
 
 1334  
         public boolean equals( Organization o1, Organization o2 )
 1335  
         {
 1336  0
             return compare(o1, o2) == 0;
 1337  
         }
 1338  
 
 1339  
         private int compareStrings( String s1, String s2 ) {
 1340  0
             if ( s1 == null && s2 == null )
 1341  
             {
 1342  0
                 return 0;
 1343  
             }
 1344  0
             else if ( s1 == null && s2 != null )
 1345  
             {
 1346  0
                 return 1;
 1347  
             }
 1348  0
             else if ( s1 != null && s2 == null )
 1349  
             {
 1350  0
                 return -1;
 1351  
             }
 1352  
 
 1353  0
             return s1.compareToIgnoreCase( s2 );
 1354  
         }
 1355  
     }
 1356  
 
 1357  18
     class ProjectComparator
 1358  
         implements Comparator<MavenProject>
 1359  
     {
 1360  
         @SuppressWarnings( "unchecked" )
 1361  
         public int compare( MavenProject p1, MavenProject p2 )
 1362  
         {
 1363  0
             return p1.getArtifact().compareTo( p2.getArtifact() );
 1364  
         }
 1365  
 
 1366  
         public boolean equals( MavenProject p1, MavenProject p2 )
 1367  
         {
 1368  0
             return p1.getArtifact().equals( p2.getArtifact() );
 1369  
         }
 1370  
     }
 1371  
 
 1372  
 }