1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.core.container.mojo;
22
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.io.OutputStreamWriter;
32 import java.io.StringReader;
33 import java.io.StringWriter;
34 import java.io.Writer;
35 import java.net.MalformedURLException;
36 import java.net.URL;
37 import java.util.Arrays;
38 import java.util.Collection;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.LinkedList;
42 import java.util.List;
43 import java.util.Locale;
44 import java.util.Set;
45 import org.apache.maven.artifact.Artifact;
46 import org.apache.maven.artifact.DependencyResolutionRequiredException;
47 import org.apache.maven.plugin.AbstractMojo;
48 import org.apache.maven.plugin.MojoFailureException;
49 import org.apache.maven.project.MavenProject;
50 import org.apache.velocity.app.VelocityEngine;
51 import org.codehaus.plexus.util.DirectoryScanner;
52 import org.jdtaus.core.container.mojo.model.ModelManager;
53
54
55
56
57
58
59
60 public abstract class AbstractContainerMojo extends AbstractMojo
61 {
62
63
64
65
66
67
68 private static final String SYS_ENABLE_CONTEXT_CLASSLOADER =
69 "org.jdtaus.core.container.ClassLoaderFactory.enableContextClassloader";
70
71
72
73
74
75
76 private MavenProject mavenProject;
77
78
79
80
81
82
83 private Integer spacesPerIndentationLevel;
84
85
86
87
88
89
90
91
92 private String encoding;
93
94
95
96
97
98
99
100 private Boolean testMode;
101
102
103
104
105
106
107
108 private String locale;
109
110
111
112
113
114
115
116 private String classPathElementsExcludeRegexp;
117
118
119
120
121
122
123
124 private String testClassPathElementsExcludeRegexp;
125
126
127 private ModelManager modelManager;
128
129
130
131
132
133
134
135 protected final String getEncoding()
136 {
137 return this.encoding;
138 }
139
140
141
142
143
144
145 protected final MavenProject getMavenProject()
146 {
147 return this.mavenProject;
148 }
149
150
151
152
153
154
155
156 protected final boolean isTestMode()
157 {
158 return this.testMode.booleanValue();
159 }
160
161
162
163
164
165
166 protected final Locale getLocale()
167 {
168 return this.locale == null
169 ? Locale.getDefault()
170 : new Locale( this.locale );
171
172 }
173
174
175
176
177
178
179
180
181
182
183 protected final Set getClasspathElements()
184 throws DependencyResolutionRequiredException
185 {
186 final Set elements = new HashSet();
187
188 elements.add( this.getMavenProject().getBuild().getOutputDirectory() );
189
190 int i = 0;
191 for ( final Iterator it = this.getMavenProject().getRuntimeArtifacts().
192 iterator(); it.hasNext(); )
193 {
194 final Artifact a = (Artifact) it.next();
195
196 if ( a.getFile() == null )
197 {
198 this.getLog().warn( a.toString() + " ignored." );
199 continue;
200 }
201
202 final String element = a.getFile().getAbsolutePath();
203
204 if ( this.getLog().isDebugEnabled() )
205 {
206 this.getLog().debug( "Runtime classpath element[" + i++ +
207 "]: " + element );
208
209 }
210
211 elements.add( element );
212 }
213
214 i = 0;
215 for ( final Iterator it = this.getMavenProject().getCompileArtifacts().
216 iterator(); it.hasNext(); )
217 {
218 final Artifact a = (Artifact) it.next();
219
220 if ( a.getFile() == null )
221 {
222 this.getLog().warn( a.toString() + " ignored." );
223 continue;
224 }
225
226 final String element = a.getFile().getAbsolutePath();
227
228 if ( this.getLog().isDebugEnabled() )
229 {
230 this.getLog().debug( "Compile classpath element[" + i++ +
231 "]: " + element );
232
233 }
234
235 elements.add( element );
236 }
237
238 return elements;
239 }
240
241
242
243
244
245
246
247
248
249 protected final Set getTestClasspathElements()
250 throws DependencyResolutionRequiredException
251 {
252 final Set elements = new HashSet();
253
254 elements.add( this.getMavenProject().getBuild().getOutputDirectory() );
255 elements.add( this.getMavenProject().getBuild().
256 getTestOutputDirectory() );
257
258 int i = 0;
259 for ( final Iterator it = this.getMavenProject().getTestArtifacts().
260 iterator(); it.hasNext(); )
261 {
262 final Artifact a = (Artifact) it.next();
263
264 if ( a.getFile() == null )
265 {
266 this.getLog().warn( a.toString() + " ignored." );
267 continue;
268 }
269
270 final String element = a.getFile().getAbsolutePath();
271
272 if ( this.getLog().isDebugEnabled() )
273 {
274 this.getLog().debug( "Test classpath element[" + i++ +
275 "]: " + element );
276
277 }
278
279 elements.add( element );
280 }
281
282 return elements;
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296 protected boolean isClasspathElementIncluded( final String element )
297 {
298 if ( element == null )
299 {
300 throw new NullPointerException( "element" );
301 }
302
303 boolean ret = !this.isClasspathElementDefaultExlude( element );
304
305 if ( ret && this.classPathElementsExcludeRegexp != null )
306 {
307 ret = !element.matches( this.classPathElementsExcludeRegexp );
308 }
309
310 return ret;
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324 protected boolean isTestClasspathElementIncluded( final String element )
325 {
326 if ( element == null )
327 {
328 throw new NullPointerException( "element" );
329 }
330
331 boolean ret = !this.isClasspathElementDefaultExlude( element );
332
333 if ( ret && this.testClassPathElementsExcludeRegexp != null )
334 {
335 ret = !element.matches( this.testClassPathElementsExcludeRegexp );
336 }
337
338 return ret;
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352 protected boolean isClasspathElementDefaultExlude( final String element )
353 {
354 return false;
355 }
356
357
358 protected static final String[] DEFAULT_SOURCE_INCLUDES =
359 {
360 "**/*.java",
361 "**/*.xml",
362 "**/*.xsd",
363 "**/*.html",
364 "**/*.vm",
365 "**/*.apt"
366 };
367
368
369
370
371
372
373 protected ModelManager getModelManager()
374 {
375 return this.modelManager;
376 }
377
378
379
380
381
382 private static final String VELOCITY_RESOURCE_LOADER =
383 "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader";
384
385
386 private VelocityEngine velocityEngine;
387
388
389 public interface SourceEditor
390 {
391
392
393
394
395
396
397
398
399
400
401
402
403 String editLine( String line ) throws MojoFailureException;
404
405
406
407
408
409
410
411 boolean isModified();
412
413 }
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429 protected final File getSource( final List roots, final String className )
430 {
431 if ( className == null )
432 {
433 throw new NullPointerException( "className" );
434 }
435 if ( roots == null )
436 {
437 throw new NullPointerException( "roots" );
438 }
439
440 File file;
441 String source;
442 File ret = null;
443 final String fileName =
444 className.replace( '.', File.separatorChar ).concat( ".java" );
445
446 for ( final Iterator it = roots.iterator(); it.hasNext(); )
447 {
448 source = (String) it.next();
449 file =
450 new File( source.concat( File.separator ).concat( fileName ) );
451
452 if ( file.canRead() && file.canWrite() )
453 {
454 ret = file;
455 break;
456 }
457 else
458 {
459 ret = null;
460 }
461 }
462
463 return ret;
464 }
465
466
467
468
469
470
471
472 protected final Collection getAllSources()
473 {
474 File file;
475 File parentRoot;
476 String sourceRoot;
477 DirectoryScanner scanner;
478 final Collection files = new LinkedList();
479
480 for ( final Iterator it = this.getMavenProject().
481 getCompileSourceRoots().iterator(); it.hasNext(); )
482 {
483 sourceRoot = (String) it.next();
484 parentRoot = new File( sourceRoot );
485
486 if ( !parentRoot.exists() || !parentRoot.isDirectory() )
487 {
488 continue;
489 }
490
491 scanner = new DirectoryScanner();
492 scanner.setBasedir( sourceRoot );
493 scanner.setIncludes( DEFAULT_SOURCE_INCLUDES );
494 scanner.addDefaultExcludes();
495 scanner.scan();
496
497 for ( final Iterator it2 =
498 Arrays.asList( scanner.getIncludedFiles() ).iterator();
499 it2.hasNext(); )
500 {
501 file = new File( parentRoot, (String) it2.next() );
502 files.add( file );
503 }
504 }
505
506 return files;
507 }
508
509
510
511
512
513
514
515 protected final Collection getTestSources()
516 {
517 File file;
518 File parentRoot;
519 String sourceRoot;
520 DirectoryScanner scanner;
521 final Collection files = new LinkedList();
522
523 for ( final Iterator it = this.getMavenProject().
524 getTestCompileSourceRoots().iterator(); it.hasNext(); )
525 {
526 sourceRoot = (String) it.next();
527 parentRoot = new File( sourceRoot );
528
529 if ( !parentRoot.exists() || !parentRoot.isDirectory() )
530 {
531 continue;
532 }
533
534 scanner = new DirectoryScanner();
535 scanner.setBasedir( sourceRoot );
536 scanner.setIncludes( DEFAULT_SOURCE_INCLUDES );
537 scanner.addDefaultExcludes();
538 scanner.scan();
539
540 for ( final Iterator it2 =
541 Arrays.asList( scanner.getIncludedFiles() ).iterator();
542 it2.hasNext(); )
543 {
544 file = new File( parentRoot, (String) it2.next() );
545 files.add( file );
546 }
547 }
548
549 return files;
550 }
551
552
553
554
555
556
557
558
559
560
561
562
563
564 protected final String edit(
565 final String str, final AbstractContainerMojo.SourceEditor editor )
566 throws MojoFailureException
567 {
568 if ( str == null )
569 {
570 throw new NullPointerException( "str" );
571 }
572 if ( editor == null )
573 {
574 throw new NullPointerException( "editor" );
575 }
576
577 int i;
578 String line;
579 String replacement;
580 final char[] chars;
581 final BufferedReader reader;
582 final StringWriter writer = new StringWriter();
583
584 try
585 {
586 reader = new BufferedReader( new StringReader( str ) );
587
588 while ( ( line = reader.readLine() ) != null )
589 {
590 replacement = editor.editLine( line );
591 if ( replacement != null )
592 {
593 writer.write( replacement.concat( "\n" ) );
594 }
595 }
596
597 replacement = editor.editLine( null );
598 if ( replacement != null )
599 {
600 writer.write( replacement.concat( "\n" ) );
601 }
602
603 reader.close();
604 writer.close();
605
606 replacement = writer.toString();
607 chars = replacement.toCharArray();
608
609
610 for ( i = chars.length - 1; i >= 0; i-- )
611 {
612 if ( chars[i] != '\n' && chars[i] != '\r' )
613 {
614 break;
615 }
616 }
617
618 replacement = replacement.substring( 0, i + 1 );
619 return replacement + '\n';
620
621 }
622 catch ( final IOException e )
623 {
624 final MojoFailureException mfe =
625 new MojoFailureException( e.getMessage() );
626
627 mfe.initCause( e );
628 throw mfe;
629 }
630 }
631
632
633
634
635
636
637
638
639
640
641
642 protected final String load( final File file ) throws
643 MojoFailureException
644 {
645 if ( file == null )
646 {
647 throw new NullPointerException( "file" );
648 }
649
650 String line;
651 BufferedReader reader = null;
652 StringWriter writer = null;
653
654 try
655 {
656 if ( this.getEncoding() == null )
657 {
658 reader = new BufferedReader( new FileReader( file ) );
659 }
660 else
661 {
662 reader = new BufferedReader( new InputStreamReader(
663 new FileInputStream( file ),
664 this.getEncoding() ) );
665
666 }
667
668 writer = new StringWriter();
669
670 while ( ( line = reader.readLine() ) != null )
671 {
672 writer.write( line.concat( "\n" ) );
673 }
674
675 reader.close();
676 reader = null;
677
678 writer.close();
679
680 final String content = writer.toString();
681 writer = null;
682
683 return content;
684 }
685 catch ( final IOException e )
686 {
687 final MojoFailureException mfe =
688 new MojoFailureException( e.getMessage() );
689
690 mfe.initCause( e );
691 throw mfe;
692 }
693 finally
694 {
695 try
696 {
697 if ( reader != null )
698 {
699 reader.close();
700 }
701 }
702 catch ( final IOException e )
703 {
704 this.getLog().error( e );
705 }
706 finally
707 {
708 try
709 {
710 if ( writer != null )
711 {
712 writer.close();
713 }
714 }
715 catch ( final IOException e )
716 {
717 this.getLog().error( e );
718 }
719 }
720 }
721 }
722
723
724
725
726
727
728
729
730
731
732
733 protected final void save( final File file, final String str ) throws
734 MojoFailureException
735 {
736 if ( file == null )
737 {
738 throw new NullPointerException( "file" );
739 }
740 if ( str == null )
741 {
742 throw new NullPointerException( "str" );
743 }
744
745 Writer fileWriter = null;
746
747 try
748 {
749 if ( this.isTestMode() )
750 {
751 this.getLog().info( str );
752 }
753 else
754 {
755 if ( this.getEncoding() == null )
756 {
757 fileWriter = new FileWriter( file );
758 }
759 else
760 {
761 fileWriter = new OutputStreamWriter(
762 new FileOutputStream( file ), this.getEncoding() );
763
764 }
765
766 this.getLog().info( AbstractContainerMojoBundle.getInstance().
767 getFileInfoMessage( Locale.getDefault(), file.getName() ) );
768
769 fileWriter.write( str );
770 fileWriter.close();
771 fileWriter = null;
772 }
773 }
774 catch ( final IOException e )
775 {
776 final MojoFailureException mfe =
777 new MojoFailureException( e.getMessage() );
778
779 mfe.initCause( e );
780 throw mfe;
781 }
782 finally
783 {
784 try
785 {
786 if ( fileWriter != null )
787 {
788 fileWriter.close();
789 }
790 }
791 catch ( final IOException e )
792 {
793 this.getLog().error( e );
794 }
795 }
796 }
797
798
799
800
801
802
803
804
805
806 protected final void indent( final StringBuffer stringBuffer )
807 {
808 if ( stringBuffer == null )
809 {
810 throw new NullPointerException( "stringBuffer" );
811 }
812
813 final char[] spaces =
814 new char[ this.spacesPerIndentationLevel.intValue() ];
815
816 Arrays.fill( spaces, ' ' );
817 stringBuffer.append( spaces );
818 }
819
820
821
822
823
824
825
826
827
828
829
830 protected final ClassLoader getRuntimeClassLoader(
831 final ClassLoader parent ) throws MojoFailureException
832 {
833 final Collection urls = new LinkedList();
834
835 try
836 {
837 int i = 0;
838 for ( final Iterator it = this.getClasspathElements().
839 iterator(); it.hasNext(); )
840 {
841 final String element = (String) it.next();
842 final URL url = new File( element ).toURI().toURL();
843
844 if ( !urls.contains( url )
845 && this.isClasspathElementIncluded( element ) )
846 {
847 urls.add( url );
848
849 if ( this.getLog().isDebugEnabled() )
850 {
851 this.getLog().debug( "runtime[" + i++ + "]="
852 + url.toExternalForm() );
853
854 }
855 }
856 }
857
858 return new ResourceLoader(
859 (URL[]) urls.toArray( new URL[ urls.size() ] ), parent );
860
861 }
862 catch ( final DependencyResolutionRequiredException e )
863 {
864 final MojoFailureException mfe =
865 new MojoFailureException( e.getMessage() );
866
867 mfe.initCause( e );
868 throw mfe;
869 }
870 catch ( final MalformedURLException e )
871 {
872 final MojoFailureException mfe =
873 new MojoFailureException( e.getMessage() );
874
875 mfe.initCause( e );
876 throw mfe;
877 }
878 }
879
880
881
882
883
884
885
886
887
888
889
890 protected final ClassLoader getTestClassLoader( final ClassLoader parent )
891 throws MojoFailureException
892 {
893 final Iterator it;
894 final Collection urls = new LinkedList();
895
896 try
897 {
898 int i = 0;
899 for ( it = this.getTestClasspathElements().iterator();
900 it.hasNext(); )
901 {
902 final String element = (String) it.next();
903 final URL url = new File( element ).toURI().toURL();
904 if ( !urls.contains( url ) &&
905 this.isTestClasspathElementIncluded( element ) )
906 {
907 urls.add( url );
908
909 if ( this.getLog().isDebugEnabled() )
910 {
911 this.getLog().debug( "test[" + i++ + "]=" +
912 url.toExternalForm() );
913
914 }
915 }
916 }
917
918 return new ResourceLoader(
919 (URL[]) urls.toArray( new URL[ urls.size() ] ), parent );
920
921 }
922 catch ( final MalformedURLException e )
923 {
924 final MojoFailureException mfe =
925 new MojoFailureException( e.getMessage() );
926
927 mfe.initCause( e );
928 throw mfe;
929 }
930 catch ( final DependencyResolutionRequiredException e )
931 {
932 final MojoFailureException mfe =
933 new MojoFailureException( e.getMessage() );
934
935 mfe.initCause( e );
936 throw mfe;
937 }
938 }
939
940
941
942
943
944
945
946
947 protected final VelocityEngine getVelocity() throws Exception
948 {
949 if ( this.velocityEngine == null )
950 {
951 final VelocityEngine engine = new VelocityEngine();
952 final java.util.Properties props = new java.util.Properties();
953 props.put( "resource.loader", "class" );
954 props.put( "class.resource.loader.class",
955 VELOCITY_RESOURCE_LOADER );
956
957 engine.init( props );
958 this.velocityEngine = engine;
959 }
960
961 return this.velocityEngine;
962 }
963
964
965
966
967
968
969
970
971
972
973 protected String formatComment( final String text )
974 {
975 if ( text == null )
976 {
977 throw new NullPointerException( "text" );
978 }
979
980 String normalized = text.replaceAll( "\\/\\*\\*", "/*" );
981 normalized = normalized.replaceAll( "\\*/", "/" );
982
983 final StringBuffer commentLinebreak = new StringBuffer();
984 commentLinebreak.append( '\n' );
985 this.indent( commentLinebreak );
986 commentLinebreak.append( " *" );
987
988 normalized =
989 normalized.replaceAll( "\n", commentLinebreak.toString() );
990
991 return normalized;
992 }
993
994
995
996
997
998
999 protected static void enableThreadContextClassLoader()
1000 {
1001 System.setProperty( SYS_ENABLE_CONTEXT_CLASSLOADER,
1002 Boolean.toString( true ) );
1003
1004 }
1005
1006
1007
1008
1009
1010
1011 protected static void disableThreadContextClassLoader()
1012 {
1013 System.setProperty( SYS_ENABLE_CONTEXT_CLASSLOADER,
1014 Boolean.toString( false ) );
1015
1016 }
1017
1018
1019 }