maven-reporting-impl-2.1/0000755000175000017500000000000011634450404015367 5ustar twernertwernermaven-reporting-impl-2.1/src/0000755000175000017500000000000011634450404016156 5ustar twernertwernermaven-reporting-impl-2.1/src/site/0000755000175000017500000000000011634450404017122 5ustar twernertwernermaven-reporting-impl-2.1/src/site/site.xml0000644000175000017500000000210511371364254020613 0ustar twernertwerner maven-reporting-impl-2.1/src/site/apt/0000755000175000017500000000000011634450404017706 5ustar twernertwernermaven-reporting-impl-2.1/src/site/apt/index.apt0000644000175000017500000000146011371614120021517 0ustar twernertwerner ----- Maven Reporting Implementation ----- Hervé Boutemy ----- 2010-05-09 ----- Maven Reporting Implementation Abstract classes to manage report generation. Until Maven 2.0.4, <<>> was included in Maven 2 core distribution: version used was completely driven by Maven version used. It was removed from Maven core starting with Maven 2.0.5 and moved to shared components to improve fexibility: starting with Maven 2.0.5, each plugin can choose its <<>> version independently from Maven. <<>> uses Doxia 1.0, then is used for reporting plugins wanting Maven 2.0.x compatibility. <<>> uses Doxia 1.1: using this version implies for a reporting plugin that it has Maven 2.1 as prerequisite. maven-reporting-impl-2.1/src/test/0000755000175000017500000000000011634450404017135 5ustar twernertwernermaven-reporting-impl-2.1/src/test/java/0000755000175000017500000000000011634450404020056 5ustar twernertwernermaven-reporting-impl-2.1/src/test/java/org/0000755000175000017500000000000011634450404020645 5ustar twernertwernermaven-reporting-impl-2.1/src/test/java/org/apache/0000755000175000017500000000000011634450404022066 5ustar twernertwernermaven-reporting-impl-2.1/src/test/java/org/apache/maven/0000755000175000017500000000000011634450404023174 5ustar twernertwernermaven-reporting-impl-2.1/src/test/java/org/apache/maven/reporting/0000755000175000017500000000000011634450404025205 5ustar twernertwerner././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmaven-reporting-impl-2.1/src/test/java/org/apache/maven/reporting/AbstractMavenReportRendererTest.javamaven-reporting-impl-2.1/src/test/java/org/apache/maven/reporting/AbstractMavenReportRendererTest.ja0000644000175000017500000001102611177405244034002 0ustar twernertwernerpackage org.apache.maven.reporting; /* * 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 * * 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. */ import java.util.Iterator; import java.util.List; import junit.framework.Assert; import junit.framework.TestCase; import junitx.util.PrivateAccessor; /** * Test case for some public method in AbstractMavenReportRenderer. */ public class AbstractMavenReportRendererTest extends TestCase { private static List applyPattern( String pattern ) throws Throwable { return (List) PrivateAccessor.invoke( AbstractMavenReportRenderer.class, "applyPattern", new Class[] { String.class }, new Object[] { pattern } ); } private static void checkPattern( String pattern, String[] expectedResult ) throws Throwable { List result = applyPattern( pattern ); Assert.assertEquals( "result size", expectedResult.length, result.size() ); int i = 0; for ( Iterator it = result.iterator(); it.hasNext(); ) { String name = (String) it.next(); String href = (String) it.next(); Assert.assertEquals( expectedResult[i], name ); Assert.assertEquals( expectedResult[i + 1], href ); i += 2; } } private static void checkPatternIllegalArgument( String cause, String pattern ) throws Throwable { try { applyPattern( pattern ); Assert.fail( cause + " should throw an IllegalArgumentException" ); } catch ( IllegalArgumentException iae ) { // ok } } /** * @throws Throwable if any */ public void testApplyPattern() throws Throwable { // the most simple test checkPattern( "test {text,url}", new String[] { "test ", null, "text", "url" } ); // check that link content is trimmed, and no problem if 2 text values are the same checkPattern( "test{ text , url }test", new String[] { "test", null, "text", "url", "test", null } ); // check brace stacking checkPattern( "test{ {text} , url }", new String[] { "test", null, "{text}", "url" } ); // check quoting checkPatternIllegalArgument( "unmatched brace", "{" ); checkPattern( "'{'", new String[] { "'{'", null } ); checkPattern( " ' { '.", new String[] { " ' { '.", null } ); // unmatched quote: the actual behavior is to ignore that they are unmatched checkPattern( " '", new String[] { " '", null } ); // but shouldn't it be different and throw an IllegalArgumentException? // checkPatternIllegalArgument( "unmatched quote", " ' " ); // checkPatternIllegalArgument( "unmatched quote", " '" ); // impact is too important to make the change for the moment // check double quoting checkPattern( " ''", new String[] { " '", null } ); checkPattern( " '' ", new String[] { " '", null } ); checkPattern( " '' ", new String[] { " '", null } ); // real world cases with quote checkPattern( "project''s info", new String[] { "project'", null, "s info", null } ); checkPattern( "it''s a question of {chance, http://en.wikipedia.org/wiki/Chance}", new String[] { "it'", null, "s a question of ", null, "chance", "http://en.wikipedia.org/wiki/Chance" } ); checkPattern( "{s'inscrire,mail@mail.com}", new String[] { "s'inscrire", "mail@mail.com" } ); // throwing an IllegalArgumentException in case of unmatched quote would avoid the following: checkPattern( "it's a question of {chance, http://en.wikipedia.org/wiki/Chance}", new String[] { "it's a question of {chance, http://en.wikipedia.org/wiki/Chance}", null } ); checkPattern( "{}test,", new String[] { "", null, "test,", null } ); } } maven-reporting-impl-2.1/src/main/0000755000175000017500000000000011634450404017102 5ustar twernertwernermaven-reporting-impl-2.1/src/main/java/0000755000175000017500000000000011634450404020023 5ustar twernertwernermaven-reporting-impl-2.1/src/main/java/org/0000755000175000017500000000000011634450404020612 5ustar twernertwernermaven-reporting-impl-2.1/src/main/java/org/apache/0000755000175000017500000000000011634450404022033 5ustar twernertwernermaven-reporting-impl-2.1/src/main/java/org/apache/maven/0000755000175000017500000000000011634450404023141 5ustar twernertwernermaven-reporting-impl-2.1/src/main/java/org/apache/maven/reporting/0000755000175000017500000000000011634450404025152 5ustar twernertwernermaven-reporting-impl-2.1/src/main/java/org/apache/maven/reporting/AbstractMavenReport.java0000644000175000017500000002240211371614120031736 0ustar twernertwernerpackage org.apache.maven.reporting; /* * 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 * * 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. */ import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.SinkFactory; import org.apache.maven.doxia.sink.render.RenderingContext; import org.apache.maven.doxia.site.decoration.DecorationModel; import org.apache.maven.doxia.siterenderer.Renderer; import org.apache.maven.doxia.siterenderer.RendererException; import org.apache.maven.doxia.siterenderer.SiteRenderingContext; import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.IOUtil; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Locale; /** * The basis for a Maven report which can be generated both as part of a site generation or * as a direct standalone invocation. * * @author Emmanuel Venisse * @version $Id: AbstractMavenReport.java 942606 2010-05-09 20:17:20Z hboutemy $ * @since 2.0 * @see #execute() * @see #generate(Sink, SinkFactory, Locale) * @see #executeReport(Locale) */ public abstract class AbstractMavenReport extends AbstractMojo implements MavenMultiPageReport { /** The current sink to use */ private Sink sink; /** The sink factory to use */ private SinkFactory sinkFactory; /** The current report output directory to use */ private File reportOutputDirectory; /** * This method is called when the report generation is invoked directly as a standalone Mojo. * * @throws MojoExecutionException if an error occurs when generating the report * @see org.apache.maven.plugins.site.ReportDocumentRender * @see org.apache.maven.plugin.Mojo#execute() */ public void execute() throws MojoExecutionException { if ( !canGenerateReport() ) { return; } Writer writer = null; try { File outputDirectory = new File( getOutputDirectory() ); String filename = getOutputName() + ".html"; Locale locale = Locale.getDefault(); SiteRenderingContext siteContext = new SiteRenderingContext(); siteContext.setDecoration( new DecorationModel() ); siteContext.setTemplateName( "org/apache/maven/doxia/siterenderer/resources/default-site.vm" ); siteContext.setLocale( locale ); RenderingContext context = new RenderingContext( outputDirectory, filename ); SiteRendererSink sink = new SiteRendererSink( context ); generate( sink, null, locale ); outputDirectory.mkdirs(); writer = new OutputStreamWriter( new FileOutputStream( new File( outputDirectory, filename ) ), "UTF-8" ); getSiteRenderer().generateDocument( writer, sink, siteContext ); //getSiteRenderer().copyResources( siteContext, new File( project.getBasedir(), "src/site/resources" ), // outputDirectory ); } catch ( RendererException e ) { throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e ); } catch ( IOException e ) { throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e ); } catch ( MavenReportException e ) { throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e ); } finally { IOUtil.close( writer ); } } /** * Generate a report. * * @param aSink the sink to use for the generation. * @param aLocale the wanted locale to generate the report, could be null. * @throws MavenReportException if any * @deprecated use {@link #generate(Sink, SinkFactory, Locale)} instead. */ public void generate( org.codehaus.doxia.sink.Sink aSink, Locale aLocale ) throws MavenReportException { getLog().warn( "Deprecated API called - not org.apache.maven.doxia.sink.Sink instance and no SinkFactory" + " available. Please update this plugin." ); generate( aSink, null, aLocale ); } /** * Generate a report. * * @param aSink * @param aLocale * @throws MavenReportException * @see org.apache.maven.reporting.MavenReport#generate(org.apache.maven.doxia.sink.Sink, java.util.Locale) * @deprecated use {@link #generate(Sink, SinkFactory, Locale)} instead. */ public void generate( Sink aSink, Locale aLocale ) throws MavenReportException { getLog().warn( "Deprecated API called - no SinkFactory available. Please update this plugin." ); generate( aSink, null, aLocale ); } /** * This method is called when the report generation is invoked by maven-site-plugin. * * @param aSink * @param aSinkFactory * @param aLocale * @throws MavenReportException */ public void generate( Sink aSink, SinkFactory aSinkFactory, Locale aLocale ) throws MavenReportException { if ( aSink == null ) { throw new MavenReportException( "You must specify a sink." ); } if ( !canGenerateReport() ) { getLog().info( "This report cannot be generated as part of the current build. " + "The report name should be referenced in this line of output." ); return; } this.sink = aSink; this.sinkFactory = aSinkFactory; executeReport( aLocale ); closeReport(); } /** {@inheritDoc} */ public String getCategoryName() { return CATEGORY_PROJECT_REPORTS; } /** {@inheritDoc} */ public File getReportOutputDirectory() { if ( reportOutputDirectory == null ) { reportOutputDirectory = new File( getOutputDirectory() ); } return reportOutputDirectory; } /** {@inheritDoc} */ public void setReportOutputDirectory( File reportOutputDirectory ) { this.reportOutputDirectory = reportOutputDirectory; } /** * Actions when closing the report. */ protected void closeReport() { getSink().close(); } /** * @return the sink used */ public Sink getSink() { return sink; } /** * @return the sink factory used */ public SinkFactory getSinkFactory() { return sinkFactory; } /** * @see org.apache.maven.reporting.MavenReport#isExternalReport() * @return false by default. */ public boolean isExternalReport() { return false; } /** {@inheritDoc} */ public boolean canGenerateReport() { return true; } /** * @return the site renderer used. */ protected abstract Renderer getSiteRenderer(); /** * The output directory when the mojo is run directly from the command line. Implementors should use this method to * return the value of a mojo parameter that the user may use to customize the output directory. *
* Note: * When the mojo is run as part of a site generation, Maven will set the effective output directory via * {@link org.apache.maven.reporting.MavenReport#setReportOutputDirectory(java.io.File)}. In this case, the return * value of this method is irrelevant. Therefore, developers should always call {@link #getReportOutputDirectory()} * to get the effective output directory for the report. The later method will eventually fallback to this method * if the mojo is not run as part of a site generation. * * @return The path to the output directory as specified in the plugin configuration for this report. */ protected abstract String getOutputDirectory(); /** * @return the Maven project instance. */ protected abstract MavenProject getProject(); /** * Execute the generation of the report. * * @param locale the wanted locale to return the report's description, could be null. * @throws MavenReportException if any */ protected abstract void executeReport( Locale locale ) throws MavenReportException; } maven-reporting-impl-2.1/src/main/java/org/apache/maven/reporting/AbstractMavenReportRenderer.java0000644000175000017500000005435111371614120033435 0ustar twernertwernerpackage org.apache.maven.reporting; /* * 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 * * 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. */ 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.List; import java.util.Properties; /** * An abstract class to manage report generation. * * @author Jason van Zyl * @author Emmanuel Venisse * @author Vincent Siveton * @version $Id: AbstractMavenReportRenderer.java 942606 2010-05-09 20:17:20Z hboutemy $ * @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(); sink.close(); } // ---------------------------------------------------------------------- // 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; switch ( section ) { case 1: sink.section1(); sink.sectionTitle1(); break; case 2: sink.section2(); sink.sectionTitle2(); break; case 3: sink.section3(); sink.sectionTitle3(); break; case 4: sink.section4(); sink.sectionTitle4(); break; case 5: sink.section5(); sink.sectionTitle5(); break; default: // TODO: warning - just don't start a section break; } text( name ); switch ( section ) { case 1: sink.sectionTitle1_(); break; case 2: sink.sectionTitle2_(); break; case 3: sink.sectionTitle3_(); break; case 4: sink.sectionTitle4_(); break; case 5: sink.sectionTitle5_(); break; default: // TODO: warning - just don't start a section break; } sink.anchor( HtmlTools.encodeId( name ) ); sink.anchor_(); } /** * 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 ) { case 1: sink.section1_(); break; case 2: sink.section2_(); break; case 3: sink.section3_(); break; case 4: sink.section4_(); break; case 5: sink.section5_(); break; default: // TODO: warning - just don't start a section break; } section = section - 1; if ( section < 0 ) { throw new IllegalStateException( "Too many closing sections" ); } } // ---------------------------------------------------------------------- // Table handler // ---------------------------------------------------------------------- /** * Convenience method to wrap the table start in the current sink. * * @see Sink#table() */ protected void startTable() { startTable( new int[] {Sink.JUSTIFY_LEFT}, false ); } /** * Convenience method to wrap the table start in the current sink. * * @param justification the justification of table cells. * @param grid whether to draw a grid around cells. * * @see Sink#table() * @see Sink#tableRows(int[],boolean) * @since 2.1 */ protected void startTable( int[] justification, boolean grid ) { sink.table(); sink.tableRows( justification, grid ); } /** * Convenience method to wrap the table ending in the current sink. * * @see Sink#table_() */ protected void endTable() { sink.tableRows_(); 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(); text( text ); sink.tableHeaderCell_(); } /** * Convenience method to wrap a table cell start in the current sink. *

The text could be a link patterned text defined by {text, url}

* * @param text the text to put in this cell, could be null. * @see #linkPatternedText(String) * @see #tableCell(String) */ protected void tableCell( String text ) { tableCell( text, false ); } /** * Convenience method to wrap a table cell start in the current sink. *

The text could be a link patterned text defined by {text, url}

*

If asHtml is true, add the text as Html

* * @param text the text to put in this cell, could be null. * @param asHtml true to add the text as Html, false otherwise. * @see #linkPatternedText(String) * @see Sink#tableCell() * @see Sink#tableCell_() * @see Sink#rawText(String) */ protected void tableCell( String text, boolean asHtml ) { sink.tableCell(); if ( asHtml ) { sink.rawText( text ); } else { linkPatternedText( text ); } sink.tableCell_(); } /** * Convenience method to wrap a table row start in the current sink. *

The texts in the content could be link patterned texts defined by {text, url}

* * @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(); if ( content != null ) { 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. *

The texts in the content could be link patterned texts defined by {text, url}

* * @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(); if ( content != null ) { 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(); text( caption ); 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(); text( paragraph ); 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 ); text( name ); sink.link_(); } /** * Convenience method to wrap a text in the current sink. *

If text is empty or has a null value, add the "-" charater

* * @param text a text, could be null. * @see Sink#text(String) */ protected void text( String text ) { if ( StringUtils.isEmpty( text ) ) // Take care of spaces { sink.text( "-" ); } else { sink.text( text ); } } /** * Convenience method to wrap a text as verbatim style in the current sink . * * @param text a text, could be null. * @see #text(String) * @see Sink#verbatim(boolean) * @see Sink#verbatim_() */ protected void verbatimText( String text ) { sink.verbatim( true ); text( text ); sink.verbatim_(); } /** * 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 ) { if ( StringUtils.isEmpty( href ) ) { verbatimText( text ); } else { sink.verbatim( true ); link( href, text ); sink.verbatim_(); } } /** * 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 ) { sink.rawText( "" ); } /** * Convenience method to wrap a patterned text in the current link. *

The text variable should contained this given pattern {text, url} * to handle the link creation.

* * @param text a text with link pattern defined. * @see #text(String) * @see #link(String, String) * @see #applyPattern(String) */ public void linkPatternedText( String text ) { if ( StringUtils.isEmpty( text ) ) { text( text ); } else { List segments = applyPattern( text ); if ( segments == null ) { text( text ); } else { for ( Iterator it = segments.iterator(); it.hasNext(); ) { String name = (String) it.next(); String href = (String) it.next(); if ( href == null ) { text( name ); } else { if ( getValidHref( href ) != null ) { link( getValidHref( href ), name ); } else { text( href ); } } } } } } /** * Create a link pattern text defined by {text, url}. *

This created pattern could be used by the method linkPatternedText(String) to * handle a text with link.

* * @param text * @param href * @return a link pattern * @see #linkPatternedText(String) */ protected static String createLinkPatternedText( String text, String href ) { if ( text == null ) { return text; } if ( href == null ) { return text; } StringBuffer sb = new StringBuffer(); sb.append( "{" ).append( text ).append( ", " ).append( href ).append( "}" ); return sb.toString(); } /** * Convenience method to display a Properties object as comma separated String. * * @param props the properties to display. * @return the properties object as comma separated String */ protected static String propertiesToString( Properties props ) { 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(); } // ---------------------------------------------------------------------- // Private methods // ---------------------------------------------------------------------- /** * Return a valid href. *

A valid href could start by mailto:.

*

For a relative path, the href should start by ./ to be valid.

* * @param href an href, could be null. * @return a valid href or null 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"}; UrlValidator urlValidator = new UrlValidator( schemes ); if ( ( EmailValidator.getInstance().isValid( href ) ) || ( ( href.indexOf( "?" ) != -1 ) && ( EmailValidator.getInstance().isValid( href.substring( 0, href.indexOf( "?" ) ) ) ) ) ) { return "mailto:" + href; } else if ( href.toLowerCase().startsWith( "mailto:" ) ) { return href; } else if ( urlValidator.isValid( href ) ) { return href; } else { String hrefTmp; if ( !href.endsWith( "/" ) ) { hrefTmp = href + "/index.html"; } else { hrefTmp = href + "index.html"; } if ( urlValidator.isValid( hrefTmp ) ) { return href; } if ( href.startsWith( "./" ) ) { if ( href.length() > 2 ) { return href.substring( 2, href.length() ); } return "."; } return null; } } /** * The method parses a text and applies the given pattern {text, url} to create * a list of text/href. * * @param text a text with or without the pattern {text, url} * @return a map of text/href */ private static List applyPattern( String text ) { if ( StringUtils.isEmpty( text ) ) { return null; } // Map defined by key/value name/href // If href == null, it means List segments = new ArrayList(); // 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.add( text.substring( lastComma + 1, lastSemi ).trim() ); segments.add( null ); } else { segments.add( text ); segments.add( null ); } return segments; } boolean inQuote = false; int braceStack = 0; int lastOffset = 0; for ( int i = 0; i < text.length(); i++ ) { char ch = text.charAt( i ); if ( ch == '\'' && !inQuote && braceStack == 0 ) { // handle: '' if ( i + 1 < text.length() && text.charAt( i + 1 ) == '\'' ) { i++; segments.add( text.substring( lastOffset, i ) ); segments.add( null ); lastOffset = i + 1; } else { inQuote = true; } } else { switch ( ch ) { case '{': if ( !inQuote ) { if ( braceStack == 0 ) { if ( i != 0 ) // handle { at first character { segments.add( text.substring( lastOffset, i ) ); segments.add( null ); } lastOffset = i + 1; } braceStack++; } break; case '}': if ( !inQuote ) { braceStack--; if ( braceStack == 0 ) { String subString = text.substring( lastOffset, i ); lastOffset = i + 1; int lastComma = subString.lastIndexOf( "," ); if ( lastComma != -1 ) { segments.add( subString.substring( 0, lastComma ).trim() ); segments.add( subString.substring( lastComma + 1 ).trim() ); } else { segments.add( subString ); segments.add( null ); } } } break; case '\'': inQuote = false; break; default: break; } } } if ( !StringUtils.isEmpty( text.substring( lastOffset, text.length() ) ) ) { segments.add( text.substring( lastOffset, text.length() ) ); segments.add( null ); } if ( braceStack != 0 ) { throw new IllegalArgumentException( "Unmatched braces in the pattern." ); } 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(); } maven-reporting-impl-2.1/src/main/java/org/apache/maven/reporting/MavenMultiPageReport.java0000644000175000017500000000247211367653450032105 0ustar twernertwernerpackage org.apache.maven.reporting; /* * 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 * * 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. */ import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.SinkFactory; import java.util.Locale; /** * Temporary copy of maven-reporting-api class to avoid * Maven 3 prerequisite, since maven-reporting-api is included * in Maven 2 then internal version is preferred. */ public interface MavenMultiPageReport extends MavenReport { void generate( Sink sink, SinkFactory sinkFactory, Locale locale ) throws MavenReportException; } maven-reporting-impl-2.1/src/main/assembly/0000755000175000017500000000000011634450404020721 5ustar twernertwernermaven-reporting-impl-2.1/pom.xml0000644000175000017500000001065411371614342016713 0ustar twernertwerner 4.0.0 org.apache.maven.shared maven-shared-components 15 org.apache.maven.reporting maven-reporting-impl 2.1 Maven Reporting Implementation Abstract classes to manage report generation. vsiveton Vincent Siveton vincent.siveton@gmail.com Java Developer -5 scm:svn:http://svn.apache.org/repos/asf/maven/shared/tags/maven-reporting-impl-2.1 scm:svn:https://svn.apache.org/repos/asf/maven/shared/tags/maven-reporting-impl-2.1 http://svn.apache.org/viewvc/maven/shared/tags/maven-reporting-impl-2.1 jira http://jira.codehaus.org/browse/MSHARED/component/13274 2.0.10 1.1.2 org.apache.maven.reporting maven-reporting-api 3.0 org.apache.maven maven-project ${mavenVersion} org.apache.maven maven-plugin-api ${mavenVersion} org.apache.maven.doxia doxia-sink-api ${doxiaVersion} org.apache.maven.doxia doxia-core ${doxiaVersion} org.apache.maven.doxia doxia-site-renderer ${doxiaVersion} commons-validator commons-validator 1.2.0 org.codehaus.plexus plexus-utils 1.5.8 junit junit 3.8.2 test junit-addons junit-addons 1.4 test reporting org.codehaus.mojo clirr-maven-plugin 2.0.4.1