Package com.atlassian.maven.plugin.clover.internal.instrumentation

Source Code of com.atlassian.maven.plugin.clover.internal.instrumentation.AbstractInstrumenter

package com.atlassian.maven.plugin.clover.internal.instrumentation;

/*
* 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 com.atlassian.maven.plugin.clover.MvnLogger;
import com.atlassian.maven.plugin.clover.internal.CompilerConfiguration;
import com.atlassian.maven.plugin.clover.internal.scanner.CloverSourceScanner;
import com.cenqua.clover.CloverInstr;
import com.cenqua.clover.Logger;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Code common for instrumentation of various source roots (main sources, test sources).
*
*/
public abstract class AbstractInstrumenter
{
    private CompilerConfiguration configuration;

    String outputSourceDirectory;
    private static final String PROP_PROJECT_BUILD_SOURCEENCODING = "project.build.sourceEncoding";

    public AbstractInstrumenter(CompilerConfiguration configuration, String outputSourceDirectory)
    {
        this.configuration = configuration;
        this.outputSourceDirectory = outputSourceDirectory;
    }

    protected CompilerConfiguration getConfiguration()
    {
        return this.configuration;
    }

    public void instrument() throws MojoExecutionException
    {
        final CloverSourceScanner scanner = getSourceScanner();
        Map filesToInstrument = scanner.getSourceFilesToInstrument();
        if ( filesToInstrument.isEmpty() )
        {
            getConfiguration().getLog().info( "No Clover instrumentation done on source files in: "
                    + getCompileSourceRoots() + " as no matching sources files found" );

        }
        else
        {
            instrumentSources( filesToInstrument, outputSourceDirectory );

        }

        // We need to copy excluded files as otherwise they won't be in the new Clover source directory and
        // thus won't be compiled by the compile plugin. This will lead to compilation errors if any other
        // Java file depends on any of these excluded files.

        if (configuration.copyExcludedFiles())
        {
            copyExcludedFiles( scanner.getExcludedFiles(), outputSourceDirectory );
        }

        //won't do its job when include files set is empty!
    }

    public String redirectSourceDirectories()
    {
        return redirectSourceDirectories( outputSourceDirectory );
    }

    protected abstract CloverSourceScanner getSourceScanner();
    protected abstract String getSourceDirectory();
    protected abstract void setSourceDirectory(String targetDirectory);
    protected abstract List getCompileSourceRoots();
    protected abstract void addCompileSourceRoot(String sourceRoot);
   
    private String redirectSourceDirectories(String targetDirectory)
    {
        String oldSourceDirectory = getSourceDirectory();
       
        if ( new File( oldSourceDirectory ).exists() )
        {
            setSourceDirectory( targetDirectory );
        }

        getConfiguration().getLog().debug( "Clover source directories before change:" );
        logSourceDirectories();

        // Maven2 limitation: changing the source directory doesn't change the compile source roots
        // See http://jira.codehaus.org/browse/MNG-1945
        List sourceRoots = new ArrayList( getCompileSourceRoots() );

        // Clean all source roots to add them again in order to keep the same original order of source roots.
        getCompileSourceRoots().removeAll( sourceRoots );

        for ( Iterator i = sourceRoots.iterator(); i.hasNext(); )
        {
            String sourceRoot = (String) i.next();
            if ( new File( oldSourceDirectory ).exists() && sourceRoot.equals( oldSourceDirectory ) )
            {
                addCompileSourceRoot( getSourceDirectory() );
            }
            // ignore the generated sources directory, because a new clover/generated-sources directory has been created by a plugin
            // during the clover forked lifecycle, which means that we will end up with the same classes included twice
            // if we use the generated-classes directory added originally
            else if (!isGeneratedSourcesDirectory(sourceRoot) && !getConfiguration().includesAllSourceRoots())
            {
                addCompileSourceRoot( sourceRoot );
            }
        }

        getConfiguration().getLog().debug( "Clover main source directories after change:" );
        logSourceDirectories();
        return oldSourceDirectory;
    }

    private boolean isGeneratedSourcesDirectory(String sourceRoot) {
        String generatedSourcesDirectoryName = File.separator + "target" + File.separator + "generated-sources";
        return sourceRoot.indexOf(generatedSourcesDirectoryName) != -1;
    }

    private void logSourceDirectories()
    {
        if ( getConfiguration().getLog().isDebugEnabled() )
        {
            for ( Iterator i = getCompileSourceRoots().iterator(); i.hasNext(); )
            {
                String sourceRoot = (String) i.next();
                getConfiguration().getLog().debug( "[Clover]  source root [" + sourceRoot + "]" );
            }
        }
    }

    /**
     * Copy all files that have been excluded by the user (using the excludes configuration property). This is required
     * as otherwise the excluded files won't be in the new Clover source directory and thus won't be compiled by the
     * compile plugin. This will lead to compilation errors if any other Java file depends on any of them.
     *
     * @throws MojoExecutionException if a failure happens during the copy
     */
    private void copyExcludedFiles(Map excludedFiles, String targetDirectory) throws MojoExecutionException
    {
        for ( Iterator sourceRoots = excludedFiles.keySet().iterator(); sourceRoots.hasNext(); )
        {
            String sourceRoot = (String) sourceRoots.next();
            String[] filesInSourceRoot = (String[]) excludedFiles.get( sourceRoot );

            for (int i = 0; i < filesInSourceRoot.length; i++) {

                File srcFile = new File(sourceRoot, filesInSourceRoot[i]);

                try
                {
                    configuration.getLog().debug("Copying excluded file: " + srcFile.getAbsolutePath() + " to " + targetDirectory );
                    FileUtils.copyFile(srcFile, new File( targetDirectory,
                        srcFile.getPath().substring(sourceRoot.length() ) ) );
                }
                catch (IOException e)
                {
                    throw new MojoExecutionException( "Failed to copy excluded file [" + srcFile + "] to ["
                        + targetDirectory + "]", e );
                }
            }
        }
    }

