Hi, I do not have the right permission to commit to maven-reporting-api. So, could someone commit the attached patch?
Thanks a lot, Cheers, Vincent
Index: src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java =================================================================== --- src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java (révision 216032) +++ src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java (copie de travail) @@ -16,11 +16,20 @@ * limitations under the License. */ +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + import org.apache.commons.validator.EmailValidator; import org.apache.commons.validator.UrlValidator; import org.codehaus.doxia.sink.Sink; +import org.codehaus.plexus.util.StringUtils; /** + * An abstract class to manage report generation. + * * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> * @author <a href="[EMAIL PROTECTED]">Emmanuel Venisse</a> * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Siveton</a> @@ -38,19 +47,19 @@ { this.sink = sink; } - + public void render() { sink.head(); sink.title(); - sink.text( getTitle() ); + text( getTitle() ); sink.title_(); sink.head_(); - + sink.body(); renderBody(); @@ -72,7 +81,7 @@ sink.table_(); } - protected void startSection( String name ) + protected void startSection( final String name ) { section = section + 1; @@ -104,7 +113,7 @@ break; } - sink.text( name ); + text( name ); switch ( section ) { @@ -163,150 +172,423 @@ } } - protected void tableHeaderCell( String text ) + protected void tableHeaderCell( final String text ) { sink.tableHeaderCell(); - sink.text( text ); + text( text ); sink.tableHeaderCell_(); } - protected void tableCell( String text ) + /** + * Add a cell in a table. + * <p>The text could be a link patterned text defined by <code>{text, url}</code></p> + * + * @see #linkPatternedText(String) + * + * @param text + */ + protected void tableCell( final String text ) { sink.tableCell(); - if ( text != null ) + linkPatternedText( text ); + + sink.tableCell_(); + } + + protected void tableRow( final String[] content ) + { + sink.tableRow(); + + for ( int i = 0; i < content.length; i++ ) { - sink.text( text ); + tableCell( content[i] ); } - else + + sink.tableRow_(); + } + + protected void tableHeader( final String[] content ) + { + sink.tableRow(); + + for ( int i = 0; i < content.length; i++ ) { - sink.nonBreakingSpace(); + tableHeaderCell( content[i] ); } - sink.tableCell_(); + sink.tableRow_(); } + protected void tableCaption( final String caption ) + { + sink.tableCaption(); + text( caption ); + sink.tableCaption_(); + } + + protected void paragraph( final String paragraph ) + { + sink.paragraph(); + + text( paragraph ); + + sink.paragraph_(); + } + + protected void link( final String href, final String name ) + { + sink.link( href ); + + text( name ); + + sink.link_(); + } + /** - * Create a cell with a potential link. - * - * @param text the text - * @param href the href + * Add a new text. + * <p>If text is empty of has a null value, add the "-" charater</p> + * + * @param text a string */ - protected void tableCellWithLink( String text, String href ) + protected void text( final String text ) { - sink.tableCell(); - - if ( text != null ) + if ( ( text == null || text.length() == 0 ) ) // Take care of spaces { - if ( href != null ) - { - String[] schemes = {"http", "https"}; - UrlValidator urlValidator = new UrlValidator( schemes ); - - if ( EmailValidator.getInstance().isValid( href ) ) - { - link( "mailto:" + href, text ); - } - else if ( href.toLowerCase().startsWith( "mailto:" ) ) - { - link( href, text ); - } - else if ( urlValidator.isValid( href ) ) - { - link( href, text ); - } - else - { - sink.text( text ); - } - } - else - { - sink.text( text ); - } + sink.text( "-" ); } else { - sink.nonBreakingSpace(); + sink.text( text ); } + } - sink.tableCell_(); + /** + * Add a verbatim text. + * + * @see #text(String) + * + * @param text a string + */ + protected void verbatimText( final String text ) + { + sink.verbatim( true ); + + text( text ); + + sink.verbatim_(); } - protected void tableRow( String[] content ) + /** + * Add a verbatim text with a specific link. + * + * @see #link(String, String) + * + * @param text a string + * @param href an href could be null + */ + protected void verbatimLink( final String text, final String href ) { - sink.tableRow(); - - for ( int i = 0; i < content.length; i++ ) + if ( StringUtils.isEmpty( href ) ) { - tableCell( content[i] ); + verbatimText( text ); + } + else + { + sink.verbatim( true ); + + link( href, text ); + + sink.verbatim_(); } + } - sink.tableRow_(); + /** + * Add a Javascript code. + * + * @param jsCode a string of Javascript + */ + protected void javaScript( final String jsCode ) + { + sink.rawText( "<script type=\"text/javascript\">\n" + jsCode + "</script>" ); } /** - * Create a new row : each cell could have a link. - * <br> - * The arrays should have the same size. - * - * @param texts an array of text - * @param hrefs an array of href + * Add a text with links inside. + * <p>The text variable should contained this given pattern <code>{text, url}</code> + * to handle the link creation.</p> + * + * @see #text(String) + * @see #applyPattern(String) + * + * @param text a text with link pattern defined. */ - protected void tableRowWithLink( String[] texts, String[] hrefs ) + public void linkPatternedText( final String text ) { - if ( hrefs.length != texts.length ) + if ( StringUtils.isEmpty( text ) ) { - throw new IllegalArgumentException( "The arrays should have the same size" ); + text( text ); + } + else + { + Map segments = applyPattern( text ); + + if ( segments == null ) + { + text( text ); + } + else + { + for (Iterator it = segments.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + + String name = (String) entry.getKey(); + String href = (String) entry.getValue(); + + if ( href == null ) + { + text( name ); + } + else + { + if ( getValidHref( href ) != null) + { + link( getValidHref( href ), name ); + } + else + { + text( text ); + } + } + } + } } + } - sink.tableRow(); + /** + * Create a link pattern text defined by <code>{text, url}</code>. + * <p>This created pattern could be used by the method <code>linkPatternedText(String)</code> to + * handle a text with link.</p> + * + * @see #linkPatternedText(String) + * + * @param text + * @param href + * @return a link pattern + */ + protected static String createLinkPatternedText( final String text, final String href ) + { + if ( text == null ) + { + return text; + } - for ( int i = 0; i < texts.length; i++ ) + if ( href == null ) { - tableCellWithLink( texts[i], hrefs[i] ); + return text; } - sink.tableRow_(); + StringBuffer sb = new StringBuffer(); + sb.append( "{" ).append( text ).append ( ", " ).append( href ).append( "}" ); + + return sb.toString(); } - - protected void tableHeader( String[] content ) + + /** + * Convenience method to display a <code>Properties</code> object comma separated. + * + * @param props + * @return the properties object as comma separated String + */ + protected static String propertiesToString( final Properties props ) { - sink.tableRow(); + StringBuffer sb = new StringBuffer(); + + if ( ( props == null ) || ( props.isEmpty() ) ) + { + return sb.toString(); + } + + for ( Iterator i = props.keySet().iterator(); i.hasNext() ; ) + { + String key = (String)i.next(); + sb.append(key).append( "=" ).append(props.get(key)); + if ( i.hasNext() ) + { + sb.append( ", " ); + } + } + + return sb.toString(); + } + + /** + * Return a valid href. + * <p>A valid href could start by <code>mailto:</code></p>. + * + * @param href an href + * @return a valid href or null if the href is not valid. + */ + private static String getValidHref( String href ) + { + href = href.trim(); + + String[] schemes = {"http", "https"}; + UrlValidator urlValidator = new UrlValidator( schemes ); - for ( int i = 0; i < content.length; i++ ) + if ( EmailValidator.getInstance().isValid( href ) ) { - tableHeaderCell( content[i] ); + return "mailto:" + href; } + else if ( href.toLowerCase().startsWith( "mailto:" ) ) + { + return href; + } + else if ( urlValidator.isValid( href ) ) + { + return href; + } + else + { + // TODO Waiting for new release of Validator + // http://issues.apache.org/bugzilla/show_bug.cgi?id=30686 + String hrefTmp = null; + if ( !href.trim().endsWith("/") ) + { + hrefTmp = href + "/index.html"; + } + else + { + hrefTmp = href + "index.html"; + } - sink.tableRow_(); - } + if ( urlValidator.isValid( hrefTmp ) ) + { + return href; + } - protected void tableCaption( String caption ) - { - sink.tableCaption(); - sink.text( caption ); - sink.tableCaption_(); + return null; + } } + + /** + * The method parses a text an apply the given pattern <code>{text, url}</code> to create + * a map of text/href. + * + * @param text a text with or without the pattern <code>{text, url}</code> + * @return a map of text/href + */ + private static Map applyPattern( final String text ) + { + if ( StringUtils.isEmpty( text ) ) + { + return null; + } + + // Map defined by key/value name/href + // If href == null, it means + Map segments = new LinkedHashMap(); - protected void paragraph( String paragraph ) - { - sink.paragraph(); + // TODO Special case http://jira.codehaus.org/browse/MEV-40 + if ( text.indexOf( "${") != -1 ) + { + int lastComma = text.lastIndexOf( "," ); + int lastSemi = text.lastIndexOf( "}" ); + if ( ( lastComma != -1 ) && ( lastSemi != -1 ) ) + { + segments.put( text.substring( lastComma + 1, lastSemi ).trim(), null ); + } + else + { + segments.put( text, null ); + } + + return segments; + } + + boolean inQuote = false; + int braceStack = 0; + int lastOffset = 0; - sink.text( paragraph ); + for ( int i = 0; i < text.length(); i++ ) { + char ch = text.charAt(i); - sink.paragraph_(); - } + if (ch == '\'') + { + // handle: '' + if ( ( i + 1 < text.length() ) && + ( text.charAt( i + 1 ) == '\'' ) ) + { + i++; + } + else + { + inQuote = true; + } + } + else + { + switch (ch) { + case '{': + if ( !inQuote ) + { + if ( braceStack == 0 ) { + if ( i != 0 ) // handle { at first character + { + segments.put( text.substring( lastOffset, i ), null); + } + lastOffset = i + 1; + braceStack++; + } + } + break; + case '}': + if ( !inQuote ) + { + braceStack--; + if (braceStack == 0) + { + String subString = text.substring( lastOffset, i ); + lastOffset = i + 1; - protected void link( String href, String name ) - { - sink.link( href ); + int lastComma = subString.lastIndexOf( "," ); + if ( lastComma != -1 ) + { + segments.put( subString.substring( 0, lastComma ).trim(), + subString.substring( lastComma + 1 ).trim() ); + } + else + { + segments.put( subString.substring( 0, lastComma ).trim(), null ); + } + } + } + break; + case '\'': + if ( inQuote ) { + inQuote = false; + } + break; + default: + break; + } + } + } - sink.text( name ); + if ( !StringUtils.isEmpty( text.substring( lastOffset, text.length() ) ) ) + { + segments.put( text.substring( lastOffset, text.length() ), null ); + } - sink.link_(); + if (braceStack != 0) + { + throw new IllegalArgumentException("Unmatched braces in the pattern."); + } + + return Collections.unmodifiableMap( segments ); } public abstract String getTitle(); Index: pom.xml =================================================================== --- pom.xml (révision 216032) +++ pom.xml (copie de travail) @@ -1,3 +1,23 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + +<!-- +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * 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 + * + * 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. + */ + --> + <project> <modelVersion>4.0.0</modelVersion> <parent> @@ -6,12 +26,17 @@ <version>2.0-beta-1-SNAPSHOT</version> </parent> <artifactId>maven-reporting-api</artifactId> - <contributors> - <contributor> + <developers> + <developer> + <id>vsiveton</id> <name>Vincent Siveton</name> <email>[EMAIL PROTECTED]</email> - </contributor> - </contributors> + <roles> + <role>Java Developer</role> + </roles> + <timezone>-5</timezone> + </developer> + </developers> <dependencies> <dependency> <groupId>org.apache.maven</groupId>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
