1 package org.apache.maven.plugin.jxr;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.Calendar;
27 import java.util.Collection;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.ResourceBundle;
32
33 import org.apache.maven.doxia.siterenderer.Renderer;
34 import org.apache.maven.jxr.JXR;
35 import org.apache.maven.jxr.JxrException;
36 import org.apache.maven.model.Organization;
37 import org.apache.maven.model.ReportPlugin;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.reporting.AbstractMavenReport;
40 import org.apache.maven.reporting.MavenReportException;
41 import org.codehaus.plexus.util.FileUtils;
42 import org.codehaus.plexus.util.ReaderFactory;
43 import org.codehaus.plexus.util.StringUtils;
44
45
46
47
48
49
50
51
52
53 public abstract class AbstractJxrReport
54 extends AbstractMavenReport
55 {
56
57
58
59
60
61 private MavenProject project;
62
63
64
65
66 private Renderer siteRenderer;
67
68
69
70
71
72
73
74
75
76 private File outputDirectory;
77
78
79
80
81
82
83 private String inputEncoding;
84
85
86
87
88
89
90 private String outputEncoding;
91
92
93
94
95
96
97 private String windowTitle;
98
99
100
101
102
103
104 private String docTitle;
105
106
107
108
109
110
111 private String bottom;
112
113
114
115
116
117
118
119
120 private String templateDir;
121
122
123
124
125
126
127
128 private String stylesheet;
129
130
131
132
133
134
135
136 private ArrayList excludes;
137
138
139
140
141
142
143
144 private ArrayList includes;
145
146
147
148
149
150
151
152 protected List reactorProjects;
153
154
155
156
157
158
159
160 protected boolean aggregate;
161
162
163
164
165
166
167
168 protected boolean skip;
169
170
171
172
173
174
175
176 private boolean linkJavadoc;
177
178
179
180
181
182
183
184 protected String getOutputEncoding()
185 {
186 return ( outputEncoding == null ) ? ReaderFactory.UTF_8 : outputEncoding;
187 }
188
189
190
191
192
193
194
195 protected List pruneSourceDirs( List sourceDirs )
196 {
197 List pruned = new ArrayList( sourceDirs.size() );
198 for ( Iterator i = sourceDirs.iterator(); i.hasNext(); )
199 {
200 String dir = (String) i.next();
201 if ( !pruned.contains( dir ) && hasSources( new File( dir ) ) )
202 {
203 pruned.add( dir );
204 }
205 }
206 return pruned;
207 }
208
209
210
211
212 protected void init()
213 {
214
215
216 Collection plugin = project.getReportPlugins();
217 if ( plugin != null )
218 {
219 for ( Iterator iter = plugin.iterator(); iter.hasNext(); )
220 {
221 ReportPlugin reportPlugin = (ReportPlugin) iter.next();
222 if ( "maven-javadoc-plugin".equals( reportPlugin.getArtifactId() ) )
223 {
224 break;
225 }
226 }
227 }
228 }
229
230
231
232
233
234
235
236 private boolean hasSources( File dir )
237 {
238 if ( dir.exists() && dir.isDirectory() )
239 {
240 File[] files = dir.listFiles();
241 for ( int i = 0; i < files.length; i++ )
242 {
243 File currentFile = files[i];
244 if ( currentFile.isFile() )
245 {
246 if ( currentFile.getName().endsWith( ".java" ) )
247 {
248 return true;
249 }
250 }
251 else
252 {
253 if ( Character.isJavaIdentifierStart( currentFile.getName().charAt( 0 ) )
254 && hasSources( currentFile ) )
255 {
256 return true;
257 }
258 }
259 }
260 }
261 return false;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275 private void createXref( Locale locale, String destinationDirectory, List sourceDirs )
276 throws IOException, JxrException
277 {
278 JXR jxr = new JXR();
279 jxr.setDest( destinationDirectory );
280 if ( StringUtils.isEmpty( inputEncoding ) )
281 {
282 String platformEncoding = System.getProperty( "file.encoding" );
283 getLog().warn( "File encoding has not been set, using platform encoding " + platformEncoding
284 + ", i.e. build is platform dependent!" );
285 }
286 jxr.setInputEncoding( inputEncoding );
287 jxr.setLocale( locale );
288 jxr.setLog( new PluginLogAdapter( getLog() ) );
289 jxr.setOutputEncoding( getOutputEncoding() );
290 jxr.setRevision( "HEAD" );
291 jxr.setJavadocLinkDir( getJavadocLocation() );
292
293 if ( excludes != null && !excludes.isEmpty() )
294 {
295 jxr.setExcludes( (String[]) excludes.toArray( new String[0] ) );
296 }
297 if ( includes != null && !includes.isEmpty() )
298 {
299 jxr.setIncludes( (String[]) includes.toArray( new String[0] ) );
300 }
301
302
303 ClassLoader savedTccl = Thread.currentThread().getContextClassLoader();
304 try {
305 Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
306 jxr.xref( sourceDirs, templateDir, windowTitle, docTitle, getBottomText( project.getInceptionYear(), project
307 .getOrganization() ) );
308 } finally {
309 Thread.currentThread().setContextClassLoader( savedTccl );
310 }
311
312
313 copyRequiredResources( destinationDirectory );
314 }
315
316
317
318
319
320
321
322
323 private String getBottomText( String inceptionYear, Organization organization )
324 {
325 int actualYear = Calendar.getInstance().get( Calendar.YEAR );
326 String year = String.valueOf( actualYear );
327
328 String bottom = StringUtils.replace( this.bottom, "{currentYear}", year );
329
330 if ( inceptionYear == null )
331 {
332 bottom = StringUtils.replace( bottom, "{inceptionYear}-", "" );
333 }
334 else
335 {
336 if ( inceptionYear.equals( year ) )
337 {
338 bottom = StringUtils.replace( bottom, "{inceptionYear}-", "" );
339 }
340 else
341 {
342 bottom = StringUtils.replace( bottom, "{inceptionYear}", inceptionYear );
343 }
344 }
345
346 if ( organization != null && StringUtils.isNotEmpty( organization.getName() ) )
347 {
348 bottom = StringUtils.replace( bottom, "{projectOrganizationName}", organization.getName() );
349 }
350 else
351 {
352 bottom = StringUtils.replace( bottom, " {projectOrganizationName}", "" );
353 }
354
355 return bottom;
356 }
357
358
359
360
361
362
363
364 private void copyRequiredResources( String dir )
365 {
366 File stylesheetFile = new File( stylesheet );
367 File destStylesheetFile = new File( dir, "stylesheet.css" );
368
369 try
370 {
371 if ( stylesheetFile.isAbsolute() )
372 {
373 FileUtils.copyFile( stylesheetFile, destStylesheetFile );
374 }
375 else
376 {
377 URL stylesheetUrl = this.getClass().getClassLoader().getResource( stylesheet );
378 FileUtils.copyURLToFile( stylesheetUrl, destStylesheetFile );
379 }
380 }
381 catch ( IOException e )
382 {
383 getLog().warn( "An error occured while copying the stylesheet to the target directory", e );
384 }
385
386 }
387
388
389
390
391 protected Renderer getSiteRenderer()
392 {
393 return siteRenderer;
394 }
395
396
397
398
399 protected String getOutputDirectory()
400 {
401 return outputDirectory.getAbsolutePath();
402 }
403
404
405
406
407 public MavenProject getProject()
408 {
409 return project;
410 }
411
412
413
414
415
416
417
418 protected ResourceBundle getBundle( Locale locale )
419 {
420 return ResourceBundle.getBundle( "jxr-report", locale, this.getClass().getClassLoader() );
421 }
422
423
424
425
426
427 protected boolean canGenerateReport( List sourceDirs )
428 {
429 boolean canGenerate = !sourceDirs.isEmpty();
430
431 if ( isAggregate() && !project.isExecutionRoot() )
432 {
433 canGenerate = false;
434 }
435 return canGenerate;
436 }
437
438
439
440
441 protected void executeReport( Locale locale )
442 throws MavenReportException
443 {
444 if ( skip )
445 {
446 getLog().info( "Skipping JXR." );
447 return;
448 }
449 List sourceDirs = constructSourceDirs();
450 if ( canGenerateReport( sourceDirs ) )
451 {
452
453 init();
454
455 try
456 {
457 createXref( locale, getDestinationDirectory(), sourceDirs );
458 }
459 catch ( JxrException e )
460 {
461 throw new MavenReportException( "Error while generating the HTML source code of the projet.", e );
462 }
463 catch ( IOException e )
464 {
465 throw new MavenReportException( "Error while generating the HTML source code of the projet.", e );
466 }
467 }
468 }
469
470
471
472
473
474
475 protected List constructSourceDirs()
476 {
477 List sourceDirs = new ArrayList( getSourceRoots() );
478 if ( isAggregate() )
479 {
480 for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
481 {
482 MavenProject project = (MavenProject) i.next();
483
484 if ( "java".equals( project.getArtifact().getArtifactHandler().getLanguage() ) )
485 {
486 sourceDirs.addAll( getSourceRoots( project ) );
487 }
488 }
489 }
490
491 sourceDirs = pruneSourceDirs( sourceDirs );
492 return sourceDirs;
493 }
494
495
496
497
498 public boolean canGenerateReport()
499 {
500 return canGenerateReport( constructSourceDirs() );
501 }
502
503
504
505
506 public boolean isExternalReport()
507 {
508 return true;
509 }
510
511
512
513
514 private String getJavadocLocation()
515 throws IOException
516 {
517 String location = null;
518 if ( linkJavadoc )
519 {
520
521
522 if ( getJavadocDir().exists() )
523 {
524
525 location = getJavadocDir().getAbsolutePath();
526 }
527 else
528 {
529
530
531
532 String stagingDirectory = System.getProperty( "stagingDirectory" );
533
534 if ( StringUtils.isNotEmpty( stagingDirectory ) )
535 {
536 String javadocDestDir = getJavadocDir().getName();
537 boolean javadocAggregate = JxrReportUtil.isJavadocAggregated( project );
538 String structureProject = JxrReportUtil.getStructure( project, false );
539
540 if ( isAggregate() && javadocAggregate )
541 {
542 File outputDirectory = new File( stagingDirectory, structureProject );
543 location = outputDirectory + "/" + javadocDestDir;
544 }
545 if ( !isAggregate() && javadocAggregate )
546 {
547 location = stagingDirectory + "/" + javadocDestDir;
548
549 String hierarchy = project.getName();
550
551 MavenProject parent = project.getParent();
552 while ( parent != null )
553 {
554 hierarchy = parent.getName();
555 parent = parent.getParent();
556 }
557 File outputDirectory = new File( stagingDirectory, hierarchy );
558 location = outputDirectory + "/" + javadocDestDir;
559 }
560 if ( isAggregate() && !javadocAggregate )
561 {
562 getLog().warn(
563 "The JXR plugin is configured to build an aggregated report at the root, "
564 + "not the Javadoc plugin." );
565 }
566 if ( !isAggregate() && !javadocAggregate )
567 {
568 location = stagingDirectory + "/" + structureProject + "/" + javadocDestDir;
569 }
570 }
571 else
572 {
573 location = getJavadocDir().getAbsolutePath();
574 }
575 }
576
577 if ( location == null )
578 {
579 getLog().warn( "Unable to locate Javadoc to link to - DISABLED" );
580 }
581 }
582
583 return location;
584 }
585
586
587
588
589
590
591 protected abstract String getDestinationDirectory();
592
593
594
595
596
597
598 protected abstract List getSourceRoots();
599
600
601
602
603
604
605
606
607 protected abstract List getSourceRoots( MavenProject project );
608
609
610
611
612
613
614 protected abstract File getJavadocDir();
615
616
617
618
619
620 protected boolean isAggregate()
621 {
622 return aggregate;
623 }
624 }