1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.apache.maven.plugins.linkcheck;
16
17 import java.io.File;
18 import java.io.FileNotFoundException;
19 import java.io.FileOutputStream;
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.io.PrintStream;
23 import java.io.Reader;
24 import java.io.UnsupportedEncodingException;
25 import java.io.Writer;
26 import java.util.ArrayList;
27
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Properties;
31
32 import org.apache.commons.lang.SystemUtils;
33 import org.apache.maven.artifact.repository.ArtifactRepository;
34
35 import org.apache.maven.model.Profile;
36 import org.apache.maven.model.Reporting;
37 import org.apache.maven.project.MavenProject;
38
39 import org.apache.maven.plugin.logging.Log;
40 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
41 import org.apache.maven.shared.invoker.DefaultInvoker;
42 import org.apache.maven.shared.invoker.InvocationOutputHandler;
43 import org.apache.maven.shared.invoker.InvocationRequest;
44 import org.apache.maven.shared.invoker.InvocationResult;
45 import org.apache.maven.shared.invoker.Invoker;
46 import org.apache.maven.shared.invoker.MavenInvocationException;
47 import org.apache.maven.shared.invoker.PrintStreamHandler;
48
49 import org.codehaus.plexus.util.FileUtils;
50 import org.codehaus.plexus.util.IOUtil;
51 import org.codehaus.plexus.util.ReaderFactory;
52 import org.codehaus.plexus.util.StringUtils;
53 import org.codehaus.plexus.util.WriterFactory;
54 import org.codehaus.plexus.util.cli.CommandLineUtils;
55
56
57
58
59
60
61
62 public class SiteInvoker
63 {
64 private final ArtifactRepository localRepository;
65 private final Log log;
66
67 public SiteInvoker( ArtifactRepository localRepository, Log log )
68 {
69 this.localRepository = localRepository;
70 this.log = log;
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 public void invokeSite( MavenProject project, File tmpReportingOutputDirectory )
88 throws IOException
89 {
90 String mavenHome = getMavenHome();
91 if ( StringUtils.isEmpty( mavenHome ) )
92 {
93 getLog().error( "Could NOT invoke Maven because no Maven Home is defined. "
94 + "You need to set the M2_HOME system env variable or a 'maven.home' Java system property." );
95 return;
96 }
97
98
99 List goals = Collections.singletonList( "site" );
100 Properties properties = new Properties();
101 properties.put( "linkcheck.skip", "true" );
102
103 File invokerLog =
104 FileUtils.createTempFile( "invoker-site-plugin", ".txt", new File( project.getBuild().getDirectory() ) );
105
106
107 MavenProject clone;
108 try
109 {
110 clone = (MavenProject) project.clone();
111 }
112 catch ( CloneNotSupportedException e )
113 {
114 IOException ioe = new IOException( "CloneNotSupportedException: " + e.getMessage() );
115 ioe.setStackTrace( e.getStackTrace() );
116 throw ioe;
117 }
118
119
120 if ( clone.getOriginalModel().getReporting() == null )
121 {
122 clone.getOriginalModel().setReporting( new Reporting() );
123 }
124
125 clone.getOriginalModel().getReporting().setOutputDirectory( tmpReportingOutputDirectory.getAbsolutePath() );
126 List profileIds = getActiveProfileIds( clone );
127
128
129 File tmpProjectFile = FileUtils.createTempFile( "pom", ".xml", project.getBasedir() );
130 Writer writer = null;
131 try
132 {
133 writer = WriterFactory.newXmlWriter( tmpProjectFile );
134 clone.writeOriginalModel( writer );
135 }
136 finally
137 {
138 IOUtil.close( writer );
139 }
140
141
142 try
143 {
144 invoke( tmpProjectFile, invokerLog, mavenHome, goals, profileIds, properties );
145 }
146 finally
147 {
148 if ( !getLog().isDebugEnabled() )
149 {
150 tmpProjectFile.delete();
151 }
152 }
153 }
154
155 private static List getActiveProfileIds( MavenProject clone )
156 {
157 List profileIds = new ArrayList();
158
159 for (Object o : clone.getActiveProfiles()) {
160 profileIds.add(((Profile) o).getId());
161 }
162
163 return profileIds;
164 }
165
166
167
168
169
170
171
172
173 private void invoke( File projectFile, File invokerLog, String mavenHome,
174 List goals, List activeProfiles, Properties properties )
175 {
176 Invoker invoker = new DefaultInvoker();
177 invoker.setMavenHome( new File( mavenHome ) );
178 File localRepoDir = new File( localRepository.getBasedir() );
179 invoker.setLocalRepositoryDirectory( localRepoDir );
180
181 InvocationRequest request = new DefaultInvocationRequest();
182 request.setLocalRepositoryDirectory( localRepoDir );
183
184 request.setInteractive( false );
185 request.setShowErrors( getLog().isErrorEnabled() );
186 request.setDebug( getLog().isDebugEnabled() );
187
188 request.setBaseDirectory( projectFile.getParentFile() );
189 request.setPomFile( projectFile );
190 request.setGoals( goals );
191 request.setProperties( properties );
192 request.setProfiles( activeProfiles );
193
194 File javaHome = getJavaHome();
195 if ( javaHome != null )
196 {
197 request.setJavaHome( javaHome );
198 }
199
200 InvocationResult invocationResult;
201 try
202 {
203 if ( getLog().isDebugEnabled() )
204 {
205 getLog().debug( "Invoking Maven for the goals: " + goals + " with properties=" + properties );
206 }
207 invocationResult = invoke( invoker, request, invokerLog, goals, properties, null );
208 }
209 catch ( MavenInvocationException e )
210 {
211 getLog().error( "Error when invoking Maven, consult the invoker log." );
212 getLog().debug( e );
213 return;
214 }
215
216 String invokerLogContent = null;
217 Reader reader = null;
218 try
219 {
220 reader = ReaderFactory.newReader( invokerLog, "UTF-8" );
221 invokerLogContent = IOUtil.toString( reader );
222 }
223 catch ( IOException e )
224 {
225 getLog().error( "IOException: " + e.getMessage() );
226 getLog().debug( e );
227 }
228 finally
229 {
230 IOUtil.close( reader );
231 }
232
233 if ( invokerLogContent != null
234 && invokerLogContent.contains("Error occurred during initialization of VM"))
235 {
236 getLog().info( "Error occurred during initialization of VM, try to use an empty MAVEN_OPTS." );
237
238 if ( getLog().isDebugEnabled() )
239 {
240 getLog().debug( "Reinvoking Maven for the goals: " + goals + " with an empty MAVEN_OPTS" );
241 }
242
243 try
244 {
245 invocationResult = invoke( invoker, request, invokerLog, goals, properties, "" );
246 }
247 catch ( MavenInvocationException e )
248 {
249 getLog().error( "Error when reinvoking Maven, consult the invoker log." );
250 getLog().debug( e );
251 return;
252 }
253 }
254
255 if ( invocationResult.getExitCode() != 0 )
256 {
257 if ( getLog().isErrorEnabled() )
258 {
259 getLog().error( "Error when invoking Maven, consult the invoker log file: "
260 + invokerLog.getAbsolutePath() );
261 }
262 }
263 }
264
265
266
267
268
269
270
271
272
273
274
275 private InvocationResult invoke( Invoker invoker, InvocationRequest request, File invokerLog, List goals,
276 Properties properties, String mavenOpts )
277 throws MavenInvocationException
278 {
279 PrintStream ps;
280 OutputStream os = null;
281 if ( invokerLog != null )
282 {
283 if ( getLog().isDebugEnabled() )
284 {
285 getLog().debug( "Using " + invokerLog.getAbsolutePath() + " to log the invoker" );
286 }
287
288 try
289 {
290 if ( !invokerLog.exists() )
291 {
292 invokerLog.getParentFile().mkdirs();
293 }
294 os = new FileOutputStream( invokerLog );
295 ps = new PrintStream( os, true, "UTF-8" );
296 }
297 catch ( FileNotFoundException e )
298 {
299 if ( getLog().isErrorEnabled() )
300 {
301 getLog().error( "FileNotFoundException: " + e.getMessage()
302 + ". Using System.out to log the invoker." );
303 }
304 ps = System.out;
305 }
306 catch ( UnsupportedEncodingException e )
307 {
308 if ( getLog().isErrorEnabled() )
309 {
310 getLog().error( "UnsupportedEncodingException: " + e.getMessage()
311 + ". Using System.out to log the invoker." );
312 }
313 ps = System.out;
314 }
315 }
316 else
317 {
318 getLog().debug( "Using System.out to log the invoker." );
319
320 ps = System.out;
321 }
322
323 if ( mavenOpts != null )
324 {
325 request.setMavenOpts( mavenOpts );
326 }
327
328 InvocationOutputHandler outputHandler = new PrintStreamHandler( ps, false );
329 request.setOutputHandler( outputHandler );
330 request.setErrorHandler( outputHandler );
331
332 outputHandler.consumeLine( "Invoking Maven for the goals: " + goals + " with properties=" + properties );
333 outputHandler.consumeLine( "" );
334 outputHandler.consumeLine( "M2_HOME=" + getMavenHome() );
335 outputHandler.consumeLine( "MAVEN_OPTS=" + getMavenOpts() );
336 outputHandler.consumeLine( "JAVA_HOME=" + getJavaHome() );
337 outputHandler.consumeLine( "JAVA_OPTS=" + getJavaOpts() );
338 outputHandler.consumeLine( "" );
339
340 try
341 {
342 return invoker.execute( request );
343 }
344 finally
345 {
346 IOUtil.close( os );
347 ps = null;
348 }
349 }
350
351
352
353
354
355
356 private String getMavenHome()
357 {
358 String mavenHome = System.getProperty( "maven.home" );
359 if ( mavenHome == null )
360 {
361 try
362 {
363 mavenHome = CommandLineUtils.getSystemEnvVars().getProperty( "M2_HOME" );
364 }
365 catch ( IOException e )
366 {
367 getLog().error( "IOException: " + e.getMessage() );
368 getLog().debug( e );
369 }
370 }
371
372 File m2Home = new File( mavenHome );
373 if ( !m2Home.exists() )
374 {
375 getLog().error( "Cannot find Maven application directory. Either specify \'maven.home\' "
376 + "system property, or M2_HOME environment variable." );
377 }
378
379 return mavenHome;
380 }
381
382
383
384
385
386 private String getMavenOpts()
387 {
388 String mavenOpts = null;
389 try
390 {
391 mavenOpts = CommandLineUtils.getSystemEnvVars().getProperty( "MAVEN_OPTS" );
392 }
393 catch ( IOException e )
394 {
395 getLog().error( "IOException: " + e.getMessage() );
396 getLog().debug( e );
397 }
398
399 return mavenOpts;
400 }
401
402
403
404
405
406
407
408 private File getJavaHome()
409 {
410 File javaHome;
411 if ( SystemUtils.IS_OS_MAC_OSX )
412 {
413 javaHome = SystemUtils.getJavaHome();
414 }
415 else
416 {
417 javaHome = new File( SystemUtils.getJavaHome(), ".." );
418 }
419
420 if ( javaHome == null || !javaHome.exists() )
421 {
422 try
423 {
424 javaHome = new File( CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_HOME" ) );
425 }
426 catch ( IOException e )
427 {
428 getLog().error( "IOException: " + e.getMessage() );
429 getLog().debug( e );
430 }
431 }
432
433 if ( javaHome == null || !javaHome.exists() )
434 {
435 getLog().error( "Cannot find Java application directory. Either specify \'java.home\' "
436 + "system property, or JAVA_HOME environment variable." );
437 }
438
439 return javaHome;
440 }
441
442
443
444
445
446 private String getJavaOpts()
447 {
448 String javaOpts = null;
449 try
450 {
451 javaOpts = CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_OPTS" );
452 }
453 catch ( IOException e )
454 {
455 getLog().error( "IOException: " + e.getMessage() );
456 getLog().debug( e );
457 }
458
459 return javaOpts;
460 }
461
462 private Log getLog()
463 {
464 return log;
465 }
466 }