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