Author: hboutemy
Date: Sat May  2 22:07:56 2009
New Revision: 770983

URL: http://svn.apache.org/viewvc?rev=770983&view=rev
Log:
merged MNG-2855 fix and unit test from trunk

Modified:
    
maven/shared/branches/maven-reporting-impl-2.0.4.x/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java

Modified: 
maven/shared/branches/maven-reporting-impl-2.0.4.x/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java
URL: 
http://svn.apache.org/viewvc/maven/shared/branches/maven-reporting-impl-2.0.4.x/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java?rev=770983&r1=770982&r2=770983&view=diff
==============================================================================
--- 
maven/shared/branches/maven-reporting-impl-2.0.4.x/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java
 (original)
+++ 
maven/shared/branches/maven-reporting-impl-2.0.4.x/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java
 Sat May  2 22:07:56 2009
@@ -1,30 +1,36 @@
 package org.apache.maven.reporting;
 
 /*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ *  http://www.apache.org/licenses/LICENSE-2.0
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 
 import org.apache.commons.validator.EmailValidator;
 import org.apache.commons.validator.UrlValidator;
+
 import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.doxia.util.HtmlTools;
+
 import org.codehaus.plexus.util.StringUtils;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -33,37 +39,44 @@
  * @author <a href="mailto:ja...@maven.org";>Jason van Zyl</a>
  * @author <a href="eveni...@apache.org">Emmanuel Venisse</a>
  * @author <a href="mailto:vincent.sive...@gmail.com";>Vincent Siveton</a>
- * @version $Id: AbstractMavenReportRenderer.java 163373 2005-02-22 03:37:00Z 
brett $
- * @todo Later it may be appropriate to create something like a 
VelocityMavenReportRenderer that could take a velocity template and pipe that 
through Doxia rather than coding them up like this.
+ * @version $Id: AbstractMavenReportRenderer.java 748481 2009-02-27 10:51:56Z 
vsiveton $
+ * @since 2.0
+ * @TODO Later it may be appropriate to create something like a 
VelocityMavenReportRenderer
+ * that could take a velocity template and pipe that through Doxia rather than 
coding them
+ * up like this.
  */
 public abstract class AbstractMavenReportRenderer
     implements MavenReportRenderer
 {
+    /** The current sink to use */
     protected Sink sink;
 
+    /** The current section number */
     private int section;
 
+    /**
+     * Default constructor.
+     *
+     * @param sink the sink to use.
+     */
     public AbstractMavenReportRenderer( Sink sink )
     {
         this.sink = sink;
     }
 
+    /** {...@inheritdoc} */
     public void render()
     {
         sink.head();
 
         sink.title();
-
         text( getTitle() );
-
         sink.title_();
 
         sink.head_();
 
         sink.body();
-
         renderBody();
-
         sink.body_();
 
         sink.flush();
@@ -71,20 +84,38 @@
         sink.close();
     }
 
-    protected void startTable()
-    {
-        sink.table();
-    }
-
-    protected void endTable()
-    {
-        sink.table_();
-    }
+    // ----------------------------------------------------------------------
+    // Section handler
+    // ----------------------------------------------------------------------
 
+    /**
+     * Convenience method to wrap section creation in the current sink. An 
anchor will be add for the name.
+     *
+     * @param name the name of this section, could be null.
+     * @see #text(String)
+     * @see Sink#section1()
+     * @see Sink#sectionTitle1()
+     * @see Sink#sectionTitle1_()
+     * @see Sink#section2()
+     * @see Sink#sectionTitle2()
+     * @see Sink#sectionTitle2_()
+     * @see Sink#section3()
+     * @see Sink#sectionTitle3()
+     * @see Sink#sectionTitle3_()
+     * @see Sink#section4()
+     * @see Sink#sectionTitle4()
+     * @see Sink#sectionTitle4_()
+     * @see Sink#section5()
+     * @see Sink#sectionTitle5()
+     * @see Sink#sectionTitle5_()
+     */
     protected void startSection( String name )
     {
         section = section + 1;
 
+        sink.anchor( HtmlTools.encodeId( name ) );
+        sink.anchor_();
+
         switch ( section )
         {
             case 1:
@@ -139,6 +170,16 @@
         }
     }
 
+    /**
+     * Convenience method to wrap section ending in the current sink.
+     *
+     * @see Sink#section1_()
+     * @see Sink#section2_()
+     * @see Sink#section3_()
+     * @see Sink#section4_()
+     * @see Sink#section5_()
+     * @IllegalStateException if too many closing sections.
+     */
     protected void endSection()
     {
         switch ( section )
@@ -172,6 +213,38 @@
         }
     }
 
