All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.plugins.linkcheck.LinkcheckReport Maven / Gradle / Ivy

Go to download

This plugin allows you to generate a linkcheck report of your project's documentation.

The newest version!
package org.apache.maven.plugins.linkcheck;

/*
 * 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.artifact.repository.ArtifactRepository;
import org.apache.maven.doxia.linkcheck.HttpBean;
import org.apache.maven.doxia.linkcheck.LinkCheck;
import org.apache.maven.doxia.linkcheck.LinkCheckException;
import org.apache.maven.doxia.linkcheck.model.LinkcheckModel;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.i18n.I18N;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Properties;

/**
 * Generates a Linkcheck report.
 *
 * @author Vincent Siveton
 * @version $Id$
 * @since 1.0
 */
@Mojo( name = "linkcheck" )
public class LinkcheckReport
    extends AbstractMavenReport
{
    // ----------------------------------------------------------------------
    // Report Components
    // ----------------------------------------------------------------------

    /**
     * Internationalization.
     */
    @Component
    private I18N i18n;

    /**
     * LinkCheck component.
     */
    @Component
    private LinkCheck linkCheck;

    // ----------------------------------------------------------------------
    // Report Parameters
    // ----------------------------------------------------------------------

    /**
     * Local Repository.
     */
    @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
    private ArtifactRepository localRepository;

    /**
     * The Maven Settings.
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    private Settings settings;

    // ----------------------------------------------------------------------
    // Linkcheck parameters
    // ----------------------------------------------------------------------

    /**
     * Whether we are offline or not.
     */
    @Parameter( property = "linkcheck.offline", defaultValue = "${settings.offline}", required = true )
    private boolean offline;

    /**
     * If online, the HTTP method should automatically follow HTTP redirects, false otherwise.
     *
     * @parameter default-value="true"
     */
    @Parameter( defaultValue = "true" )
    private boolean httpFollowRedirect;

    /**
     * The location of the Linkcheck cache file.
     */
    @Parameter( defaultValue = "${project.build.directory}/linkcheck/linkcheck.cache", required = true )
    protected File linkcheckCache;

    /**
     * The location of the Linkcheck report file.
     */
    @Parameter( defaultValue = "${project.build.directory}/linkcheck/linkcheck.xml", required = true )
    protected File linkcheckOutput;

    // CHECKSTYLE_OFF: LineLength
    /**
     * The HTTP method to use. Currently supported are "GET" and "HEAD".
     * 
*
HTTP GET
*
The HTTP GET method is defined in section 9.3 of RFC2616: * The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.
*
HTTP HEAD
*
The HTTP HEAD method is defined in section 9.4 of RFC2616: * The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.
*
*/ // CHECKSTYLE_ON: LineLength @Parameter( defaultValue = "head", required = true ) private String httpMethod; /** * The list of HTTP errors to ignored, like 404. * * @see {@link org.apache.commons.httpclient.HttpStatus} for all defined values. */ @Parameter private Integer[] excludedHttpStatusErrors; /** * The list of HTTP warnings to ignored, like 301. * * @see {@link org.apache.commons.httpclient.HttpStatus} for all defined values. */ @Parameter private Integer[] excludedHttpStatusWarnings; /** * A list of pages to exclude.
* Note:
*
    *
  • This report, i.e. linkcheck.html, is always excluded.
  • *
  • May contain Ant-style wildcards and double wildcards, e.g. apidocs/**, etc.
  • *
*/ @Parameter private String[] excludedPages; /** * The list of links to exclude.
* Note: Patterns like **/dummy/* are allowed for excludedLink. */ @Parameter private String[] excludedLinks; /** * The file encoding to use when Linkcheck reads the source files. If the property * project.build.sourceEncoding is not set, the platform default encoding is used. */ @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" ) private String encoding; /** * The extra HttpClient parameters to be used when fetching links. For instance: * *
     * <httpClientParameters>
     *  <property>
     *   <name>http.protocol.max-redirects</name>
     *   <value>10</value>
     *  </property>
     * </httpClientParameters>
     * 
* * See HttpClient preference page */ @Parameter( property = "httpClientParameters" ) private Properties httpClientParameters; /** * Set the timeout to be used when fetching links. A value of zero means the timeout is not used. */ @Parameter( property = "timeout", defaultValue = "2000" ) private int timeout; /** * true to skip the report execution, false otherwise. * The purpose is to prevent infinite call when {@link #forceSite} is enable. */ @Parameter( property = "linkcheck.skip", defaultValue = "false" ) private boolean skip; /** * true to force the site generation, false otherwise. * Using this parameter ensures that all documents have been correctly generated. */ @Parameter( property = "linkcheck.forceSite", defaultValue = "true" ) private boolean forceSite; /** * The base URL to use for absolute links (eg /index.html) in the site. */ @Parameter( property = "linkcheck.baseURL", defaultValue = "${project.url}" ) private String baseURL; // ---------------------------------------------------------------------- // Instance fields // ---------------------------------------------------------------------- /** Result of the linkcheck in {@link #execute()} */ private LinkcheckModel result; protected static final String ICON_SUCCESS = "images/icon_success_sml.gif"; protected static final String ICON_WARNING = "images/icon_warning_sml.gif"; protected static final String ICON_INFO = "images/icon_info_sml.gif"; protected static final String ICON_ERROR = "images/icon_error_sml.gif"; private static final String PLUGIN_RESOURCES_BASE = "org/apache/maven/plugin/linkcheck"; private static final String RESOURCE_NAMES[] = { ICON_SUCCESS, ICON_WARNING, ICON_INFO, ICON_ERROR }; // ---------------------------------------------------------------------- // Public methods // ---------------------------------------------------------------------- /** {@inheritDoc} */ public String getDescription( Locale locale ) { return i18n.getString( "linkcheck-report", locale, "report.linkcheck.description" ); } /** {@inheritDoc} */ public String getName( Locale locale ) { return i18n.getString( "linkcheck-report", locale, "report.linkcheck.name" ); } /** {@inheritDoc} */ public String getOutputName() { return "linkcheck"; } /** {@inheritDoc} */ public boolean canGenerateReport() { return !skip; } /** {@inheritDoc} */ public void execute() throws MojoExecutionException { if ( !canGenerateReport() ) { return; } checkEncoding(); try { result = executeLinkCheck( getBasedir() ); } catch ( LinkCheckException e ) { throw new MojoExecutionException( "LinkCheckException: " + e.getMessage(), e ); } } // ---------------------------------------------------------------------- // Protected methods // ---------------------------------------------------------------------- /** {@inheritDoc} */ protected void executeReport( Locale locale ) throws MavenReportException { if ( result == null ) { getLog().debug( "Calling execute()" ); try { this.execute(); } catch ( MojoExecutionException e ) { throw new MavenReportException( "MojoExecutionException: " + e.getMessage(), e ); } } if ( result != null ) { generateReport( locale, result ); // free memory result = null; } } // ---------------------------------------------------------------------- // Private methods // ---------------------------------------------------------------------- private void checkEncoding() { if ( StringUtils.isEmpty( encoding ) ) { if ( getLog().isWarnEnabled() ) { getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING + ", i.e. build is platform dependent!" ); } encoding = ReaderFactory.FILE_ENCODING; } } private File getBasedir() throws MojoExecutionException { File basedir; if ( forceSite ) { basedir = new File( linkcheckOutput.getParentFile(), "tmpsite" ); basedir.mkdirs(); List documents = null; try { documents = FileUtils.getFiles( basedir, "**/*.html", null ); } catch ( IOException e ) { getLog().error( "IOException: " + e.getMessage() ); getLog().debug( e ); } // if the site was not already generated, invoke it if ( documents == null || ( documents != null && documents.size() == 0 ) ) { getLog().info( "Invoking the maven-site-plugin to ensure that all files are generated..." ); try { SiteInvoker invoker = new SiteInvoker( localRepository, getLog() ); invoker.invokeSite( project, basedir ); } catch ( IOException e ) { throw new MojoExecutionException( "IOException: " + e.getMessage(), e ); } } } else { getLog().warn( "The number of documents analyzed by Linkcheck could differ from the actual " + "number of documents!" ); basedir = outputDirectory; basedir.mkdirs(); } return basedir; } /** * Execute the Linkcheck tool. * * @param basedir not null * @throws LinkCheckException if any */ private LinkcheckModel executeLinkCheck( File basedir ) throws LinkCheckException { // Wrap linkcheck linkCheck.setOnline( !offline ); linkCheck.setBasedir( basedir ); linkCheck.setBaseURL( baseURL ); linkCheck.setReportOutput( linkcheckOutput ); linkCheck.setLinkCheckCache( linkcheckCache ); linkCheck.setExcludedLinks( excludedLinks ); linkCheck.setExcludedPages( getExcludedPages() ); linkCheck.setExcludedHttpStatusErrors( asIntArray( excludedHttpStatusErrors ) ); linkCheck.setExcludedHttpStatusWarnings( asIntArray( excludedHttpStatusWarnings ) ); linkCheck.setEncoding( ( StringUtils.isNotEmpty( encoding ) ? encoding : ReaderFactory.UTF_8 ) ); HttpBean bean = new HttpBean(); bean.setMethod( httpMethod ); bean.setFollowRedirects( httpFollowRedirect ); bean.setTimeout( timeout ); if ( httpClientParameters != null ) { bean.setHttpClientParameters( httpClientParameters ); } Proxy proxy = settings.getActiveProxy(); if ( proxy != null ) { bean.setProxyHost( proxy.getHost() ); bean.setProxyPort( proxy.getPort() ); bean.setProxyUser( proxy.getUsername() ); bean.setProxyPassword( proxy.getPassword() ); } linkCheck.setHttp( bean ); return linkCheck.execute(); } /** * @return the excludedPages defined by the user and also this report. */ private String[] getExcludedPages() { List pagesToExclude = ( excludedPages != null ? new ArrayList( Arrays.asList( excludedPages ) ) : new ArrayList() ); // Exclude this report pagesToExclude.add( getOutputName() + ".html" ); return (String[]) pagesToExclude.toArray( new String[pagesToExclude.size()] ); } // ---------------------------------------------------------------------- // Linkcheck report // ---------------------------------------------------------------------- private void generateReport( Locale locale, LinkcheckModel linkcheckModel ) { LinkcheckReportGenerator reportGenerator = new LinkcheckReportGenerator( i18n ); reportGenerator.setExcludedHttpStatusErrors( excludedHttpStatusErrors ); reportGenerator.setExcludedHttpStatusWarnings( excludedHttpStatusWarnings ); reportGenerator.setExcludedLinks( excludedLinks ); reportGenerator.setExcludedPages( excludedPages ); reportGenerator.setHttpFollowRedirect( httpFollowRedirect ); reportGenerator.setHttpMethod( httpMethod ); reportGenerator.setOffline( offline ); reportGenerator.generateReport( locale, linkcheckModel, getSink() ); closeReport(); // Copy the images copyStaticResources(); } private void copyStaticResources() { try { getLog().debug( "Copying static linkcheck resources." ); for ( String resourceName : RESOURCE_NAMES ) { URL url = this.getClass().getClassLoader().getResource( PLUGIN_RESOURCES_BASE + "/" + resourceName ); FileUtils.copyURLToFile( url, new File( getReportOutputDirectory(), resourceName ) ); } } catch ( IOException e ) { getLog().error( "Unable to copy icons for linkcheck report." ); getLog().debug( e ); } } private static int[] asIntArray( Integer[] array ) { if ( array == null ) { return null; } int[] newArray = new int[array.length]; for ( int i = 0; i < array.length; i++ ) { newArray[i] = array[i]; } return newArray; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy