1 package org.apache.maven.tools.plugin.generator;
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.io.OutputStreamWriter;
25 import java.io.PrintWriter;
26 import java.io.Writer;
27 import java.net.URI;
28 import java.net.URISyntaxException;
29 import java.text.MessageFormat;
30 import java.util.ArrayList;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Locale;
34 import java.util.ResourceBundle;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37
38 import org.apache.maven.plugin.descriptor.MojoDescriptor;
39 import org.apache.maven.plugin.descriptor.Parameter;
40 import org.apache.maven.project.MavenProject;
41 import org.apache.maven.tools.plugin.EnhancedParameterWrapper;
42 import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
43 import org.apache.maven.tools.plugin.PluginToolsRequest;
44 import org.apache.maven.tools.plugin.javadoc.JavadocLinkGenerator;
45 import org.codehaus.plexus.util.StringUtils;
46 import org.codehaus.plexus.util.io.CachingOutputStream;
47 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
48 import org.codehaus.plexus.util.xml.XMLWriter;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import static java.nio.charset.StandardCharsets.UTF_8;
53
54
55
56
57 public class PluginXdocGenerator
58 implements Generator
59 {
60
61
62
63
64 private static final Pattern HTML_LINK_PATTERN = Pattern.compile( "<a href=\\\"([^\\\"]*)\\\">(.*?)</a>" );
65
66 private static final Logger LOG = LoggerFactory.getLogger( PluginXdocGenerator.class );
67
68
69
70
71 private final Locale locale;
72
73
74
75
76 private final MavenProject project;
77
78
79
80
81
82 private final File reportOutputDirectory;
83
84 private final boolean disableInternalJavadocLinkValidation;
85
86
87
88
89
90 public PluginXdocGenerator()
91 {
92 this( null );
93 }
94
95
96
97
98
99
100 public PluginXdocGenerator( MavenProject project )
101 {
102 this( project, Locale.ENGLISH, new File( "" ).getAbsoluteFile(), false );
103 }
104
105
106
107
108
109 public PluginXdocGenerator( MavenProject project, Locale locale, File reportOutputDirectory,
110 boolean disableInternalJavadocLinkValidation )
111 {
112 this.project = project;
113 if ( locale == null )
114 {
115 this.locale = Locale.ENGLISH;
116 }
117 else
118 {
119 this.locale = locale;
120 }
121 this.reportOutputDirectory = reportOutputDirectory;
122 this.disableInternalJavadocLinkValidation = disableInternalJavadocLinkValidation;
123 }
124
125
126
127
128
129 @Override
130 public void execute( File destinationDirectory, PluginToolsRequest request )
131 throws GeneratorException
132 {
133 try
134 {
135 if ( request.getPluginDescriptor().getMojos() != null )
136 {
137 List<MojoDescriptor> mojos = request.getPluginDescriptor().getMojos();
138 for ( MojoDescriptor descriptor : mojos )
139 {
140 processMojoDescriptor( descriptor, destinationDirectory );
141 }
142 }
143 }
144 catch ( IOException e )
145 {
146 throw new GeneratorException( e.getMessage(), e );
147 }
148
149 }
150
151
152
153
154
155
156 protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, File destinationDirectory )
157 throws IOException
158 {
159 File outputFile = new File( destinationDirectory, getMojoFilename( mojoDescriptor, "xml" ) );
160 try ( Writer writer = new OutputStreamWriter( new CachingOutputStream( outputFile ), UTF_8 ) )
161 {
162 XMLWriter w = new PrettyPrintXMLWriter( new PrintWriter( writer ), UTF_8.name(), null );
163 writeBody( mojoDescriptor, w );
164
165 writer.flush();
166 }
167 }
168
169
170
171
172
173
174 private String getMojoFilename( MojoDescriptor mojo, String ext )
175 {
176 return mojo.getGoal() + "-mojo." + ext;
177 }
178
179
180
181
182
183 private void writeBody( MojoDescriptor mojoDescriptor, XMLWriter w )
184 {
185 w.startElement( "document" );
186 w.addAttribute( "xmlns", "http://maven.apache.org/XDOC/2.0" );
187 w.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
188 w.addAttribute( "xsi:schemaLocation",
189 "http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd" );
190
191
192
193
194
195 w.startElement( "properties" );
196
197 w.startElement( "title" );
198 w.writeText( mojoDescriptor.getFullGoalName() );
199 w.endElement();
200
201 w.endElement();
202
203
204
205
206
207 w.startElement( "body" );
208
209 w.startElement( "section" );
210
211 w.addAttribute( "name", mojoDescriptor.getFullGoalName() );
212
213 writeReportNotice( mojoDescriptor, w );
214
215 w.startElement( "p" );
216 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.fullname" ) );
217 w.endElement();
218 w.startElement( "p" );
219 w.writeMarkup( mojoDescriptor.getPluginDescriptor().getGroupId() + ":"
220 + mojoDescriptor.getPluginDescriptor().getArtifactId() + ":"
221 + mojoDescriptor.getPluginDescriptor().getVersion() + ":" + mojoDescriptor.getGoal() );
222 w.endElement();
223
224 String context = "goal " + mojoDescriptor.getGoal();
225 if ( StringUtils.isNotEmpty( mojoDescriptor.getDeprecated() ) )
226 {
227 w.startElement( "p" );
228 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.deprecated" ) );
229 w.endElement();
230 w.startElement( "div" );
231 w.writeMarkup( getXhtmlWithValidatedLinks( mojoDescriptor.getDeprecated(), context ) );
232 w.endElement();
233 }
234
235 w.startElement( "p" );
236 w.writeMarkup( getString( "pluginxdoc.description" ) );
237 w.endElement();
238 w.startElement( "div" );
239 if ( StringUtils.isNotEmpty( mojoDescriptor.getDescription() ) )
240 {
241 w.writeMarkup( getXhtmlWithValidatedLinks( mojoDescriptor.getDescription(), context ) );
242 }
243 else
244 {
245 w.writeText( getString( "pluginxdoc.nodescription" ) );
246 }
247 w.endElement();
248
249 writeGoalAttributes( mojoDescriptor, w );
250
251 writeGoalParameterTable( mojoDescriptor, w );
252
253 w.endElement();
254
255 w.endElement();
256
257 w.endElement();
258 }
259
260
261
262
263
264 private void writeReportNotice( MojoDescriptor mojoDescriptor, XMLWriter w )
265 {
266 if ( GeneratorUtils.isMavenReport( mojoDescriptor.getImplementation(), project ) )
267 {
268 w.startElement( "p" );
269 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.notice.note" ) );
270 w.writeText( getString( "pluginxdoc.mojodescriptor.notice.isMavenReport" ) );
271 w.endElement();
272 }
273 }
274
275
276
277
278
279 private void writeGoalAttributes( MojoDescriptor mojoDescriptor, XMLWriter w )
280 {
281 w.startElement( "p" );
282 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.attributes" ) );
283 w.endElement();
284
285 boolean addedUl = false;
286 String value;
287 if ( mojoDescriptor.isProjectRequired() )
288 {
289 addedUl = addUl( w, addedUl );
290 w.startElement( "li" );
291 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.projectRequired" ) );
292 w.endElement();
293 }
294
295 if ( mojoDescriptor.isRequiresReports() )
296 {
297 addedUl = addUl( w, addedUl );
298 w.startElement( "li" );
299 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.reportingMojo" ) );
300 w.endElement();
301 }
302
303 if ( mojoDescriptor.isAggregator() )
304 {
305 addedUl = addUl( w, addedUl );
306 w.startElement( "li" );
307 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.aggregator" ) );
308 w.endElement();
309 }
310
311 if ( mojoDescriptor.isDirectInvocationOnly() )
312 {
313 addedUl = addUl( w, addedUl );
314 w.startElement( "li" );
315 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.directInvocationOnly" ) );
316 w.endElement();
317 }
318
319 value = mojoDescriptor.isDependencyResolutionRequired();
320 if ( StringUtils.isNotEmpty( value ) )
321 {
322 addedUl = addUl( w, addedUl );
323 w.startElement( "li" );
324 w.writeMarkup( format( "pluginxdoc.mojodescriptor.dependencyResolutionRequired", value ) );
325 w.endElement();
326 }
327
328 if ( mojoDescriptor instanceof ExtendedMojoDescriptor )
329 {
330 ExtendedMojoDescriptor extendedMojoDescriptor = (ExtendedMojoDescriptor) mojoDescriptor;
331
332 value = extendedMojoDescriptor.getDependencyCollectionRequired();
333 if ( StringUtils.isNotEmpty( value ) )
334 {
335 addedUl = addUl( w, addedUl );
336 w.startElement( "li" );
337 w.writeMarkup( format( "pluginxdoc.mojodescriptor.dependencyCollectionRequired", value ) );
338 w.endElement();
339 }
340 }
341
342 addedUl = addUl( w, addedUl );
343 w.startElement( "li" );
344 w.writeMarkup( getString( mojoDescriptor.isThreadSafe()
345 ? "pluginxdoc.mojodescriptor.threadSafe"
346 : "pluginxdoc.mojodescriptor.notThreadSafe" ) );
347 w.endElement();
348
349 value = mojoDescriptor.getSince();
350 if ( StringUtils.isNotEmpty( value ) )
351 {
352 addedUl = addUl( w, addedUl );
353 w.startElement( "li" );
354 w.writeMarkup( format( "pluginxdoc.mojodescriptor.since", value ) );
355 w.endElement();
356 }
357
358 value = mojoDescriptor.getPhase();
359 if ( StringUtils.isNotEmpty( value ) )
360 {
361 addedUl = addUl( w, addedUl );
362 w.startElement( "li" );
363 w.writeMarkup( format( "pluginxdoc.mojodescriptor.phase", value ) );
364 w.endElement();
365 }
366
367 value = mojoDescriptor.getExecutePhase();
368 if ( StringUtils.isNotEmpty( value ) )
369 {
370 addedUl = addUl( w, addedUl );
371 w.startElement( "li" );
372 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executePhase", value ) );
373 w.endElement();
374 }
375
376 value = mojoDescriptor.getExecuteGoal();
377 if ( StringUtils.isNotEmpty( value ) )
378 {
379 addedUl = addUl( w, addedUl );
380 w.startElement( "li" );
381 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executeGoal", value ) );
382 w.endElement();
383 }
384
385 value = mojoDescriptor.getExecuteLifecycle();
386 if ( StringUtils.isNotEmpty( value ) )
387 {
388 addedUl = addUl( w, addedUl );
389 w.startElement( "li" );
390 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executeLifecycle", value ) );
391 w.endElement();
392 }
393
394 if ( mojoDescriptor.isOnlineRequired() )
395 {
396 addedUl = addUl( w, addedUl );
397 w.startElement( "li" );
398 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.onlineRequired" ) );
399 w.endElement();
400 }
401
402 if ( !mojoDescriptor.isInheritedByDefault() )
403 {
404 addedUl = addUl( w, addedUl );
405 w.startElement( "li" );
406 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.inheritedByDefault" ) );
407 w.endElement();
408 }
409
410 if ( addedUl )
411 {
412 w.endElement();
413 }
414 }
415
416
417
418
419
420 private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w )
421 {
422 List<Parameter> parameterList = mojoDescriptor.getParameters();
423
424
425 List<Parameter> list = filterParameters( parameterList );
426
427 if ( !list.isEmpty() )
428 {
429 writeParameterSummary( list, w, mojoDescriptor.getGoal() );
430 writeParameterDetails( list, w, mojoDescriptor.getGoal() );
431 }
432 else
433 {
434 w.startElement( "subsection" );
435 w.addAttribute( "name", getString( "pluginxdoc.mojodescriptor.parameters" ) );
436
437 w.startElement( "p" );
438 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.noParameter" ) );
439 w.endElement();
440
441 w.endElement();
442 }
443 }
444
445
446
447
448
449
450
451 private List<Parameter> filterParameters( List<Parameter> parameterList )
452 {
453 List<Parameter> filtered = new ArrayList<>();
454
455 if ( parameterList != null )
456 {
457 for ( Parameter parameter : parameterList )
458 {
459 if ( parameter.isEditable() )
460 {
461 String expression = parameter.getExpression();
462
463 if ( expression == null || !expression.startsWith( "${component." ) )
464 {
465 filtered.add( parameter );
466 }
467 }
468 }
469 }
470
471 return filtered;
472 }
473
474
475
476
477
478 private void writeParameterDetails( List<Parameter> parameterList, XMLWriter w, String goal )
479 {
480 w.startElement( "subsection" );
481 w.addAttribute( "name", getString( "pluginxdoc.mojodescriptor.parameter.details" ) );
482
483 for ( Iterator<Parameter> parameters = parameterList.iterator(); parameters.hasNext(); )
484 {
485 Parameter parameter = parameters.next();
486
487 w.startElement( "h4" );
488 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.name_internal", parameter.getName() ) );
489 w.endElement();
490
491 String context = "Parameter " + parameter.getName() + " in goal " + goal;
492 if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) )
493 {
494 w.startElement( "div" );
495 String deprecated = getXhtmlWithValidatedLinks( parameter.getDeprecated(), context );
496 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.deprecated", deprecated ) );
497 w.endElement();
498 }
499
500 w.startElement( "div" );
501 if ( StringUtils.isNotEmpty( parameter.getDescription() ) )
502 {
503
504 w.writeMarkup( getXhtmlWithValidatedLinks( parameter.getDescription(), context ) );
505 }
506 else
507 {
508 w.writeMarkup( getString( "pluginxdoc.nodescription" ) );
509 }
510 w.endElement();
511
512 boolean addedUl = false;
513 addedUl = addUl( w, addedUl, parameter.getType() );
514 String typeValue = getLinkedType( parameter, false );
515 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.type" ), typeValue, w );
516
517 if ( StringUtils.isNotEmpty( parameter.getSince() ) )
518 {
519 addedUl = addUl( w, addedUl );
520 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), parameter.getSince(), w );
521 }
522
523 if ( parameter.isRequired() )
524 {
525 addedUl = addUl( w, addedUl );
526 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.yes" ),
527 w );
528 }
529 else
530 {
531 addedUl = addUl( w, addedUl );
532 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.no" ),
533 w );
534 }
535
536 String expression = parameter.getExpression();
537 addedUl = addUl( w, addedUl, expression );
538 String property = getPropertyFromExpression( expression );
539 if ( property == null )
540 {
541 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.expression" ), expression, w );
542 }
543 else
544 {
545 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.property" ), property, w );
546 }
547
548 addedUl = addUl( w, addedUl, parameter.getDefaultValue() );
549 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.default" ),
550 escapeXml( parameter.getDefaultValue() ), w );
551
552 addedUl = addUl( w, addedUl, parameter.getAlias() );
553 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.alias" ), escapeXml( parameter.getAlias() ),
554 w );
555
556 if ( addedUl )
557 {
558 w.endElement();
559 }
560
561 if ( parameters.hasNext() )
562 {
563 w.writeMarkup( "<hr/>" );
564 }
565 }
566
567 w.endElement();
568 }
569
570 static String getShortType( String type )
571 {
572
573 int startTypeArguments = type.indexOf( '<' );
574 if ( startTypeArguments == -1 )
575 {
576 return getShortTypeOfSimpleType( type );
577 }
578 else
579 {
580 StringBuilder shortType = new StringBuilder();
581 shortType.append( getShortTypeOfSimpleType( type.substring( 0, startTypeArguments ) ) );
582 shortType.append( "<" )
583 .append( getShortTypeOfTypeArgument(
584 type.substring( startTypeArguments + 1, type.lastIndexOf( ">" ) ) ) )
585 .append( ">" );
586 return shortType.toString();
587 }
588
589 }
590
591 private static String getShortTypeOfTypeArgument( String type )
592 {
593 String[] typeArguments = type.split( ",\\s*" );
594 StringBuilder shortType = new StringBuilder();
595 for ( int i = 0; i < typeArguments.length; i++ )
596 {
597 String typeArgument = typeArguments[i];
598 if ( typeArgument.contains( "<" ) )
599 {
600
601 return "...";
602 }
603 else
604 {
605 shortType.append( getShortTypeOfSimpleType( typeArgument ) );
606 if ( i < typeArguments.length - 1 )
607 {
608 shortType.append( "," );
609 }
610 }
611 }
612 return shortType.toString();
613 }
614
615 private static String getShortTypeOfSimpleType( String type )
616 {
617 int index = type.lastIndexOf( '.' );
618 return type.substring( index + 1 );
619 }
620
621 private String getLinkedType( Parameter parameter, boolean isShortType )
622 {
623 final String typeValue;
624 if ( isShortType )
625 {
626 typeValue = getShortType( parameter.getType() );
627 }
628 else
629 {
630 typeValue = parameter.getType();
631 }
632 if ( parameter instanceof EnhancedParameterWrapper )
633 {
634 EnhancedParameterWrapper enhancedParameter = (EnhancedParameterWrapper) parameter;
635 if ( enhancedParameter.getTypeJavadocUrl() != null )
636 {
637 URI javadocUrl = enhancedParameter.getTypeJavadocUrl();
638
639 if ( javadocUrl.isAbsolute()
640 || disableInternalJavadocLinkValidation
641 || JavadocLinkGenerator.isLinkValid( javadocUrl, reportOutputDirectory.toPath() ) )
642 {
643 return format( "pluginxdoc.mojodescriptor.parameter.type_link",
644 new Object[] { escapeXml( typeValue ), enhancedParameter.getTypeJavadocUrl() } );
645 }
646 }
647 }
648 return escapeXml( typeValue );
649 }
650
651 private boolean addUl( XMLWriter w, boolean addedUl, String content )
652 {
653 if ( StringUtils.isNotEmpty( content ) )
654 {
655 return addUl( w, addedUl );
656 }
657 return addedUl;
658 }
659
660 private boolean addUl( XMLWriter w, boolean addedUl )
661 {
662 if ( !addedUl )
663 {
664 w.startElement( "ul" );
665 addedUl = true;
666 }
667 return addedUl;
668 }
669
670 private String getPropertyFromExpression( String expression )
671 {
672 if ( StringUtils.isNotEmpty( expression ) && expression.startsWith( "${" ) && expression.endsWith( "}" )
673 && !expression.substring( 2 ).contains( "${" ) )
674 {
675
676 return expression.substring( 2, expression.length() - 1 );
677 }
678
679 return null;
680 }
681
682
683
684
685
686
687 private void writeDetail( String param, String value, XMLWriter w )
688 {
689 if ( StringUtils.isNotEmpty( value ) )
690 {
691 w.startElement( "li" );
692 w.writeMarkup( format( "pluginxdoc.detail", new String[]{ param, value } ) );
693 w.endElement();
694 }
695 }
696
697
698
699
700
701 private void writeParameterSummary( List<Parameter> parameterList, XMLWriter w, String goal )
702 {
703 List<Parameter> requiredParams = getParametersByRequired( true, parameterList );
704 if ( !requiredParams.isEmpty() )
705 {
706 writeParameterList( getString( "pluginxdoc.mojodescriptor.requiredParameters" ),
707 requiredParams, w, goal );
708 }
709
710 List<Parameter> optionalParams = getParametersByRequired( false, parameterList );
711 if ( !optionalParams.isEmpty() )
712 {
713 writeParameterList( getString( "pluginxdoc.mojodescriptor.optionalParameters" ),
714 optionalParams, w, goal );
715 }
716 }
717
718
719
720
721
722
723 private void writeParameterList( String title, List<Parameter> parameterList, XMLWriter w, String goal )
724 {
725 w.startElement( "subsection" );
726 w.addAttribute( "name", title );
727
728 w.startElement( "table" );
729 w.addAttribute( "border", "0" );
730
731 w.startElement( "tr" );
732 w.startElement( "th" );
733 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.name" ) );
734 w.endElement();
735 w.startElement( "th" );
736 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.type" ) );
737 w.endElement();
738 w.startElement( "th" );
739 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.since" ) );
740 w.endElement();
741 w.startElement( "th" );
742 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.description" ) );
743 w.endElement();
744 w.endElement();
745
746 for ( Parameter parameter : parameterList )
747 {
748 w.startElement( "tr" );
749
750
751 w.startElement( "td" );
752 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.name_link", parameter.getName() ) );
753 w.endElement();
754
755
756 w.startElement( "td" );
757 w.writeMarkup( "<code>" + getLinkedType( parameter, true ) + "</code>" );
758 w.endElement();
759
760
761 w.startElement( "td" );
762 if ( StringUtils.isNotEmpty( parameter.getSince() ) )
763 {
764 w.writeMarkup( "<code>" + parameter.getSince() + "</code>" );
765 }
766 else
767 {
768 w.writeMarkup( "<code>-</code>" );
769 }
770 w.endElement();
771
772
773 w.startElement( "td" );
774 String description;
775 String context = "Parameter " + parameter.getName() + " in goal " + goal;
776 if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) )
777 {
778 String deprecated = getXhtmlWithValidatedLinks( parameter.getDescription(), context );
779 description = format( "pluginxdoc.mojodescriptor.parameter.deprecated", deprecated );
780 }
781 else if ( StringUtils.isNotEmpty( parameter.getDescription() ) )
782 {
783 description = getXhtmlWithValidatedLinks( parameter.getDescription(), context );
784 }
785 else
786 {
787 description = getString( "pluginxdoc.nodescription" );
788 }
789 w.writeMarkup( description + "<br/>" );
790
791 if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) )
792 {
793 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.defaultValue",
794 escapeXml( parameter.getDefaultValue() ) ) );
795 w.writeMarkup( "<br/>" );
796 }
797
798 String property = getPropertyFromExpression( parameter.getExpression() );
799 if ( property != null )
800 {
801 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.property.description", property ) );
802 w.writeMarkup( "<br/>" );
803 }
804
805 if ( StringUtils.isNotEmpty( parameter.getAlias() ) )
806 {
807 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.alias.description",
808 escapeXml( parameter.getAlias() ) ) );
809 }
810
811 w.endElement();
812 w.endElement();
813 }
814
815 w.endElement();
816 w.endElement();
817 }
818
819
820
821
822
823
824 private List<Parameter> getParametersByRequired( boolean required, List<Parameter> parameterList )
825 {
826 List<Parameter> list = new ArrayList<>();
827
828 for ( Parameter parameter : parameterList )
829 {
830 if ( parameter.isRequired() == required )
831 {
832 list.add( parameter );
833 }
834 }
835
836 return list;
837 }
838
839
840
841
842
843
844 private ResourceBundle getBundle()
845 {
846 return ResourceBundle.getBundle( "pluginxdoc", locale, getClass().getClassLoader() );
847 }
848
849
850
851
852
853
854 private String getString( String key )
855 {
856 return getBundle().getString( key );
857 }
858
859
860
861
862
863
864
865
866
867 private String format( String key, Object arg1 )
868 {
869 return format( key, new Object[]{ arg1 } );
870 }
871
872
873
874
875
876
877
878
879
880 private String format( String key, Object[] args )
881 {
882 String pattern = getString( key );
883
884 pattern = StringUtils.replace( pattern, "'", "''" );
885
886 MessageFormat messageFormat = new MessageFormat( "" );
887 messageFormat.setLocale( locale );
888 messageFormat.applyPattern( pattern );
889
890 return messageFormat.format( args );
891 }
892
893
894
895
896
897 private String escapeXml( String text )
898 {
899 if ( text != null )
900 {
901 text = text.replace( "&", "&" );
902 text = text.replace( "<", "<" );
903 text = text.replace( ">", ">" );
904 text = text.replace( "\"", """ );
905 text = text.replace( "\'", "'" );
906 }
907 return text;
908 }
909
910 String getXhtmlWithValidatedLinks( String xhtmlText, String context )
911 {
912 if ( disableInternalJavadocLinkValidation )
913 {
914 return xhtmlText;
915 }
916 StringBuffer sanitizedXhtmlText = new StringBuffer();
917
918 Matcher matcher = HTML_LINK_PATTERN.matcher( xhtmlText );
919 while ( matcher.find() )
920 {
921 URI link;
922 try
923 {
924 link = new URI( matcher.group( 1 ) );
925 if ( !link.isAbsolute() && !JavadocLinkGenerator.isLinkValid( link, reportOutputDirectory.toPath() ) )
926 {
927 matcher.appendReplacement( sanitizedXhtmlText, matcher.group( 2 ) );
928 LOG.debug( "Removed invalid link {} in {}", link, context );
929 }
930 else
931 {
932 matcher.appendReplacement( sanitizedXhtmlText, matcher.group( 0 ) );
933 }
934 }
935 catch ( URISyntaxException e )
936 {
937 LOG.warn( "Invalid URI {} found in {}. Cannot validate, leave untouched", matcher.group( 1 ), context );
938 matcher.appendReplacement( sanitizedXhtmlText, matcher.group( 0 ) );
939 }
940 }
941 matcher.appendTail( sanitizedXhtmlText );
942 return sanitizedXhtmlText.toString();
943 }
944 }