+    // ----------------------------------------------------------------------
+    // Table handler
+    // ----------------------------------------------------------------------
+
+    /**
+     * Convenience method to wrap the table start in the current sink.
+     *
+     * @see Sink#table()
+     */
+    protected void startTable()
+    {
+        sink.table();
+    }
+
+    /**
+     * Convenience method to wrap the table ending in the current sink.
+     *
+     * @see Sink#table_()
+     */
+    protected void endTable()
+    {
+        sink.table_();
+    }
+
+    /**
+     * Convenience method to wrap the table header cell start in the current 
sink.
+     *
+     * @param text the text to put in this cell, could be null.
+     * @see #text(String)
+     * @see Sink#tableHeaderCell()
+     * @see Sink#tableHeaderCell_()
+     */
     protected void tableHeaderCell( String text )
     {
         sink.tableHeaderCell();
@@ -182,11 +255,12 @@
     }
 
     /**
-     * Add a cell in a table.
+     * Convenience method to wrap a table cell start in the current sink.
      * <p>The text could be a link patterned text defined by <code>{text, 
url}</code></p>
      *
-     * @param text
+     * @param text the text to put in this cell, could be null.
      * @see #linkPatternedText(String)
+     * @see #tableCell(String)
      */
     protected void tableCell( String text )
     {
@@ -194,11 +268,16 @@
     }
 
     /**
-     * Add a cell in a table.
+     * Convenience method to wrap a table cell start in the current sink.
+     * <p>The text could be a link patterned text defined by <code>{text, 
url}</code></p>
      * <p>If <code>asHtml</code> is true, add the text as Html</p>
      *
-     * @param text
-     * @param asHtml
+     * @param text the text to put in this cell, could be null.
+     * @param asHtml <tt>true</tt> to add the text as Html, <tt>false</tt> 
otherwise.
+     * @see #linkPatternedText(String)
+     * @see Sink#tableCell()
+     * @see Sink#tableCell_()
+     * @see Sink#rawText(String)
      */
     protected void tableCell( String text, boolean asHtml )
     {
@@ -216,30 +295,62 @@
         sink.tableCell_();
     }
 
+    /**
+     * Convenience method to wrap a table row start in the current sink.
+     * <p>The texts in the <code>content</code> could be link patterned texts 
defined by <code>{text, url}</code></p>
+     *
+     * @param content an array of text to put in the cells in this row, could 
be null.
+     * @see #tableCell(String)
+     * @see Sink#tableRow()
+     * @see Sink#tableRow_()
+     */
     protected void tableRow( String[] content )
     {
         sink.tableRow();
 
-        for ( int i = 0; i < content.length; i++ )
+        if ( content != null )
         {
-            tableCell( content[i] );
+            for ( int i = 0; i < content.length; i++ )
+            {
+                tableCell( content[i] );
+            }
         }
 
         sink.tableRow_();
     }
 
+    /**
+     * Convenience method to wrap a table header row start in the current sink.
+     * <p>The texts in the <code>content</code> could be link patterned texts 
defined by <code>{text, url}</code></p>
+     *
+     * @param content an array of text to put in the cells in this row header, 
could be null.
+     * @see #tableHeaderCell(String)
+     * @see Sink#tableRow()
+     * @see Sink#tableRow_()
+     */
     protected void tableHeader( String[] content )
     {
         sink.tableRow();
 
-        for ( int i = 0; i < content.length; i++ )
+        if ( content != null )
         {
-            tableHeaderCell( content[i] );
+            for ( int i = 0; i < content.length; i++ )
+            {
+                tableHeaderCell( content[i] );
+            }
         }
 
         sink.tableRow_();
     }
 
+    /**
+     * Convenience method to wrap a table caption in the current sink.
+     *
+     * @param caption the caption of the table, could be null.
+     * @see #text(String)
+     * @see Sink#tableCaption()
+     * @see Sink#tableCaption_()
+     */
     protected void tableCaption( String caption )
     {
         sink.tableCaption();
@@ -249,6 +360,18 @@
         sink.tableCaption_();
     }
 
