Coverage Report - org.apache.maven.plugin.ant.AntBuildWriter
 
Classes in this File Line Coverage Branch Coverage Complexity
AntBuildWriter
61%
384/626
37%
76/204
5,6
 
 1  
 package org.apache.maven.plugin.ant;
 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.io.File;
 23  
 import java.io.FileOutputStream;
 24  
 import java.io.IOException;
 25  
 import java.io.OutputStreamWriter;
 26  
 import java.net.URL;
 27  
 import java.util.ArrayList;
 28  
 import java.util.Arrays;
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 import java.util.Map;
 32  
 import java.util.Properties;
 33  
 import java.util.SortedMap;
 34  
 import java.util.TreeMap;
 35  
 
 36  
 import org.apache.maven.artifact.Artifact;
 37  
 import org.apache.maven.model.Dependency;
 38  
 import org.apache.maven.model.Profile;
 39  
 import org.apache.maven.model.Repository;
 40  
 import org.apache.maven.model.Resource;
 41  
 import org.apache.maven.project.MavenProject;
 42  
 import org.apache.maven.settings.Settings;
 43  
 import org.apache.tools.ant.Main;
 44  
 import org.codehaus.plexus.util.FileUtils;
 45  
 import org.codehaus.plexus.util.IOUtil;
 46  
 import org.codehaus.plexus.util.StringUtils;
 47  
 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
 48  
 import org.codehaus.plexus.util.xml.XMLWriter;
 49  
 import org.codehaus.plexus.util.xml.XmlWriterUtil;
 50  
 
 51  
 /**
 52  
  * Write Ant build files from <code>Maven Project</code> for <a href="http://ant.apache.org">Ant</a> 1.6.2 or above:
 53  
  * <ul>
 54  
  * <li>build.xml</li>
 55  
  * <li>maven-build.xml</li>
 56  
  * <li>maven-build.properties</li>
 57  
  * </ul>
 58  
  *
 59  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 60  
  * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 61  
  * @version $Id: AntBuildWriter.java 831567 2009-10-31 17:14:41Z bentmann $
 62  
  */
 63  
 public class AntBuildWriter
 64  
 {
 65  
     /**
 66  
      * The default line indenter
 67  
      */
 68  
     protected static final int DEFAULT_INDENTATION_SIZE = XmlWriterUtil.DEFAULT_INDENTATION_SIZE;
 69  
 
 70  
     /**
 71  
      * The default build file name (build.xml)
 72  
      */
 73  
     protected static final String DEFAULT_BUILD_FILENAME = Main.DEFAULT_BUILD_FILENAME;
 74  
 
 75  
     /**
 76  
      * The default generated build file name
 77  
      */
 78  
     protected static final String DEFAULT_MAVEN_BUILD_FILENAME = "maven-build.xml";
 79  
 
 80  
     /**
 81  
      * The default build properties file name
 82  
      */
 83  
     protected static final String DEFAULT_MAVEN_PROPERTIES_FILENAME = "maven-build.properties";
 84  
 
 85  
     private MavenProject project;
 86  
 
 87  
     private ArtifactResolverWrapper artifactResolverWrapper;
 88  
 
 89  
     private File localRepository;
 90  
 
 91  
     private Settings settings;
 92  
 
 93  
     private boolean overwrite;
 94  
 
 95  
     private Properties executionProperties;
 96  
 
 97  
     /**
 98  
      * @param project
 99  
      * @param artifactResolverWrapper
 100  
      * @param settings
 101  
      * @param overwrite
 102  
      */
 103  
     public AntBuildWriter( MavenProject project, ArtifactResolverWrapper artifactResolverWrapper, Settings settings,
 104  
                            boolean overwrite, Properties executionProperties )
 105  3
     {
 106  3
         this.project = project;
 107  3
         this.artifactResolverWrapper = artifactResolverWrapper;
 108  3
         this.localRepository = new File( artifactResolverWrapper.getLocalRepository().getBasedir() );
 109  3
         this.settings = settings;
 110  3
         this.overwrite = overwrite;
 111  3
         this.executionProperties = ( executionProperties != null ) ? executionProperties : new Properties();
 112  3
     }
 113  
 
 114  
     /**
 115  
      * Generate Ant build XML files
 116  
      *
 117  
      * @throws IOException
 118  
      */
 119  
     protected void writeBuildXmls()
 120  
         throws IOException
 121  
     {
 122  3
         writeGeneratedBuildXml();
 123  3
         writeBuildXml();
 124  3
     }
 125  
 
 126  
     /**
 127  
      * Generate <code>maven-build.properties</code> only for a non-POM project
 128  
      *
 129  
      * @see #DEFAULT_MAVEN_PROPERTIES_FILENAME
 130  
      * @throws IOException
 131  
      */
 132  
     protected void writeBuildProperties()
 133  
         throws IOException
 134  
     {
 135  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 136  
         {
 137  0
             return;
 138  
         }
 139  
 
 140  3
         Properties properties = new Properties();
 141  
 
 142  
         // ----------------------------------------------------------------------
 143  
         // Build properties
 144  
         // ----------------------------------------------------------------------
 145  
 
 146  3
         addProperty( properties, "maven.build.finalName", AntBuildWriterUtil.toRelative( project.getBasedir(), project
 147  
             .getBuild().getFinalName() ) );
 148  
 
 149  
         // target
 150  3
         addProperty( properties, "maven.build.dir", AntBuildWriterUtil.toRelative( project.getBasedir(), project.getBuild()
 151  
             .getDirectory() ) );
 152  3
         addProperty( properties, "project.build.directory", "${maven.build.dir}" );
 153  
 
 154  
         // ${maven.build.dir}/classes
 155  3
         addProperty( properties, "maven.build.outputDir", "${maven.build.dir}/"
 156  
             + AntBuildWriterUtil.toRelative( new File( project.getBasedir(), properties.getProperty( "maven.build.dir" ) ),
 157  
                                     project.getBuild().getOutputDirectory() ) );
 158  3
         addProperty( properties, "project.build.outputDirectory", "${maven.build.outputDir}" );
 159  
 
 160  
         // src/main/java
 161  3
         if ( !project.getCompileSourceRoots().isEmpty() )
 162  
         {
 163  3
             String[] compileSourceRoots = (String[]) project.getCompileSourceRoots().toArray( new String[0] );
 164  6
             for ( int i = 0; i < compileSourceRoots.length; i++ )
 165  
             {
 166  3
                 addProperty( properties, "maven.build.srcDir." + i, AntBuildWriterUtil.toRelative( project.getBasedir(),
 167  
                                                                                           compileSourceRoots[i] ) );
 168  
             }
 169  
         }
 170  
         // src/main/resources
 171  3
         if ( project.getBuild().getResources() != null )
 172  
         {
 173  3
             Resource[] array = (Resource[]) project.getBuild().getResources().toArray( new Resource[0] );
 174  6
             for ( int i = 0; i < array.length; i++ )
 175  
             {
 176  3
                 addProperty( properties, "maven.build.resourceDir." + i, AntBuildWriterUtil.toRelative( project.getBasedir(),
 177  
                                                                                                array[i].getDirectory() ) );
 178  
             }
 179  
         }
 180  
 
 181  
         // ${maven.build.dir}/test-classes
 182  3
         addProperty( properties, "maven.build.testOutputDir", "${maven.build.dir}/"
 183  
             + AntBuildWriterUtil.toRelative( new File( project.getBasedir(), properties.getProperty( "maven.build.dir" ) ),
 184  
                                     project.getBuild().getTestOutputDirectory() ) );
 185  
         // src/test/java
 186  3
         if ( !project.getTestCompileSourceRoots().isEmpty() )
 187  
         {
 188  3
             String[] compileSourceRoots = (String[]) project.getTestCompileSourceRoots().toArray( new String[0] );
 189  6
             for ( int i = 0; i < compileSourceRoots.length; i++ )
 190  
             {
 191  3
                 addProperty( properties, "maven.build.testDir." + i, AntBuildWriterUtil.toRelative( project.getBasedir(),
 192  
                                                                                            compileSourceRoots[i] ) );
 193  
             }
 194  
         }
 195  
         // src/test/resources
 196  3
         if ( project.getBuild().getTestResources() != null )
 197  
         {
 198  3
             Resource[] array = (Resource[]) project.getBuild().getTestResources().toArray( new Resource[0] );
 199  6
             for ( int i = 0; i < array.length; i++ )
 200  
             {
 201  3
                 addProperty( properties, "maven.build.testResourceDir." + i, AntBuildWriterUtil
 202  
                     .toRelative( project.getBasedir(), array[i].getDirectory() ) );
 203  
             }
 204  
         }
 205  
 
 206  3
         addProperty( properties, "maven.test.reports", "${maven.build.dir}/test-reports" );
 207  
 
 208  3
         addProperty( properties, "maven.reporting.outputDirectory", "${maven.build.dir}/site" );
 209  
 
 210  
         // ----------------------------------------------------------------------
 211  
         // Settings properties
 212  
         // ----------------------------------------------------------------------
 213  
 
 214  3
         addProperty( properties, "maven.settings.offline", String.valueOf( settings.isOffline() ) );
 215  3
         addProperty( properties, "maven.settings.interactiveMode", String.valueOf( settings.isInteractiveMode() ) );
 216  3
         addProperty( properties, "maven.repo.local", getLocalRepositoryPath() );
 217  
 
 218  
         // ----------------------------------------------------------------------
 219  
         // Project properties
 220  
         // ----------------------------------------------------------------------
 221  
 
 222  3
         if ( project.getProperties() != null )
 223  
         {
 224  3
             for ( Iterator it = project.getProperties().entrySet().iterator(); it.hasNext(); )
 225  
             {
 226  1
                 Map.Entry property = (Map.Entry) it.next();
 227  1
                 addProperty( properties, property.getKey().toString(), property.getValue().toString() );
 228  
             }
 229  
         }
 230  
 
 231  3
         FileOutputStream os =
 232  
             new FileOutputStream( new File( project.getBasedir(), DEFAULT_MAVEN_PROPERTIES_FILENAME ) );
 233  
         try
 234  
         {
 235  3
             properties.store( os, "Generated by Maven Ant Plugin - DO NOT EDIT THIS FILE!" );
 236  
         }
 237  
         finally
 238  
         {
 239  3
             IOUtil.close( os );
 240  3
         }
 241  3
     }
 242  
 
 243  
     /**
 244  
      * Generate an <code>maven-build.xml</code>
 245  
      *
 246  
      * @see #DEFAULT_MAVEN_BUILD_FILENAME
 247  
      * @throws IOException
 248  
      */
 249  
     private void writeGeneratedBuildXml()
 250  
         throws IOException
 251  
     {
 252  
         // TODO: parameter
 253  3
         File outputFile = new File( project.getBasedir(), DEFAULT_MAVEN_BUILD_FILENAME );
 254  
 
 255  3
         String encoding = "UTF-8";
 256  
 
 257  3
         OutputStreamWriter w = new OutputStreamWriter( new FileOutputStream( outputFile ), encoding );
 258  
 
 259  3
         XMLWriter writer = new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", DEFAULT_INDENTATION_SIZE ), encoding,
 260  
                                                      null );
 261  
 
 262  
         // ----------------------------------------------------------------------
 263  
         // <!-- comments -->
 264  
         // ----------------------------------------------------------------------
 265  
 
 266  3
         AntBuildWriterUtil.writeHeader( writer );
 267  
 
 268  
         // ----------------------------------------------------------------------
 269  
         // <project/>
 270  
         // ----------------------------------------------------------------------
 271  
 
 272  3
         writer.startElement( "project" );
 273  3
         writer.addAttribute( "name", project.getArtifactId() + "-from-maven" );
 274  3
         writer.addAttribute( "default", "package" );
 275  3
         writer.addAttribute( "basedir", "." );
 276  
 
 277  3
         XmlWriterUtil.writeLineBreak( writer );
 278  
 
 279  
         // ----------------------------------------------------------------------
 280  
         // <property/>
 281  
         // ----------------------------------------------------------------------
 282  
 
 283  3
         writeProperties( writer );
 284  
 
 285  
         // ----------------------------------------------------------------------
 286  
         // <path/>
 287  
         // ----------------------------------------------------------------------
 288  
 
 289  3
         writeBuildPathDefinition( writer );
 290  
 
 291  
         // ----------------------------------------------------------------------
 292  
         // <target name="clean" />
 293  
         // ----------------------------------------------------------------------
 294  
 
 295  3
         writeCleanTarget( writer );
 296  
 
 297  
         // ----------------------------------------------------------------------
 298  
         // <target name="compile" />
 299  
         // ----------------------------------------------------------------------
 300  
 
 301  3
         List compileSourceRoots = AntBuildWriterUtil.removeEmptyCompileSourceRoots( project.getCompileSourceRoots() );
 302  3
         writeCompileTarget( writer, compileSourceRoots );
 303  
 
 304  
         // ----------------------------------------------------------------------
 305  
         // <target name="compile-tests" />
 306  
         // ----------------------------------------------------------------------
 307  
 
 308  3
         List testCompileSourceRoots = AntBuildWriterUtil.removeEmptyCompileSourceRoots( project
 309  
             .getTestCompileSourceRoots() );
 310  3
         writeCompileTestsTarget( writer, testCompileSourceRoots );
 311  
 
 312  
         // ----------------------------------------------------------------------
 313  
         // <target name="test" />
 314  
         // ----------------------------------------------------------------------
 315  
 
 316  3
         writeTestTargets( writer, testCompileSourceRoots );
 317  
 
 318  
         // ----------------------------------------------------------------------
 319  
         // <target name="javadoc" />
 320  
         // ----------------------------------------------------------------------
 321  3
         writeJavadocTarget( writer );
 322  
 
 323  
         // ----------------------------------------------------------------------
 324  
         // <target name="package" />
 325  
         // ----------------------------------------------------------------------
 326  3
         writePackageTarget( writer );
 327  
 
 328  
         // ----------------------------------------------------------------------
 329  
         // <target name="get-deps" />
 330  
         // ----------------------------------------------------------------------
 331  3
         writeGetDepsTarget( writer );
 332  
 
 333  3
         XmlWriterUtil.writeLineBreak( writer );
 334  
 
 335  3
         writer.endElement(); // project
 336  
 
 337  3
         XmlWriterUtil.writeLineBreak( writer );
 338  
 
 339  3
         IOUtil.close( w );
 340  3
     }
 341  
 
 342  
     /**
 343  
      * Generate an generic <code>build.xml</code> if not already exist
 344  
      *
 345  
      * @see #DEFAULT_BUILD_FILENAME
 346  
      * @throws IOException
 347  
      */
 348  
     private void writeBuildXml()
 349  
         throws IOException
 350  
     {
 351  3
         File outputFile = new File( project.getBasedir(), DEFAULT_BUILD_FILENAME );
 352  
 
 353  3
         if ( outputFile.exists() && !overwrite )
 354  
         {
 355  3
             return;
 356  
         }
 357  
 
 358  0
         String encoding = "UTF-8";
 359  
 
 360  0
         OutputStreamWriter w = new OutputStreamWriter( new FileOutputStream( outputFile ), encoding );
 361  
 
 362  0
         XMLWriter writer = new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", DEFAULT_INDENTATION_SIZE ), encoding,
 363  
                                                      null );
 364  
 
 365  
         // ----------------------------------------------------------------------
 366  
         // <!-- comments -->
 367  
         // ----------------------------------------------------------------------
 368  
 
 369  0
         AntBuildWriterUtil.writeAntVersionHeader( writer );
 370  
 
 371  
         // ----------------------------------------------------------------------
 372  
         // <project/>
 373  
         // ----------------------------------------------------------------------
 374  
 
 375  0
         writer.startElement( "project" );
 376  0
         writer.addAttribute( "name", project.getArtifactId() );
 377  0
         writer.addAttribute( "default", "package" );
 378  0
         writer.addAttribute( "basedir", "." );
 379  
 
 380  0
         XmlWriterUtil.writeLineBreak( writer );
 381  
 
 382  0
         XmlWriterUtil.writeCommentText( writer, "Import " + DEFAULT_MAVEN_BUILD_FILENAME
 383  
             + " into the current project", 1 );
 384  
 
 385  0
         writer.startElement( "import" );
 386  0
         writer.addAttribute( "file", DEFAULT_MAVEN_BUILD_FILENAME );
 387  0
         writer.endElement(); // import
 388  
 
 389  0
         XmlWriterUtil.writeLineBreak( writer, 1, 1 );
 390  
 
 391  0
         XmlWriterUtil.writeCommentText( writer, "Help target", 1 );
 392  
 
 393  0
         writer.startElement( "target" );
 394  0
         writer.addAttribute( "name", "help" );
 395  
 
 396  0
         writer.startElement( "echo" );
 397  0
         writer.addAttribute( "message", "Please run: $ant -projecthelp" );
 398  0
         writer.endElement(); // echo
 399  
 
 400  0
         writer.endElement(); // target
 401  
 
 402  0
         XmlWriterUtil.writeLineBreak( writer, 2 );
 403  
 
 404  0
         writer.endElement(); // project
 405  
 
 406  0
         XmlWriterUtil.writeLineBreak( writer );
 407  
 
 408  0
         IOUtil.close( w );
 409  0
     }
 410  
 
 411  
     /**
 412  
      * Write properties in the writer only for a non-POM project.
 413  
      *
 414  
      * @param writer
 415  
      */
 416  
     private void writeProperties( XMLWriter writer )
 417  
     {
 418  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 419  
         {
 420  0
             return;
 421  
         }
 422  
 
 423  
         // TODO: optional in m1
 424  
         // TODO: USD properties
 425  3
         XmlWriterUtil.writeCommentText( writer, "Build environment properties", 1 );
 426  
 
 427  
         // ----------------------------------------------------------------------
 428  
         // File properties to override local properties
 429  
         // ----------------------------------------------------------------------
 430  
 
 431  3
         writer.startElement( "property" );
 432  3
         writer.addAttribute( "file", "${user.home}/.m2/maven.properties" );
 433  3
         writer.endElement(); // property
 434  
 
 435  3
         writer.startElement( "property" );
 436  3
         writer.addAttribute( "file", DEFAULT_MAVEN_PROPERTIES_FILENAME );
 437  3
         writer.endElement(); // property
 438  
 
 439  
         // ----------------------------------------------------------------------
 440  
         // Build properties
 441  
         // ----------------------------------------------------------------------
 442  
 
 443  3
         XmlWriterUtil.writeLineBreak( writer, 2, 1 );
 444  
 
 445  3
         writer.startElement( "property" );
 446  3
         writer.addAttribute( "name", "maven.build.finalName" );
 447  3
         writer.addAttribute( "value", project.getBuild().getFinalName() );
 448  3
         writer.endElement(); // property
 449  
 
 450  3
         writer.startElement( "property" );
 451  3
         writer.addAttribute( "name", "maven.build.dir" );
 452  3
         writer.addAttribute( "value", AntBuildWriterUtil.toRelative( project.getBasedir(), project.getBuild().getDirectory() ) );
 453  3
         writer.endElement(); // property
 454  
 
 455  3
         writer.startElement( "property" );
 456  3
         writer.addAttribute( "name", "maven.build.outputDir" );
 457  3
         writer.addAttribute( "value", "${maven.build.dir}/"
 458  
             + AntBuildWriterUtil.toRelative( new File( project.getBuild().getDirectory() ), project.getBuild()
 459  
                 .getOutputDirectory() ) );
 460  3
         writer.endElement(); // property
 461  
 
 462  3
         if ( !project.getCompileSourceRoots().isEmpty() )
 463  
         {
 464  3
             String[] compileSourceRoots = (String[]) project.getCompileSourceRoots().toArray( new String[0] );
 465  6
             for ( int i = 0; i < compileSourceRoots.length; i++ )
 466  
             {
 467  3
                 writer.startElement( "property" );
 468  3
                 writer.addAttribute( "name", "maven.build.srcDir." + i );
 469  3
                 writer.addAttribute( "value", AntBuildWriterUtil.toRelative( project.getBasedir(), compileSourceRoots[i] ) );
 470  3
                 writer.endElement(); // property
 471  
             }
 472  
         }
 473  
 
 474  3
         if ( project.getBuild().getResources() != null )
 475  
         {
 476  3
             Resource[] array = (Resource[]) project.getBuild().getResources().toArray( new Resource[0] );
 477  6
             for ( int i = 0; i < array.length; i++ )
 478  
             {
 479  3
                 writer.startElement( "property" );
 480  3
                 writer.addAttribute( "name", "maven.build.resourceDir." + i );
 481  3
                 writer.addAttribute( "value", AntBuildWriterUtil.toRelative( project.getBasedir(), array[i].getDirectory() ) );
 482  3
                 writer.endElement(); // property
 483  
             }
 484  
         }
 485  
 
 486  3
         writer.startElement( "property" );
 487  3
         writer.addAttribute( "name", "maven.build.testOutputDir" );
 488  3
         writer.addAttribute( "value", "${maven.build.dir}/"
 489  
             + AntBuildWriterUtil.toRelative( new File( project.getBuild().getDirectory() ), project.getBuild()
 490  
                 .getTestOutputDirectory() ) );
 491  3
         writer.endElement(); // property
 492  
 
 493  3
         if ( !project.getTestCompileSourceRoots().isEmpty() )
 494  
         {
 495  3
             String[] compileSourceRoots = (String[]) project.getTestCompileSourceRoots().toArray( new String[0] );
 496  6
             for ( int i = 0; i < compileSourceRoots.length; i++ )
 497  
             {
 498  3
                 writer.startElement( "property" );
 499  3
                 writer.addAttribute( "name", "maven.build.testDir." + i );
 500  3
                 writer.addAttribute( "value", AntBuildWriterUtil.toRelative( project.getBasedir(), compileSourceRoots[i] ) );
 501  3
                 writer.endElement(); // property
 502  
             }
 503  
         }
 504  
 
 505  3
         if ( project.getBuild().getTestResources() != null )
 506  
         {
 507  3
             Resource[] array = (Resource[]) project.getBuild().getTestResources().toArray( new Resource[0] );
 508  6
             for ( int i = 0; i < array.length; i++ )
 509  
             {
 510  3
                 writer.startElement( "property" );
 511  3
                 writer.addAttribute( "name", "maven.build.testResourceDir." + i );
 512  3
                 writer.addAttribute( "value", AntBuildWriterUtil.toRelative( project.getBasedir(), array[i].getDirectory() ) );
 513  3
                 writer.endElement(); // property
 514  
             }
 515  
         }
 516  
 
 517  3
         writer.startElement( "property" );
 518  3
         writer.addAttribute( "name", "maven.test.reports" );
 519  3
         writer.addAttribute( "value", "${maven.build.dir}/test-reports" );
 520  3
         writer.endElement(); // property
 521  
 
 522  3
         String reportingOutputDir = project.getReporting().getOutputDirectory();
 523  
         // workaround for MNG-3475
 524  3
         if ( !new File( reportingOutputDir ).isAbsolute() )
 525  
         {
 526  0
             reportingOutputDir = new File( project.getBasedir(), reportingOutputDir ).getAbsolutePath();
 527  
         }
 528  3
         writer.startElement( "property" );
 529  3
         writer.addAttribute( "name", "maven.reporting.outputDirectory" );
 530  3
         writer.addAttribute( "value", "${maven.build.dir}/"
 531  
             + AntBuildWriterUtil.toRelative( new File( project.getBuild().getDirectory() ), reportingOutputDir ) );
 532  3
         writer.endElement(); // property
 533  
 
 534  
         // ----------------------------------------------------------------------
 535  
         // Setting properties
 536  
         // ----------------------------------------------------------------------
 537  
 
 538  3
         XmlWriterUtil.writeLineBreak( writer, 2, 1 );
 539  
 
 540  3
         writer.startElement( "property" );
 541  3
         writer.addAttribute( "name", "maven.repo.local" );
 542  3
         writer.addAttribute( "value", "${user.home}/.m2/repository" );
 543  3
         writer.endElement(); // property
 544  
 
 545  3
         writer.startElement( "property" );
 546  3
         writer.addAttribute( "name", "maven.settings.offline" );
 547  3
         writer.addAttribute( "value", String.valueOf( settings.isOffline() ) );
 548  3
         writer.endElement(); // property
 549  
 
 550  3
         writer.startElement( "property" );
 551  3
         writer.addAttribute( "name", "maven.settings.interactiveMode" );
 552  3
         writer.addAttribute( "value", String.valueOf( settings.isInteractiveMode() ) );
 553  3
         writer.endElement(); // property
 554  
 
 555  3
         XmlWriterUtil.writeLineBreak( writer );
 556  3
     }
 557  
 
 558  
     /**
 559  
      * Check if the local repository is in the default location:
 560  
      * <code>${user.home}/.m2/repository</code>. If that is the case then return
 561  
      * the path with the system property "user.home" in it. If not then just
 562  
      * return the absolute path to the local repository.
 563  
      */
 564  
     private String getLocalRepositoryPath()
 565  
     {
 566  3
         String userHome = System.getProperty( "user.home" );
 567  3
         String defaultPath = ( userHome + "/.m2/repository" ).replace( '\\', '/' );
 568  3
         String actualPath = localRepository.getAbsolutePath().replace( '\\', '/' );
 569  3
         if ( actualPath.equals( defaultPath ) )
 570  
         {
 571  0
             return "${user.home}/.m2/repository";
 572  
         }
 573  
         else
 574  
         {
 575  3
             return localRepository.getAbsolutePath();
 576  
         }
 577  
     }
 578  
 
 579  
     /**
 580  
      * Write path definition in the writer only for a non-POM project.
 581  
      *
 582  
      * @param writer
 583  
      */
 584  
     private void writeBuildPathDefinition( XMLWriter writer )
 585  
     {
 586  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 587  
         {
 588  0
             return;
 589  
         }
 590  
 
 591  3
         XmlWriterUtil.writeCommentText( writer, "Defining classpaths", 1 );
 592  
 
 593  3
         writeBuildPathDefinition( writer, "build.classpath", project.getCompileArtifacts() );
 594  
 
 595  3
         writeBuildPathDefinition( writer, "build.test.classpath", project.getTestArtifacts() );
 596  
 
 597  3
         XmlWriterUtil.writeLineBreak( writer );
 598  3
     }
 599  
 
 600  
     private void writeBuildPathDefinition( XMLWriter writer, String id, List artifacts )
 601  
     {
 602  6
         writer.startElement( "path" );
 603  6
         writer.addAttribute( "id", id );
 604  
 
 605  6
         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
 606  
         {
 607  6
             Artifact artifact = (Artifact) i.next();
 608  
 
 609  6
             writer.startElement( "pathelement" );
 610  
 
 611  
             String path;
 612  6
             if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
 613  
             {
 614  0
                 path = getUninterpolatedSystemPath( artifact );
 615  
             }
 616  
             else
 617  
             {
 618  6
                 path = "${maven.repo.local}/" + artifactResolverWrapper.getLocalArtifactPath( artifact );
 619  
             }
 620  6
             writer.addAttribute( "location", path );
 621  
 
 622  6
             writer.endElement(); // pathelement
 623  
         }
 624  
 
 625  6
         writer.endElement(); // path
 626  6
     }
 627  
 
 628  
     private String getUninterpolatedSystemPath( Artifact artifact )
 629  
     {
 630  0
         String managementKey = artifact.getDependencyConflictId();
 631  
 
 632  0
         for ( Iterator it = project.getOriginalModel().getDependencies().iterator(); it.hasNext(); )
 633  
         {
 634  0
             Dependency dependency = (Dependency) it.next();
 635  0
             if ( managementKey.equals( dependency.getManagementKey() ) )
 636  
             {
 637  0
                 return dependency.getSystemPath();
 638  
             }
 639  
         }
 640  
 
 641  0
         for ( Iterator itp = project.getOriginalModel().getProfiles().iterator(); itp.hasNext(); )
 642  
         {
 643  0
             Profile profile = (Profile) itp.next();
 644  0
             for ( Iterator it = profile.getDependencies().iterator(); it.hasNext(); )
 645  
             {
 646  0
                 Dependency dependency = (Dependency) it.next();
 647  0
                 if ( managementKey.equals( dependency.getManagementKey() ) )
 648  
                 {
 649  0
                     return dependency.getSystemPath();
 650  
                 }
 651  
             }
 652  
         }
 653  
 
 654  0
         String path = artifact.getFile().getAbsolutePath();
 655  
 
 656  0
         Properties props = new Properties();
 657  0
         props.putAll( project.getProperties() );
 658  0
         props.putAll( executionProperties );
 659  0
         props.remove( "user.dir" );
 660  0
         props.put( "basedir", project.getBasedir().getAbsolutePath() );
 661  
 
 662  0
         SortedMap candidateProperties = new TreeMap();
 663  0
         for ( Iterator it = props.keySet().iterator(); it.hasNext(); )
 664  
         {
 665  0
             String key = (String) it.next();
 666  0
             String value = new File( props.getProperty( key ) ).getPath();
 667  0
             if ( path.startsWith( value ) && value.length() > 0 )
 668  
             {
 669  0
                 candidateProperties.put( value, key );
 670  
             }
 671  
         }
 672  0
         if ( !candidateProperties.isEmpty() )
 673  
         {
 674  0
             String value = candidateProperties.lastKey().toString();
 675  0
             String key = candidateProperties.get( value ).toString();
 676  0
             path = path.substring( value.length() );
 677  0
             path = path.replace( '\\', '/' );
 678  0
             return "${" + key + "}" + path;
 679  
         }
 680  
 
 681  0
         return path;
 682  
     }
 683  
 
 684  
     /**
 685  
      * Write clean target in the writer depending the packaging of the project.
 686  
      *
 687  
      * @param writer
 688  
      */
 689  
     private void writeCleanTarget( XMLWriter writer )
 690  
     {
 691  3
         XmlWriterUtil.writeCommentText( writer, "Cleaning up target", 1 );
 692  
 
 693  3
         writer.startElement( "target" );
 694  3
         writer.addAttribute( "name", "clean" );
 695  3
         writer.addAttribute( "description", "Clean the output directory" );
 696  
 
 697  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 698  
         {
 699  0
             if ( project.getModules() != null )
 700  
             {
 701  0
                 for ( Iterator it = project.getModules().iterator(); it.hasNext(); )
 702  
                 {
 703  0
                     String moduleSubPath = (String) it.next();
 704  0
                     AntBuildWriterUtil.writeAntTask( writer, project, moduleSubPath, "clean" );
 705  
                 }
 706  
             }
 707  
         }
 708  
         else
 709  
         {
 710  3
             writer.startElement( "delete" );
 711  3
             writer.addAttribute( "dir", "${maven.build.dir}" );
 712  3
             writer.endElement(); // delete
 713  
         }
 714  
 
 715  3
         writer.endElement(); // target
 716  
 
 717  3
         XmlWriterUtil.writeLineBreak( writer );
 718  3
     }
 719  
 
 720  
     /**
 721  
      * Write compile target in the writer depending the packaging of the project.
 722  
      *
 723  
      * @param writer
 724  
      * @param compileSourceRoots
 725  
      * @throws IOException if any
 726  
      */
 727  
     private void writeCompileTarget( XMLWriter writer, List compileSourceRoots )
 728  
         throws IOException
 729  
     {
 730  3
         XmlWriterUtil.writeCommentText( writer, "Compilation target", 1 );
 731  
 
 732  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 733  
         {
 734  0
             writer.startElement( "target" );
 735  0
             writer.addAttribute( "name", "compile" );
 736  0
             writer.addAttribute( "description", "Compile the code" );
 737  0
             if ( project.getModules() != null )
 738  
             {
 739  0
                 for ( Iterator it = project.getModules().iterator(); it.hasNext(); )
 740  
                 {
 741  0
                     String moduleSubPath = (String) it.next();
 742  0
                     AntBuildWriterUtil.writeAntTask( writer, project, moduleSubPath, "compile" );
 743  
                 }
 744  
             }
 745  0
             writer.endElement(); // target
 746  
         }
 747  
         else
 748  
         {
 749  3
             writer.startElement( "target" );
 750  3
             writer.addAttribute( "name", "compile" );
 751  3
             writer.addAttribute( "depends", "get-deps" );
 752  3
             writer.addAttribute( "description", "Compile the code" );
 753  
 
 754  3
             writeCompileTasks( writer, "${maven.build.outputDir}", compileSourceRoots,
 755  
                                project.getBuild().getResources(), null, false );
 756  
 
 757  3
             writer.endElement(); // target
 758  
         }
 759  
 
 760  3
         XmlWriterUtil.writeLineBreak( writer );
 761  3
     }
 762  
 
 763  
     /**
 764  
      * Write compile-test target in the writer depending the packaging of the project.
 765  
      *
 766  
      * @param writer
 767  
      * @param testCompileSourceRoots
 768  
      * @throws IOException if any
 769  
      */
 770  
     private void writeCompileTestsTarget( XMLWriter writer, List testCompileSourceRoots )
 771  
         throws IOException
 772  
     {
 773  3
         XmlWriterUtil.writeCommentText( writer, "Test-compilation target", 1 );
 774  
 
 775  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 776  
         {
 777  0
             writer.startElement( "target" );
 778  0
             writer.addAttribute( "name", "compile-tests" );
 779  0
             writer.addAttribute( "description", "Compile the test code" );
 780  0
             if ( project.getModules() != null )
 781  
             {
 782  0
                 for ( Iterator it = project.getModules().iterator(); it.hasNext(); )
 783  
                 {
 784  0
                     String moduleSubPath = (String) it.next();
 785  0
                     AntBuildWriterUtil.writeAntTask( writer, project, moduleSubPath, "compile-tests" );
 786  
                 }
 787  
             }
 788  0
             writer.endElement(); // target
 789  
         }
 790  
         else
 791  
         {
 792  3
             writer.startElement( "target" );
 793  3
             writer.addAttribute( "name", "compile-tests" );
 794  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "depends", "compile", 2 );
 795  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "description", "Compile the test code", 2 );
 796  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "unless", "maven.test.skip", 2 );
 797  
 
 798  3
             writeCompileTasks( writer, "${maven.build.testOutputDir}", testCompileSourceRoots,
 799  
                                project.getBuild().getTestResources(), "${maven.build.outputDir}", true );
 800  
 
 801  3
             writer.endElement(); // target
 802  
         }
 803  
 
 804  3
         XmlWriterUtil.writeLineBreak( writer );
 805  3
     }
 806  
 
 807  
     /**
 808  
      * Write test target in the writer depending the packaging of the project.
 809  
      *
 810  
      * @param writer
 811  
      * @param testCompileSourceRoots
 812  
      */
 813  
     private void writeTestTargets( XMLWriter writer, List testCompileSourceRoots )
 814  
         throws IOException
 815  
     {
 816  3
         XmlWriterUtil.writeCommentText( writer, "Run all tests", 1 );
 817  
 
 818  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 819  
         {
 820  0
             writer.startElement( "target" );
 821  0
             writer.addAttribute( "name", "test" );
 822  0
             writer.addAttribute( "description", "Run the test cases" );
 823  0
             if ( project.getModules() != null )
 824  
             {
 825  0
                 for ( Iterator it = project.getModules().iterator(); it.hasNext(); )
 826  
                 {
 827  0
                     String moduleSubPath = (String) it.next();
 828  0
                     AntBuildWriterUtil.writeAntTask( writer, project, moduleSubPath, "test" );
 829  
                 }
 830  
             }
 831  0
             writer.endElement(); // target
 832  
         }
 833  
         else
 834  
         {
 835  3
             writer.startElement( "target" );
 836  3
             writer.addAttribute( "name", "test" );
 837  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "depends", "compile-tests, junit-missing", 2 );
 838  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "unless", "junit.skipped", 2 );
 839  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "description", "Run the test cases", 2 );
 840  
 
 841  3
             if ( !testCompileSourceRoots.isEmpty() )
 842  
             {
 843  0
                 writer.startElement( "mkdir" );
 844  0
                 writer.addAttribute( "dir", "${maven.test.reports}" );
 845  0
                 writer.endElement(); // mkdir
 846  
 
 847  0
                 writer.startElement( "junit" );
 848  0
                 writer.addAttribute( "printSummary", "yes" );
 849  0
                 writer.addAttribute( "haltonerror", "true" );
 850  0
                 writer.addAttribute( "haltonfailure", "true" );
 851  0
                 writer.addAttribute( "fork", "true" );
 852  0
                 writer.addAttribute( "dir", "." );
 853  
 
 854  0
                 writer.startElement( "sysproperty" );
 855  0
                 writer.addAttribute( "key", "basedir" );
 856  0
                 writer.addAttribute( "value", "." );
 857  0
                 writer.endElement(); // sysproperty
 858  
 
 859  0
                 writer.startElement( "formatter" );
 860  0
                 writer.addAttribute( "type", "xml" );
 861  0
                 writer.endElement(); // formatter
 862  
 
 863  0
                 writer.startElement( "formatter" );
 864  0
                 writer.addAttribute( "type", "plain" );
 865  0
                 writer.addAttribute( "usefile", "false" );
 866  0
                 writer.endElement(); // formatter
 867  
 
 868  0
                 writer.startElement( "classpath" );
 869  0
                 writer.startElement( "path" );
 870  0
                 writer.addAttribute( "refid", "build.test.classpath" );
 871  0
                 writer.endElement(); // path
 872  0
                 writer.startElement( "pathelement" );
 873  0
                 writer.addAttribute( "location", "${maven.build.outputDir}" );
 874  0
                 writer.endElement(); // pathelement
 875  0
                 writer.startElement( "pathelement" );
 876  0
                 writer.addAttribute( "location", "${maven.build.testOutputDir}" );
 877  0
                 writer.endElement(); // pathelement
 878  0
                 writer.endElement(); // classpath
 879  
 
 880  0
                 writer.startElement( "batchtest" );
 881  0
                 writer.addAttribute( "todir", "${maven.test.reports}" );
 882  0
                 writer.addAttribute( "unless", "test" );
 883  
 
 884  0
                 List includes = getTestIncludes();
 885  0
                 List excludes = getTestExcludes();
 886  
 
 887  0
                 writeTestFilesets( writer, testCompileSourceRoots, includes, excludes );
 888  
 
 889  0
                 writer.endElement(); // batchtest
 890  
 
 891  0
                 writer.startElement( "batchtest" );
 892  0
                 writer.addAttribute( "todir", "${maven.test.reports}" );
 893  0
                 writer.addAttribute( "if", "test" );
 894  
 
 895  0
                 includes = Arrays.asList( new String[] { "**/${test}.java" } );
 896  
 
 897  0
                 writeTestFilesets( writer, testCompileSourceRoots, includes, excludes );
 898  
 
 899  0
                 writer.endElement(); // batchtest
 900  
 
 901  0
                 writer.endElement(); // junit
 902  
             }
 903  3
             writer.endElement(); // target
 904  
 
 905  3
             XmlWriterUtil.writeLineBreak( writer, 2, 1 );
 906  
 
 907  3
             writer.startElement( "target" );
 908  3
             writer.addAttribute( "name", "test-junit-present" );
 909  
 
 910  3
             writer.startElement( "available" );
 911  3
             writer.addAttribute( "classname", "junit.framework.Test" );
 912  3
             writer.addAttribute( "property", "junit.present" );
 913  3
             writer.endElement(); // available
 914  
 
 915  3
             writer.endElement(); // target
 916  
 
 917  3
             XmlWriterUtil.writeLineBreak( writer, 2, 1 );
 918  
 
 919  3
             writer.startElement( "target" );
 920  3
             writer.addAttribute( "name", "test-junit-status" );
 921  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "depends", "test-junit-present", 2 );
 922  3
             writer.startElement( "condition" );
 923  3
             writer.addAttribute( "property", "junit.missing" );
 924  3
             writer.startElement( "and" );
 925  3
             writer.startElement( "isfalse" );
 926  3
             writer.addAttribute( "value", "${junit.present}" );
 927  3
             writer.endElement(); // isfalse
 928  3
             writer.startElement( "isfalse" );
 929  3
             writer.addAttribute( "value", "${maven.test.skip}" );
 930  3
             writer.endElement(); // isfalse
 931  3
             writer.endElement(); // and
 932  3
             writer.endElement(); // condition
 933  3
             writer.startElement( "condition" );
 934  3
             writer.addAttribute( "property", "junit.skipped" );
 935  3
             writer.startElement( "or" );
 936  3
             writer.startElement( "isfalse" );
 937  3
             writer.addAttribute( "value", "${junit.present}" );
 938  3
             writer.endElement(); // isfalse
 939  3
             writer.startElement( "istrue" );
 940  3
             writer.addAttribute( "value", "${maven.test.skip}" );
 941  3
             writer.endElement(); // istrue
 942  3
             writer.endElement(); // or
 943  3
             writer.endElement(); // condition
 944  3
             writer.endElement(); // target
 945  
 
 946  3
             XmlWriterUtil.writeLineBreak( writer, 2, 1 );
 947  
 
 948  3
             writer.startElement( "target" );
 949  3
             writer.addAttribute( "name", "junit-missing" );
 950  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "depends", "test-junit-status", 2 );
 951  3
             AntBuildWriterUtil.addWrapAttribute( writer, "target", "if", "junit.missing", 2 );
 952  
 
 953  3
             writer.startElement( "echo" );
 954  3
             writer.writeText( StringUtils.repeat( "=", 35 ) + " WARNING " + StringUtils.repeat( "=", 35 ) );
 955  3
             writer.endElement(); // echo
 956  
 
 957  3
             writer.startElement( "echo" );
 958  3
             writer.writeText( " JUnit is not present in your $ANT_HOME/lib directory. Tests not executed." );
 959  3
             writer.endElement(); // echo
 960  
 
 961  3
             writer.startElement( "echo" );
 962  3
             writer.writeText( StringUtils.repeat( "=", 79 ) );
 963  3
             writer.endElement(); // echo
 964  
 
 965  3
             writer.endElement(); // target
 966  
         }
 967  
 
 968  3
         XmlWriterUtil.writeLineBreak( writer );
 969  3
     }
 970  
 
 971  
     /**
 972  
      * Gets the include patterns for the unit tests.
 973  
      *
 974  
      * @return A list of strings with include patterns, might be empty but never <code>null</code>.
 975  
      */
 976  
     private List getTestIncludes()
 977  
         throws IOException
 978  
     {
 979  0
         List includes = getSelectorList( AntBuildWriterUtil.getMavenSurefirePluginOptions( project, "includes", null ) );
 980  0
         if ( includes == null || includes.isEmpty() )
 981  
         {
 982  0
             includes = Arrays.asList( new String[] { "**/Test*.java", "**/*Test.java", "**/*TestCase.java" } );
 983  
         }
 984  0
         return includes;
 985  
     }
 986  
 
 987  
     /**
 988  
      * Gets the exclude patterns for the unit tests.
 989  
      *
 990  
      * @return A list of strings with exclude patterns, might be empty but never <code>null</code>.
 991  
      */
 992  
     private List getTestExcludes()
 993  
         throws IOException
 994  
     {
 995  0
         List excludes = getSelectorList( AntBuildWriterUtil.getMavenSurefirePluginOptions( project, "excludes", null ) );
 996  0
         if ( excludes == null || excludes.isEmpty() )
 997  
         {
 998  0
             excludes = Arrays.asList( new String[] { "**/*Abstract*Test.java" } );
 999  
         }
 1000  0
         return excludes;
 1001  
     }
 1002  
 
 1003  
     /**
 1004  
      * Write the <code>&lt;fileset&gt;</code> elements for the test compile source roots.
 1005  
      *
 1006  
      * @param writer
 1007  
      * @param testCompileSourceRoots
 1008  
      * @param includes
 1009  
      * @param excludes
 1010  
      */
 1011  
     private void writeTestFilesets( XMLWriter writer, List testCompileSourceRoots, List includes, List excludes )
 1012  
     {
 1013  0
         for ( int i = 0; i < testCompileSourceRoots.size(); i++ )
 1014  
         {
 1015  0
             writer.startElement( "fileset" );
 1016  0
             writer.addAttribute( "dir", "${maven.build.testDir." + i + "}" );
 1017  
             // TODO: m1 allows additional test exclusions via maven.ant.excludeTests
 1018  0
             AntBuildWriterUtil.writeIncludesExcludes( writer, includes, excludes );
 1019  0
             writer.endElement(); // fileset
 1020  
         }
 1021  0
     }
 1022  
 
 1023  
     /**
 1024  
      * Write javadoc target in the writer depending the packaging of the project.
 1025  
      *
 1026  
      * @param writer
 1027  
      * @throws IOException if any
 1028  
      */
 1029  
     private void writeJavadocTarget( XMLWriter writer )
 1030  
         throws IOException
 1031  
     {
 1032  3
         XmlWriterUtil.writeCommentText( writer, "Javadoc target", 1 );
 1033  
 
 1034  3
         writer.startElement( "target" );
 1035  3
         writer.addAttribute( "name", "javadoc" );
 1036  3
         writer.addAttribute( "description", "Generates the Javadoc of the application" );
 1037  
 
 1038  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 1039  
         {
 1040  0
             if ( project.getModules() != null )
 1041  
             {
 1042  0
                 for ( Iterator it = project.getModules().iterator(); it.hasNext(); )
 1043  
                 {
 1044  0
                     String moduleSubPath = (String) it.next();
 1045  0
                     AntBuildWriterUtil.writeAntTask( writer, project, moduleSubPath, "javadoc" );
 1046  
                 }
 1047  
             }
 1048  
         }
 1049  
         else
 1050  
         {
 1051  3
             AntBuildWriterUtil.writeJavadocTask( writer, project, artifactResolverWrapper );
 1052  
         }
 1053  
 
 1054  3
         writer.endElement(); // target
 1055  
 
 1056  3
         XmlWriterUtil.writeLineBreak( writer );
 1057  3
     }
 1058  
 
 1059  
     /**
 1060  
      * Write package target in the writer depending the packaging of the project.
 1061  
      *
 1062  
      * @param writer
 1063  
      * @throws IOException if any
 1064  
      */
 1065  
     private void writePackageTarget( XMLWriter writer )
 1066  
         throws IOException
 1067  
     {
 1068  3
         String synonym = null; // type of the package we are creating (for example jar)
 1069  3
         XmlWriterUtil.writeCommentText( writer, "Package target", 1 );
 1070  
 
 1071  3
         writer.startElement( "target" );
 1072  3
         writer.addAttribute( "name", "package" );
 1073  
 
 1074  3
         if ( !AntBuildWriterUtil.isPomPackaging( project ) )
 1075  
         {
 1076  3
             writer.addAttribute( "depends", "compile,test" );
 1077  
         }
 1078  3
         writer.addAttribute( "description", "Package the application" );
 1079  
 
 1080  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 1081  
         {
 1082  0
             if ( project.getModules() != null )
 1083  
             {
 1084  0
                 for ( Iterator it = project.getModules().iterator(); it.hasNext(); )
 1085  
                 {
 1086  0
                     String moduleSubPath = (String) it.next();
 1087  0
                     AntBuildWriterUtil.writeAntTask( writer, project, moduleSubPath, "package" );
 1088  
                 }
 1089  
             }
 1090  
         }
 1091  
         else
 1092  
         {
 1093  3
             if ( AntBuildWriterUtil.isJarPackaging( project ) )
 1094  
             {
 1095  3
                 AntBuildWriterUtil.writeJarTask( writer, project );
 1096  3
                 synonym = "jar";
 1097  
             }
 1098  0
             else if ( AntBuildWriterUtil.isEarPackaging( project ) )
 1099  
             {
 1100  0
                 AntBuildWriterUtil.writeEarTask( writer, project, artifactResolverWrapper );
 1101  0
                 synonym = "ear";
 1102  
             }
 1103  0
             else if ( AntBuildWriterUtil.isWarPackaging( project ) )
 1104  
             {
 1105  0
                 AntBuildWriterUtil.writeWarTask( writer, project, artifactResolverWrapper );
 1106  0
                 synonym = "war";
 1107  
             }
 1108  
             else
 1109  
             {
 1110  0
                 writer.startElement( "echo" );
 1111  0
                 writer.addAttribute( "message", "No Ant task exists for the packaging '" + project.getPackaging()
 1112  
                     + "'. " + "You could overrided the Ant package target in your build.xml." );
 1113  0
                 writer.endElement(); // echo
 1114  
             }
 1115  
         }
 1116  
 
 1117  3
         writer.endElement(); // target
 1118  
 
 1119  3
         XmlWriterUtil.writeLineBreak( writer );
 1120  
 
 1121  3
         if ( synonym != null )
 1122  
         {
 1123  3
             XmlWriterUtil.writeCommentText( writer,
 1124  
                                                  "A dummy target for the package named after the type it creates", 1 );
 1125  3
             writer.startElement( "target" );
 1126  3
             writer.addAttribute( "name", synonym );
 1127  3
             writer.addAttribute( "depends", "package" );
 1128  3
             writer.addAttribute( "description", "Builds the " + synonym + " for the application" );
 1129  3
             writer.endElement(); //target
 1130  
 
 1131  3
             XmlWriterUtil.writeLineBreak( writer );
 1132  
         }
 1133  3
     }
 1134  
 
 1135  
     private void writeCompileTasks( XMLWriter writer, String outputDirectory, List compileSourceRoots,
 1136  
                                    List resources, String additionalClassesDirectory, boolean isTest )
 1137  
         throws IOException
 1138  
     {
 1139  6
         writer.startElement( "mkdir" );
 1140  6
         writer.addAttribute( "dir", outputDirectory );
 1141  6
         writer.endElement(); // mkdir
 1142  
 
 1143  6
         if ( !compileSourceRoots.isEmpty() )
 1144  
         {
 1145  0
             writer.startElement( "javac" );
 1146  0
             writer.addAttribute( "destdir", outputDirectory );
 1147  0
             Map[] includes = AntBuildWriterUtil.getMavenCompilerPluginOptions( project, "includes", null );
 1148  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "includes", getCommaSeparatedList( includes,
 1149  
                                                                                                      "include" ), 3 );
 1150  0
             Map[] excludes = AntBuildWriterUtil.getMavenCompilerPluginOptions( project, "excludes", null );
 1151  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "excludes", getCommaSeparatedList( excludes,
 1152  
                                                                                                      "exclude" ), 3 );
 1153  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "encoding", AntBuildWriterUtil
 1154  
                 .getMavenCompilerPluginBasicOption( project, "encoding", null ), 3 );
 1155  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "nowarn", AntBuildWriterUtil
 1156  
                 .getMavenCompilerPluginBasicOption( project, "showWarnings", "false" ), 3 );
 1157  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "debug", AntBuildWriterUtil
 1158  
                 .getMavenCompilerPluginBasicOption( project, "debug", "true" ), 3 );
 1159  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "optimize", AntBuildWriterUtil
 1160  
                 .getMavenCompilerPluginBasicOption( project, "optimize", "false" ), 3 );
 1161  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "deprecation", AntBuildWriterUtil
 1162  
                 .getMavenCompilerPluginBasicOption( project, "showDeprecation", "true" ), 3 );
 1163  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "target", AntBuildWriterUtil
 1164  
                 .getMavenCompilerPluginBasicOption( project, "target", "1.1" ), 3 );
 1165  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "verbose", AntBuildWriterUtil
 1166  
                 .getMavenCompilerPluginBasicOption( project, "verbose", "false" ), 3 );
 1167  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "fork", AntBuildWriterUtil
 1168  
                 .getMavenCompilerPluginBasicOption( project, "fork", "false" ), 3 );
 1169  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "memoryMaximumSize", AntBuildWriterUtil
 1170  
                 .getMavenCompilerPluginBasicOption( project, "meminitial", null ), 3 );
 1171  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "memoryInitialSize", AntBuildWriterUtil
 1172  
                 .getMavenCompilerPluginBasicOption( project, "maxmem", null ), 3 );
 1173  0
             AntBuildWriterUtil.addWrapAttribute( writer, "javac", "source", AntBuildWriterUtil
 1174  
                 .getMavenCompilerPluginBasicOption( project, "source", "1.3" ), 3 );
 1175  
 
 1176  0
             String[] compileSourceRootsArray = (String[]) compileSourceRoots.toArray( new String[0] );
 1177  0
             for ( int i = 0; i < compileSourceRootsArray.length; i++ )
 1178  
             {
 1179  0
                 writer.startElement( "src" );
 1180  0
                 writer.startElement( "pathelement" );
 1181  0
                 if ( isTest )
 1182  
                 {
 1183  0
                     writer.addAttribute( "location", "${maven.build.testDir." + i + "}" );
 1184  
                 }
 1185  
                 else
 1186  
                 {
 1187  0
                     writer.addAttribute( "location", "${maven.build.srcDir." + i + "}" );
 1188  
                 }
 1189  0
                 writer.endElement(); // pathelement
 1190  0
                 writer.endElement(); // src
 1191  
             }
 1192  
 
 1193  0
             if ( additionalClassesDirectory == null )
 1194  
             {
 1195  0
                 writer.startElement( "classpath" );
 1196  0
                 if ( isTest )
 1197  
                 {
 1198  0
                     writer.addAttribute( "refid", "build.test.classpath" );
 1199  
                 }
 1200  
                 else
 1201  
                 {
 1202  0
                     writer.addAttribute( "refid", "build.classpath" );
 1203  
                 }
 1204  0
                 writer.endElement(); // classpath
 1205  
             }
 1206  
             else
 1207  
             {
 1208  0
                 writer.startElement( "classpath" );
 1209  0
                 writer.startElement( "path" );
 1210  0
                 if ( isTest )
 1211  
                 {
 1212  0
                     writer.addAttribute( "refid", "build.test.classpath" );
 1213  
                 }
 1214  
                 else
 1215  
                 {
 1216  0
                     writer.addAttribute( "refid", "build.classpath" );
 1217  
                 }
 1218  0
                 writer.endElement(); // path
 1219  0
                 writer.startElement( "pathelement" );
 1220  0
                 writer.addAttribute( "location", additionalClassesDirectory );
 1221  0
                 writer.endElement(); // pathelement
 1222  0
                 writer.endElement(); // classpath
 1223  
             }
 1224  
 
 1225  0
             writer.endElement(); // javac
 1226  
         }
 1227  
 
 1228  6
         Resource[] array = (Resource[]) resources.toArray( new Resource[0] );
 1229  12
         for ( int i = 0; i < array.length; i++ )
 1230  
         {
 1231  6
             Resource resource = array[i];
 1232  
 
 1233  6
             if ( new File( resource.getDirectory() ).exists() )
 1234  
             {
 1235  5
                 String outputDir = outputDirectory;
 1236  5
                 if ( resource.getTargetPath() != null && resource.getTargetPath().length() > 0 )
 1237  
                 {
 1238  0
                     outputDir = outputDir + "/" + resource.getTargetPath();
 1239  
 
 1240  0
                     writer.startElement( "mkdir" );
 1241  0
                     writer.addAttribute( "dir", outputDir );
 1242  0
                     writer.endElement(); // mkdir
 1243  
                 }
 1244  
 
 1245  5
                 writer.startElement( "copy" );
 1246  5
                 writer.addAttribute( "todir", outputDir );
 1247  
 
 1248  5
                 writer.startElement( "fileset" );
 1249  5
                 if ( isTest )
 1250  
                 {
 1251  2
                     writer.addAttribute( "dir", "${maven.build.testResourceDir." + i + "}" );
 1252  
                 }
 1253  
                 else
 1254  
                 {
 1255  3
                     writer.addAttribute( "dir", "${maven.build.resourceDir." + i + "}" );
 1256  
                 }
 1257  
 
 1258  5
                 AntBuildWriterUtil.writeIncludesExcludes( writer, resource.getIncludes(), resource.getExcludes() );
 1259  
 
 1260  5
                 writer.endElement(); // fileset
 1261  
 
 1262  5
                 writer.endElement(); // copy
 1263  
             }
 1264  
         }
 1265  6
     }
 1266  
 
 1267  
     /**
 1268  
      * Write get-deps target in the writer only for a non-POM project
 1269  
      *
 1270  
      * @param writer
 1271  
      */
 1272  
     private void writeGetDepsTarget( XMLWriter writer )
 1273  
     {
 1274  3
         if ( AntBuildWriterUtil.isPomPackaging( project ) )
 1275  
         {
 1276  0
             return;
 1277  
         }
 1278  
 
 1279  3
         XmlWriterUtil.writeCommentText( writer, "Download dependencies target", 1 );
 1280  
 
 1281  3
         writer.startElement( "target" );
 1282  3
         writer.addAttribute( "name", "test-offline" );
 1283  
 
 1284  3
         writer.startElement( "condition" );
 1285  3
         writer.addAttribute( "property", "maven.mode.offline" );
 1286  3
         writer.startElement( "equals" );
 1287  3
         writer.addAttribute( "arg1", "${maven.settings.offline}" );
 1288  3
         writer.addAttribute( "arg2", "true" );
 1289  3
         writer.endElement(); // equals
 1290  3
         writer.endElement(); // condition
 1291  3
         writer.endElement(); // target
 1292  
 
 1293  3
         XmlWriterUtil.writeLineBreak( writer, 2, 1 );
 1294  
 
 1295  3
         writer.startElement( "target" );
 1296  3
         writer.addAttribute( "name", "get-deps" );
 1297  3
         AntBuildWriterUtil.addWrapAttribute( writer, "target", "depends", "test-offline", 2 );
 1298  3
         AntBuildWriterUtil.addWrapAttribute( writer, "target", "description", "Download all dependencies", 2 );
 1299  3
         AntBuildWriterUtil.addWrapAttribute( writer, "target", "unless", "maven.mode.offline", 2 ); // TODO: check, and differs from m1
 1300  
 
 1301  3
         writer.startElement( "mkdir" );
 1302  3
         writer.addAttribute( "dir", "${maven.repo.local}" );
 1303  3
         writer.endElement(); // mkdir
 1304  
 
 1305  3
         String basedir = project.getBasedir().getAbsolutePath();
 1306  
 
 1307  
         // TODO: proxy - probably better to use wagon!
 1308  3
         for ( Iterator i = project.getTestArtifacts().iterator(); i.hasNext(); )
 1309  
         {
 1310  3
             Artifact artifact = (Artifact) i.next();
 1311  
 
 1312  3
             if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
 1313  
             {
 1314  0
                 continue;
 1315  
             }
 1316  
 
 1317  3
             String path = artifactResolverWrapper.getLocalArtifactPath( artifact );
 1318  
 
 1319  3
             if ( !new File( path ).exists() )
 1320  
             {
 1321  3
                 File parentDirs = new File( path ).getParentFile();
 1322  3
                 if ( parentDirs != null )
 1323  
                 {
 1324  3
                     writer.startElement( "mkdir" );
 1325  
                     // Replace \ with / in the parent dir path
 1326  3
                     writer.addAttribute( "dir", "${maven.repo.local}/" + parentDirs.getPath().replace( '\\', '/' ) );
 1327  3
                     writer.endElement(); // mkdir
 1328  
                 }
 1329  
 
 1330  3
                 for ( Iterator j = project.getRepositories().iterator(); j.hasNext(); )
 1331  
                 {
 1332  3
                     Repository repository = (Repository) j.next();
 1333  3
                     String url = repository.getUrl();
 1334  
 
 1335  3
                     String localDir = getProjectRepoDirectory( url, basedir );
 1336  3
                     if ( localDir != null )
 1337  
                     {
 1338  0
                         if ( localDir.length() > 0 && !localDir.endsWith( "/" ) )
 1339  
                         {
 1340  0
                             localDir += '/';
 1341  
                         }
 1342  
 
 1343  0
                         writer.startElement( "copy" );
 1344  0
                         writer.addAttribute( "file", localDir + path );
 1345  0
                         AntBuildWriterUtil.addWrapAttribute( writer, "copy", "tofile", "${maven.repo.local}/" + path, 3 );
 1346  0
                         AntBuildWriterUtil.addWrapAttribute( writer, "copy", "failonerror", "false", 3 );
 1347  0
                         writer.endElement(); // copy
 1348  
                     }
 1349  
                     else
 1350  
                     {
 1351  3
                         writer.startElement( "get" );
 1352  3
                         writer.addAttribute( "src", url + '/' + path );
 1353  3
                         AntBuildWriterUtil.addWrapAttribute( writer, "get", "dest", "${maven.repo.local}/" + path, 3 );
 1354  3
                         AntBuildWriterUtil.addWrapAttribute( writer, "get", "usetimestamp", "false", 3 );
 1355  3
                         AntBuildWriterUtil.addWrapAttribute( writer, "get", "ignoreerrors", "true", 3 );
 1356  3
                         writer.endElement(); // get
 1357  
                     }
 1358  
                 }
 1359  
             }
 1360  
         }
 1361  
 
 1362  3
         writer.endElement(); // target
 1363  
 
 1364  3
         XmlWriterUtil.writeLineBreak( writer );
 1365  3
     }
 1366  
 
 1367  
     /**
 1368  
      * Gets the relative path to a repository that is rooted in the project. The returned path (if any) will always use
 1369  
      * the forward slash ('/') as the directory separator. For example, the path "target/it-repo" will be returned for a
 1370  
      * repository constructed from the URL "file://${basedir}/target/it-repo".
 1371  
      * 
 1372  
      * @param repoUrl The URL to the repository, must not be <code>null</code>.
 1373  
      * @param projectDir The absolute path to the base directory of the project, must not be <code>null</code>
 1374  
      * @return The path to the repository (relative to the project base directory) or <code>null</code> if the
 1375  
      *         repository is not rooted in the project.
 1376  
      */
 1377  
     static String getProjectRepoDirectory( String repoUrl, String projectDir )
 1378  
     {
 1379  
         try
 1380  
         {
 1381  
             /*
 1382  
              * NOTE: The usual way of constructing repo URLs rooted in the project is "file://${basedir}" or
 1383  
              * "file:/${basedir}". None of these forms delivers a valid URL on both Unix and Windows (even ignoring URL
 1384  
              * encoding), one platform will end up with the first directory of the path being interpreted as the host
 1385  
              * name...
 1386  
              */
 1387  12
             if ( repoUrl.regionMatches( true, 0, "file://", 0, 7 ) )
 1388  
             {
 1389  4
                 String temp = repoUrl.substring( 7 );
 1390  4
                 if ( !temp.startsWith( "/" ) && !temp.regionMatches( true, 0, "localhost/", 0, 10 ) )
 1391  
                 {
 1392  3
                     repoUrl = "file:///" + temp;
 1393  
                 }
 1394  
             }
 1395  12
             String path = FileUtils.toFile( new URL( repoUrl ) ).getPath();
 1396  8
             if ( path.startsWith( projectDir ) )
 1397  
             {
 1398  7
                 path = path.substring( projectDir.length() ).replace( '\\', '/' );
 1399  7
                 if ( path.startsWith( "/" ) )
 1400  
                 {
 1401  5
                     path = path.substring( 1 );
 1402  
                 }
 1403  7
                 if ( path.endsWith( "/" ) )
 1404  
                 {
 1405  0
                     path = path.substring( 0, path.length() - 1 );
 1406  
                 }
 1407  7
                 return path;
 1408  
             }
 1409  
         }
 1410  4
         catch ( Exception e )
 1411  
         {
 1412  
             // not a "file:" URL or simply malformed
 1413  1
         }
 1414  5
         return null;
 1415  
     }
 1416  
 
 1417  
     // ----------------------------------------------------------------------
 1418  
     // Convenience methods
 1419  
     // ----------------------------------------------------------------------
 1420  
 
 1421  
     /**
 1422  
      * Put a property in properties defined by a name and a value
 1423  
      *
 1424  
      * @param properties not null
 1425  
      * @param name
 1426  
      * @param value not null
 1427  
      */
 1428  
     private static void addProperty( Properties properties, String name, String value )
 1429  
     {
 1430  46
         properties.put( name, StringUtils.isNotEmpty( value ) ? value : "" );
 1431  46
     }
 1432  
 
 1433  
     /**
 1434  
      * @param includes an array of includes or exludes map
 1435  
      * @param key a key wanted in the map, like <code>include</code> or <code>exclude</code>
 1436  
      * @return a String with comma-separated value of a key in each map
 1437  
      */
 1438  
     private static String getCommaSeparatedList( Map[] includes, String key )
 1439  
     {
 1440  0
         if ( ( includes == null ) || ( includes.length == 0 ) )
 1441  
         {
 1442  0
             return null;
 1443  
         }
 1444  
 
 1445  0
         StringBuffer sb = new StringBuffer();
 1446  0
         for ( int i = 0; i < includes.length; i++ )
 1447  
         {
 1448  0
             String s = (String) includes[i].get( key );
 1449  0
             if ( StringUtils.isEmpty( s ) )
 1450  
             {
 1451  0
                 continue;
 1452  
             }
 1453  
 
 1454  0
             sb.append( s );
 1455  
 
 1456  0
             if ( i < ( includes.length - 1 ) )
 1457  
             {
 1458  0
                 sb.append( "," );
 1459  
             }
 1460  
         }
 1461  
 
 1462  0
         if ( sb.length() == 0 )
 1463  
         {
 1464  0
             return null;
 1465  
         }
 1466  
 
 1467  0
         return sb.toString();
 1468  
     }
 1469  
 
 1470  
     /**
 1471  
      * Flattens the specified file selector options into a simple string list. For instance, the input
 1472  
      *
 1473  
      * <pre>
 1474  
      * [ {include=&quot;*Test.java&quot;}, {include=&quot;*TestCase.java&quot;} ]
 1475  
      * </pre>
 1476  
      *
 1477  
      * is converted to
 1478  
      *
 1479  
      * <pre>
 1480  
      * [ &quot;*Test.java&quot;, &quot;*TestCase.java&quot; ]
 1481  
      * </pre>
 1482  
      *
 1483  
      * @param options The file selector options to flatten, may be <code>null</code>.
 1484  
      * @return The string list, might be empty but never <code>null</code>.
 1485  
      */
 1486  
     private static List getSelectorList( Map[] options )
 1487  
     {
 1488  0
         List list = new ArrayList();
 1489  0
         if ( options != null && options.length > 0 )
 1490  
         {
 1491  0
             for ( int i = 0; i < options.length; i++ )
 1492  
             {
 1493  0
                 Map option = options[i];
 1494  0
                 list.addAll( option.values() );
 1495  
             }
 1496  
         }
 1497  0
         return list;
 1498  
     }
 1499  
 
 1500  
 }