Package org.apache.maven.report.projectinfo

Source Code of org.apache.maven.report.projectinfo.LicenseReport$LicenseRenderer

package org.apache.maven.report.projectinfo;

/*
* 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.routines.UrlValidator;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.util.HtmlTools;
import org.apache.maven.model.License;
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.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.i18n.I18N;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Generates the Project License report.
*
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton </a>
* @version $Id: LicenseReport.java 1481337 2013-05-11 14:36:51Z rfscholte $
* @since 2.0
*/
@Mojo( name = "license" )
public class LicenseReport
    extends AbstractProjectInfoReport
{
    // ----------------------------------------------------------------------
    // Mojo parameters
    // ----------------------------------------------------------------------

    /**
     * The Maven Settings.
     */
    @Component
    private Settings settings;

    /**
     * Whether the system is currently offline.
     */
    @Parameter( property = "settings.offline" )
    private boolean offline;

    /**
     * Whether the only render links to the license documents instead of inlining them.
     * <br/>
     * If the system is in {@link #offline} mode, the linkOnly parameter will be always <code>true</code>.
     *
     * @since 2.3
     */
    @Parameter( defaultValue = "false" )
    private boolean linkOnly;

    // ----------------------------------------------------------------------
    // Public methods
    // ----------------------------------------------------------------------

    @Override
    public void executeReport( Locale locale )
    {
        LicenseRenderer r =
            new LicenseRenderer( getSink(), getProject(), getI18N( locale ), locale, settings, linkOnly );

        r.render();
    }

    @Override
    public boolean canGenerateReport()
    {
        if ( !offline )
        {
            return true;
        }

        for ( License license : project.getModel().getLicenses() )
        {
            String url = license.getUrl();

            URL licenseUrl = null;
            try
            {
                licenseUrl = getLicenseURL( project, url );
            }
            catch ( MalformedURLException e )
            {
                getLog().error( e.getMessage() );
            }
            catch ( IOException e )
            {
                getLog().error( e.getMessage() );
            }

            if ( licenseUrl != null && licenseUrl.getProtocol().equals( "file" ) )
            {
                return true;
            }

            if ( licenseUrl != null
                && ( licenseUrl.getProtocol().equals( "http" ) || licenseUrl.getProtocol().equals( "https" ) ) )
            {
                linkOnly = true;
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public String getOutputName()
    {
        return "license";
    }

    @Override
    protected String getI18Nsection()
    {
        return "license";
    }

    /**
     * @param project not null
     * @param url     not null
     * @return a valid URL object from the url string
     * @throws IOException if any
     */
    protected static URL getLicenseURL( MavenProject project, String url )
        throws IOException
    {
        URL licenseUrl = null;
        UrlValidator urlValidator = new UrlValidator( UrlValidator.ALLOW_ALL_SCHEMES );
        // UrlValidator does not accept file URLs because the file
        // URLs do not contain a valid authority (no hostname).
        // As a workaround accept license URLs that start with the
        // file scheme.
        if ( urlValidator.isValid( url ) || StringUtils.defaultString( url ).startsWith( "file://" ) )
        {
            try
            {
                licenseUrl = new URL( url );
            }
            catch ( MalformedURLException e )
            {
                throw new MalformedURLException(
                    "The license url '" + url + "' seems to be invalid: " + e.getMessage() );
            }
        }
        else
        {
            File licenseFile = new File( project.getBasedir(), url );
            if ( !licenseFile.exists() )
            {
                // Workaround to allow absolute path names while
                // staying compatible with the way it was...
                licenseFile = new File( url );
            }
            if ( !licenseFile.exists() )
            {
                throw new IOException( "Maven can't find the file '" + licenseFile + "' on the system." );
            }
            try
            {
                licenseUrl = licenseFile.toURI().toURL();
            }
            catch ( MalformedURLException e )
            {
                throw new MalformedURLException(
                    "The license url '" + url + "' seems to be invalid: " + e.getMessage() );
            }
        }

        return licenseUrl;
    }

    // ----------------------------------------------------------------------
    // Private
    // ----------------------------------------------------------------------

    /**
     * Internal renderer class
     */
    private static class LicenseRenderer
        extends AbstractProjectInfoRenderer
    {
        private final MavenProject project;

        private final Settings settings;

        private final boolean linkOnly;

        LicenseRenderer( Sink sink, MavenProject project, I18N i18n, Locale locale, Settings settings,
                         boolean linkOnly )
        {
            super( sink, i18n, locale );

            this.project = project;

            this.settings = settings;

            this.linkOnly = linkOnly;
        }

        @Override
        protected String getI18Nsection()
        {
            return "license";
        }

        @Override
        public void renderBody()
        {
            List<License> licenses = project.getModel().getLicenses();

            if ( licenses.isEmpty() )
            {
                startSection( getTitle() );

                paragraph( getI18nString( "nolicense" ) );

                endSection();

                return;
            }

            // Overview
            startSection( getI18nString( "overview.title" ) );

            paragraph( getI18nString( "overview.intro" ) );

            endSection();

            // License
            startSection( getI18nString( "title" ) );

            if ( licenses.size() > 1 )
            {
                // multiple licenses
                paragraph( getI18nString( "multiple" ) );

                if ( !linkOnly )
                {
                    // add an index before licenses content
                    sink.list();
                    for ( License license : licenses )
                    {
                        String name = license.getName();

                        sink.listItem();
                        link( "#" + HtmlTools.encodeId( name ), name );
                        sink.listItem_();
                    }
                    sink.list_();
                }
            }

            for ( License license : licenses )
            {
                String name = license.getName();
                String url = license.getUrl();
                String comments = license.getComments();

                startSection( name );

                if ( !StringUtils.isEmpty( comments ) )
                {
                    paragraph( comments );
                }

                if ( url != null )
                {
                    try
                    {
                        URL licenseUrl = getLicenseURL( project, url );

                        if ( linkOnly )
                        {
                            link( licenseUrl.toExternalForm(), licenseUrl.toExternalForm() );
                        }
                        else
                        {
                            renderLicenseContent( licenseUrl );
                        }
                    }
                    catch ( MalformedURLException e )
                    {
                        // I18N message
                        paragraph( e.getMessage() );
                    }
                    catch ( IOException e )
                    {
                        // I18N message
                        paragraph( e.getMessage() );
                    }
                }

                endSection();
            }

            endSection();
        }

        /**
         * Render the license content into the report.
         *
         * @param licenseUrl the license URL
         */
        private void renderLicenseContent( URL licenseUrl )
        {
            try
            {
                // All licenses are supposed in English...
                String licenseContent = ProjectInfoReportUtils.getContent( licenseUrl, settings );

                // TODO: we should check for a text/html mime type instead, and possibly use a html parser to do this a bit more cleanly/reliably.
                String licenseContentLC = licenseContent.toLowerCase( Locale.ENGLISH );
                int bodyStart = licenseContentLC.indexOf( "<body" );
                int bodyEnd = licenseContentLC.indexOf( "</body>" );

                if ( ( licenseContentLC.contains( "<!doctype html" ) || licenseContentLC.contains( "<html>" ) )
                    && ( ( bodyStart >= 0 ) && ( bodyEnd > bodyStart ) ) )
                {
                    bodyStart = licenseContentLC.indexOf( ">", bodyStart ) + 1;
                    String body = licenseContent.substring( bodyStart, bodyEnd );

                    link( licenseUrl.toExternalForm(), "[Original text]" );
                    paragraph( "Copy of the license follows." );

                    body = replaceRelativeLinks( body, baseURL( licenseUrl ).toExternalForm() );
                    sink.rawText( body );
                }
                else
                {
                    verbatimText( licenseContent );
                }
            }
            catch ( IOException e )
            {
                paragraph( "Can't read the url [" + licenseUrl + "] : " + e.getMessage() );
            }
        }

        private static URL baseURL( URL aUrl )
        {
            String urlTxt = aUrl.toExternalForm();
            int lastSlash = urlTxt.lastIndexOf( '/' );
            if ( lastSlash > -1 )
            {
                try
                {
                    return new URL( urlTxt.substring( 0, lastSlash + 1 ) );
                }
                catch ( MalformedURLException e )
                {
                    throw new AssertionError( e );
                }
            }

            return aUrl;
        }

        private static String replaceRelativeLinks( String html, String baseURL )
        {
            String url = baseURL;
            if ( !url.endsWith( "/" ) )
            {
                url += "/";
            }

            String serverURL = url.substring( 0, url.indexOf( '/', url.indexOf( "//" ) + 2 ) );

            String content = replaceParts( html, url, serverURL, "[aA]", "[hH][rR][eE][fF]" );
            content = replaceParts( content, url, serverURL, "[iI][mM][gG]", "[sS][rR][cC]" );
            return content;
        }

        private static String replaceParts( String html, String baseURL, String serverURL, String tagPattern,
                                            String attributePattern )
        {
            Pattern anchor = Pattern.compile(
                "(<\\s*" + tagPattern + "\\s+[^>]*" + attributePattern + "\\s*=\\s*\")([^\"]*)\"([^>]*>)" );
            StringBuilder sb = new StringBuilder( html );

            int indx = 0;
            boolean done = false;
            while ( !done )
            {
                Matcher mAnchor = anchor.matcher( sb );
                if ( mAnchor.find( indx ) )
                {
                    indx = mAnchor.end( 3 );

                    if ( mAnchor.group( 2 ).startsWith( "#" ) )
                    {
                        // relative link - don't want to alter this one!
                    }
                    if ( mAnchor.group( 2 ).startsWith( "/" ) )
                    {
                        // root link
                        sb.insert( mAnchor.start( 2 ), serverURL );
                        indx += serverURL.length();
                    }
                    else if ( mAnchor.group( 2 ).indexOf( ':' ) < 0 )
                    {
                        // relative link
                        sb.insert( mAnchor.start( 2 ), baseURL );
                        indx += baseURL.length();
                    }
                }
                else
                {
                    done = true;
                }
            }
            return sb.toString();
        }
    }
}
TOP

Related Classes of org.apache.maven.report.projectinfo.LicenseReport$LicenseRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.