+    // ----------------------------------------------------------------------
+    // Paragraph handler
+    // ----------------------------------------------------------------------
+
+    /**
+     * Convenience method to wrap a paragraph in the current sink.
+     *
+     * @param paragraph the paragraph to add, could be null.
+     * @see #text(String)
+     * @see Sink#paragraph()
+     * @see Sink#paragraph_()
+     */
     protected void paragraph( String paragraph )
     {
         sink.paragraph();
@@ -258,6 +381,15 @@
         sink.paragraph_();
     }
 
+    /**
+     * Convenience method to wrap a link in the current sink.
+     *
+     * @param href the link to add, cannot be null.
+     * @param name the link name.
+     * @see #text(String)
+     * @see Sink#link(String)
+     * @see Sink#link_()
+     */
     protected void link( String href, String name )
     {
         sink.link( href );
@@ -268,14 +400,15 @@
     }
 
     /**
-     * Add a new text.
-     * <p>If text is empty of has a null value, add the "-" charater</p>
+     * Convenience method to wrap a text in the current sink.
+     * <p>If text is empty or has a <code>null</code> value, add the 
<code>"-"</code> charater</p>
      *
-     * @param text a string
+     * @param text a text, could be null.
+     * @see Sink#text(String)
      */
     protected void text( String text )
     {
-        if ( text == null || text.length() == 0 ) // Take care of spaces
+        if ( StringUtils.isEmpty( text ) ) // Take care of spaces
         {
             sink.text( "-" );
         }
@@ -286,10 +419,12 @@
     }
 
     /**
-     * Add a verbatim text.
+     * Convenience method to wrap a text as verbatim style in the current sink 
.
      *
-     * @param text a string
+     * @param text a text, could be null.
      * @see #text(String)
+     * @see Sink#verbatim(boolean)
+     * @see Sink#verbatim_()
      */
     protected void verbatimText( String text )
     {
@@ -301,11 +436,14 @@
     }
 
     /**
-     * Add a verbatim text with a specific link.
+     * Convenience method to wrap a text with a given link href as verbatim 
style in the current sink.
      *
      * @param text a string
      * @param href an href could be null
      * @see #link(String, String)
+     * @see #verbatimText(String)
+     * @see Sink#verbatim(boolean)
+     * @see Sink#verbatim_()
      */
     protected void verbatimLink( String text, String href )
     {
@@ -324,9 +462,10 @@
     }
 
     /**
-     * Add a Javascript code.
+     * Convenience method to add a Javascript code in the current sink.
      *
      * @param jsCode a string of Javascript
+     * @see Sink#rawText(String)
      */
     protected void javaScript( String jsCode )
     {
@@ -334,12 +473,13 @@
     }
 
     /**
-     * Add a text with links inside.
+     * Convenience method to wrap a patterned text in the current link.
      * <p>The text variable should contained this given pattern <code>{text, 
url}</code>
      * to handle the link creation.</p>
      *
      * @param text a text with link pattern defined.
      * @see #text(String)
+     * @see #link(String, String)
      * @see #applyPattern(String)
      */
     public void linkPatternedText( String text )
