1 package org.apache.maven.plugins.pdf;
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.ArtifactNotFoundException;
26 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
27 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
28 import org.apache.maven.doxia.Doxia;
29 import org.apache.maven.doxia.docrenderer.AbstractDocumentRenderer;
30 import org.apache.maven.doxia.docrenderer.DocumentRenderer;
31 import org.apache.maven.doxia.docrenderer.DocumentRendererContext;
32 import org.apache.maven.doxia.docrenderer.DocumentRendererException;
33 import org.apache.maven.doxia.docrenderer.pdf.PdfRenderer;
34 import org.apache.maven.doxia.document.DocumentMeta;
35 import org.apache.maven.doxia.document.DocumentModel;
36 import org.apache.maven.doxia.document.DocumentTOCItem;
37 import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Writer;
38 import org.apache.maven.doxia.index.IndexEntry;
39 import org.apache.maven.doxia.index.IndexingSink;
40 import org.apache.maven.doxia.markup.HtmlMarkup;
41 import org.apache.maven.doxia.module.xdoc.XdocSink;
42 import org.apache.maven.doxia.parser.ParseException;
43 import org.apache.maven.doxia.parser.manager.ParserNotFoundException;
44 import org.apache.maven.doxia.sink.Sink;
45 import org.apache.maven.doxia.sink.SinkAdapter;
46 import org.apache.maven.doxia.sink.SinkEventAttributeSet;
47 import org.apache.maven.doxia.sink.SinkEventAttributes;
48 import org.apache.maven.doxia.site.decoration.DecorationModel;
49 import org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Reader;
50 import org.apache.maven.doxia.siterenderer.Renderer;
51 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
52 import org.apache.maven.doxia.tools.SiteTool;
53 import org.apache.maven.doxia.tools.SiteToolException;
54 import org.apache.maven.execution.MavenSession;
55 import org.apache.maven.model.MailingList;
56 import org.apache.maven.model.ReportPlugin;
57 import org.apache.maven.model.ReportSet;
58 import org.apache.maven.plugin.AbstractMojo;
59 import org.apache.maven.plugin.InvalidPluginException;
60 import org.apache.maven.plugin.MojoExecution;
61 import org.apache.maven.plugin.MojoExecutionException;
62 import org.apache.maven.plugin.MojoFailureException;
63 import org.apache.maven.plugin.PluginConfigurationException;
64 import org.apache.maven.plugin.PluginManager;
65 import org.apache.maven.plugin.PluginManagerException;
66 import org.apache.maven.plugin.PluginNotFoundException;
67 import org.apache.maven.plugin.descriptor.MojoDescriptor;
68 import org.apache.maven.plugin.descriptor.PluginDescriptor;
69 import org.apache.maven.plugin.version.PluginVersionNotFoundException;
70 import org.apache.maven.plugin.version.PluginVersionResolutionException;
71 import org.apache.maven.plugins.annotations.Component;
72 import org.apache.maven.plugins.annotations.Mojo;
73 import org.apache.maven.plugins.annotations.Parameter;
74 import org.apache.maven.project.MavenProject;
75 import org.apache.maven.project.MavenProjectBuilder;
76 import org.apache.maven.project.ProjectBuildingException;
77 import org.apache.maven.reporting.AbstractMavenReportRenderer;
78 import org.apache.maven.reporting.MavenReport;
79 import org.apache.maven.reporting.MavenReportException;
80 import org.apache.maven.settings.Settings;
81 import org.codehaus.classworlds.ClassRealm;
82 import org.codehaus.plexus.i18n.I18N;
83 import org.codehaus.plexus.util.FileUtils;
84 import org.codehaus.plexus.util.IOUtil;
85 import org.codehaus.plexus.util.PathTool;
86 import org.codehaus.plexus.util.ReaderFactory;
87 import org.codehaus.plexus.util.StringUtils;
88 import org.codehaus.plexus.util.WriterFactory;
89 import org.apache.commons.io.input.XmlStreamReader;
90 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
91
92 import javax.swing.text.AttributeSet;
93 import java.io.File;
94 import java.io.IOException;
95 import java.io.Reader;
96 import java.io.StringReader;
97 import java.io.StringWriter;
98 import java.io.Writer;
99 import java.lang.reflect.InvocationHandler;
100 import java.lang.reflect.Method;
101 import java.lang.reflect.Proxy;
102 import java.util.ArrayList;
103 import java.util.HashMap;
104 import java.util.Iterator;
105 import java.util.List;
106 import java.util.Locale;
107 import java.util.Map;
108
109
110
111
112
113
114
115 @Mojo( name = "pdf", threadSafe = true )
116 public class PdfMojo
117 extends AbstractMojo
118 {
119
120
121
122 private static final String EOL = System.getProperty( "line.separator" );
123
124
125
126
127
128
129
130
131 @Component( hint = "fo" )
132 private PdfRenderer foRenderer;
133
134
135
136
137 @Component
138 private I18N i18n;
139
140
141
142
143 @Component( hint = "itext" )
144 private PdfRenderer itextRenderer;
145
146
147
148
149
150 @Parameter( property = "locales" )
151 private String locales;
152
153
154
155
156 @Component
157 private Renderer siteRenderer;
158
159
160
161
162 @Component
163 private SiteTool siteTool;
164
165
166
167
168
169
170 @Component( role = PluginManager.class )
171 private PluginManager pluginManager;
172
173
174
175
176
177
178 @Component
179 private Doxia doxia;
180
181
182
183
184
185
186 @Component
187 private ArtifactFactory artifactFactory;
188
189
190
191
192
193
194 @Component
195 private MavenProjectBuilder mavenProjectBuilder;
196
197
198
199
200
201
202
203
204 @Component
205 private MavenProject project;
206
207
208
209
210
211
212 @Component
213 private Settings settings;
214
215
216
217
218
219
220 @Component
221 private MavenSession session;
222
223
224
225
226 @Parameter( defaultValue = "${basedir}/src/site", required = true )
227 private File siteDirectory;
228
229
230
231
232
233
234 @Parameter( defaultValue = "${project.build.directory}/generated-site", required = true )
235 private File generatedSiteDirectory;
236
237
238
239
240 @Parameter( defaultValue = "${project.build.directory}/pdf", required = true )
241 private File outputDirectory;
242
243
244
245
246 @Parameter( defaultValue = "${project.build.directory}/pdf", required = true )
247 private File workingDirectory;
248
249
250
251
252 @Parameter( defaultValue = "src/site/pdf.xml" )
253 private File docDescriptor;
254
255
256
257
258 @Parameter( property = "implementation", defaultValue = "fo", required = true )
259 private String implementation;
260
261
262
263
264 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
265 private ArtifactRepository localRepository;
266
267
268
269
270
271
272 @Parameter( property = "project.remoteArtifactRepositories" )
273 private List remoteRepositories;
274
275
276
277
278
279 @Parameter( property = "aggregate", defaultValue = "true" )
280 private boolean aggregate;
281
282
283
284
285 @Parameter( defaultValue = "${plugin.version}", readonly = true )
286 private String pluginVersion;
287
288
289
290
291
292
293
294
295 @Parameter( property = "includeReports", defaultValue = "true" )
296 private boolean includeReports;
297
298
299
300
301
302
303
304
305 @Parameter( property = "generateTOC", defaultValue = "start" )
306 private String generateTOC;
307
308
309
310
311
312
313
314
315
316 @Parameter( property = "validate", defaultValue = "false" )
317 private boolean validate;
318
319
320
321
322
323
324
325
326
327 private DocumentRenderer docRenderer;
328
329
330
331
332 private Locale defaultLocale;
333
334
335
336
337 private List localesList;
338
339
340
341
342 private DecorationModel defaultDecorationModel;
343
344
345
346
347
348
349 private File siteDirectoryTmp;
350
351
352
353
354
355
356 private File generatedSiteDirectoryTmp;
357
358
359
360
361
362
363 private Map generatedMavenReports;
364
365
366
367
368
369
370 public void execute()
371 throws MojoExecutionException, MojoFailureException
372 {
373 init();
374
375 try
376 {
377 generatePdf();
378 }
379 catch ( IOException e )
380 {
381 debugLogGeneratedModel( getDocumentModel( Locale.ENGLISH ) );
382
383 throw new MojoExecutionException( "Error during document generation: " + e.getMessage(), e );
384 }
385
386 try
387 {
388 copyGeneratedPdf();
389 }
390 catch ( IOException e )
391 {
392 throw new MojoExecutionException( "Error copying generated PDF: " + e.getMessage(), e );
393 }
394 }
395
396
397
398
399
400
401
402
403 private void init()
404 {
405 if ( "fo".equalsIgnoreCase( implementation ) )
406 {
407 this.docRenderer = foRenderer;
408 }
409 else if ( "itext".equalsIgnoreCase( implementation ) )
410 {
411 this.docRenderer = itextRenderer;
412 }
413 else
414 {
415 getLog().warn( "Invalid 'implementation' parameter: '" + implementation
416 + "', using 'fo' as default." );
417
418 this.docRenderer = foRenderer;
419 }
420
421 if ( !( "none".equalsIgnoreCase( generateTOC )
422 || "start".equalsIgnoreCase( generateTOC ) || "end".equalsIgnoreCase( generateTOC ) ) )
423 {
424 getLog().warn( "Invalid 'generateTOC' parameter: '" + generateTOC
425 + "', using 'start' as default." );
426
427 this.generateTOC = "start";
428 }
429 }
430
431
432
433
434
435
436
437
438 private void copyGeneratedPdf()
439 throws MojoExecutionException, IOException
440 {
441 if ( outputDirectory.getCanonicalPath().equals( workingDirectory.getCanonicalPath() ) )
442 {
443 return;
444 }
445
446 String outputName = getDocumentModel( getDefaultLocale() ).getOutputName().trim();
447 if ( !outputName.endsWith( ".pdf" ) )
448 {
449 outputName = outputName.concat( ".pdf" );
450 }
451
452 for ( final Iterator iterator = getAvailableLocales().iterator(); iterator.hasNext(); )
453 {
454 final Locale locale = (Locale) iterator.next();
455
456 File generatedPdfSource = new File( getLocaleDirectory( workingDirectory, locale), outputName );
457
458 if ( !generatedPdfSource.exists() )
459 {
460 getLog().warn( "Unable to find the generated pdf: " + generatedPdfSource.getAbsolutePath() );
461 continue;
462 }
463
464 File generatedPdfDest = new File( getLocaleDirectory( outputDirectory, locale), outputName );
465
466 FileUtils.copyFile( generatedPdfSource, generatedPdfDest );
467 generatedPdfSource.delete();
468 }
469 }
470
471
472
473
474
475
476
477
478 private void generatePdf()
479 throws MojoExecutionException, IOException
480 {
481 Locale.setDefault( getDefaultLocale() );
482
483 for ( final Iterator iterator = getAvailableLocales().iterator(); iterator.hasNext(); )
484 {
485 final Locale locale = (Locale) iterator.next();
486
487 final File workingDir = getLocaleDirectory( workingDirectory, locale );
488
489 File siteDirectoryFile = getLocaleDirectory( getSiteDirectoryTmp(), locale );
490
491 copyResources( locale );
492
493 generateMavenReports( locale );
494
495 DocumentRendererContext context = new DocumentRendererContext();
496 context.put( "project", project );
497 context.put( "settings", settings );
498 context.put( "PathTool", new PathTool() );
499 context.put( "FileUtils", new FileUtils() );
500 context.put( "StringUtils", new StringUtils() );
501 context.put( "i18n", i18n );
502 context.put( "generateTOC", generateTOC );
503 context.put( "validate", Boolean.valueOf( validate ) );
504
505 final DocumentModel model = aggregate ? getDocumentModel( locale ) : null;
506
507 try
508 {
509
510 ( (AbstractDocumentRenderer) docRenderer ).render( siteDirectoryFile, workingDir, model, context );
511 }
512 catch ( DocumentRendererException e )
513 {
514 throw new MojoExecutionException( "Error during document generation: " + e.getMessage(), e );
515 }
516 }
517 }
518
519
520
521
522
523
524 private File getSiteDirectoryTmp()
525 throws IOException
526 {
527 if ( this.siteDirectoryTmp == null )
528 {
529 final File tmpSiteDir = new File( workingDirectory, "site.tmp" );
530 prepareTempSiteDirectory( tmpSiteDir );
531
532 this.siteDirectoryTmp = tmpSiteDir;
533 }
534
535 return this.siteDirectoryTmp;
536 }
537
538
539
540
541
542 private File getGeneratedSiteDirectoryTmp()
543 {
544 if ( this.generatedSiteDirectoryTmp == null )
545 {
546 this.generatedSiteDirectoryTmp = new File( workingDirectory, "generated-site.tmp" );
547 }
548
549 return this.generatedSiteDirectoryTmp;
550 }
551
552
553
554
555
556
557
558
559
560
561
562 private void prepareTempSiteDirectory( final File tmpSiteDir )
563 throws IOException
564 {
565
566 tmpSiteDir.mkdirs();
567
568
569 if ( siteDirectory.exists() )
570 {
571 FileUtils.copyDirectoryStructure( siteDirectory, tmpSiteDir );
572 }
573
574
575 List files =
576 FileUtils.getFileAndDirectoryNames( tmpSiteDir, FileUtils.getDefaultExcludesAsString(), null, true,
577 true, true, true );
578 for ( final Iterator it = files.iterator(); it.hasNext(); )
579 {
580 final File file = new File( it.next().toString() );
581
582 if ( file.isDirectory() )
583 {
584 FileUtils.deleteDirectory( file );
585 }
586 else
587 {
588 file.delete();
589 }
590 }
591
592 copySiteDir( generatedSiteDirectory, tmpSiteDir );
593 }
594
595
596
597
598
599
600
601
602
603 private void copySiteDir( final File from, final File to )
604 throws IOException
605 {
606 if ( from == null || !from.exists() )
607 {
608 return;
609 }
610
611
612 for ( final Iterator iterator = getAvailableLocales().iterator(); iterator.hasNext(); )
613 {
614 final Locale locale = (Locale) iterator.next();
615
616 String excludes = getDefaultExcludesWithLocales( getAvailableLocales(), getDefaultLocale() );
617 List siteFiles = FileUtils.getFileNames( siteDirectory, "**/*", excludes, false );
618 File siteDirectoryLocale = new File( siteDirectory, locale.getLanguage() );
619 if ( !locale.getLanguage().equals( getDefaultLocale().getLanguage() ) && siteDirectoryLocale.exists() )
620 {
621 siteFiles = FileUtils.getFileNames( siteDirectoryLocale, "**/*", excludes, false );
622 }
623
624 List generatedSiteFiles = FileUtils.getFileNames( from, "**/*", excludes, false );
625 File fromLocale = new File( from, locale.getLanguage() );
626 if ( !locale.getLanguage().equals( getDefaultLocale().getLanguage() ) && fromLocale.exists() )
627 {
628 generatedSiteFiles = FileUtils.getFileNames( fromLocale, "**/*", excludes, false );
629 }
630
631 for ( final Iterator it = generatedSiteFiles.iterator(); it.hasNext(); )
632 {
633 final String generatedSiteFile = it.next().toString();
634
635 if ( siteFiles.contains( generatedSiteFile ) )
636 {
637 getLog().warn( "Generated-site already contains a file in site: " + generatedSiteFile
638 + ". Ignoring copying it!" );
639 continue;
640 }
641
642 if ( !locale.getLanguage().equals( getDefaultLocale().getLanguage() ) )
643 {
644 if ( fromLocale.exists() )
645 {
646 File in = new File( fromLocale, generatedSiteFile );
647 File out = new File( new File( to, locale.getLanguage() ), generatedSiteFile );
648 out.getParentFile().mkdirs();
649 FileUtils.copyFile( in, out );
650 }
651 }
652 else
653 {
654 File in = new File( from, generatedSiteFile );
655 File out = new File( to, generatedSiteFile );
656 out.getParentFile().mkdirs();
657 FileUtils.copyFile( in, out );
658 }
659 }
660 }
661 }
662
663
664
665
666
667
668
669
670
671
672 private DocumentModel getDocumentModel( Locale locale )
673 throws MojoExecutionException
674 {
675 if ( docDescriptor.exists() )
676 {
677 DocumentModel doc = getDocumentModelFromDescriptor( locale );
678
679
680 appendGeneratedReports( doc, locale );
681
682 return doc;
683 }
684
685 DocumentModel model = new DocumentModelBuilder( project, getDefaultDecorationModel() ).getDocumentModel();
686
687 model.getMeta().setGenerator( getDefaultGenerator() );
688 model.getMeta().setLanguage( locale.getLanguage() );
689 model.getCover().setCoverType( i18n.getString( "pdf-plugin", getDefaultLocale(), "toc.type" ) );
690 model.getToc().setName( i18n.getString( "pdf-plugin", getDefaultLocale(), "toc.title" ) );
691
692 appendGeneratedReports( model, locale );
693
694 debugLogGeneratedModel( model );
695
696 return model;
697 }
698
699
700
701
702
703
704
705
706 private DocumentModel getDocumentModelFromDescriptor( Locale locale )
707 throws MojoExecutionException
708 {
709 DocumentModel model = null;
710
711 try
712 {
713 model =
714 new DocumentDescriptorReader( project, getLog() ).readAndFilterDocumentDescriptor( docDescriptor );
715 }
716 catch ( XmlPullParserException ex )
717 {
718 throw new MojoExecutionException( "Error reading DocumentDescriptor!", ex );
719 }
720 catch ( IOException io )
721 {
722 throw new MojoExecutionException( "Error opening DocumentDescriptor!", io );
723 }
724
725 if ( model.getMeta() == null )
726 {
727 model.setMeta( new DocumentMeta() );
728 }
729
730 if ( StringUtils.isEmpty( model.getMeta().getLanguage() ) )
731 {
732 model.getMeta().setLanguage( locale.getLanguage() );
733 }
734
735 if ( StringUtils.isEmpty( model.getMeta().getGenerator() ) )
736 {
737 model.getMeta().setGenerator( getDefaultGenerator() );
738 }
739
740 return model;
741 }
742
743
744
745
746
747
748
749
750 private File getLocaleDirectory( File basedir, Locale locale )
751 {
752 if ( locale.getLanguage().equals( getDefaultLocale().getLanguage() ) )
753 {
754 return basedir;
755 }
756
757 return new File( basedir, locale.getLanguage() );
758 }
759
760
761
762
763
764 private Locale getDefaultLocale()
765 {
766 if ( this.defaultLocale == null )
767 {
768 this.defaultLocale = (Locale) getAvailableLocales().get( 0 );
769 }
770
771 return this.defaultLocale;
772 }
773
774
775
776
777
778 private List getAvailableLocales()
779 {
780 if ( this.localesList == null )
781 {
782 this.localesList = siteTool.getAvailableLocales( locales );
783 }
784
785 return this.localesList;
786 }
787
788
789
790
791
792 private DecorationModel getDefaultDecorationModel()
793 throws MojoExecutionException
794 {
795 if ( this.defaultDecorationModel == null )
796 {
797 final Locale locale = getDefaultLocale();
798
799 final File basedir = project.getBasedir();
800 final String relativePath =
801 siteTool.getRelativePath( siteDirectory.getAbsolutePath(), basedir.getAbsolutePath() );
802
803 final File descriptorFile = siteTool.getSiteDescriptorFromBasedir( relativePath, basedir, locale );
804 DecorationModel decoration = null;
805
806 if ( descriptorFile.exists() )
807 {
808 XmlStreamReader reader = null;
809 try
810 {
811 reader = new XmlStreamReader( descriptorFile );
812 String enc = reader.getEncoding();
813
814 String siteDescriptorContent = IOUtil.toString( reader );
815 siteDescriptorContent =
816 siteTool.getInterpolatedSiteDescriptorContent( new HashMap( 2 ), project,
817 siteDescriptorContent, enc, enc );
818
819 decoration = new DecorationXpp3Reader().read( new StringReader( siteDescriptorContent ) );
820 }
821 catch ( XmlPullParserException e )
822 {
823 throw new MojoExecutionException( "Error parsing site descriptor", e );
824 }
825 catch ( IOException e )
826 {
827 throw new MojoExecutionException( "Error reading site descriptor", e );
828 }
829 catch ( SiteToolException e )
830 {
831 throw new MojoExecutionException( "Error when interpoling site descriptor", e );
832 }
833 finally
834 {
835 IOUtil.close( reader );
836 }
837 }
838
839 this.defaultDecorationModel = decoration;
840 }
841
842 return this.defaultDecorationModel;
843 }
844
845
846
847
848
849
850
851
852 private void copyResources( Locale locale )
853 throws MojoExecutionException
854 {
855 final DecorationModel decorationModel = getDefaultDecorationModel();
856 if ( decorationModel == null )
857 {
858 return;
859 }
860
861 File skinFile;
862 try
863 {
864 skinFile =
865 siteTool.getSkinArtifactFromRepository( localRepository, project.getRemoteArtifactRepositories(),
866 decorationModel ).getFile();
867 }
868 catch ( SiteToolException e )
869 {
870 throw new MojoExecutionException( "SiteToolException: " + e.getMessage(), e );
871 }
872
873 if ( skinFile == null )
874 {
875 return;
876 }
877
878 if ( getLog().isDebugEnabled() )
879 {
880 getLog().debug( "Copy resources from skin artifact: '" + skinFile + "'..." );
881 }
882
883 try
884 {
885 final SiteRenderingContext context =
886 siteRenderer.createContextForSkin( skinFile, new HashMap( 2 ), decorationModel, project.getName(),
887 locale );
888 context.addSiteDirectory( new File( siteDirectory, locale.getLanguage() ) );
889
890 for ( final Iterator i = context.getSiteDirectories().iterator(); i.hasNext(); )
891 {
892 final File siteDirectoryFile = (File) i.next();
893
894 siteRenderer.copyResources( context, new File( siteDirectoryFile, "resources" ), workingDirectory );
895 }
896 }
897 catch ( IOException e )
898 {
899 throw new MojoExecutionException( "IOException: " + e.getMessage(), e );
900 }
901 }
902
903
904
905
906
907
908 private String getDefaultGenerator()
909 {
910 return "Maven PDF Plugin v. " + pluginVersion + ", '" + implementation + "' implementation.";
911 }
912
913
914
915
916
917
918 private void debugLogGeneratedModel( final DocumentModel docModel )
919 {
920 if ( getLog().isDebugEnabled() && project != null )
921 {
922 final File outputDir = new File( project.getBuild().getDirectory(), "pdf" );
923
924 if ( !outputDir.exists() )
925 {
926 outputDir.mkdirs();
927 }
928
929 final File doc = FileUtils.createTempFile( "pdf", ".xml", outputDir );
930 final DocumentXpp3Writer xpp3 = new DocumentXpp3Writer();
931
932 Writer w = null;
933 try
934 {
935 w = WriterFactory.newXmlWriter( doc );
936 xpp3.write( w, docModel );
937
938 getLog().debug( "Generated a default document model: " + doc.getAbsolutePath() );
939 }
940 catch ( IOException e )
941 {
942 getLog().error( "Failed to write document model: " + e.getMessage() );
943 getLog().debug( e );
944 }
945 finally
946 {
947 IOUtil.close( w );
948 }
949 }
950 }
951
952
953
954
955
956
957
958
959
960
961 private void generateMavenReports( Locale locale )
962 throws MojoExecutionException, IOException
963 {
964 if ( !includeReports )
965 {
966 getLog().info( "Skipped report generation." );
967 return;
968 }
969
970 if ( project.getReporting() == null )
971 {
972 getLog().info( "No report was specified." );
973 return;
974 }
975
976 for ( final Iterator it = project.getReporting().getPlugins().iterator(); it.hasNext(); )
977 {
978 final ReportPlugin reportPlugin = (ReportPlugin) it.next();
979
980 final PluginDescriptor pluginDescriptor = getPluginDescriptor( reportPlugin );
981
982 if ( pluginDescriptor != null )
983 {
984 List goals = new ArrayList( 8 );
985 for ( final Iterator it2 = reportPlugin.getReportSets().iterator(); it2.hasNext(); )
986 {
987 final ReportSet reportSet = (ReportSet) it2.next();
988
989 for ( final Iterator it3 = reportSet.getReports().iterator(); it3.hasNext(); )
990 {
991 goals.add( it3.next().toString() );
992 }
993 }
994
995 List mojoDescriptors = pluginDescriptor.getMojos();
996 for ( final Iterator it2 = mojoDescriptors.iterator(); it2.hasNext(); )
997 {
998 final MojoDescriptor mojoDescriptor = (MojoDescriptor) it2.next();
999
1000 if ( goals.isEmpty() || ( !goals.isEmpty() && goals.contains( mojoDescriptor.getGoal() ) ) )
1001 {
1002 MavenReport report = getMavenReport( mojoDescriptor );
1003
1004 generateMavenReport( mojoDescriptor, report, locale );
1005 }
1006 }
1007 }
1008 }
1009
1010
1011 if ( !getGeneratedMavenReports( locale ).isEmpty() )
1012 {
1013 File outDir = new File( getGeneratedSiteDirectoryTmp(), "xdoc" );
1014 if ( !locale.getLanguage().equals( defaultLocale.getLanguage() ) )
1015 {
1016 outDir = new File( new File( getGeneratedSiteDirectoryTmp(), locale.getLanguage() ), "xdoc" );
1017 }
1018 outDir.mkdirs();
1019
1020 File piReport = new File( outDir, "project-info.xml" );
1021
1022 StringWriter sw = new StringWriter();
1023
1024 PdfSink sink = new PdfSink( sw );
1025 ProjectInfoRenderer r = new ProjectInfoRenderer( sink, getGeneratedMavenReports( locale ), i18n, locale );
1026 r.render();
1027
1028 writeGeneratedReport( sw.toString(), piReport );
1029 }
1030
1031
1032 copySiteDir( getGeneratedSiteDirectoryTmp(), getSiteDirectoryTmp() );
1033 copySiteDir( generatedSiteDirectory, getSiteDirectoryTmp() );
1034 }
1035
1036
1037
1038
1039
1040
1041
1042
1043 private PluginDescriptor getPluginDescriptor( ReportPlugin reportPlugin )
1044 throws MojoExecutionException
1045 {
1046 try
1047 {
1048 return pluginManager.verifyReportPlugin( reportPlugin, project, session );
1049 }
1050 catch ( ArtifactResolutionException e )
1051 {
1052 throw new MojoExecutionException( "ArtifactResolutionException: " + e.getMessage(), e );
1053 }
1054 catch ( ArtifactNotFoundException e )
1055 {
1056 throw new MojoExecutionException( "ArtifactNotFoundException: " + e.getMessage(), e );
1057 }
1058 catch ( PluginNotFoundException e )
1059 {
1060 throw new MojoExecutionException( "PluginNotFoundException: " + e.getMessage(), e );
1061 }
1062 catch ( PluginVersionResolutionException e )
1063 {
1064 throw new MojoExecutionException( "PluginVersionResolutionException: " + e.getMessage(), e );
1065 }
1066 catch ( InvalidVersionSpecificationException e )
1067 {
1068 throw new MojoExecutionException( "InvalidVersionSpecificationException: " + e.getMessage(), e );
1069 }
1070 catch ( InvalidPluginException e )
1071 {
1072 throw new MojoExecutionException( "InvalidPluginException: " + e.getMessage(), e );
1073 }
1074 catch ( PluginManagerException e )
1075 {
1076 throw new MojoExecutionException( "PluginManagerException: " + e.getMessage(), e );
1077 }
1078 catch ( PluginVersionNotFoundException e )
1079 {
1080 throw new MojoExecutionException( "PluginVersionNotFoundException: " + e.getMessage(), e );
1081 }
1082 catch ( NoSuchMethodError e )
1083 {
1084 getLog().info( "Ignoring api call removed in maven 3, no reports are generated!" );
1085 getLog().debug( e );
1086 return null;
1087 }
1088 }
1089
1090
1091
1092
1093
1094
1095
1096 private MavenReport getMavenReport( MojoDescriptor mojoDescriptor )
1097 throws MojoExecutionException
1098 {
1099 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
1100 try
1101 {
1102 Thread.currentThread()
1103 .setContextClassLoader( mojoDescriptor.getPluginDescriptor().getClassRealm().getClassLoader() );
1104
1105 MojoExecution mojoExecution = new MojoExecution( mojoDescriptor );
1106
1107 return pluginManager.getReport( project, mojoExecution, session );
1108 }
1109 catch ( ArtifactNotFoundException e )
1110 {
1111 throw new MojoExecutionException( "ArtifactNotFoundException: " + e.getMessage(), e );
1112 }
1113 catch ( ArtifactResolutionException e )
1114 {
1115 throw new MojoExecutionException( "ArtifactResolutionException: " + e.getMessage(), e );
1116 }
1117 catch ( PluginConfigurationException e )
1118 {
1119 throw new MojoExecutionException( "PluginConfigurationException: " + e.getMessage(), e );
1120 }
1121 catch ( PluginManagerException e )
1122 {
1123 throw new MojoExecutionException( "PluginManagerException: " + e.getMessage(), e );
1124 }
1125 finally
1126 {
1127 Thread.currentThread().setContextClassLoader( oldClassLoader );
1128 }
1129 }
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142 private void generateMavenReport( MojoDescriptor mojoDescriptor, MavenReport report, Locale locale )
1143 throws IOException, MojoExecutionException
1144 {
1145 if ( report == null )
1146 {
1147 return;
1148 }
1149
1150 String localReportName = report.getName( locale );
1151 if ( !report.canGenerateReport() )
1152 {
1153 getLog().info( "Skipped \"" + localReportName + "\" report." );
1154 getLog().debug( "canGenerateReport() was false." );
1155
1156 return;
1157 }
1158
1159 if ( report.isExternalReport() )
1160 {
1161 getLog().info( "Skipped external \"" + localReportName + "\" report." );
1162 getLog().debug( "isExternalReport() was false." );
1163
1164 return;
1165 }
1166
1167 for ( final Iterator it = getGeneratedMavenReports( locale ).iterator(); it.hasNext(); )
1168 {
1169 MavenReport generatedReport = (MavenReport) it.next();
1170
1171 if ( report.getName( locale ).equals( generatedReport.getName( locale ) ) )
1172 {
1173 if ( getLog().isDebugEnabled() )
1174 {
1175 getLog().debug( report.getName( locale ) + " was already generated." );
1176 }
1177 return;
1178 }
1179 }
1180
1181 File outDir = new File( getGeneratedSiteDirectoryTmp(), "xdoc" );
1182 if ( !locale.getLanguage().equals( defaultLocale.getLanguage() ) )
1183 {
1184 outDir = new File( new File( getGeneratedSiteDirectoryTmp(), locale.getLanguage() ), "xdoc" );
1185 }
1186 outDir.mkdirs();
1187
1188 File generatedReport = new File( outDir, report.getOutputName() + ".xml" );
1189
1190 String excludes = getDefaultExcludesWithLocales( getAvailableLocales(), getDefaultLocale() );
1191 List files = FileUtils.getFileNames( siteDirectory, "*/" + report.getOutputName() + ".*", excludes, false );
1192 if ( !locale.getLanguage().equals( defaultLocale.getLanguage() ) )
1193 {
1194 files =
1195 FileUtils.getFileNames( new File( siteDirectory, locale.getLanguage() ), "*/"
1196 + report.getOutputName() + ".*", excludes, false );
1197 }
1198
1199 if ( files.size() != 0 )
1200 {
1201 String displayLanguage = locale.getDisplayLanguage( Locale.ENGLISH );
1202
1203 if ( getLog().isInfoEnabled() )
1204 {
1205 getLog().info(
1206 "Skipped \"" + report.getName( locale ) + "\" report, file \""
1207 + report.getOutputName() + "\" already exists for the " + displayLanguage
1208 + " version." );
1209 }
1210
1211 return;
1212 }
1213
1214 if ( getLog().isInfoEnabled() )
1215 {
1216 getLog().info( "Generating \"" + localReportName + "\" report." );
1217 }
1218
1219 StringWriter sw = new StringWriter();
1220
1221 PdfSink sink = null;
1222 try
1223 {
1224 sink = new PdfSink( sw );
1225 org.codehaus.doxia.sink.Sink proxy = (org.codehaus.doxia.sink.Sink) Proxy.newProxyInstance(
1226 org.codehaus.doxia.sink.Sink.class.getClassLoader(),
1227 new Class[] { org.codehaus.doxia.sink.Sink.class }, new SinkDelegate( sink ) );
1228 report.generate( proxy, locale );
1229 }
1230 catch ( MavenReportException e )
1231 {
1232 throw new MojoExecutionException( "MavenReportException: " + e.getMessage(), e );
1233 }
1234 catch ( LinkageError e )
1235 {
1236 if ( getLog().isErrorEnabled() )
1237 {
1238 ClassRealm reportPluginRealm = mojoDescriptor.getPluginDescriptor().getClassRealm();
1239 StringBuilder sb = new StringBuilder( 1024 );
1240 sb.append( report.getClass().getName() ).append( "#generate(...) caused a linkage error (" );
1241 sb.append( e.getClass().getName() )
1242 .append( ") and may be out-of-date. Check the realms:" ).append( EOL );
1243 sb.append( "Maven Report Plugin realm = " ).append( reportPluginRealm.getId() ).append( EOL );
1244 for ( int i = 0; i < reportPluginRealm.getConstituents().length; i++ )
1245 {
1246 sb.append( "urls[" ).append( i ).append( "] = " ).append( reportPluginRealm.getConstituents()[i] );
1247 if ( i != ( reportPluginRealm.getConstituents().length - 1 ) )
1248 {
1249 sb.append( EOL );
1250 }
1251 }
1252
1253 getLog().error( sb.toString() );
1254 }
1255
1256 throw e;
1257 }
1258 finally
1259 {
1260 if ( sink != null )
1261 {
1262 sink.close();
1263 }
1264 }
1265
1266 writeGeneratedReport( sw.toString(), generatedReport );
1267
1268 if ( isValidGeneratedReport( mojoDescriptor, generatedReport, localReportName ) )
1269 {
1270 getGeneratedMavenReports( locale ).add( report );
1271 }
1272 }
1273
1274
1275
1276
1277
1278
1279
1280
1281 private List getGeneratedMavenReports( Locale locale )
1282 {
1283 if ( this.generatedMavenReports == null )
1284 {
1285 this.generatedMavenReports = new HashMap( 2 );
1286 }
1287
1288 if ( this.generatedMavenReports.get( locale ) == null )
1289 {
1290 this.generatedMavenReports.put( locale, new ArrayList( 2 ) );
1291 }
1292
1293 return ( (List) this.generatedMavenReports.get( locale ) );
1294 }
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312 private void appendGeneratedReports( DocumentModel model, Locale locale )
1313 {
1314 if ( !includeReports )
1315 {
1316 return;
1317 }
1318 if ( getGeneratedMavenReports( locale ).isEmpty() )
1319 {
1320 return;
1321 }
1322
1323 final DocumentTOCItem documentTOCItem = new DocumentTOCItem();
1324 documentTOCItem.setName( i18n.getString( "pdf-plugin", locale, "toc.project-info.item" ) );
1325 documentTOCItem.setRef( "/project-info" );
1326
1327 List addedRef = new ArrayList( 4 );
1328
1329 List items = new ArrayList( 4 );
1330
1331
1332 for ( final Iterator it = getGeneratedMavenReports( locale ).iterator(); it.hasNext(); )
1333 {
1334 final MavenReport report = (MavenReport) it.next();
1335
1336 final DocumentTOCItem reportItem = new DocumentTOCItem();
1337 reportItem.setName( report.getName( locale ) );
1338 reportItem.setRef( "/" + report.getOutputName() );
1339
1340 items.add( reportItem );
1341
1342 addedRef.add( report.getOutputName() );
1343 }
1344
1345
1346 try
1347 {
1348 if ( generatedSiteDirectory.exists() )
1349 {
1350 String excludes = getDefaultExcludesWithLocales( getAvailableLocales(), getDefaultLocale() );
1351 List generatedDirs = FileUtils.getDirectoryNames( generatedSiteDirectory, "*", excludes, true );
1352 if ( !locale.getLanguage().equals( getDefaultLocale().getLanguage() ) )
1353 {
1354 generatedDirs =
1355 FileUtils.getFileNames( new File( generatedSiteDirectory, locale.getLanguage() ), "*",
1356 excludes, true );
1357 }
1358
1359 for ( final Iterator it = generatedDirs.iterator(); it.hasNext(); )
1360 {
1361 final String generatedDir = it.next().toString();
1362
1363 List generatedFiles =
1364 FileUtils.getFileNames( new File( generatedDir ), "**.*", excludes, false );
1365
1366 for ( final Iterator it2 = generatedFiles.iterator(); it2.hasNext(); )
1367 {
1368 final String generatedFile = it2.next().toString();
1369 final String ref = generatedFile.substring( 0, generatedFile.lastIndexOf( '.' ) );
1370
1371 if ( !addedRef.contains( ref ) )
1372 {
1373 final String title =
1374 getGeneratedDocumentTitle( new File( generatedDir, generatedFile ) );
1375
1376 if ( title != null )
1377 {
1378 final DocumentTOCItem reportItem = new DocumentTOCItem();
1379 reportItem.setName( title );
1380 reportItem.setRef( "/" + ref );
1381
1382 items.add( reportItem );
1383 }
1384 }
1385 }
1386 }
1387 }
1388 }
1389 catch ( IOException e )
1390 {
1391 getLog().error( "IOException: " + e.getMessage() );
1392 getLog().debug( e );
1393 }
1394
1395
1396 documentTOCItem.setItems( items );
1397 model.getToc().addItem( documentTOCItem );
1398 }
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408 private String getGeneratedDocumentTitle( final File f )
1409 throws IOException
1410 {
1411 final IndexEntry entry = new IndexEntry( "index" );
1412 final IndexingSink titleSink = new IndexingSink( entry );
1413
1414 Reader reader = null;
1415 try
1416 {
1417 reader = ReaderFactory.newXmlReader( f );
1418
1419 doxia.parse( reader, f.getParentFile().getName(), titleSink );
1420 }
1421 catch ( ParseException e )
1422 {
1423 getLog().error( "ParseException: " + e.getMessage() );
1424 getLog().debug( e );
1425 return null;
1426 }
1427 catch ( ParserNotFoundException e )
1428 {
1429 getLog().error( "ParserNotFoundException: " + e.getMessage() );
1430 getLog().debug( e );
1431 return null;
1432 }
1433 finally
1434 {
1435 IOUtil.close( reader );
1436 }
1437
1438 return titleSink.getTitle();
1439 }
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450 private boolean isValidGeneratedReport( MojoDescriptor mojoDescriptor, File generatedReport,
1451 String localReportName )
1452 {
1453 SinkAdapter sinkAdapter = new SinkAdapter();
1454 Reader reader = null;
1455 try
1456 {
1457 reader = ReaderFactory.newXmlReader( generatedReport );
1458
1459 doxia.parse( reader, generatedReport.getParentFile().getName(), sinkAdapter );
1460 }
1461 catch ( ParseException e )
1462 {
1463 StringBuilder sb = new StringBuilder( 1024 );
1464
1465 sb.append( EOL ).append( EOL );
1466 sb.append( "Error when parsing the generated report: " ).append( generatedReport.getAbsolutePath() );
1467 sb.append( EOL );
1468 sb.append( e.getMessage() );
1469 sb.append( EOL ).append( EOL );
1470
1471 sb.append( "You could:" ).append( EOL );
1472 sb.append( " * exclude all reports using -DincludeReports=false" ).append( EOL );
1473 sb.append( " * remove the " );
1474 sb.append( mojoDescriptor.getPluginDescriptor().getGroupId() );
1475 sb.append( ":" );
1476 sb.append( mojoDescriptor.getPluginDescriptor().getArtifactId() );
1477 sb.append( ":" );
1478 sb.append( mojoDescriptor.getPluginDescriptor().getVersion() );
1479 sb.append( " from the <reporting/> part. To not affect the site generation, " );
1480 sb.append( "you could create a PDF profile." ).append( EOL );
1481 sb.append( EOL );
1482
1483 MavenProject pluginProject = getReportPluginProject( mojoDescriptor.getPluginDescriptor() );
1484
1485 if ( pluginProject == null )
1486 {
1487 sb.append( "You could also contact the Plugin team." ).append( EOL );
1488 }
1489 else
1490 {
1491 sb.append( "You could also contact the Plugin team:" ).append( EOL );
1492 if ( pluginProject.getMailingLists() != null && !pluginProject.getMailingLists().isEmpty() )
1493 {
1494 boolean appended = false;
1495 for ( Iterator i = pluginProject.getMailingLists().iterator(); i.hasNext(); )
1496 {
1497 MailingList mailingList = (MailingList) i.next();
1498
1499 if ( StringUtils.isNotEmpty( mailingList.getName() )
1500 && StringUtils.isNotEmpty( mailingList.getPost() ) )
1501 {
1502 if ( !appended )
1503 {
1504 sb.append( " Mailing Lists:" ).append( EOL );
1505 appended = true;
1506 }
1507 sb.append( " " ).append( mailingList.getName() );
1508 sb.append( ": " ).append( mailingList.getPost() );
1509 sb.append( EOL );
1510 }
1511 }
1512 }
1513 if ( StringUtils.isNotEmpty( pluginProject.getUrl() ) )
1514 {
1515 sb.append( " Web Site:" ).append( EOL );
1516 sb.append( " " ).append( pluginProject.getUrl() );
1517 sb.append( EOL );
1518 }
1519 if ( pluginProject.getIssueManagement() != null
1520 && StringUtils.isNotEmpty( pluginProject.getIssueManagement().getUrl() ) )
1521 {
1522 sb.append( " Issue Tracking:" ).append( EOL );
1523 sb.append( " " ).append( pluginProject.getIssueManagement().getUrl() );
1524 sb.append( EOL );
1525 }
1526 }
1527
1528 sb.append( EOL ).append( "Ignoring the \"" ).append( localReportName )
1529 .append( "\" report in the PDF." ).append( EOL );
1530
1531 getLog().error( sb.toString() );
1532 getLog().debug( e );
1533
1534 return false;
1535 }
1536 catch ( ParserNotFoundException e )
1537 {
1538 getLog().error( "ParserNotFoundException: " + e.getMessage() );
1539 getLog().debug( e );
1540
1541 return false;
1542 }
1543 catch ( IOException e )
1544 {
1545 getLog().error( "IOException: " + e.getMessage() );
1546 getLog().debug( e );
1547
1548 return false;
1549 }
1550 finally
1551 {
1552 IOUtil.close( reader );
1553 }
1554
1555 return true;
1556 }
1557
1558
1559
1560
1561
1562
1563 private MavenProject getReportPluginProject( PluginDescriptor pluginDescriptor )
1564 {
1565 Artifact artifact =
1566 artifactFactory.createProjectArtifact( pluginDescriptor.getGroupId(),
1567 pluginDescriptor.getArtifactId(),
1568 pluginDescriptor.getVersion(), Artifact.SCOPE_COMPILE );
1569 try
1570 {
1571 return mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, localRepository );
1572 }
1573 catch ( ProjectBuildingException e )
1574 {
1575 getLog().error( "ProjectBuildingException: " + e.getMessage() );
1576 getLog().debug( e );
1577 }
1578
1579 return null;
1580 }
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597 private static void writeGeneratedReport( String content, File toFile )
1598 throws IOException
1599 {
1600 if ( StringUtils.isEmpty( content ) )
1601 {
1602 return;
1603 }
1604
1605 Writer writer = null;
1606 try
1607 {
1608 writer = WriterFactory.newXmlWriter( toFile );
1609
1610 writer.write( StringUtils.replace( content, "<table><table", "<table" ) );
1611 }
1612 finally
1613 {
1614 IOUtil.close( writer );
1615 }
1616 }
1617
1618
1619
1620
1621
1622
1623
1624
1625 private static String getDefaultExcludesWithLocales( List locales, Locale defaultLocale )
1626 {
1627 String excludesLocales = FileUtils.getDefaultExcludesAsString();
1628 for ( final Iterator it = locales.iterator(); it.hasNext(); )
1629 {
1630 final Locale locale = (Locale) it.next();
1631
1632 if ( !locale.getLanguage().equals( defaultLocale.getLanguage() ) )
1633 {
1634 excludesLocales = excludesLocales + ",**/" + locale.getLanguage() + "/*";
1635 }
1636 }
1637
1638 return excludesLocales;
1639 }
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650 private static class PdfSink
1651 extends XdocSink
1652 {
1653 protected PdfSink( Writer writer )
1654 {
1655 super( writer );
1656 }
1657
1658
1659 public void table()
1660 {
1661 super.table();
1662
1663
1664 writeStartTag( HtmlMarkup.TABLE );
1665 }
1666
1667
1668 public void text( String text )
1669 {
1670
1671 super.text( StringUtils.replace( text, "\u0092", "'" ) );
1672 }
1673 }
1674
1675
1676
1677
1678
1679
1680 private static class ProjectInfoRenderer
1681 extends AbstractMavenReportRenderer
1682 {
1683 private final List generatedReports;
1684
1685 private final I18N i18n;
1686
1687 private final Locale locale;
1688
1689 ProjectInfoRenderer( Sink sink, List generatedReports, I18N i18n, Locale locale )
1690 {
1691 super( sink );
1692
1693 this.generatedReports = generatedReports;
1694 this.i18n = i18n;
1695 this.locale = locale;
1696 }
1697
1698
1699 public String getTitle()
1700 {
1701 return i18n.getString( "pdf-plugin", locale, "report.project-info.title" );
1702 }
1703
1704
1705 public void renderBody()
1706 {
1707 sink.section1();
1708 sink.sectionTitle1();
1709 sink.text( i18n.getString( "pdf-plugin", locale, "report.project-info.title" ) );
1710 sink.sectionTitle1_();
1711
1712 sink.paragraph();
1713 sink.text( i18n.getString( "pdf-plugin", locale, "report.project-info.description1" ) + " " );
1714 sink.link( "http://maven.apache.org" );
1715 sink.text( "Maven" );
1716 sink.link_();
1717 sink.text( " " + i18n.getString( "pdf-plugin", locale, "report.project-info.description2" ) );
1718 sink.paragraph_();
1719
1720 sink.section2();
1721 sink.sectionTitle2();
1722 sink.text( i18n.getString( "pdf-plugin", locale, "report.project-info.sectionTitle" ) );
1723 sink.sectionTitle2_();
1724
1725 sink.table();
1726
1727 sink.tableRows( new int[] { Sink.JUSTIFY_LEFT, Sink.JUSTIFY_LEFT }, false );
1728
1729 String name = i18n.getString( "pdf-plugin", locale, "report.project-info.column.document" );
1730 String description = i18n.getString( "pdf-plugin", locale, "report.project-info.column.description" );
1731
1732 sink.tableRow();
1733
1734 sink.tableHeaderCell( SinkEventAttributeSet.CENTER );
1735
1736 sink.text( name );
1737
1738 sink.tableHeaderCell_();
1739
1740 sink.tableHeaderCell( SinkEventAttributeSet.CENTER );
1741
1742 sink.text( description );
1743
1744 sink.tableHeaderCell_();
1745
1746 sink.tableRow_();
1747
1748 if ( generatedReports != null )
1749 {
1750 for ( final Iterator it = generatedReports.iterator(); it.hasNext(); )
1751 {
1752 final MavenReport report = (MavenReport) it.next();
1753
1754 sink.tableRow();
1755 sink.tableCell();
1756 sink.link( report.getOutputName() + ".html" );
1757 sink.text( report.getName( locale ) );
1758 sink.link_();
1759 sink.tableCell_();
1760 sink.tableCell();
1761 sink.text( report.getDescription( locale ) );
1762 sink.tableCell_();
1763 sink.tableRow_();
1764 }
1765 }
1766
1767 sink.tableRows_();
1768
1769 sink.table_();
1770
1771 sink.section2_();
1772
1773 sink.section1_();
1774 }
1775 }
1776
1777
1778
1779
1780
1781
1782
1783 private static class SinkDelegate
1784 implements InvocationHandler
1785 {
1786 private final Sink sink;
1787
1788 SinkDelegate( Sink sink )
1789 {
1790 this.sink = sink;
1791 }
1792
1793
1794 public Object invoke( Object proxy, Method method, Object[] args )
1795 throws Throwable
1796 {
1797 Class[] parameterTypes = method.getParameterTypes();
1798
1799 for ( int i = parameterTypes.length - 1; i >= 0; i-- )
1800 {
1801 if ( AttributeSet.class.isAssignableFrom( parameterTypes[i] ) )
1802 {
1803 parameterTypes[i] = SinkEventAttributes.class;
1804 }
1805 }
1806
1807 if ( args != null )
1808 {
1809 for ( int i = args.length - 1; i >= 0; i-- )
1810 {
1811 if ( AttributeSet.class.isInstance( args[i] ) )
1812 {
1813 args[i] = new SinkEventAttributeSet( (AttributeSet) args[i] );
1814 }
1815 }
1816 }
1817
1818 Method target = Sink.class.getMethod( method.getName(), parameterTypes );
1819
1820 return target.invoke( sink, args );
1821 }
1822 }
1823 }