1 package org.apache.maven.plugin.javadoc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.io.OutputStreamWriter;
31 import java.io.PrintStream;
32 import java.io.Reader;
33 import java.io.UnsupportedEncodingException;
34 import java.lang.reflect.Modifier;
35 import java.net.URL;
36 import java.net.URLClassLoader;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Properties;
43 import java.util.Set;
44 import java.util.StringTokenizer;
45 import java.util.jar.JarEntry;
46 import java.util.jar.JarInputStream;
47 import java.util.regex.Matcher;
48 import java.util.regex.Pattern;
49 import java.util.regex.PatternSyntaxException;
50
51 import org.apache.commons.httpclient.HttpClient;
52 import org.apache.commons.httpclient.UsernamePasswordCredentials;
53 import org.apache.commons.httpclient.auth.AuthScope;
54 import org.apache.commons.httpclient.methods.GetMethod;
55 import org.apache.commons.lang.SystemUtils;
56 import org.apache.maven.artifact.Artifact;
57 import org.apache.maven.plugin.logging.Log;
58 import org.apache.maven.project.MavenProject;
59 import org.apache.maven.settings.Proxy;
60 import org.apache.maven.settings.Settings;
61 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
62 import org.apache.maven.shared.invoker.DefaultInvoker;
63 import org.apache.maven.shared.invoker.InvocationOutputHandler;
64 import org.apache.maven.shared.invoker.InvocationRequest;
65 import org.apache.maven.shared.invoker.InvocationResult;
66 import org.apache.maven.shared.invoker.Invoker;
67 import org.apache.maven.shared.invoker.MavenInvocationException;
68 import org.apache.maven.shared.invoker.PrintStreamHandler;
69 import org.codehaus.plexus.util.FileUtils;
70 import org.codehaus.plexus.util.IOUtil;
71 import org.codehaus.plexus.util.ReaderFactory;
72 import org.codehaus.plexus.util.StringUtils;
73 import org.codehaus.plexus.util.cli.CommandLineException;
74 import org.codehaus.plexus.util.cli.CommandLineUtils;
75 import org.codehaus.plexus.util.cli.Commandline;
76
77
78
79
80
81
82
83
84 public class JavadocUtil
85 {
86
87 public static final int DEFAULT_TIMEOUT = 2000;
88
89
90
91
92
93
94
95
96
97
98 protected static List pruneDirs( MavenProject project, List dirs )
99 {
100 List pruned = new ArrayList( dirs.size() );
101 for ( Iterator i = dirs.iterator(); i.hasNext(); )
102 {
103 String dir = (String) i.next();
104
105 if ( dir == null )
106 {
107 continue;
108 }
109
110 File directory = new File( dir );
111 if ( !directory.isAbsolute() )
112 {
113 directory = new File( project.getBasedir(), directory.getPath() );
114 }
115
116 if ( directory.isDirectory() && !pruned.contains( directory.getAbsolutePath() ) )
117 {
118 pruned.add( directory.getAbsolutePath() );
119 }
120 }
121
122 return pruned;
123 }
124
125
126
127
128
129
130
131
132 protected static List pruneFiles( List files )
133 {
134 List pruned = new ArrayList( files.size() );
135 for ( Iterator i = files.iterator(); i.hasNext(); )
136 {
137 String f = (String) i.next();
138
139 if ( f == null )
140 {
141 continue;
142 }
143
144 File file = new File( f );
145 if ( file.isFile() && !pruned.contains( f ) )
146 {
147 pruned.add( f );
148 }
149 }
150
151 return pruned;
152 }
153
154
155
156
157
158
159
160
161
162
163 protected static List getExcludedNames( List sourcePaths, String[] subpackagesList, String[] excludedPackages )
164 {
165 List excludedNames = new ArrayList();
166 for ( Iterator i = sourcePaths.iterator(); i.hasNext(); )
167 {
168 String path = (String) i.next();
169 for ( int j = 0; j < subpackagesList.length; j++ )
170 {
171 List excludes = getExcludedPackages( path, excludedPackages );
172 excludedNames.addAll( excludes );
173 }
174 }
175
176 return excludedNames;
177 }
178
179
180
181
182
183
184
185 protected static List getCompileArtifacts( Set artifacts )
186 {
187 return getCompileArtifacts( artifacts, false );
188 }
189
190
191
192
193
194
195
196 protected static List getCompileArtifacts( Set artifacts, boolean withTestScope )
197 {
198 List list = new ArrayList( artifacts.size() );
199
200 for ( Iterator i = artifacts.iterator(); i.hasNext(); )
201 {
202 Artifact a = (Artifact) i.next();
203
204
205 if ( a.getArtifactHandler().isAddedToClasspath() )
206 {
207
208 if ( withTestScope )
209 {
210 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() )
211 || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
212 || Artifact.SCOPE_SYSTEM.equals( a.getScope() )
213 || Artifact.SCOPE_TEST.equals( a.getScope() ) )
214 {
215 list.add( a );
216 }
217 }
218 else
219 {
220 if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
221 || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
222 {
223 list.add( a );
224 }
225 }
226 }
227 }
228
229 return list;
230 }
231
232
233
234
235
236
237
238
239
240
241 protected static String quotedArgument( String value )
242 {
243 String arg = value;
244
245 if ( StringUtils.isNotEmpty( arg ) )
246 {
247 if ( arg.indexOf( "'" ) != -1 )
248 {
249 arg = StringUtils.replace( arg, "'", "\\'" );
250 }
251 arg = "'" + arg + "'";
252
253
254 arg = StringUtils.replace( arg, "\n", " " );
255 }
256
257 return arg;
258 }
259
260
261
262
263
264
265
266
267 protected static String quotedPathArgument( String value )
268 {
269 String path = value;
270
271 if ( StringUtils.isNotEmpty( path ) )
272 {
273 path = path.replace( '\\', '/' );
274 if ( path.indexOf( "\'" ) != -1 )
275 {
276 String split[] = path.split( "\'" );
277 path = "";
278
279 for ( int i = 0; i < split.length; i++ )
280 {
281 if ( i != split.length - 1 )
282 {
283 path = path + split[i] + "\\'";
284 }
285 else
286 {
287 path = path + split[i];
288 }
289 }
290 }
291 path = "'" + path + "'";
292 }
293
294 return path;
295 }
296
297
298
299
300
301
302
303
304
305
306 protected static void copyJavadocResources( File outputDirectory, File javadocDir )
307 throws IOException
308 {
309 copyJavadocResources( outputDirectory, javadocDir, null );
310 }
311
312
313
314
315
316
317
318
319
320
321
322 protected static void copyJavadocResources( File outputDirectory, File javadocDir, String excludedocfilessubdir )
323 throws IOException
324 {
325 List excludes = new ArrayList();
326 excludes.addAll( Arrays.asList( FileUtils.getDefaultExcludes() ) );
327
328 if ( StringUtils.isNotEmpty( excludedocfilessubdir ) )
329 {
330 StringTokenizer st = new StringTokenizer( excludedocfilessubdir, ":" );
331 String current;
332 while ( st.hasMoreTokens() )
333 {
334 current = st.nextToken();
335 excludes.add( "**/" + current + "/**" );
336 }
337 }
338
339 if ( javadocDir.exists() && javadocDir.isDirectory() )
340 {
341 List docFiles =
342 FileUtils.getDirectoryNames( javadocDir, "**/doc-files", StringUtils.join( excludes.iterator(),
343 "," ), false, true );
344 for ( Iterator it = docFiles.iterator(); it.hasNext(); )
345 {
346 String docFile = (String) it.next();
347
348 File docFileOutput = new File( outputDirectory, docFile );
349 FileUtils.mkdir( docFileOutput.getAbsolutePath() );
350 FileUtils.copyDirectoryStructure( new File( javadocDir, docFile ), docFileOutput );
351 List files =
352 FileUtils.getFileAndDirectoryNames( docFileOutput,
353 StringUtils.join( excludes.iterator(), "," ), null, true,
354 true, true, true );
355 for ( Iterator it2 = files.iterator(); it2.hasNext(); )
356 {
357 File file = new File( it2.next().toString() );
358
359 if ( file.isDirectory() )
360 {
361 FileUtils.deleteDirectory( file );
362 }
363 else
364 {
365 file.delete();
366 }
367 }
368 }
369 }
370 }
371
372
373
374
375
376
377
378
379
380
381 protected static List getIncludedFiles( File sourceDirectory, String[] fileList, String[] excludePackages )
382 {
383 List files = new ArrayList();
384
385 for ( int j = 0; j < fileList.length; j++ )
386 {
387 boolean include = true;
388 for ( int k = 0; k < excludePackages.length && include; k++ )
389 {
390
391 String[] excludeName = excludePackages[k].split( "[*]" );
392
393 if ( excludeName.length == 0 )
394 {
395 continue;
396 }
397
398 if ( excludeName.length > 1 )
399 {
400 int u = 0;
401 while ( include && u < excludeName.length )
402 {
403 if ( !"".equals( excludeName[u].trim() ) && fileList[j].indexOf( excludeName[u] ) != -1 )
404 {
405 include = false;
406 }
407 u++;
408 }
409 }
410 else
411 {
412 if ( fileList[j].startsWith( sourceDirectory.toString() + File.separatorChar + excludeName[0] ) )
413 {
414 if ( excludeName[0].endsWith( String.valueOf( File.separatorChar ) ) )
415 {
416 int i = fileList[j].lastIndexOf( File.separatorChar );
417 String packageName = fileList[j].substring( 0, i + 1 );
418 File currentPackage = new File( packageName );
419 File excludedPackage = new File( sourceDirectory, excludeName[0] );
420 if ( currentPackage.equals( excludedPackage )
421 && fileList[j].substring( i ).indexOf( ".java" ) != -1 )
422 {
423 include = true;
424 }
425 else
426 {
427 include = false;
428 }
429 }
430 else
431 {
432 include = false;
433 }
434 }
435 }
436 }
437
438 if ( include )
439 {
440 files.add( quotedPathArgument( fileList[j] ) );
441 }
442 }
443
444 return files;
445 }
446
447
448
449
450
451
452
453
454
455 protected static List getExcludedPackages( String sourceDirectory, String[] excludePackagenames )
456 {
457 List files = new ArrayList();
458 for ( int i = 0; i < excludePackagenames.length; i++ )
459 {
460 String[] fileList = FileUtils.getFilesFromExtension( sourceDirectory, new String[] { "java" } );
461 for ( int j = 0; j < fileList.length; j++ )
462 {
463 String[] excludeName = excludePackagenames[i].split( "[*]" );
464 int u = 0;
465 while ( u < excludeName.length )
466 {
467 if ( !"".equals( excludeName[u].trim() ) && fileList[j].indexOf( excludeName[u] ) != -1
468 && sourceDirectory.indexOf( excludeName[u] ) == -1 )
469 {
470 files.add( fileList[j] );
471 }
472 u++;
473 }
474 }
475 }
476
477 List excluded = new ArrayList();
478 for ( Iterator it = files.iterator(); it.hasNext(); )
479 {
480 String file = (String) it.next();
481 int idx = file.lastIndexOf( File.separatorChar );
482 String tmpStr = file.substring( 0, idx );
483 tmpStr = tmpStr.replace( '\\', '/' );
484 String[] srcSplit = tmpStr.split( sourceDirectory.replace( '\\', '/' ) + '/' );
485 String excludedPackage = srcSplit[1].replace( '/', '.' );
486
487 if ( !excluded.contains( excludedPackage ) )
488 {
489 excluded.add( excludedPackage );
490 }
491 }
492
493 return excluded;
494 }
495
496
497
498
499
500
501
502
503 protected static void addFilesFromSource( List files, File sourceDirectory, String[] excludePackages )
504 {
505 String[] fileList = FileUtils.getFilesFromExtension( sourceDirectory.getPath(), new String[] { "java" } );
506 if ( fileList != null && fileList.length != 0 )
507 {
508 List tmpFiles = getIncludedFiles( sourceDirectory, fileList, excludePackages );
509 files.addAll( tmpFiles );
510 }
511 }
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527 protected static float getJavadocVersion( File javadocExe )
528 throws IOException, CommandLineException, IllegalArgumentException, PatternSyntaxException
529 {
530 if ( ( javadocExe == null ) || ( !javadocExe.exists() ) || ( !javadocExe.isFile() ) )
531 {
532 throw new IOException( "The javadoc executable '" + javadocExe + "' doesn't exist or is not a file. " );
533 }
534
535 Commandline cmd = new Commandline();
536 cmd.setExecutable( javadocExe.getAbsolutePath() );
537 cmd.setWorkingDirectory( javadocExe.getParentFile() );
538 cmd.createArg().setValue( "-J-version" );
539
540 CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
541 CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
542
543 int exitCode = CommandLineUtils.executeCommandLine( cmd, out, err );
544
545 if ( exitCode != 0 )
546 {
547 StringBuffer msg = new StringBuffer( "Exit code: " + exitCode + " - " + err.getOutput() );
548 msg.append( '\n' );
549 msg.append( "Command line was:" + CommandLineUtils.toString( cmd.getCommandline() ) );
550 throw new CommandLineException( msg.toString() );
551 }
552
553 if ( StringUtils.isNotEmpty( err.getOutput() ) )
554 {
555 return parseJavadocVersion( err.getOutput() );
556 }
557 else if ( StringUtils.isNotEmpty( out.getOutput() ) )
558 {
559 return parseJavadocVersion( out.getOutput() );
560 }
561
562 throw new IllegalArgumentException( "No output found from the command line 'javadoc -J-version'" );
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606 protected static float parseJavadocVersion( String output )
607 throws IllegalArgumentException, PatternSyntaxException
608 {
609 if ( StringUtils.isEmpty( output ) )
610 {
611 throw new IllegalArgumentException( "The output could not be null." );
612 }
613
614 Pattern pattern = Pattern.compile( "(?s).*?([0-9]+\\.[0-9]+)(\\.([0-9]+))?.*" );
615
616 Matcher matcher = pattern.matcher( output );
617 if ( !matcher.matches() )
618 {
619 throw new PatternSyntaxException( "Unrecognized version of Javadoc: '" + output + "'", pattern.pattern(),
620 pattern.toString().length() - 1 );
621 }
622
623 String version = matcher.group( 3 );
624 if ( version == null )
625 {
626 version = matcher.group( 1 );
627 }
628 else
629 {
630 version = matcher.group( 1 ) + version;
631 }
632
633 return Float.parseFloat( version );
634 }
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665 protected static String parseJavadocMemory( String memory )
666 throws IllegalArgumentException
667 {
668 if ( StringUtils.isEmpty( memory ) )
669 {
670 throw new IllegalArgumentException( "The memory could not be null." );
671 }
672
673 Pattern p = Pattern.compile( "^\\s*(\\d+)\\s*?\\s*$" );
674 Matcher m = p.matcher( memory );
675 if ( m.matches() )
676 {
677 return m.group( 1 ) + "m";
678 }
679
680 p = Pattern.compile( "^\\s*(\\d+)\\s*k(b)?\\s*$", Pattern.CASE_INSENSITIVE );
681 m = p.matcher( memory );
682 if ( m.matches() )
683 {
684 return m.group( 1 ) + "k";
685 }
686
687 p = Pattern.compile( "^\\s*(\\d+)\\s*m(b)?\\s*$", Pattern.CASE_INSENSITIVE );
688 m = p.matcher( memory );
689 if ( m.matches() )
690 {
691 return m.group( 1 ) + "m";
692 }
693
694 p = Pattern.compile( "^\\s*(\\d+)\\s*g(b)?\\s*$", Pattern.CASE_INSENSITIVE );
695 m = p.matcher( memory );
696 if ( m.matches() )
697 {
698 return ( Integer.parseInt( m.group( 1 ) ) * 1024 ) + "m";
699 }
700
701 p = Pattern.compile( "^\\s*(\\d+)\\s*t(b)?\\s*$", Pattern.CASE_INSENSITIVE );
702 m = p.matcher( memory );
703 if ( m.matches() )
704 {
705 return ( Integer.parseInt( m.group( 1 ) ) * 1024 * 1024 ) + "m";
706 }
707
708 throw new IllegalArgumentException( "Could convert not to a memory size: " + memory );
709 }
710
711
712
713
714
715
716
717
718
719 protected static void fetchURL( Settings settings, URL url )
720 throws IOException
721 {
722 if ( url == null )
723 {
724 throw new IllegalArgumentException( "The url is null" );
725 }
726
727 HttpClient httpClient = null;
728 if ( !"file".equals( url.getProtocol() ) )
729 {
730 httpClient = new HttpClient();
731 httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( DEFAULT_TIMEOUT );
732 httpClient.getHttpConnectionManager().getParams().setSoTimeout( DEFAULT_TIMEOUT );
733
734 if ( settings != null )
735 {
736 Proxy activeProxy = settings.getActiveProxy();
737
738 if ( activeProxy != null )
739 {
740 String proxyHost = settings.getActiveProxy().getHost();
741 int proxyPort = settings.getActiveProxy().getPort();
742
743 String proxyUser = settings.getActiveProxy().getUsername();
744 String proxyPass = settings.getActiveProxy().getPassword();
745
746 if ( StringUtils.isNotEmpty( proxyHost ) )
747 {
748 httpClient.getHostConfiguration().setProxy( proxyHost, proxyPort );
749 }
750
751 if ( StringUtils.isNotEmpty( proxyUser ) )
752 {
753 AuthScope authScope =
754 new AuthScope( AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM,
755 AuthScope.ANY_SCHEME );
756 UsernamePasswordCredentials usernamePasswordCredentials =
757 new UsernamePasswordCredentials( proxyUser, proxyPass );
758 httpClient.getState().setProxyCredentials( authScope, usernamePasswordCredentials );
759 }
760 }
761 }
762 }
763
764 InputStream in = null;
765 try
766 {
767 if ( httpClient != null )
768 {
769 GetMethod getMethod = new GetMethod( url.toString() );
770
771 try
772 {
773 int status = httpClient.executeMethod( getMethod );
774 if ( status != 200 )
775 {
776 throw new FileNotFoundException( url.toString() );
777 }
778 }
779 finally
780 {
781 getMethod.releaseConnection();
782 }
783 }
784 else
785 {
786 in = url.openStream();
787 }
788 }
789 finally
790 {
791 IOUtil.close( in );
792 }
793 }
794
795
796
797
798
799
800
801 protected static boolean validateEncoding( String charsetName )
802 {
803 if ( StringUtils.isEmpty( charsetName ) )
804 {
805 return false;
806 }
807
808 OutputStream ost = new ByteArrayOutputStream();
809 OutputStreamWriter osw = null;
810 try
811 {
812 osw = new OutputStreamWriter( ost, charsetName );
813 }
814 catch ( UnsupportedEncodingException exc )
815 {
816 return false;
817 }
818 finally
819 {
820 IOUtil.close( osw );
821 }
822 return true;
823 }
824
825
826
827
828
829
830
831
832
833 protected static String hideProxyPassword( String cmdLine, Settings settings )
834 {
835 if ( cmdLine == null )
836 {
837 throw new IllegalArgumentException( "cmdLine could not be null" );
838 }
839
840 if ( settings == null )
841 {
842 return cmdLine;
843 }
844
845 Proxy activeProxy = settings.getActiveProxy();
846 if ( activeProxy != null && StringUtils.isNotEmpty( activeProxy.getHost() )
847 && StringUtils.isNotEmpty( activeProxy.getUsername() )
848 && StringUtils.isNotEmpty( activeProxy.getPassword() ) )
849 {
850 String pass = "-J-Dhttp.proxyPassword=\"" + activeProxy.getPassword() + "\"";
851 String hidepass =
852 "-J-Dhttp.proxyPassword=\"" + StringUtils.repeat( "*", activeProxy.getPassword().length() ) + "\"";
853
854 return StringUtils.replace( cmdLine, pass, hidepass );
855 }
856
857 return cmdLine;
858 }
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874 protected static List getTagletClassNames( File jarFile )
875 throws IOException, ClassNotFoundException, NoClassDefFoundError
876 {
877 List classes = getClassNamesFromJar( jarFile );
878 ClassLoader cl;
879
880
881 File tools = new File( System.getProperty( "java.home" ), "../lib/tools.jar" );
882 if ( tools.exists() && tools.isFile() )
883 {
884 cl = new URLClassLoader( new URL[] { jarFile.toURI().toURL(), tools.toURI().toURL() }, null );
885 }
886 else
887 {
888 cl = new URLClassLoader( new URL[] { jarFile.toURI().toURL() }, null );
889 }
890
891 List tagletClasses = new ArrayList();
892
893 Class tagletClass = cl.loadClass( "com.sun.tools.doclets.Taglet" );
894 for ( Iterator it = classes.iterator(); it.hasNext(); )
895 {
896 String s = (String) it.next();
897
898 Class c = cl.loadClass( s );
899
900 if ( tagletClass.isAssignableFrom( c ) && !Modifier.isAbstract( c.getModifiers() ) )
901 {
902 tagletClasses.add( c.getName() );
903 }
904 }
905
906 return tagletClasses;
907 }
908
909
910
911
912
913
914
915
916
917 protected static void copyResource( URL url, File file )
918 throws IOException
919 {
920 if ( file == null )
921 {
922 throw new IOException( "The file " + file + " can't be null." );
923 }
924 if ( url == null )
925 {
926 throw new IOException( "The url " + url + " could not be null." );
927 }
928
929 InputStream is = url.openStream();
930 if ( is == null )
931 {
932 throw new IOException( "The resource " + url + " doesn't exists." );
933 }
934
935 if ( !file.getParentFile().exists() )
936 {
937 file.getParentFile().mkdirs();
938 }
939
940 FileOutputStream os = null;
941 try
942 {
943 os = new FileOutputStream( file );
944
945 IOUtil.copy( is, os );
946 }
947 finally
948 {
949 IOUtil.close( is );
950
951 IOUtil.close( os );
952 }
953 }
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970 protected static void invokeMaven( Log log, File localRepositoryDir, File projectFile, List goals,
971 Properties properties, File invokerLog )
972 {
973 if ( projectFile == null )
974 {
975 throw new IllegalArgumentException( "projectFile should be not null." );
976 }
977 if ( !projectFile.isFile() )
978 {
979 throw new IllegalArgumentException( projectFile.getAbsolutePath() + " is not a file." );
980 }
981 if ( goals == null || goals.size() == 0 )
982 {
983 throw new IllegalArgumentException( "goals should be not empty." );
984 }
985 if ( localRepositoryDir == null || !localRepositoryDir.isDirectory() )
986 {
987 throw new IllegalArgumentException( "localRepositoryDir '" + localRepositoryDir
988 + "' should be a directory." );
989 }
990
991 String mavenHome = getMavenHome( log );
992 if ( StringUtils.isEmpty( mavenHome ) )
993 {
994 String msg =
995 "Could NOT invoke Maven because no Maven Home is defined. You need to have set the M2_HOME "
996 + "system env variable or a maven.home Java system properties.";
997 if ( log != null )
998 {
999 log.error( msg );
1000 }
1001 else
1002 {
1003 System.err.println( msg );
1004 }
1005 return;
1006 }
1007
1008 Invoker invoker = new DefaultInvoker();
1009 invoker.setMavenHome( new File( mavenHome ) );
1010 invoker.setLocalRepositoryDirectory( localRepositoryDir );
1011
1012 InvocationRequest request = new DefaultInvocationRequest();
1013 request.setBaseDirectory( projectFile.getParentFile() );
1014 request.setPomFile( projectFile );
1015 if ( log != null )
1016 {
1017 request.setDebug( log.isDebugEnabled() );
1018 }
1019 else
1020 {
1021 request.setDebug( true );
1022 }
1023 request.setGoals( goals );
1024 if ( properties != null )
1025 {
1026 request.setProperties( properties );
1027 }
1028 File javaHome = getJavaHome( log );
1029 if ( javaHome != null )
1030 {
1031 request.setJavaHome( javaHome );
1032 }
1033
1034 InvocationResult result;
1035 try
1036 {
1037 if ( log != null )
1038 {
1039 log.debug( "Invoking Maven for the goals: " + goals + " with properties=" + properties );
1040 }
1041 result = invoke( log, invoker, request, invokerLog, goals, properties, null );
1042 }
1043 catch ( MavenInvocationException e )
1044 {
1045 if ( log != null )
1046 {
1047 if ( log.isDebugEnabled() )
1048 {
1049 log.error( "MavenInvocationException: " + e.getMessage(), e );
1050 }
1051 else
1052 {
1053 log.error( "MavenInvocationException: " + e.getMessage() );
1054 }
1055 log.error( "Error when invoking Maven, consult the invoker log." );
1056 }
1057 return;
1058 }
1059
1060 String invokerLogContent = null;
1061 Reader reader = null;
1062 try
1063 {
1064 reader = ReaderFactory.newReader( invokerLog, "UTF-8" );
1065 invokerLogContent = IOUtil.toString( reader );
1066 }
1067 catch ( IOException e )
1068 {
1069 if ( log != null )
1070 {
1071 log.error( "IOException: " + e.getMessage() );
1072 }
1073 }
1074 finally
1075 {
1076 IOUtil.close( reader );
1077 }
1078
1079 if ( invokerLogContent != null
1080 && invokerLogContent.indexOf( "Error occurred during initialization of VM" ) != -1 )
1081 {
1082 if ( log != null )
1083 {
1084 log.info( "Error occurred during initialization of VM, try to use an empty MAVEN_OPTS." );
1085
1086 log.debug( "Reinvoking Maven for the goals: " + goals + " with an empty MAVEN_OPTS" );
1087 }
1088 try
1089 {
1090 result = invoke( log, invoker, request, invokerLog, goals, properties, "" );
1091 }
1092 catch ( MavenInvocationException e )
1093 {
1094 if ( log != null )
1095 {
1096 if ( log.isDebugEnabled() )
1097 {
1098 log.error( "MavenInvocationException: " + e.getMessage(), e );
1099 }
1100 else
1101 {
1102 log.error( "MavenInvocationException: " + e.getMessage() );
1103 }
1104 log.error( "Error when reinvoking Maven, consult the invoker log." );
1105 }
1106 return;
1107 }
1108 }
1109
1110 if ( result.getExitCode() != 0 )
1111 {
1112 if ( log != null )
1113 {
1114 log.error( "Error when invoking Maven, consult the invoker log file: "
1115 + invokerLog.getAbsolutePath() );
1116 }
1117 }
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 private static List getClassNamesFromJar( File jarFile )
1130 throws IOException
1131 {
1132 if ( jarFile == null || !jarFile.exists() || !jarFile.isFile() )
1133 {
1134 throw new IOException( "The jar '" + jarFile + "' doesn't exist or is not a file." );
1135 }
1136
1137 List classes = new ArrayList();
1138 JarInputStream jarStream = null;
1139
1140 try
1141 {
1142 jarStream = new JarInputStream( new FileInputStream( jarFile ) );
1143 JarEntry jarEntry = jarStream.getNextJarEntry();
1144 while ( jarEntry != null )
1145 {
1146 if ( jarEntry == null )
1147 {
1148 break;
1149 }
1150
1151 if ( jarEntry.getName().toLowerCase( Locale.ENGLISH ).endsWith( ".class" ) )
1152 {
1153 String name = jarEntry.getName().substring( 0, jarEntry.getName().indexOf( "." ) );
1154
1155 classes.add( name.replaceAll( "/", "\\." ) );
1156 }
1157
1158 jarStream.closeEntry();
1159 jarEntry = jarStream.getNextJarEntry();
1160 }
1161 }
1162 finally
1163 {
1164 IOUtil.close( jarStream );
1165 }
1166
1167 return classes;
1168 }
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 private static InvocationResult invoke( Log log, Invoker invoker, InvocationRequest request, File invokerLog,
1183 List goals, Properties properties, String mavenOpts )
1184 throws MavenInvocationException
1185 {
1186 PrintStream ps;
1187 OutputStream os = null;
1188 if ( invokerLog != null )
1189 {
1190 log.debug( "Using " + invokerLog.getAbsolutePath() + " to log the invoker" );
1191
1192 try
1193 {
1194 if ( !invokerLog.exists() )
1195 {
1196 invokerLog.getParentFile().mkdirs();
1197 }
1198 os = new FileOutputStream( invokerLog );
1199 ps = new PrintStream( os, true, "UTF-8" );
1200 }
1201 catch ( FileNotFoundException e )
1202 {
1203 if ( log != null )
1204 {
1205 log.error( "FileNotFoundException: " + e.getMessage() + ". Using System.out to log the invoker." );
1206 }
1207 ps = System.out;
1208 }
1209 catch ( UnsupportedEncodingException e )
1210 {
1211 if ( log != null )
1212 {
1213 log.error( "UnsupportedEncodingException: " + e.getMessage()
1214 + ". Using System.out to log the invoker." );
1215 }
1216 ps = System.out;
1217 }
1218 }
1219 else
1220 {
1221 log.debug( "Using System.out to log the invoker." );
1222
1223 ps = System.out;
1224 }
1225
1226 if ( mavenOpts != null )
1227 {
1228 request.setMavenOpts( mavenOpts );
1229 }
1230
1231 InvocationOutputHandler outputHandler = new PrintStreamHandler( ps, false );
1232 request.setOutputHandler( outputHandler );
1233
1234 outputHandler.consumeLine( "Invoking Maven for the goals: " + goals + " with properties=" + properties );
1235 outputHandler.consumeLine( "" );
1236 outputHandler.consumeLine( "M2_HOME=" + getMavenHome( log ) );
1237 outputHandler.consumeLine( "MAVEN_OPTS=" + getMavenOpts( log ) );
1238 outputHandler.consumeLine( "JAVA_HOME=" + getJavaHome( log ) );
1239 outputHandler.consumeLine( "JAVA_OPTS=" + getJavaOpts( log ) );
1240 outputHandler.consumeLine( "" );
1241
1242 try
1243 {
1244 return invoker.execute( request );
1245 }
1246 finally
1247 {
1248 IOUtil.close( os );
1249 ps = null;
1250 }
1251 }
1252
1253
1254
1255
1256
1257
1258
1259 private static String getMavenHome( Log log )
1260 {
1261 String mavenHome = System.getProperty( "maven.home" );
1262 if ( mavenHome == null )
1263 {
1264 try
1265 {
1266 mavenHome = CommandLineUtils.getSystemEnvVars().getProperty( "M2_HOME" );
1267 }
1268 catch ( IOException e )
1269 {
1270 if ( log != null )
1271 {
1272 log.debug( "IOException: " + e.getMessage() );
1273 }
1274 }
1275 }
1276
1277 File m2Home = new File( mavenHome );
1278 if ( !m2Home.exists() )
1279 {
1280 if ( log != null )
1281 {
1282 log
1283 .error( "Cannot find Maven application directory. Either specify \'maven.home\' system property, or "
1284 + "M2_HOME environment variable." );
1285 }
1286 }
1287
1288 return mavenHome;
1289 }
1290
1291
1292
1293
1294
1295
1296 private static String getMavenOpts( Log log )
1297 {
1298 String mavenOpts = null;
1299 try
1300 {
1301 mavenOpts = CommandLineUtils.getSystemEnvVars().getProperty( "MAVEN_OPTS" );
1302 }
1303 catch ( IOException e )
1304 {
1305 if ( log != null )
1306 {
1307 log.debug( "IOException: " + e.getMessage() );
1308 }
1309 }
1310
1311 return mavenOpts;
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321 private static File getJavaHome( Log log )
1322 {
1323 File javaHome;
1324 if ( SystemUtils.IS_OS_MAC_OSX )
1325 {
1326 javaHome = SystemUtils.getJavaHome();
1327 }
1328 else
1329 {
1330 javaHome = new File( SystemUtils.getJavaHome(), ".." );
1331 }
1332
1333 if ( javaHome == null || !javaHome.exists() )
1334 {
1335 try
1336 {
1337 javaHome = new File( CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_HOME" ) );
1338 }
1339 catch ( IOException e )
1340 {
1341 if ( log != null )
1342 {
1343 log.debug( "IOException: " + e.getMessage() );
1344 }
1345 }
1346 }
1347
1348 if ( javaHome == null || !javaHome.exists() )
1349 {
1350 if ( log != null )
1351 {
1352 log.error( "Cannot find Java application directory. Either specify \'java.home\' system property, or "
1353 + "JAVA_HOME environment variable." );
1354 }
1355 }
1356
1357 return javaHome;
1358 }
1359
1360
1361
1362
1363
1364
1365 private static String getJavaOpts( Log log )
1366 {
1367 String javaOpts = null;
1368 try
1369 {
1370 javaOpts = CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_OPTS" );
1371 }
1372 catch ( IOException e )
1373 {
1374 if ( log != null )
1375 {
1376 log.debug( "IOException: " + e.getMessage() );
1377 }
1378 }
1379
1380 return javaOpts;
1381 }
1382 }