    private void instrumentSources( Map filesToInstrument, String outputDir ) throws MojoExecutionException {

        Logger.setInstance(new MvnLogger(configuration.getLog()));
        // only make dirs when there is src to instrument. see CLMVN-118
        new File(outputDir).mkdirs();
        int result = CloverInstr.mainImpl( createCliArgs( filesToInstrument, outputDir ) );
        if ( result != 0 )
        {
            throw new MojoExecutionException( "Clover has failed to instrument the source files "
                + "in the [" + outputDir + "] directory" );
        }
    }

    /**
     * @return the CLI args to be passed to CloverInstr
     */
    private String[] createCliArgs( Map filesToInstrument,  String outputDir ) throws MojoExecutionException
    {
        List parameters = new ArrayList();

        parameters.add( "-p" );
        parameters.add( getConfiguration().getFlushPolicy() );
        parameters.add( "-f" );
        parameters.add( "" + getConfiguration().getFlushInterval() );

        parameters.add( "-i" );
        parameters.add( getConfiguration().resolveCloverDatabase() );

        parameters.add( "-d" );
        parameters.add( outputDir );

        if ( getConfiguration().getLog().isDebugEnabled() )
        {
            parameters.add( "-v" );
        }

        if (getConfiguration().getDistributedCoverage() != null && getConfiguration().getDistributedCoverage().isEnabled()) {
            parameters.add("--distributedCoverage");
            parameters.add(getConfiguration().getDistributedCoverage().toString());
        }

        if ( getConfiguration().getJdk() != null )
        {
           if ( getConfiguration().getJdk().equals( "1.4" ) )
            {
                parameters.add( "--source" );
                parameters.add( "1.4" );
            }
            else if ( getConfiguration().getJdk().equals( "1.5" ) )
            {
                parameters.add( "--source" );
                parameters.add( "1.5" );
            }
            else if ( getConfiguration().getJdk().equals( "1.6" ) )
            {
                parameters.add( "--source" );
                parameters.add( "1.6" );
            }
            else if ( getConfiguration().getJdk().equals( "1.7" ) )
            {
                parameters.add( "--source" );
                parameters.add( "1.7" );
            }
            else
            {
                throw new MojoExecutionException( "Unsupported jdk version [" + getConfiguration().getJdk()
                    + "]. Valid values are [1.4], [1.5], [1.6] and [1.7]" );
            }
        }

        if (!getConfiguration().isUseFullyQualifiedJavaLang())
        {
            parameters.add("--dontFullyQualifyJavaLang");
        }

        if (getConfiguration().getEncoding() != null) {
            parameters.add("--encoding");
            parameters.add(getConfiguration().getEncoding());
        } else if (getConfiguration().getProject().getProperties().get(PROP_PROJECT_BUILD_SOURCEENCODING) != null) {
            parameters.add("--encoding");
            parameters.add(getConfiguration().getProject().getProperties().get(PROP_PROJECT_BUILD_SOURCEENCODING));
        }

        if (getConfiguration().getInstrumentation() != null) {
            parameters.add("--instrlevel");
            parameters.add(getConfiguration().getInstrumentation());
        }

        for ( Iterator sourceRoots = filesToInstrument.keySet().iterator(); sourceRoots.hasNext(); )
        {
            final String srcDir = (String) sourceRoots.next();
            String[] filesInSourceRoot = (String[]) filesToInstrument.get(srcDir);
            for (int i = 0; i < filesInSourceRoot.length; i++) {
                String s = filesInSourceRoot[i];

                File file = new File(srcDir, s);
                parameters.add( file.getPath() );
            }
        }

        // custom contexts
        addCustomContexts(parameters, getConfiguration().getMethodContexts().entrySet(), "-mc");
        addCustomContexts(parameters, getConfiguration().getStatementContexts().entrySet(), "-sc");

        // Log parameters
        if ( getConfiguration().getLog().isDebugEnabled() )
        {
            getConfiguration().getLog().debug( "Parameter list being passed to Clover CLI:" );
            for ( Iterator it = parameters.iterator(); it.hasNext(); )
            {
                String param = (String) it.next();
                getConfiguration().getLog().debug( "  parameter = [" + param + "]" );
            }
        }

        return (String[]) parameters.toArray( new String[0] );
    }

    private void addCustomContexts(List parameters, Set/*<Map.Entry<<String,<String>>>*/ contexts, String flag) {
        for (Iterator iterator = contexts.iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            parameters.add(flag);
            parameters.add(entry.getKey() + "=" + entry.getValue());
        }
    }
}
TOP

Related Classes of com.atlassian.maven.plugin.clover.internal.instrumentation.AbstractInstrumenter

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.