001package org.apache.maven.tools.plugin.generator; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import static java.nio.charset.StandardCharsets.UTF_8; 023 024import org.apache.maven.plugin.descriptor.MojoDescriptor; 025import org.apache.maven.plugin.descriptor.Parameter; 026import org.apache.maven.project.MavenProject; 027import org.apache.maven.tools.plugin.ExtendedMojoDescriptor; 028import org.apache.maven.tools.plugin.PluginToolsRequest; 029import org.codehaus.plexus.util.StringUtils; 030import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; 031import org.codehaus.plexus.util.xml.XMLWriter; 032 033import java.io.File; 034import java.io.FileOutputStream; 035import java.io.IOException; 036import java.io.OutputStreamWriter; 037import java.io.PrintWriter; 038import java.io.Writer; 039import java.text.MessageFormat; 040import java.util.ArrayList; 041import java.util.Iterator; 042import java.util.List; 043import java.util.Locale; 044import java.util.ResourceBundle; 045 046/** 047 * Generate xdoc documentation for each mojo. 048 */ 049public class PluginXdocGenerator 050 implements Generator 051{ 052 /** 053 * locale 054 */ 055 private final Locale locale; 056 057 /** 058 * project 059 */ 060 private final MavenProject project; 061 062 /** 063 * Default constructor using <code>Locale.ENGLISH</code> as locale. 064 * Used only in test cases. 065 */ 066 public PluginXdocGenerator() 067 { 068 this.project = null; 069 this.locale = Locale.ENGLISH; 070 } 071 072 /** 073 * Constructor using <code>Locale.ENGLISH</code> as locale. 074 * 075 * @param project not null Maven project. 076 */ 077 public PluginXdocGenerator( MavenProject project ) 078 { 079 this.project = project; 080 this.locale = Locale.ENGLISH; 081 } 082 083 /** 084 * @param project not null. 085 * @param locale not null wanted locale. 086 */ 087 public PluginXdocGenerator( MavenProject project, Locale locale ) 088 { 089 this.project = project; 090 if ( locale == null ) 091 { 092 this.locale = Locale.ENGLISH; 093 } 094 else 095 { 096 this.locale = locale; 097 } 098 } 099 100 101 /** 102 * {@inheritDoc} 103 */ 104 @Override 105 public void execute( File destinationDirectory, PluginToolsRequest request ) 106 throws GeneratorException 107 { 108 try 109 { 110 if ( request.getPluginDescriptor().getMojos() != null ) 111 { 112 @SuppressWarnings( "unchecked" ) List<MojoDescriptor> mojos = request.getPluginDescriptor().getMojos(); 113 114 for ( MojoDescriptor descriptor : mojos ) 115 { 116 processMojoDescriptor( descriptor, destinationDirectory ); 117 } 118 } 119 } 120 catch ( IOException e ) 121 { 122 throw new GeneratorException( e.getMessage(), e ); 123 } 124 125 } 126 127 /** 128 * @param mojoDescriptor not null 129 * @param destinationDirectory not null 130 * @throws IOException if any 131 */ 132 protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, File destinationDirectory ) 133 throws IOException 134 { 135 File outputFile = new File( destinationDirectory, getMojoFilename( mojoDescriptor, "xml" ) ); 136 try ( Writer writer = new OutputStreamWriter( new FileOutputStream( outputFile ), UTF_8 ) ) 137 { 138 XMLWriter w = new PrettyPrintXMLWriter( new PrintWriter( writer ), UTF_8.name(), null ); 139 writeBody( mojoDescriptor, w ); 140 141 writer.flush(); 142 } 143 } 144 145 /** 146 * @param mojo not null 147 * @param ext not null 148 * @return the output file name 149 */ 150 private String getMojoFilename( MojoDescriptor mojo, String ext ) 151 { 152 return mojo.getGoal() + "-mojo." + ext; 153 } 154 155 /** 156 * @param mojoDescriptor not null 157 * @param w not null 158 */ 159 private void writeBody( MojoDescriptor mojoDescriptor, XMLWriter w ) 160 { 161 w.startElement( "document" ); 162 w.addAttribute( "xmlns", "http://maven.apache.org/XDOC/2.0" ); 163 w.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" ); 164 w.addAttribute( "xsi:schemaLocation", 165 "http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd" ); 166 167 // ---------------------------------------------------------------------- 168 // 169 // ---------------------------------------------------------------------- 170 171 w.startElement( "properties" ); 172 173 w.startElement( "title" ); 174 w.writeText( mojoDescriptor.getFullGoalName() ); 175 w.endElement(); // title 176 177 w.endElement(); // properties 178 179 // ---------------------------------------------------------------------- 180 // 181 // ---------------------------------------------------------------------- 182 183 w.startElement( "body" ); 184 185 w.startElement( "section" ); 186 187 w.addAttribute( "name", mojoDescriptor.getFullGoalName() ); 188 189 writeReportNotice( mojoDescriptor, w ); 190 191 w.startElement( "p" ); 192 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.fullname" ) ); 193 w.endElement(); //p 194 w.startElement( "p" ); 195 w.writeMarkup( mojoDescriptor.getPluginDescriptor().getGroupId() + ":" 196 + mojoDescriptor.getPluginDescriptor().getArtifactId() + ":" 197 + mojoDescriptor.getPluginDescriptor().getVersion() + ":" + mojoDescriptor.getGoal() ); 198 w.endElement(); //p 199 200 if ( StringUtils.isNotEmpty( mojoDescriptor.getDeprecated() ) ) 201 { 202 w.startElement( "p" ); 203 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.deprecated" ) ); 204 w.endElement(); // p 205 w.startElement( "div" ); 206 w.writeMarkup( GeneratorUtils.makeHtmlValid( mojoDescriptor.getDeprecated() ) ); 207 w.endElement(); // div 208 } 209 210 w.startElement( "p" ); 211 w.writeMarkup( getString( "pluginxdoc.description" ) ); 212 w.endElement(); //p 213 w.startElement( "div" ); 214 if ( StringUtils.isNotEmpty( mojoDescriptor.getDescription() ) ) 215 { 216 w.writeMarkup( GeneratorUtils.makeHtmlValid( mojoDescriptor.getDescription() ) ); 217 } 218 else 219 { 220 w.writeText( getString( "pluginxdoc.nodescription" ) ); 221 } 222 w.endElement(); // div 223 224 writeGoalAttributes( mojoDescriptor, w ); 225 226 writeGoalParameterTable( mojoDescriptor, w ); 227 228 w.endElement(); // section 229 230 w.endElement(); // body 231 232 w.endElement(); // document 233 } 234 235 /** 236 * @param mojoDescriptor not null 237 * @param w not null 238 */ 239 private void writeReportNotice( MojoDescriptor mojoDescriptor, XMLWriter w ) 240 { 241 if ( GeneratorUtils.isMavenReport( mojoDescriptor.getImplementation(), project ) ) 242 { 243 w.startElement( "p" ); 244 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.notice.note" ) ); 245 w.writeText( getString( "pluginxdoc.mojodescriptor.notice.isMavenReport" ) ); 246 w.endElement(); //p 247 } 248 } 249 250 /** 251 * @param mojoDescriptor not null 252 * @param w not null 253 */ 254 private void writeGoalAttributes( MojoDescriptor mojoDescriptor, XMLWriter w ) 255 { 256 w.startElement( "p" ); 257 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.attributes" ) ); 258 w.endElement(); //p 259 260 boolean addedUl = false; 261 String value; 262 if ( mojoDescriptor.isProjectRequired() ) 263 { 264 addedUl = addUl( w, addedUl ); 265 w.startElement( "li" ); 266 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.projectRequired" ) ); 267 w.endElement(); //li 268 } 269 270 if ( mojoDescriptor.isRequiresReports() ) 271 { 272 addedUl = addUl( w, addedUl ); 273 w.startElement( "li" ); 274 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.reportingMojo" ) ); 275 w.endElement(); // li 276 } 277 278 if ( mojoDescriptor.isAggregator() ) 279 { 280 addedUl = addUl( w, addedUl ); 281 w.startElement( "li" ); 282 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.aggregator" ) ); 283 w.endElement(); //li 284 } 285 286 if ( mojoDescriptor.isDirectInvocationOnly() ) 287 { 288 addedUl = addUl( w, addedUl ); 289 w.startElement( "li" ); 290 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.directInvocationOnly" ) ); 291 w.endElement(); //li 292 } 293 294 value = mojoDescriptor.isDependencyResolutionRequired(); 295 if ( StringUtils.isNotEmpty( value ) ) 296 { 297 addedUl = addUl( w, addedUl ); 298 w.startElement( "li" ); 299 w.writeMarkup( format( "pluginxdoc.mojodescriptor.dependencyResolutionRequired", value ) ); 300 w.endElement(); //li 301 } 302 303 if ( mojoDescriptor instanceof ExtendedMojoDescriptor ) 304 { 305 ExtendedMojoDescriptor extendedMojoDescriptor = (ExtendedMojoDescriptor) mojoDescriptor; 306 307 value = extendedMojoDescriptor.getDependencyCollectionRequired(); 308 if ( StringUtils.isNotEmpty( value ) ) 309 { 310 addedUl = addUl( w, addedUl ); 311 w.startElement( "li" ); 312 w.writeMarkup( format( "pluginxdoc.mojodescriptor.dependencyCollectionRequired", value ) ); 313 w.endElement(); //li 314 } 315 316 if ( extendedMojoDescriptor.isThreadSafe() ) 317 { 318 addedUl = addUl( w, addedUl ); 319 w.startElement( "li" ); 320 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.threadSafe" ) ); 321 w.endElement(); //li 322 } 323 324 } 325 326 value = mojoDescriptor.getSince(); 327 if ( StringUtils.isNotEmpty( value ) ) 328 { 329 addedUl = addUl( w, addedUl ); 330 w.startElement( "li" ); 331 w.writeMarkup( format( "pluginxdoc.mojodescriptor.since", value ) ); 332 w.endElement(); //li 333 } 334 335 value = mojoDescriptor.getPhase(); 336 if ( StringUtils.isNotEmpty( value ) ) 337 { 338 addedUl = addUl( w, addedUl ); 339 w.startElement( "li" ); 340 w.writeMarkup( format( "pluginxdoc.mojodescriptor.phase", value ) ); 341 w.endElement(); //li 342 } 343 344 value = mojoDescriptor.getExecutePhase(); 345 if ( StringUtils.isNotEmpty( value ) ) 346 { 347 addedUl = addUl( w, addedUl ); 348 w.startElement( "li" ); 349 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executePhase", value ) ); 350 w.endElement(); //li 351 } 352 353 value = mojoDescriptor.getExecuteGoal(); 354 if ( StringUtils.isNotEmpty( value ) ) 355 { 356 addedUl = addUl( w, addedUl ); 357 w.startElement( "li" ); 358 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executeGoal", value ) ); 359 w.endElement(); //li 360 } 361 362 value = mojoDescriptor.getExecuteLifecycle(); 363 if ( StringUtils.isNotEmpty( value ) ) 364 { 365 addedUl = addUl( w, addedUl ); 366 w.startElement( "li" ); 367 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executeLifecycle", value ) ); 368 w.endElement(); //li 369 } 370 371 if ( mojoDescriptor.isOnlineRequired() ) 372 { 373 addedUl = addUl( w, addedUl ); 374 w.startElement( "li" ); 375 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.onlineRequired" ) ); 376 w.endElement(); //li 377 } 378 379 if ( !mojoDescriptor.isInheritedByDefault() ) 380 { 381 addedUl = addUl( w, addedUl ); 382 w.startElement( "li" ); 383 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.inheritedByDefault" ) ); 384 w.endElement(); //li 385 } 386 387 if ( addedUl ) 388 { 389 w.endElement(); //ul 390 } 391 } 392 393 /** 394 * @param mojoDescriptor not null 395 * @param w not null 396 */ 397 private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w ) 398 { 399 List<Parameter> parameterList = mojoDescriptor.getParameters(); 400 401 // remove components and read-only parameters 402 List<Parameter> list = filterParameters( parameterList ); 403 404 if ( !list.isEmpty() ) 405 { 406 writeParameterSummary( mojoDescriptor, list, w ); 407 408 writeParameterDetails( mojoDescriptor, list, w ); 409 } 410 else 411 { 412 w.startElement( "subsection" ); 413 w.addAttribute( "name", getString( "pluginxdoc.mojodescriptor.parameters" ) ); 414 415 w.startElement( "p" ); 416 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.noParameter" ) ); 417 w.endElement(); //p 418 419 w.endElement(); 420 } 421 } 422 423 /** 424 * Filter parameters to only retain those which must be documented, ie not components nor readonly. 425 * 426 * @param parameterList not null 427 * @return the parameters list without components. 428 */ 429 private List<Parameter> filterParameters( List<Parameter> parameterList ) 430 { 431 List<Parameter> filtered = new ArrayList<>(); 432 433 if ( parameterList != null ) 434 { 435 for ( Parameter parameter : parameterList ) 436 { 437 if ( parameter.isEditable() ) 438 { 439 String expression = parameter.getExpression(); 440 441 if ( expression == null || !expression.startsWith( "${component." ) ) 442 { 443 filtered.add( parameter ); 444 } 445 } 446 } 447 } 448 449 return filtered; 450 } 451 452 /** 453 * @param mojoDescriptor not null 454 * @param parameterList not null 455 * @param w not null 456 */ 457 private void writeParameterDetails( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w ) 458 { 459 w.startElement( "subsection" ); 460 w.addAttribute( "name", getString( "pluginxdoc.mojodescriptor.parameter.details" ) ); 461 462 for ( Iterator<Parameter> parameters = parameterList.iterator(); parameters.hasNext(); ) 463 { 464 Parameter parameter = parameters.next(); 465 466 w.startElement( "h4" ); 467 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.name_internal", parameter.getName() ) ); 468 w.endElement(); 469 470 if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) ) 471 { 472 w.startElement( "div" ); 473 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.deprecated", 474 GeneratorUtils.makeHtmlValid( parameter.getDeprecated() ) ) ); 475 w.endElement(); // div 476 } 477 478 w.startElement( "div" ); 479 if ( StringUtils.isNotEmpty( parameter.getDescription() ) ) 480 { 481 w.writeMarkup( GeneratorUtils.makeHtmlValid( parameter.getDescription() ) ); 482 } 483 else 484 { 485 w.writeMarkup( getString( "pluginxdoc.nodescription" ) ); 486 } 487 w.endElement(); // div 488 489 boolean addedUl = false; 490 addedUl = addUl( w, addedUl, parameter.getType() ); 491 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.type" ), parameter.getType(), w ); 492 493 if ( StringUtils.isNotEmpty( parameter.getSince() ) ) 494 { 495 addedUl = addUl( w, addedUl ); 496 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), parameter.getSince(), w ); 497 } 498 else 499 { 500 if ( StringUtils.isNotEmpty( mojoDescriptor.getSince() ) ) 501 { 502 addedUl = addUl( w, addedUl ); 503 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), mojoDescriptor.getSince(), 504 w ); 505 } 506 } 507 508 if ( parameter.isRequired() ) 509 { 510 addedUl = addUl( w, addedUl ); 511 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.yes" ), 512 w ); 513 } 514 else 515 { 516 addedUl = addUl( w, addedUl ); 517 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.no" ), 518 w ); 519 } 520 521 String expression = parameter.getExpression(); 522 addedUl = addUl( w, addedUl, expression ); 523 String property = getPropertyFromExpression( expression ); 524 if ( property == null ) 525 { 526 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.expression" ), expression, w ); 527 } 528 else 529 { 530 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.property" ), property, w ); 531 } 532 533 addedUl = addUl( w, addedUl, parameter.getDefaultValue() ); 534 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.default" ), 535 escapeXml( parameter.getDefaultValue() ), w ); 536 537 addedUl = addUl( w, addedUl, parameter.getAlias() ); 538 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.alias" ), escapeXml( parameter.getAlias() ), 539 w ); 540 541 if ( addedUl ) 542 { 543 w.endElement(); //ul 544 } 545 546 if ( parameters.hasNext() ) 547 { 548 w.writeMarkup( "<hr/>" ); 549 } 550 } 551 552 w.endElement(); 553 } 554 555 private boolean addUl( XMLWriter w, boolean addedUl, String content ) 556 { 557 if ( StringUtils.isNotEmpty( content ) ) 558 { 559 return addUl( w, addedUl ); 560 } 561 return addedUl; 562 } 563 564 private boolean addUl( XMLWriter w, boolean addedUl ) 565 { 566 if ( !addedUl ) 567 { 568 w.startElement( "ul" ); 569 addedUl = true; 570 } 571 return addedUl; 572 } 573 574 private String getPropertyFromExpression( String expression ) 575 { 576 if ( StringUtils.isNotEmpty( expression ) && expression.startsWith( "${" ) && expression.endsWith( "}" ) 577 && !expression.substring( 2 ).contains( "${" ) ) 578 { 579 // expression="${xxx}" -> property="xxx" 580 return expression.substring( 2, expression.length() - 1 ); 581 } 582 // no property can be extracted 583 return null; 584 } 585 586 /** 587 * @param param not null 588 * @param value could be null 589 * @param w not null 590 */ 591 private void writeDetail( String param, String value, XMLWriter w ) 592 { 593 if ( StringUtils.isNotEmpty( value ) ) 594 { 595 w.startElement( "li" ); 596 w.writeMarkup( format( "pluginxdoc.detail", new String[]{ param, value } ) ); 597 w.endElement(); //li 598 } 599 } 600 601 /** 602 * @param mojoDescriptor not null 603 * @param parameterList not null 604 * @param w not null 605 */ 606 private void writeParameterSummary( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w ) 607 { 608 List<Parameter> requiredParams = getParametersByRequired( true, parameterList ); 609 if ( requiredParams.size() > 0 ) 610 { 611 writeParameterList( mojoDescriptor, getString( "pluginxdoc.mojodescriptor.requiredParameters" ), 612 requiredParams, w ); 613 } 614 615 List<Parameter> optionalParams = getParametersByRequired( false, parameterList ); 616 if ( optionalParams.size() > 0 ) 617 { 618 writeParameterList( mojoDescriptor, getString( "pluginxdoc.mojodescriptor.optionalParameters" ), 619 optionalParams, w ); 620 } 621 } 622 623 /** 624 * @param mojoDescriptor not null 625 * @param title not null 626 * @param parameterList not null 627 * @param w not null 628 */ 629 private void writeParameterList( MojoDescriptor mojoDescriptor, String title, List<Parameter> parameterList, 630 XMLWriter w ) 631 { 632 w.startElement( "subsection" ); 633 w.addAttribute( "name", title ); 634 635 w.startElement( "table" ); 636 w.addAttribute( "border", "0" ); 637 638 w.startElement( "tr" ); 639 w.startElement( "th" ); 640 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.name" ) ); 641 w.endElement(); //th 642 w.startElement( "th" ); 643 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.type" ) ); 644 w.endElement(); //th 645 w.startElement( "th" ); 646 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.since" ) ); 647 w.endElement(); //th 648 w.startElement( "th" ); 649 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.description" ) ); 650 w.endElement(); //th 651 w.endElement(); //tr 652 653 for ( Parameter parameter : parameterList ) 654 { 655 w.startElement( "tr" ); 656 657 // name 658 w.startElement( "td" ); 659 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.name_link", parameter.getName() ) ); 660 w.endElement(); //td 661 662 //type 663 w.startElement( "td" ); 664 int index = parameter.getType().lastIndexOf( "." ); 665 w.writeMarkup( "<code>" + parameter.getType().substring( index + 1 ) + "</code>" ); 666 w.endElement(); //td 667 668 // since 669 w.startElement( "td" ); 670 if ( StringUtils.isNotEmpty( parameter.getSince() ) ) 671 { 672 w.writeMarkup( "<code>" + parameter.getSince() + "</code>" ); 673 } 674 else 675 { 676 if ( StringUtils.isNotEmpty( mojoDescriptor.getSince() ) ) 677 { 678 w.writeMarkup( "<code>" + mojoDescriptor.getSince() + "</code>" ); 679 } 680 else 681 { 682 w.writeMarkup( "<code>-</code>" ); 683 } 684 } 685 w.endElement(); //td 686 687 // description 688 w.startElement( "td" ); 689 String description; 690 if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) ) 691 { 692 description = format( "pluginxdoc.mojodescriptor.parameter.deprecated", 693 GeneratorUtils.makeHtmlValid( parameter.getDeprecated() ) ); 694 } 695 else if ( StringUtils.isNotEmpty( parameter.getDescription() ) ) 696 { 697 description = GeneratorUtils.makeHtmlValid( parameter.getDescription() ); 698 } 699 else 700 { 701 description = getString( "pluginxdoc.nodescription" ); 702 } 703 w.writeMarkup( description + "<br/>" ); 704 705 if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) ) 706 { 707 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.defaultValue", 708 escapeXml( parameter.getDefaultValue() ) ) ); 709 w.writeMarkup( "<br/>" ); 710 } 711 712 String property = getPropertyFromExpression( parameter.getExpression() ); 713 if ( property != null ) 714 { 715 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.property.description", property ) ); 716 w.writeMarkup( "<br/>" ); 717 } 718 719 if ( StringUtils.isNotEmpty( parameter.getAlias() ) ) 720 { 721 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.alias.description", 722 escapeXml( parameter.getAlias() ) ) ); 723 } 724 725 w.endElement(); //td 726 w.endElement(); //tr 727 } 728 729 w.endElement(); //table 730 w.endElement(); //section 731 } 732 733 /** 734 * @param required <code>true</code> for required parameters, <code>false</code> otherwise. 735 * @param parameterList not null 736 * @return list of parameters depending the value of <code>required</code> 737 */ 738 private List<Parameter> getParametersByRequired( boolean required, List<Parameter> parameterList ) 739 { 740 List<Parameter> list = new ArrayList<>(); 741 742 for ( Parameter parameter : parameterList ) 743 { 744 if ( parameter.isRequired() == required ) 745 { 746 list.add( parameter ); 747 } 748 } 749 750 return list; 751 } 752 753 /** 754 * Gets the resource bundle for the <code>locale</code> instance variable. 755 * 756 * @return The resource bundle for the <code>locale</code> instance variable. 757 */ 758 private ResourceBundle getBundle() 759 { 760 return ResourceBundle.getBundle( "pluginxdoc", locale, getClass().getClassLoader() ); 761 } 762 763 /** 764 * @param key not null 765 * @return Localized, text identified by <code>key</code>. 766 * @see #getBundle() 767 */ 768 private String getString( String key ) 769 { 770 return getBundle().getString( key ); 771 } 772 773 /** 774 * Convenience method. 775 * 776 * @param key not null 777 * @param arg1 not null 778 * @return Localized, formatted text identified by <code>key</code>. 779 * @see #format(String, Object[]) 780 */ 781 private String format( String key, Object arg1 ) 782 { 783 return format( key, new Object[]{ arg1 } ); 784 } 785 786 /** 787 * Looks up the value for <code>key</code> in the <code>ResourceBundle</code>, 788 * then formats that value for the specified <code>Locale</code> using <code>args</code>. 789 * 790 * @param key not null 791 * @param args not null 792 * @return Localized, formatted text identified by <code>key</code>. 793 */ 794 private String format( String key, Object[] args ) 795 { 796 String pattern = getString( key ); 797 // we don't need quoting so spare us the confusion in the resource bundle to double them up in some keys 798 pattern = StringUtils.replace( pattern, "'", "''" ); 799 800 MessageFormat messageFormat = new MessageFormat( "" ); 801 messageFormat.setLocale( locale ); 802 messageFormat.applyPattern( pattern ); 803 804 return messageFormat.format( args ); 805 } 806 807 /** 808 * @param text the string to escape 809 * @return A string escaped with XML entities 810 */ 811 private String escapeXml( String text ) 812 { 813 if ( text != null ) 814 { 815 text = text.replaceAll( "&", "&" ); 816 text = text.replaceAll( "<", "<" ); 817 text = text.replaceAll( ">", ">" ); 818 text = text.replaceAll( "\"", """ ); 819 text = text.replaceAll( "\'", "'" ); 820 } 821 return text; 822 } 823 824}