@@ -350,7 +490,7 @@
         }
         else
         {
-            Map segments = applyPattern( text );
+            List segments = applyPattern( text );
 
             if ( segments == null )
             {
@@ -358,12 +498,10 @@
             }
             else
             {
-                for ( Iterator it = segments.entrySet().iterator(); 
it.hasNext(); )
+                for ( Iterator it = segments.iterator(); it.hasNext(); )
                 {
-                    Map.Entry entry = (Map.Entry) it.next();
-
-                    String name = (String) entry.getKey();
-                    String href = (String) entry.getValue();
+                    String name = (String) it.next();
+                    String href = (String) it.next();
 
                     if ( href == null )
                     {
@@ -414,9 +552,9 @@
     }
 
     /**
-     * Convenience method to display a <code>Properties</code> object comma 
separated.
+     * Convenience method to display a <code>Properties</code> object as comma 
separated String.
      *
-     * @param props
+     * @param props the properties to display.
      * @return the properties object as comma separated String
      */
     protected static String propertiesToString( Properties props )
@@ -441,16 +579,25 @@
         return sb.toString();
     }
 
+    // ----------------------------------------------------------------------
+    // Private methods
+    // ----------------------------------------------------------------------
+
     /**
      * Return a valid href.
      * <p>A valid href could start by <code>mailto:</code>.</p>
      * <p>For a relative path, the href should start by <code>./</code> to be 
valid.</p>
      *
-     * @param href an href
-     * @return a valid href or null if the href is not valid.
+     * @param href an href, could be null.
+     * @return a valid href or <code>null</code> if the href is null or not 
valid.
      */
     private static String getValidHref( String href )
     {
+        if ( StringUtils.isEmpty( href ) )
+        {
+            return null;
+        }
+
         href = href.trim();
 
         String[] schemes = {"http", "https"};
@@ -472,8 +619,6 @@
         }
         else
         {
-            // TODO Waiting for new release of Validator
-            // http://issues.apache.org/bugzilla/show_bug.cgi?id=30686
             String hrefTmp;
             if ( !href.endsWith( "/" ) )
             {
@@ -495,10 +640,8 @@
                 {
                     return href.substring(2, href.length() );
                 }
-                else
-                {
-                    return ".";
-                }
+
+                return ".";
             }
 
             return null;
@@ -512,7 +655,7 @@
      * @param text a text with or without the pattern <code>{text, url}</code>
      * @return a map of text/href
      */
-    private static Map applyPattern( String text )
+    private static List applyPattern( String text )
     {
         if ( StringUtils.isEmpty( text ) )
         {
@@ -521,7 +664,7 @@
 
         // Map defined by key/value name/href
         // If href == null, it means
-        Map segments = new LinkedHashMap();
+        List segments = new ArrayList();
 
         // TODO Special case http://jira.codehaus.org/browse/MEV-40
         if ( text.indexOf( "${" ) != -1 )
@@ -530,11 +673,13 @@
             int lastSemi = text.lastIndexOf( "}" );
             if ( lastComma != -1 && lastSemi != -1 )
             {
-                segments.put( text.substring( lastComma + 1, lastSemi 
).trim(), null );
+                segments.add( text.substring( lastComma + 1, lastSemi ).trim() 
);
+                segments.add( null );
             }
             else
             {
-                segments.put( text, null );
+                segments.add( text );
+                segments.add( null );
             }
 
             return segments;
@@ -554,6 +699,9 @@
                 if ( i + 1 < text.length() && text.charAt( i + 1 ) == '\'' )
                 {
                     i++;
+                    segments.add( text.substring( lastOffset, i ) );
+                    segments.add( null );
+                    lastOffset = i + 1;
                 }
                 else
                 {
@@ -571,11 +719,12 @@
                             {
                                 if ( i != 0 ) // handle { at first character
                                 {
-                                    segments.put( text.substring( lastOffset, 
i ), null );
+                                    segments.add( text.substring( lastOffset, 
i ) );
+                                    segments.add( null );
                                 }
                                 lastOffset = i + 1;
-                                braceStack++;
                             }
+                            braceStack++;
                         }
                         break;
                     case '}':
@@ -590,12 +739,13 @@
                                 int lastComma = subString.lastIndexOf( "," );
                                 if ( lastComma != -1 )
                                 {
-                                    segments.put( subString.substring( 0, 
lastComma ).trim(),
-                                                  subString.substring( 
lastComma + 1 ).trim() );
+                                    segments.add( subString.substring( 0, 
lastComma ).trim() );
+                                    segments.add( subString.substring( 
lastComma + 1 ).trim() );
                                 }
                                 else
                                 {
-                                    segments.put( subString.substring( 0, 
lastComma ).trim(), null );
+                                    segments.add( subString );
+                                    segments.add( null );
                                 }
                             }
                         }
@@ -611,7 +761,8 @@
 
         if ( !StringUtils.isEmpty( text.substring( lastOffset, text.length() ) 
) )
         {
-            segments.put( text.substring( lastOffset, text.length() ), null );
+            segments.add( text.substring( lastOffset, text.length() ) );
+            segments.add( null );
         }
 
         if ( braceStack != 0 )
@@ -619,10 +770,24 @@
             throw new IllegalArgumentException( "Unmatched braces in the 
pattern." );
         }
 
-        return Collections.unmodifiableMap( segments );
+        if ( inQuote )
+        {
+            //throw new IllegalArgumentException( "Unmatched quote in the 
pattern." );
+            //TODO: warning...
+        }
+
+        return Collections.unmodifiableList( segments );
     }
 
+    // ----------------------------------------------------------------------
+    // Abstract methods
+    // ----------------------------------------------------------------------
+
+    /** {...@inheritdoc} */
     public abstract String getTitle();
 
+    /**
+     * Renderer the body content of the report.
+     */
     protected abstract void renderBody();
 }


Reply via email to