From 741179ac0c8827484b0467247a2c328df5f35c5b Mon Sep 17 00:00:00 2001 From: Vincent Siveton Date: Wed, 6 Aug 2008 19:03:43 +0000 Subject: [PATCH] o deprecated toText and move this method to PluginUtils git-svn-id: https://svn.apache.org/repos/asf/maven/plugin-tools/trunk@683374 13f79535-47bb-0310-9956-ffa450edef68 --- .../plugin/generator/PluginHelpGenerator.java | 265 +---------------- .../maven/tools/plugin/util/PluginUtils.java | 273 +++++++++++++++++- 2 files changed, 280 insertions(+), 258 deletions(-) diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java index 63a5115..d6122cc 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java @@ -22,7 +22,6 @@ package org.apache.maven.tools.plugin.generator; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.io.StringReader; import java.io.Writer; import java.util.ArrayList; import java.util.Date; @@ -30,12 +29,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Stack; - -import javax.swing.text.MutableAttributeSet; -import javax.swing.text.html.HTML; -import javax.swing.text.html.HTMLEditorKit; -import javax.swing.text.html.parser.ParserDelegator; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.Parameter; @@ -130,7 +123,7 @@ public class PluginHelpGenerator /** * Creates a minimalistic mojo descriptor for the generated help goal. - * + * * @param pluginDescriptor The descriptor of the plugin for which to generate a help goal, must not be * null. * @return The mojo descriptor for the generated help goal, never null. @@ -202,13 +195,13 @@ public class PluginHelpGenerator { throw new RuntimeException( "Failed to setup parameters for help goal", e ); } - + return descriptor; } /** * Find the best package name, based on the number of hits of actual Mojo classes. - * + * * @param pluginDescriptor * @return the best name of the package for the generated mojo */ @@ -257,7 +250,7 @@ public class PluginHelpGenerator /** * Generates the HelpMojo class. - * + * * @param writer * @param pluginDescriptor * @param helpDescriptor @@ -622,7 +615,7 @@ public class PluginHelpGenerator /** * Gets the effective string to use for the plugin/mojo/parameter description. - * + * * @param description The description of the element, may be null. * @return The effective description string, never null. */ @@ -630,7 +623,7 @@ public class PluginHelpGenerator { if ( StringUtils.isNotEmpty( description ) ) { - return StringUtils.escape( toText( description ) ); + return StringUtils.escape( PluginUtils.toText( description ) ); } else { @@ -650,253 +643,13 @@ public class PluginHelpGenerator * to a single space. The resulting space denotes a possible point for line wrapping. *
  • Each space in preformatted text will be converted to a non-breaking space (U+00A0).
  • * - * + * * @param html The HTML fragment to convert to plain text, may be null. * @return A string with HTML tags converted into pure text, never null. + * @deprecated since 2.4.3, using {@link PluginUtils#toText(String)} instead of. */ protected static String toText( String html ) { - if ( StringUtils.isEmpty( html ) ) - { - return ""; - } - - final StringBuffer sb = new StringBuffer(); - - HTMLEditorKit.Parser parser = new ParserDelegator(); - HTMLEditorKit.ParserCallback htmlCallback = new HTMLEditorKit.ParserCallback() - { - /** - * Holds the index of the current item in a numbered list. - */ - class Counter - { - public int value; - } - - /** - * A flag whether the parser is currently in the body element. - */ - private boolean body; - - /** - * A flag whether the parser is currently processing preformatted text, actually a counter to track nesting. - */ - private int preformatted; - - /** - * The current indentation depth for the output. - */ - private int depth; - - /** - * A stack of {@link Counter} objects corresponding to the nesting of (un-)ordered lists. A - * null element denotes an unordered list. - */ - private Stack numbering = new Stack(); - - /** - * A flag whether an implicit line break is pending in the output buffer. This flag is used to postpone the - * output of implicit line breaks until we are sure that are not to be merged with other implicit line - * breaks. - */ - private boolean pendingNewline; - - /** - * A flag whether we have just parsed a simple tag. - */ - private boolean simpleTag; - - /** {@inheritDoc} */ - public void handleSimpleTag( HTML.Tag t, MutableAttributeSet a, int pos ) - { - simpleTag = true; - if ( body && HTML.Tag.BR.equals( t ) ) - { - newline( false ); - } - } - - /** {@inheritDoc} */ - public void handleStartTag( HTML.Tag t, MutableAttributeSet a, int pos ) - { - simpleTag = false; - if ( body && ( t.breaksFlow() || t.isBlock() ) ) - { - newline( true ); - } - if ( HTML.Tag.OL.equals( t ) ) - { - numbering.push( new Counter() ); - } - else if ( HTML.Tag.UL.equals( t ) ) - { - numbering.push( null ); - } - else if ( HTML.Tag.LI.equals( t ) ) - { - Counter counter = (Counter) numbering.peek(); - if ( counter == null ) - { - text( "-\t" ); - } - else - { - text( ++counter.value + ".\t" ); - } - depth++; - } - else if ( HTML.Tag.DD.equals( t ) ) - { - depth++; - } - else if ( t.isPreformatted() ) - { - preformatted++; - } - else if ( HTML.Tag.BODY.equals( t ) ) - { - body = true; - } - } - - /** {@inheritDoc} */ - public void handleEndTag( HTML.Tag t, int pos ) - { - if ( HTML.Tag.OL.equals( t ) || HTML.Tag.UL.equals( t ) ) - { - numbering.pop(); - } - else if ( HTML.Tag.LI.equals( t ) || HTML.Tag.DD.equals( t ) ) - { - depth--; - } - else if ( t.isPreformatted() ) - { - preformatted--; - } - else if ( HTML.Tag.BODY.equals( t ) ) - { - body = false; - } - if ( body && ( t.breaksFlow() || t.isBlock() ) && !HTML.Tag.LI.equals( t ) ) - { - if ( ( HTML.Tag.P.equals( t ) || HTML.Tag.PRE.equals( t ) || HTML.Tag.OL.equals( t ) - || HTML.Tag.UL.equals( t ) || HTML.Tag.DL.equals( t ) ) - && numbering.isEmpty() ) - { - newline( pendingNewline = false ); - } - else - { - newline( true ); - } - } - } - - /** {@inheritDoc} */ - public void handleText( char[] data, int pos ) - { - /* - * NOTE: Parsers before JRE 1.6 will parse XML-conform simple tags like
    as "
    " followed by - * the text event ">..." so we need to watch out for the closing angle bracket. - */ - int offset = 0; - if ( simpleTag && data[0] == '>' ) - { - simpleTag = false; - for ( ++offset; offset < data.length && data[offset] <= ' '; ) - { - offset++; - } - } - if ( offset < data.length ) - { - String text = new String( data, offset, data.length - offset ); - text( text ); - } - } - - /** {@inheritDoc} */ - public void flush() - { - flushPendingNewline(); - } - - /** - * Writes a line break to the plain text output. - * - * @param implicit A flag whether this is an explicit or implicit line break. Explicit line breaks are - * always written to the output whereas consecutive implicit line breaks are merged into a single - * line break. - */ - private void newline( boolean implicit ) - { - if ( implicit ) - { - pendingNewline = true; - } - else - { - flushPendingNewline(); - sb.append( '\n' ); - } - } - - /** - * Flushes a pending newline (if any). - */ - private void flushPendingNewline() - { - if ( pendingNewline ) - { - pendingNewline = false; - if ( sb.length() > 0 ) - { - sb.append( '\n' ); - } - } - } - - /** - * Writes the specified character data to the plain text output. If the last output was a line break, the - * character data will automatically be prefixed with the current indent. - * - * @param data The character data, must not be null. - */ - private void text( String data ) - { - flushPendingNewline(); - if ( sb.length() <= 0 || sb.charAt( sb.length() - 1 ) == '\n' ) - { - for ( int i = 0; i < depth; i++ ) - { - sb.append( '\t' ); - } - } - String text; - if ( preformatted > 0 ) - { - text = data.replace( ' ', '\u00A0' ); - } - else - { - text = data.replace( '\n', ' ' ); - } - sb.append( text ); - } - }; - - try - { - parser.parse( new StringReader( PluginUtils.makeHtmlValid( html ) ), htmlCallback, true ); - } - catch ( IOException e ) - { - throw new RuntimeException( e ); - } - - return sb.toString().replace( '\"', '\'' ); // for CDATA + return PluginUtils.toText( html ); } - } diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java index ca2aacb..58f8b97 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java @@ -22,6 +22,8 @@ package org.apache.maven.tools.plugin.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; +import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; @@ -32,9 +34,15 @@ import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.parser.ParserDelegator; + import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.descriptor.MojoDescriptor; @@ -237,7 +245,7 @@ public final class PluginUtils /** * Fixes some javadoc comment to become a valid XHTML snippet. - * + * * @param description Javadoc description with HTML tags, may be null. * @return The description with valid XHTML tags, never null. */ @@ -398,7 +406,7 @@ public final class PluginUtils /** * Sorts the specified mojo descriptors by goal name. - * + * * @param mojoDescriptors The mojo descriptors to sort, may be null. */ public static void sortMojos( List mojoDescriptors ) @@ -419,4 +427,265 @@ public final class PluginUtils } } + /** + * Converts a HTML fragment as extracted from a javadoc comment to a plain text string. This method tries to retain + * as much of the text formatting as possible by means of the following transformations: + * + * + * @param html The HTML fragment to convert to plain text, may be null. + * @return A string with HTML tags converted into pure text, never null. + * @since 2.4.3 + */ + public static String toText( String html ) + { + if ( StringUtils.isEmpty( html ) ) + { + return ""; + } + + final StringBuffer sb = new StringBuffer(); + + HTMLEditorKit.Parser parser = new ParserDelegator(); + HTMLEditorKit.ParserCallback htmlCallback = new HTMLEditorKit.ParserCallback() + { + /** + * Holds the index of the current item in a numbered list. + */ + class Counter + { + public int value; + } + + /** + * A flag whether the parser is currently in the body element. + */ + private boolean body; + + /** + * A flag whether the parser is currently processing preformatted text, actually a counter to track nesting. + */ + private int preformatted; + + /** + * The current indentation depth for the output. + */ + private int depth; + + /** + * A stack of {@link Counter} objects corresponding to the nesting of (un-)ordered lists. A + * null element denotes an unordered list. + */ + private Stack numbering = new Stack(); + + /** + * A flag whether an implicit line break is pending in the output buffer. This flag is used to postpone the + * output of implicit line breaks until we are sure that are not to be merged with other implicit line + * breaks. + */ + private boolean pendingNewline; + + /** + * A flag whether we have just parsed a simple tag. + */ + private boolean simpleTag; + + /** {@inheritDoc} */ + public void handleSimpleTag( HTML.Tag t, MutableAttributeSet a, int pos ) + { + simpleTag = true; + if ( body && HTML.Tag.BR.equals( t ) ) + { + newline( false ); + } + } + + /** {@inheritDoc} */ + public void handleStartTag( HTML.Tag t, MutableAttributeSet a, int pos ) + { + simpleTag = false; + if ( body && ( t.breaksFlow() || t.isBlock() ) ) + { + newline( true ); + } + if ( HTML.Tag.OL.equals( t ) ) + { + numbering.push( new Counter() ); + } + else if ( HTML.Tag.UL.equals( t ) ) + { + numbering.push( null ); + } + else if ( HTML.Tag.LI.equals( t ) ) + { + Counter counter = (Counter) numbering.peek(); + if ( counter == null ) + { + text( "-\t" ); + } + else + { + text( ++counter.value + ".\t" ); + } + depth++; + } + else if ( HTML.Tag.DD.equals( t ) ) + { + depth++; + } + else if ( t.isPreformatted() ) + { + preformatted++; + } + else if ( HTML.Tag.BODY.equals( t ) ) + { + body = true; + } + } + + /** {@inheritDoc} */ + public void handleEndTag( HTML.Tag t, int pos ) + { + if ( HTML.Tag.OL.equals( t ) || HTML.Tag.UL.equals( t ) ) + { + numbering.pop(); + } + else if ( HTML.Tag.LI.equals( t ) || HTML.Tag.DD.equals( t ) ) + { + depth--; + } + else if ( t.isPreformatted() ) + { + preformatted--; + } + else if ( HTML.Tag.BODY.equals( t ) ) + { + body = false; + } + if ( body && ( t.breaksFlow() || t.isBlock() ) && !HTML.Tag.LI.equals( t ) ) + { + if ( ( HTML.Tag.P.equals( t ) || HTML.Tag.PRE.equals( t ) || HTML.Tag.OL.equals( t ) + || HTML.Tag.UL.equals( t ) || HTML.Tag.DL.equals( t ) ) + && numbering.isEmpty() ) + { + newline( pendingNewline = false ); + } + else + { + newline( true ); + } + } + } + + /** {@inheritDoc} */ + public void handleText( char[] data, int pos ) + { + /* + * NOTE: Parsers before JRE 1.6 will parse XML-conform simple tags like
    as "
    " followed by + * the text event ">..." so we need to watch out for the closing angle bracket. + */ + int offset = 0; + if ( simpleTag && data[0] == '>' ) + { + simpleTag = false; + for ( ++offset; offset < data.length && data[offset] <= ' '; ) + { + offset++; + } + } + if ( offset < data.length ) + { + String text = new String( data, offset, data.length - offset ); + text( text ); + } + } + + /** {@inheritDoc} */ + public void flush() + { + flushPendingNewline(); + } + + /** + * Writes a line break to the plain text output. + * + * @param implicit A flag whether this is an explicit or implicit line break. Explicit line breaks are + * always written to the output whereas consecutive implicit line breaks are merged into a single + * line break. + */ + private void newline( boolean implicit ) + { + if ( implicit ) + { + pendingNewline = true; + } + else + { + flushPendingNewline(); + sb.append( '\n' ); + } + } + + /** + * Flushes a pending newline (if any). + */ + private void flushPendingNewline() + { + if ( pendingNewline ) + { + pendingNewline = false; + if ( sb.length() > 0 ) + { + sb.append( '\n' ); + } + } + } + + /** + * Writes the specified character data to the plain text output. If the last output was a line break, the + * character data will automatically be prefixed with the current indent. + * + * @param data The character data, must not be null. + */ + private void text( String data ) + { + flushPendingNewline(); + if ( sb.length() <= 0 || sb.charAt( sb.length() - 1 ) == '\n' ) + { + for ( int i = 0; i < depth; i++ ) + { + sb.append( '\t' ); + } + } + String text; + if ( preformatted > 0 ) + { + text = data.replace( ' ', '\u00A0' ); + } + else + { + text = data.replace( '\n', ' ' ); + } + sb.append( text ); + } + }; + + try + { + parser.parse( new StringReader( makeHtmlValid( html ) ), htmlCallback, true ); + } + catch ( IOException e ) + { + throw new RuntimeException( e ); + } + + return sb.toString().replace( '\"', '\'' ); // for CDATA + } }