1 package org.apache.maven.report.projectinfo;
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.artifact.factory.ArtifactFactory;
24 import org.apache.maven.artifact.repository.ArtifactRepository;
25 import org.apache.maven.artifact.resolver.ArtifactResolver;
26 import org.apache.maven.doxia.sink.render.RenderingContext;
27 import org.apache.maven.doxia.site.decoration.Body;
28 import org.apache.maven.doxia.site.decoration.DecorationModel;
29 import org.apache.maven.doxia.siterenderer.Renderer;
30 import org.apache.maven.doxia.siterenderer.RendererException;
31 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
32 import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
33 import org.apache.maven.doxia.tools.SiteTool;
34 import org.apache.maven.doxia.tools.SiteToolException;
35 import org.apache.maven.model.Plugin;
36 import org.apache.maven.plugin.MojoExecutionException;
37 import org.apache.maven.plugins.annotations.Component;
38 import org.apache.maven.plugins.annotations.Parameter;
39 import org.apache.maven.project.MavenProject;
40 import org.apache.maven.reporting.AbstractMavenReport;
41 import org.apache.maven.reporting.MavenReportException;
42 import org.apache.maven.settings.Settings;
43 import org.codehaus.plexus.i18n.I18N;
44 import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
45 import org.codehaus.plexus.interpolation.InterpolationException;
46 import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
47 import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
48 import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
49 import org.codehaus.plexus.util.IOUtil;
50 import org.codehaus.plexus.util.StringUtils;
51 import org.codehaus.plexus.util.xml.Xpp3Dom;
52
53
54 import java.io.File;
55 import java.io.FileOutputStream;
56 import java.io.IOException;
57 import java.io.OutputStreamWriter;
58 import java.io.Writer;
59 import java.net.MalformedURLException;
60 import java.net.URL;
61 import java.net.URLClassLoader;
62 import java.text.MessageFormat;
63 import java.util.HashMap;
64 import java.util.List;
65 import java.util.Locale;
66 import java.util.Map;
67 import java.util.MissingResourceException;
68 import java.util.ResourceBundle;
69
70
71
72
73
74
75
76
77 public abstract class AbstractProjectInfoReport
78 extends AbstractMavenReport
79 {
80
81
82
83
84
85
86
87
88
89 @Component
90 protected SiteTool siteTool;
91
92
93
94
95 @Component
96 protected Renderer siteRenderer;
97
98
99
100
101 @Component
102 protected ArtifactResolver resolver;
103
104
105
106
107 @Component
108 protected ArtifactFactory factory;
109
110
111
112
113 @Component
114 private I18N i18n;
115
116
117
118
119
120
121
122
123
124
125 @Parameter( property = "project.reporting.outputDirectory", required = true )
126 protected File outputDirectory;
127
128
129
130
131 @Component
132 protected MavenProject project;
133
134
135
136
137 @Parameter( property = "localRepository", required = true, readonly = true )
138 protected ArtifactRepository localRepository;
139
140
141
142
143
144
145 @Parameter( property = "project.remoteArtifactRepositories" )
146 protected List<ArtifactRepository> remoteRepositories;
147
148
149
150
151
152
153 @Component
154 protected Settings settings;
155
156
157
158
159
160
161
162 @Parameter( defaultValue = "${project.basedir}/src/site/custom/project-info-report.properties" )
163 protected String customBundle;
164
165
166
167
168
169 @Override
170 public void execute()
171 throws MojoExecutionException
172 {
173 if ( !canGenerateReport() )
174 {
175 return;
176 }
177
178
179 Writer writer = null;
180 try
181 {
182 String filename = getOutputName() + ".html";
183
184 DecorationModel model = new DecorationModel();
185 model.setBody( new Body() );
186
187 Map<String, Object> attributes = new HashMap<String, Object>();
188 attributes.put( "outputEncoding", "UTF-8" );
189 attributes.put( "project", project );
190
191 Locale locale = Locale.getDefault();
192 Artifact defaultSkin =
193 siteTool.getDefaultSkinArtifact( localRepository, project.getRemoteArtifactRepositories() );
194
195 SiteRenderingContext siteContext =
196 siteRenderer.createContextForSkin( defaultSkin.getFile(), attributes, model, getName( locale ), locale );
197
198 RenderingContext context = new RenderingContext( outputDirectory, filename );
199
200 SiteRendererSink sink = new SiteRendererSink( context );
201
202 generate( sink, null, locale );
203
204 outputDirectory.mkdirs();
205
206 writer = new OutputStreamWriter( new FileOutputStream( new File( outputDirectory, filename ) ), "UTF-8" );
207
208 siteRenderer.generateDocument( writer, sink, siteContext );
209
210 siteRenderer.copyResources( siteContext, new File( project.getBasedir(), "src/site/resources" ),
211 outputDirectory );
212 }
213 catch ( RendererException e )
214 {
215 throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH )
216 + " report generation.", e );
217 }
218 catch ( IOException e )
219 {
220 throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH )
221 + " report generation.", e );
222 }
223 catch ( SiteToolException e )
224 {
225 throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH )
226 + " report generation.", e );
227 }
228 catch ( MavenReportException e )
229 {
230 throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH )
231 + " report generation.", e );
232 }
233 finally
234 {
235 IOUtil.close( writer );
236 }
237 }
238
239 @Override
240 public String getCategoryName()
241 {
242 return CATEGORY_PROJECT_INFORMATION;
243 }
244
245
246
247
248
249 @Override
250 protected String getOutputDirectory()
251 {
252 return outputDirectory.getAbsolutePath();
253 }
254
255 @Override
256 public File getReportOutputDirectory()
257 {
258 return outputDirectory;
259 }
260
261 @Override
262 public void setReportOutputDirectory( File reportOutputDirectory )
263 {
264 this.outputDirectory = reportOutputDirectory;
265 }
266
267 @Override
268 protected MavenProject getProject()
269 {
270 return project;
271 }
272
273 protected Plugin getPlugin( String pluginId )
274 {
275 if ( ( getProject().getBuild() == null ) || ( getProject().getBuild().getPluginsAsMap() == null ) )
276 {
277 return null;
278 }
279
280 Plugin plugin = (Plugin) getProject().getBuild().getPluginsAsMap().get( pluginId );
281
282 if ( ( plugin == null ) && ( getProject().getBuild().getPluginManagement() != null ) && (
283 getProject().getBuild().getPluginManagement().getPluginsAsMap() != null ) )
284 {
285 plugin = (Plugin) getProject().getBuild().getPluginManagement().getPluginsAsMap().get( pluginId );
286 }
287
288 return plugin;
289 }
290
291 protected String getPluginParameter( String pluginId, String param )
292 {
293 Plugin plugin = getPlugin( pluginId );
294 if ( plugin != null )
295 {
296 Xpp3Dom xpp3Dom = (Xpp3Dom) plugin.getConfiguration();
297 if ( xpp3Dom != null && xpp3Dom.getChild( param ) != null
298 && StringUtils.isNotEmpty( xpp3Dom.getChild( param ).getValue() ) )
299 {
300 return xpp3Dom.getChild( param ).getValue();
301 }
302 }
303
304 return null;
305 }
306
307 @Override
308 protected Renderer getSiteRenderer()
309 {
310 return siteRenderer;
311 }
312
313 protected String getI18nString( Locale locale, String key )
314 {
315 return getI18N( locale ).getString( "project-info-report", locale, "report." + getI18Nsection() + '.' + key );
316 }
317
318 protected I18N getI18N( Locale locale )
319 {
320 if ( customBundle != null )
321 {
322 File customBundleFile = new File( customBundle );
323 if ( customBundleFile.isFile() && customBundleFile.getName().endsWith( ".properties" ) )
324 {
325 if ( !i18n.getClass().isAssignableFrom( CustomI18N.class ) )
326 {
327
328 i18n = new CustomI18N( project, settings, customBundleFile, locale, i18n );
329 }
330 else if ( !i18n.getDefaultLanguage().equals( locale.getLanguage() ) )
331 {
332 i18n = new CustomI18N( project, settings, customBundleFile, locale, i18n );
333 }
334 }
335 }
336
337 return i18n;
338 }
339
340 protected abstract String getI18Nsection();
341
342
343 public String getName( Locale locale )
344 {
345 return getI18nString( locale, "name" );
346 }
347
348
349 public String getDescription( Locale locale )
350 {
351 return getI18nString( locale, "description" );
352 }
353
354 private static class CustomI18N
355 implements I18N
356 {
357 private final MavenProject project;
358
359 private final Settings settings;
360
361 private final String bundleName;
362
363 private final Locale locale;
364
365 private final I18N i18nOriginal;
366
367 private ResourceBundle bundle;
368
369 private final static Object[] NO_ARGS = new Object[0];
370
371 public CustomI18N( MavenProject project, Settings settings, File customBundleFile, Locale locale,
372 I18N i18nOriginal )
373 {
374 super();
375 this.project = project;
376 this.settings = settings;
377 this.locale = locale;
378 this.i18nOriginal = i18nOriginal;
379 this.bundleName =
380 customBundleFile.getName().substring( 0, customBundleFile.getName().indexOf( ".properties" ) );
381
382 URLClassLoader classLoader = null;
383 try
384 {
385 classLoader = new URLClassLoader( new URL[] { customBundleFile.getParentFile().toURI().toURL() } );
386 }
387 catch ( MalformedURLException e )
388 {
389 }
390
391 this.bundle = ResourceBundle.getBundle( this.bundleName, locale, classLoader );
392 if ( !this.bundle.getLocale().getLanguage().equals( locale.getLanguage() ) )
393 {
394 this.bundle = ResourceBundle.getBundle( this.bundleName, Locale.getDefault(), classLoader );
395 }
396 }
397
398
399 public String getDefaultLanguage()
400 {
401 return locale.getLanguage();
402 }
403
404
405 public String getDefaultCountry()
406 {
407 return locale.getCountry();
408 }
409
410
411 public String getDefaultBundleName()
412 {
413 return bundleName;
414 }
415
416
417 public String[] getBundleNames()
418 {
419 return new String[] { bundleName };
420 }
421
422
423 public ResourceBundle getBundle()
424 {
425 return bundle;
426 }
427
428
429 public ResourceBundle getBundle( String bundleName )
430 {
431 return bundle;
432 }
433
434
435 public ResourceBundle getBundle( String bundleName, String languageHeader )
436 {
437 return bundle;
438 }
439
440
441 public ResourceBundle getBundle( String bundleName, Locale locale )
442 {
443 return bundle;
444 }
445
446
447 public Locale getLocale( String languageHeader )
448 {
449 return new Locale( languageHeader );
450 }
451
452
453 public String getString( String key )
454 {
455 return getString( bundleName, locale, key );
456 }
457
458
459 public String getString( String key, Locale locale )
460 {
461 return getString( bundleName, locale, key );
462 }
463
464
465 public String getString( String bundleName, Locale locale, String key )
466 {
467 String value;
468
469 if ( locale == null )
470 {
471 locale = getLocale( null );
472 }
473
474 ResourceBundle rb = getBundle( bundleName, locale );
475 value = getStringOrNull( rb, key );
476
477 if ( value == null )
478 {
479
480 value = i18nOriginal.getString( bundleName, locale, key );
481 }
482
483 if ( value.indexOf( "${" ) < 0 )
484 {
485 return value;
486 }
487
488 final RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
489 try
490 {
491 interpolator.addValueSource( new EnvarBasedValueSource() );
492 }
493 catch ( final IOException e )
494 {
495 }
496
497 interpolator.addValueSource( new PropertiesBasedValueSource( System.getProperties() ) );
498 interpolator.addValueSource( new PropertiesBasedValueSource( project.getProperties() ) );
499 interpolator.addValueSource( new PrefixedObjectValueSource( "project", project ) );
500 interpolator.addValueSource( new PrefixedObjectValueSource( "pom", project ) );
501 interpolator.addValueSource( new PrefixedObjectValueSource( "settings", settings ) );
502
503 try
504 {
505 value = interpolator.interpolate( value );
506 }
507 catch ( final InterpolationException e )
508 {
509 }
510
511 return value;
512 }
513
514
515 public String format( String key, Object arg1 )
516 {
517 return format( bundleName, locale, key, new Object[] { arg1 } );
518 }
519
520
521 public String format( String key, Object arg1, Object arg2 )
522 {
523 return format( bundleName, locale, key, new Object[] { arg1, arg2 } );
524 }
525
526
527 public String format( String bundleName, Locale locale, String key, Object arg1 )
528 {
529 return format( bundleName, locale, key, new Object[] { arg1 } );
530 }
531
532
533 public String format( String bundleName, Locale locale, String key, Object arg1, Object arg2 )
534 {
535 return format( bundleName, locale, key, new Object[] { arg1, arg2 } );
536 }
537
538
539 public String format( String bundleName, Locale locale, String key, Object[] args )
540 {
541 if ( locale == null )
542 {
543 locale = getLocale( null );
544 }
545
546 String value = getString( bundleName, locale, key );
547 if ( args == null )
548 {
549 args = NO_ARGS;
550 }
551
552 MessageFormat messageFormat = new MessageFormat( "" );
553 messageFormat.setLocale( locale );
554 messageFormat.applyPattern( value );
555
556 return messageFormat.format( args );
557 }
558
559 private String getStringOrNull( ResourceBundle rb, String key )
560 {
561 if ( rb != null )
562 {
563 try
564 {
565 return rb.getString( key );
566 }
567 catch ( MissingResourceException ignored )
568 {
569
570 }
571 }
572 return null;
573 }
574 }
575 }