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