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 317 addedUl = addUl( w, addedUl ); 318 w.startElement( "li" ); 319 w.writeMarkup( getString( mojoDescriptor.isThreadSafe() 320 ? "pluginxdoc.mojodescriptor.threadSafe" 321 : "pluginxdoc.mojodescriptor.notThreadSafe" ) ); 322 w.endElement(); //li 323 324 value = mojoDescriptor.getSince(); 325 if ( StringUtils.isNotEmpty( value ) ) 326 { 327 addedUl = addUl( w, addedUl ); 328 w.startElement( "li" ); 329 w.writeMarkup( format( "pluginxdoc.mojodescriptor.since", value ) ); 330 w.endElement(); //li 331 } 332 333 value = mojoDescriptor.getPhase(); 334 if ( StringUtils.isNotEmpty( value ) ) 335 { 336 addedUl = addUl( w, addedUl ); 337 w.startElement( "li" ); 338 w.writeMarkup( format( "pluginxdoc.mojodescriptor.phase", value ) ); 339 w.endElement(); //li 340 } 341 342 value = mojoDescriptor.getExecutePhase(); 343 if ( StringUtils.isNotEmpty( value ) ) 344 { 345 addedUl = addUl( w, addedUl ); 346 w.startElement( "li" ); 347 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executePhase", value ) ); 348 w.endElement(); //li 349 } 350 351 value = mojoDescriptor.getExecuteGoal(); 352 if ( StringUtils.isNotEmpty( value ) ) 353 { 354 addedUl = addUl( w, addedUl ); 355 w.startElement( "li" ); 356 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executeGoal", value ) ); 357 w.endElement(); //li 358 } 359 360 value = mojoDescriptor.getExecuteLifecycle(); 361 if ( StringUtils.isNotEmpty( value ) ) 362 { 363 addedUl = addUl( w, addedUl ); 364 w.startElement( "li" ); 365 w.writeMarkup( format( "pluginxdoc.mojodescriptor.executeLifecycle", value ) ); 366 w.endElement(); //li 367 } 368 369 if ( mojoDescriptor.isOnlineRequired() ) 370 { 371 addedUl = addUl( w, addedUl ); 372 w.startElement( "li" ); 373 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.onlineRequired" ) ); 374 w.endElement(); //li 375 } 376 377 if ( !mojoDescriptor.isInheritedByDefault() ) 378 { 379 addedUl = addUl( w, addedUl ); 380 w.startElement( "li" ); 381 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.inheritedByDefault" ) ); 382 w.endElement(); //li 383 } 384 385 if ( addedUl ) 386 { 387 w.endElement(); //ul 388 } 389 } 390 391 /** 392 * @param mojoDescriptor not null 393 * @param w not null 394 */ 395 private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w ) 396 { 397 List<Parameter> parameterList = mojoDescriptor.getParameters(); 398 399 // remove components and read-only parameters 400 List<Parameter> list = filterParameters( parameterList ); 401 402 if ( !list.isEmpty() ) 403 { 404 writeParameterSummary( mojoDescriptor, list, w ); 405 406 writeParameterDetails( mojoDescriptor, list, w ); 407 } 408 else 409 { 410 w.startElement( "subsection" ); 411 w.addAttribute( "name", getString( "pluginxdoc.mojodescriptor.parameters" ) ); 412 413 w.startElement( "p" ); 414 w.writeMarkup( getString( "pluginxdoc.mojodescriptor.noParameter" ) ); 415 w.endElement(); //p 416 417 w.endElement(); 418 } 419 } 420 421 /** 422 * Filter parameters to only retain those which must be documented, ie not components nor readonly. 423 * 424 * @param parameterList not null 425 * @return the parameters list without components. 426 */ 427 private List<Parameter> filterParameters( List<Parameter> parameterList ) 428 { 429 List<Parameter> filtered = new ArrayList<>(); 430 431 if ( parameterList != null ) 432 { 433 for ( Parameter parameter : parameterList ) 434 { 435 if ( parameter.isEditable() ) 436 { 437 String expression = parameter.getExpression(); 438 439 if ( expression == null || !expression.startsWith( "${component." ) ) 440 { 441 filtered.add( parameter ); 442 } 443 } 444 } 445 } 446 447 return filtered; 448 } 449 450 /** 451 * @param mojoDescriptor not null 452 * @param parameterList not null 453 * @param w not null 454 */ 455 private void writeParameterDetails( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w ) 456 { 457 w.startElement( "subsection" ); 458 w.addAttribute( "name", getString( "pluginxdoc.mojodescriptor.parameter.details" ) ); 459 460 for ( Iterator<Parameter> parameters = parameterList.iterator(); parameters.hasNext(); ) 461 { 462 Parameter parameter = parameters.next(); 463 464 w.startElement( "h4" ); 465 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.name_internal", parameter.getName() ) ); 466 w.endElement(); 467 468 if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) ) 469 { 470 w.startElement( "div" ); 471 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.deprecated", 472 GeneratorUtils.makeHtmlValid( parameter.getDeprecated() ) ) ); 473 w.endElement(); // div 474 } 475 476 w.startElement( "div" ); 477 if ( StringUtils.isNotEmpty( parameter.getDescription() ) ) 478 { 479 w.writeMarkup( GeneratorUtils.makeHtmlValid( parameter.getDescription() ) ); 480 } 481 else 482 { 483 w.writeMarkup( getString( "pluginxdoc.nodescription" ) ); 484 } 485 w.endElement(); // div 486 487 boolean addedUl = false; 488 addedUl = addUl( w, addedUl, parameter.getType() ); 489 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.type" ), parameter.getType(), w ); 490 491 if ( StringUtils.isNotEmpty( parameter.getSince() ) ) 492 { 493 addedUl = addUl( w, addedUl ); 494 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), parameter.getSince(), w ); 495 } 496 else 497 { 498 if ( StringUtils.isNotEmpty( mojoDescriptor.getSince() ) ) 499 { 500 addedUl = addUl( w, addedUl ); 501 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), mojoDescriptor.getSince(), 502 w ); 503 } 504 } 505 506 if ( parameter.isRequired() ) 507 { 508 addedUl = addUl( w, addedUl ); 509 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.yes" ), 510 w ); 511 } 512 else 513 { 514 addedUl = addUl( w, addedUl ); 515 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.no" ), 516 w ); 517 } 518 519 String expression = parameter.getExpression(); 520 addedUl = addUl( w, addedUl, expression ); 521 String property = getPropertyFromExpression( expression ); 522 if ( property == null ) 523 { 524 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.expression" ), expression, w ); 525 } 526 else 527 { 528 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.property" ), property, w ); 529 } 530 531 addedUl = addUl( w, addedUl, parameter.getDefaultValue() ); 532 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.default" ), 533 escapeXml( parameter.getDefaultValue() ), w ); 534 535 addedUl = addUl( w, addedUl, parameter.getAlias() ); 536 writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.alias" ), escapeXml( parameter.getAlias() ), 537 w ); 538 539 if ( addedUl ) 540 { 541 w.endElement(); //ul 542 } 543 544 if ( parameters.hasNext() ) 545 { 546 w.writeMarkup( "<hr/>" ); 547 } 548 } 549 550 w.endElement(); 551 } 552 553 private boolean addUl( XMLWriter w, boolean addedUl, String content ) 554 { 555 if ( StringUtils.isNotEmpty( content ) ) 556 { 557 return addUl( w, addedUl ); 558 } 559 return addedUl; 560 } 561 562 private boolean addUl( XMLWriter w, boolean addedUl ) 563 { 564 if ( !addedUl ) 565 { 566 w.startElement( "ul" ); 567 addedUl = true; 568 } 569 return addedUl; 570 } 571 572 private String getPropertyFromExpression( String expression ) 573 { 574 if ( StringUtils.isNotEmpty( expression ) && expression.startsWith( "${" ) && expression.endsWith( "}" ) 575 && !expression.substring( 2 ).contains( "${" ) ) 576 { 577 // expression="${xxx}" -> property="xxx" 578 return expression.substring( 2, expression.length() - 1 ); 579 } 580 // no property can be extracted 581 return null; 582 } 583 584 /** 585 * @param param not null 586 * @param value could be null 587 * @param w not null 588 */ 589 private void writeDetail( String param, String value, XMLWriter w ) 590 { 591 if ( StringUtils.isNotEmpty( value ) ) 592 { 593 w.startElement( "li" ); 594 w.writeMarkup( format( "pluginxdoc.detail", new String[]{ param, value } ) ); 595 w.endElement(); //li 596 } 597 } 598 599 /** 600 * @param mojoDescriptor not null 601 * @param parameterList not null 602 * @param w not null 603 */ 604 private void writeParameterSummary( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w ) 605 { 606 List<Parameter> requiredParams = getParametersByRequired( true, parameterList ); 607 if ( requiredParams.size() > 0 ) 608 { 609 writeParameterList( mojoDescriptor, getString( "pluginxdoc.mojodescriptor.requiredParameters" ), 610 requiredParams, w ); 611 } 612 613 List<Parameter> optionalParams = getParametersByRequired( false, parameterList ); 614 if ( optionalParams.size() > 0 ) 615 { 616 writeParameterList( mojoDescriptor, getString( "pluginxdoc.mojodescriptor.optionalParameters" ), 617 optionalParams, w ); 618 } 619 } 620 621 /** 622 * @param mojoDescriptor not null 623 * @param title not null 624 * @param parameterList not null 625 * @param w not null 626 */ 627 private void writeParameterList( MojoDescriptor mojoDescriptor, String title, List<Parameter> parameterList, 628 XMLWriter w ) 629 { 630 w.startElement( "subsection" ); 631 w.addAttribute( "name", title ); 632 633 w.startElement( "table" ); 634 w.addAttribute( "border", "0" ); 635 636 w.startElement( "tr" ); 637 w.startElement( "th" ); 638 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.name" ) ); 639 w.endElement(); //th 640 w.startElement( "th" ); 641 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.type" ) ); 642 w.endElement(); //th 643 w.startElement( "th" ); 644 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.since" ) ); 645 w.endElement(); //th 646 w.startElement( "th" ); 647 w.writeText( getString( "pluginxdoc.mojodescriptor.parameter.description" ) ); 648 w.endElement(); //th 649 w.endElement(); //tr 650 651 for ( Parameter parameter : parameterList ) 652 { 653 w.startElement( "tr" ); 654 655 // name 656 w.startElement( "td" ); 657 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.name_link", parameter.getName() ) ); 658 w.endElement(); //td 659 660 //type 661 w.startElement( "td" ); 662 int index = parameter.getType().lastIndexOf( "." ); 663 w.writeMarkup( "<code>" + parameter.getType().substring( index + 1 ) + "</code>" ); 664 w.endElement(); //td 665 666 // since 667 w.startElement( "td" ); 668 if ( StringUtils.isNotEmpty( parameter.getSince() ) ) 669 { 670 w.writeMarkup( "<code>" + parameter.getSince() + "</code>" ); 671 } 672 else 673 { 674 if ( StringUtils.isNotEmpty( mojoDescriptor.getSince() ) ) 675 { 676 w.writeMarkup( "<code>" + mojoDescriptor.getSince() + "</code>" ); 677 } 678 else 679 { 680 w.writeMarkup( "<code>-</code>" ); 681 } 682 } 683 w.endElement(); //td 684 685 // description 686 w.startElement( "td" ); 687 String description; 688 if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) ) 689 { 690 description = format( "pluginxdoc.mojodescriptor.parameter.deprecated", 691 GeneratorUtils.makeHtmlValid( parameter.getDeprecated() ) ); 692 } 693 else if ( StringUtils.isNotEmpty( parameter.getDescription() ) ) 694 { 695 description = GeneratorUtils.makeHtmlValid( parameter.getDescription() ); 696 } 697 else 698 { 699 description = getString( "pluginxdoc.nodescription" ); 700 } 701 w.writeMarkup( description + "<br/>" ); 702 703 if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) ) 704 { 705 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.defaultValue", 706 escapeXml( parameter.getDefaultValue() ) ) ); 707 w.writeMarkup( "<br/>" ); 708 } 709 710 String property = getPropertyFromExpression( parameter.getExpression() ); 711 if ( property != null ) 712 { 713 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.property.description", property ) ); 714 w.writeMarkup( "<br/>" ); 715 } 716 717 if ( StringUtils.isNotEmpty( parameter.getAlias() ) ) 718 { 719 w.writeMarkup( format( "pluginxdoc.mojodescriptor.parameter.alias.description", 720 escapeXml( parameter.getAlias() ) ) ); 721 } 722 723 w.endElement(); //td 724 w.endElement(); //tr 725 } 726 727 w.endElement(); //table 728 w.endElement(); //section 729 } 730 731 /** 732 * @param required <code>true</code> for required parameters, <code>false</code> otherwise. 733 * @param parameterList not null 734 * @return list of parameters depending the value of <code>required</code> 735 */ 736 private List<Parameter> getParametersByRequired( boolean required, List<Parameter> parameterList ) 737 { 738 List<Parameter> list = new ArrayList<>(); 739 740 for ( Parameter parameter : parameterList ) 741 { 742 if ( parameter.isRequired() == required ) 743 { 744 list.add( parameter ); 745 } 746 } 747 748 return list; 749 } 750 751 /** 752 * Gets the resource bundle for the <code>locale</code> instance variable. 753 * 754 * @return The resource bundle for the <code>locale</code> instance variable. 755 */ 756 private ResourceBundle getBundle() 757 { 758 return ResourceBundle.getBundle( "pluginxdoc", locale, getClass().getClassLoader() ); 759 } 760 761 /** 762 * @param key not null 763 * @return Localized, text identified by <code>key</code>. 764 * @see #getBundle() 765 */ 766 private String getString( String key ) 767 { 768 return getBundle().getString( key ); 769 } 770 771 /** 772 * Convenience method. 773 * 774 * @param key not null 775 * @param arg1 not null 776 * @return Localized, formatted text identified by <code>key</code>. 777 * @see #format(String, Object[]) 778 */ 779 private String format( String key, Object arg1 ) 780 { 781 return format( key, new Object[]{ arg1 } ); 782 } 783 784 /** 785 * Looks up the value for <code>key</code> in the <code>ResourceBundle</code>, 786 * then formats that value for the specified <code>Locale</code> using <code>args</code>. 787 * 788 * @param key not null 789 * @param args not null 790 * @return Localized, formatted text identified by <code>key</code>. 791 */ 792 private String format( String key, Object[] args ) 793 { 794 String pattern = getString( key ); 795 // we don't need quoting so spare us the confusion in the resource bundle to double them up in some keys 796 pattern = StringUtils.replace( pattern, "'", "''" ); 797 798 MessageFormat messageFormat = new MessageFormat( "" ); 799 messageFormat.setLocale( locale ); 800 messageFormat.applyPattern( pattern ); 801 802 return messageFormat.format( args ); 803 } 804 805 /** 806 * @param text the string to escape 807 * @return A string escaped with XML entities 808 */ 809 private String escapeXml( String text ) 810 { 811 if ( text != null ) 812 { 813 text = text.replaceAll( "&", "&" ); 814 text = text.replaceAll( "<", "<" ); 815 text = text.replaceAll( ">", ">" ); 816 text = text.replaceAll( "\"", """ ); 817 text = text.replaceAll( "\'", "'" ); 818 } 819 return text; 820 } 821 822}