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

com.greenpepper.maven.AbstractCompilerMojo Maven / Gradle / Ivy

There is a newer version: 4.2.4
Show newest version
/*
 * Copyright (c) 2007 Pyxis Technologies inc.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA,
 * or see the FSF site: http://www.fsf.org.
 */

package com.greenpepper.maven;

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

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.compiler.Compiler;
import org.codehaus.plexus.compiler.CompilerConfiguration;
import org.codehaus.plexus.compiler.CompilerError;
import org.codehaus.plexus.compiler.CompilerException;
import org.codehaus.plexus.compiler.CompilerOutputStyle;
import org.codehaus.plexus.compiler.manager.CompilerManager;
import org.codehaus.plexus.compiler.manager.NoSuchCompilerException;
import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
import org.codehaus.plexus.compiler.util.scan.mapping.SingleTargetSourceMapping;
import org.codehaus.plexus.compiler.util.scan.mapping.SourceMapping;
import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;

import com.greenpepper.maven.plugin.utils.CompilationFailureException;

/**
 * 

Abstract AbstractCompilerMojo class.

* * @author others * @author Trygve Laugstøl * @version $Id: StaleSourceScannerTest.java 2393 2005-08-08 22:32:59Z kenney $ */ public abstract class AbstractCompilerMojo extends AbstractSourceManagementMojo { // ---------------------------------------------------------------------- // Configurables // ---------------------------------------------------------------------- /** * Whether to include debugging information in the compiled class files. * The default value is true. * * @parameter property="maven.compiler.debug" default-value="true" * @deprecated */ private boolean debug; /** * Whether to output messages about what the compiler is doing * * @parameter default-value="false" */ private boolean verbose; /** * Output source locations where deprecated APIs are used * * @parameter default-value="false" */ private boolean showDeprecation; /** * Optimize compiled code using the compiler's optimization methods * * @parameter default-value="false" */ private boolean optimize; /** * Output warnings * * @parameter default-value="false" */ private boolean showWarnings; /** * The -source argument for the Java compiler * * @parameter default-value="1.6" */ private String source; /** * The -target argument for the Java compiler * * @parameter default-value="1.6" */ private String target; /** * The -encoding argument for the Java compiler * * @parameter */ private String encoding; /** * The granularity in milliseconds of the last modification * date for testing whether a source needs recompilation * * @parameter property="lastModGranularityMs" default-value="0" */ private int staleMillis; /** * The compiler id of the compiler to use. * * @parameter default-value="javac" */ private String compilerId; /** * Version of the compiler to use, ex. "1.3", "1.5" * * @parameter default-value="1.6" */ private String compilerVersion; /** * Runs the compiler in a separate process. *

* If not set the compiler will default to a executable. * * @parameter default-value="false" */ private boolean fork; /** * The executable of the compiler to use. * * @parameter */ private String executable; /** * Arguments to be passed to the compiler if fork is set to true. *

* This is because the list of valid arguments passed to a Java compiler * varies based on the compiler version. * * @parameter */ private Map compilerArguments; /** * Used to control the name of the output file when compiling a set of * sources to a single file. * * @parameter property="project.build.finalName" */ private String outputFileName; // ---------------------------------------------------------------------- // Read-only parameters // ---------------------------------------------------------------------- /** * The target directory of the compiler if fork is true. * * @parameter property="project.build.directory" * @required * @readonly */ private File buildDirectory; /** * Plexus compiler manager. * * @component */ private CompilerManager compilerManager; /** *

getSourceInclusionScanner.

* * @param staleMillis a int. * @return a {@link org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner} object. */ protected abstract SourceInclusionScanner getSourceInclusionScanner( int staleMillis ); /** *

getSourceInclusionScanner.

* * @param inputFileEnding a {@link java.lang.String} object. * @return a {@link org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner} object. */ protected abstract SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding ); /** *

getClasspathElements.

* * @return a {@link java.util.List} object. */ protected abstract List getClasspathElements(); /** *

getCompileSourceRoots.

* * @return a {@link java.util.List} object. */ protected abstract List getCompileSourceRoots(); /** *

getOutputDirectory.

* * @return a {@link java.io.File} object. */ protected abstract File getOutputDirectory(); /** *

execute.

* * @throws org.apache.maven.plugin.MojoExecutionException if any. * @throws com.greenpepper.maven.plugin.utils.CompilationFailureException if any. */ @SuppressWarnings("unchecked") public void execute() throws MojoExecutionException, CompilationFailureException { // ---------------------------------------------------------------------- // Look up the compiler. This is done before other code than can // cause the mojo to return before the lookup is done possibly resulting // in misconfigured POMs still building. // ---------------------------------------------------------------------- Compiler compiler; getLog().debug( "Using compiler '" + compilerId + "'." ); try { compiler = compilerManager.getCompiler( compilerId ); } catch ( NoSuchCompilerException e ) { throw new MojoExecutionException( "No such compiler '" + e.getCompilerId() + "'." ); } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- List compileSourceRoots = removeEmptyCompileSourceRoots( getCompileSourceRoots() ); if ( compileSourceRoots.isEmpty() ) { getLog().info( "No sources to compile" ); return; } if ( getLog().isDebugEnabled() ) { getLog().debug( "Source directories: " + compileSourceRoots.toString().replace( ',', '\n' ) ); getLog().debug( "Classpath: " + getClasspathElements().toString().replace( ',', '\n' ) ); getLog().debug( "Output directory: " + getOutputDirectory() ); } // ---------------------------------------------------------------------- // Create the compiler configuration // ---------------------------------------------------------------------- CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); compilerConfiguration.setOutputLocation( getOutputDirectory().getAbsolutePath() ); compilerConfiguration.setClasspathEntries( getClasspathElements() ); compilerConfiguration.setSourceLocations( compileSourceRoots ); compilerConfiguration.setOptimize( optimize ); compilerConfiguration.setDebug( debug ); compilerConfiguration.setVerbose( verbose ); compilerConfiguration.setShowWarnings( showWarnings ); compilerConfiguration.setShowDeprecation( showDeprecation ); compilerConfiguration.setSourceVersion( source ); compilerConfiguration.setTargetVersion( target ); compilerConfiguration.setSourceEncoding( encoding ); if ( compilerArguments != null ) { LinkedHashMap cplrArgsCopy = new LinkedHashMap(); for (Object o : compilerArguments.entrySet()) { Map.Entry me = (Map.Entry) o; String key = (String) me.getKey(); if (!key.startsWith("-")) { key = "-" + key; } cplrArgsCopy.put(key, me.getValue()); } compilerConfiguration.setCustomCompilerArguments( cplrArgsCopy ); } compilerConfiguration.setFork( fork ); compilerConfiguration.setExecutable( executable ); compilerConfiguration.setWorkingDirectory( basedir ); compilerConfiguration.setCompilerVersion( compilerVersion ); compilerConfiguration.setBuildDirectory( buildDirectory ); compilerConfiguration.setOutputFileName( outputFileName ); Set staleSources; boolean canUpdateTarget; try { staleSources = computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( staleMillis ) ); canUpdateTarget = compiler.canUpdateTarget( compilerConfiguration ); if ( compiler.getCompilerOutputStyle().equals( CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES ) && !canUpdateTarget ) { getLog().info( "RESCANNING!" ); String inputFileEnding = compiler.getInputFileEnding( compilerConfiguration ); Set sources = computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( inputFileEnding ) ); compilerConfiguration.setSourceFiles( sources ); } else { compilerConfiguration.setSourceFiles( staleSources ); } } catch ( CompilerException e ) { throw new MojoExecutionException( "Error while computing stale sources.", e ); } if ( staleSources.isEmpty() ) { getLog().info( "Nothing to compile - all classes are up to date" ); return; } // ---------------------------------------------------------------------- // Dump configuration // ---------------------------------------------------------------------- if ( getLog().isDebugEnabled() ) { getLog().debug( "Classpath:" ); for (Object o : getClasspathElements()) { String s = (String) o; getLog().debug(" " + s); } getLog().debug( "Source roots:" ); for (Object o : getCompileSourceRoots()) { String root = (String) o; getLog().debug(" " + root); } if ( fork ) { try { String[] cl = compiler.createCommandLine( compilerConfiguration ); if ( cl != null && cl.length > 0 ) { StringBuffer sb = new StringBuffer(); sb.append( cl[0] ); for ( int i = 1; i < cl.length; i++ ) { sb.append( " " ); sb.append( cl[i] ); } getLog().debug( "Command line options:" ); getLog().debug( sb ); } } catch ( CompilerException ce ) { getLog().debug( ce ); } } } // ---------------------------------------------------------------------- // Compile! // ---------------------------------------------------------------------- List messages; try { messages = compiler.compile( compilerConfiguration ); } catch ( Exception e ) { throw new MojoExecutionException( "Fatal error compiling", e ); } boolean compilationError = false; for ( CompilerError message : messages) { if ( message.isError() ) { compilationError = true; } } if ( compilationError ) { throw new CompilationFailureException( messages ); } else { for (CompilerError message : messages) { getLog().warn(message.toString()); } } } @SuppressWarnings("unchecked") private Set computeStaleSources( CompilerConfiguration compilerConfiguration, Compiler compiler, SourceInclusionScanner scanner ) throws MojoExecutionException, CompilerException { CompilerOutputStyle outputStyle = compiler.getCompilerOutputStyle(); SourceMapping mapping; File outputDirectory; if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE ) { mapping = new SuffixMapping( compiler.getInputFileEnding( compilerConfiguration ), compiler .getOutputFileEnding( compilerConfiguration ) ); outputDirectory = getOutputDirectory(); } else if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES ) { mapping = new SingleTargetSourceMapping( compiler.getInputFileEnding( compilerConfiguration ), compiler .getOutputFile( compilerConfiguration ) ); outputDirectory = buildDirectory; } else { throw new MojoExecutionException( "Unknown compiler output style: '" + outputStyle + "'." ); } scanner.addSourceMapping( mapping ); Set staleSources = new HashSet(); for (Object o : getCompileSourceRoots()) { String sourceRoot = (String) o; File rootFile = new File(sourceRoot); if (!rootFile.isDirectory()) { continue; } try { staleSources.addAll(scanner.getIncludedSources(rootFile, outputDirectory)); } catch (InclusionScanException e) { throw new MojoExecutionException( "Error scanning source root: \'" + sourceRoot + "\' " + "for stale files to recompile.", e); } } return staleSources; } @SuppressWarnings("unchecked") private static List removeEmptyCompileSourceRoots( List compileSourceRootsList ) { List newCompileSourceRootsList = new ArrayList(); if ( compileSourceRootsList != null ) { // copy as I may be modifying it for (Object aCompileSourceRootsList : compileSourceRootsList) { String srcDir = (String) aCompileSourceRootsList; if (!newCompileSourceRootsList.contains(srcDir) && new File(srcDir).exists()) { newCompileSourceRootsList.add(srcDir); } } } return newCompileSourceRootsList; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy