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