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