o Adding source-scanner support, for selectively including source files to be compiled, or processed in some way. This is going to be a core-plugin facility, so it's in maven-plugin.

o Added support to maven-compiler-plugin for a source scanner to determine the files that actually need recompiling...currently based on lastModification date.
o All of this stuff needs a good integration test, but it shouldn't mess any existing functionality up for now. Unit tests for the scanner stuff are included.


git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@163698 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2005-03-29 05:28:08 +00:00
parent 6872f9eaa2
commit 67830a13fb
8 changed files with 879 additions and 42 deletions

View File

@ -0,0 +1,42 @@
package org.apache.maven.plugin.util.scan;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.plugin.util.scan.mapping.SourceMapping;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author jdcasey
*/
public abstract class AbstractSourceInclusionScanner
implements SourceInclusionScanner
{
private final List sourceMappings = new ArrayList();
public final void addSourceMapping( SourceMapping sourceMapping )
{
sourceMappings.add( sourceMapping );
}
protected final List getSourceMappings()
{
return Collections.unmodifiableList( sourceMappings );
}
}

View File

@ -0,0 +1,36 @@
package org.apache.maven.plugin.util.scan;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.
*/
/**
* @author jdcasey
*/
public class InclusionScanException
extends Exception
{
public InclusionScanException( String message )
{
super( message );
}
public InclusionScanException( String message, Throwable cause )
{
super( message, cause );
}
}

View File

@ -0,0 +1,32 @@
package org.apache.maven.plugin.util.scan;
import org.apache.maven.plugin.util.scan.mapping.SourceMapping;
import java.io.File;
import java.util.Set;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.
*/
/**
* @author jdcasey
*/
public interface SourceInclusionScanner
{
void addSourceMapping( SourceMapping sourceMapping );
Set getIncludedSources( File sourceDir, File targetDir ) throws InclusionScanException;
}

View File

@ -0,0 +1,133 @@
package org.apache.maven.plugin.util.scan;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.plugin.util.scan.mapping.SourceMapping;
import org.codehaus.plexus.util.DirectoryScanner;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* @author jdcasey
*/
public class StaleSourceScanner
extends AbstractSourceInclusionScanner
{
private final long lastUpdatedWithinMsecs;
private final Set sourceIncludes;
private final Set sourceExcludes;
public StaleSourceScanner( long lastUpdatedWithinMsecs )
{
this( lastUpdatedWithinMsecs, Collections.singleton("**/*"), Collections.EMPTY_SET );
}
public StaleSourceScanner()
{
this( 0, Collections.singleton("**/*"), Collections.EMPTY_SET );
}
public StaleSourceScanner( long lastUpdatedWithinMsecs, Set sourceIncludes, Set sourceExcludes )
{
this.lastUpdatedWithinMsecs = lastUpdatedWithinMsecs;
this.sourceIncludes = sourceIncludes;
this.sourceExcludes = sourceExcludes;
}
public Set getIncludedSources( File sourceDir, File targetDir )
throws InclusionScanException
{
Set matchingSources = new HashSet();
List srcMappings = getSourceMappings();
String[] potentialIncludes = scanForSources( sourceDir );
for ( int i = 0; i < potentialIncludes.length; i++ )
{
String path = potentialIncludes[i];
File sourceFile = new File( sourceDir, path );
staleSourceFileTesting: for ( Iterator patternIt = srcMappings.iterator(); patternIt.hasNext(); )
{
SourceMapping mapping = (SourceMapping) patternIt.next();
Set targetFiles = mapping.getTargetFiles( targetDir, path );
// never include files that don't have corresponding target mappings.
// the targets don't have to exist on the filesystem, but the
// mappers must tell us to look for them.
for ( Iterator targetIt = targetFiles.iterator(); targetIt.hasNext(); )
{
File targetFile = (File) targetIt.next();
if ( !targetFile.exists()
|| ( targetFile.lastModified() + lastUpdatedWithinMsecs < sourceFile.lastModified() ) )
{
matchingSources.add( sourceFile );
break staleSourceFileTesting;
}
}
}
}
return matchingSources;
}
private String[] scanForSources( File sourceDir )
{
DirectoryScanner ds = new DirectoryScanner();
ds.setFollowSymlinks(true);
ds.setBasedir( sourceDir );
String[] includes = null;
if ( sourceIncludes.isEmpty() )
{
includes = new String[0];
}
else
{
includes = (String[]) sourceIncludes.toArray( new String[sourceIncludes.size()] );
}
ds.setIncludes( includes );
String[] excludes = null;
if ( sourceExcludes.isEmpty() )
{
excludes = new String[0];
}
else
{
excludes = (String[]) sourceExcludes.toArray( new String[sourceExcludes.size()] );
}
ds.setExcludes( excludes );
ds.scan();
return ds.getIncludedFiles();
}
}

View File

@ -0,0 +1,32 @@
package org.apache.maven.plugin.util.scan.mapping;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.plugin.util.scan.InclusionScanException;
import java.io.File;
import java.util.Set;
/**
* @author jdcasey
*/
public interface SourceMapping
{
Set getTargetFiles(File targetDir, String source) throws InclusionScanException;
}

View File

@ -0,0 +1,70 @@
package org.apache.maven.plugin.util.scan.mapping;
import org.apache.maven.plugin.util.scan.InclusionScanException;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.
*/
/**
* @author jdcasey
*/
public final class SuffixMapping
implements SourceMapping
{
private final String sourceSuffix;
private final Set targetSuffixes;
public SuffixMapping( String sourceSuffix, String targetSuffix )
{
this.sourceSuffix = sourceSuffix;
this.targetSuffixes = Collections.singleton( targetSuffix );
}
public SuffixMapping( String sourceSuffix, Set targetSuffixes )
{
this.sourceSuffix = sourceSuffix;
this.targetSuffixes = Collections.unmodifiableSet( targetSuffixes );
}
public Set getTargetFiles( File targetDir, String source )
throws InclusionScanException
{
Set targetFiles = new HashSet();
if(source.endsWith(sourceSuffix))
{
String base = source.substring( 0, source.length() - sourceSuffix.length() );
for ( Iterator it = targetSuffixes.iterator(); it.hasNext(); )
{
String suffix = (String) it.next();
targetFiles.add( new File( targetDir, base + suffix ) );
}
}
return targetFiles;
}
}

View File

@ -0,0 +1,440 @@
package org.apache.maven.plugin.util.scan;
import org.apache.maven.plugin.util.scan.StaleSourceScanner;
import org.apache.maven.plugin.util.scan.mapping.SuffixMapping;
import org.codehaus.plexus.util.IOUtil;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Set;
import junit.framework.TestCase;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.
*/
/**
* @author jdcasey
*/
public class StaleSourceScannerTest
extends TestCase
{
private static final String TESTFILE_DEST_MARKER_FILE = StaleSourceScanner.class.getName().replace('.', '/') + "-testMarker.txt";
// test 1.
public void testWithDefaultConstructorShouldFindOneStaleSource() throws Exception
{
File base = new File(getTestBaseDir(), "test1");
long now = System.currentTimeMillis();
File targetFile = new File(base, "file.xml");
writeFile(targetFile);
targetFile.setLastModified(now - 60000);
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
sourceFile.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner();
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 1, result.size());
assertTrue("expected stale source file not found in result", result.contains(sourceFile));
}
// test 2.
public void testWithDefaultConstructorShouldNotFindStaleSources() throws Exception
{
File base = new File(getTestBaseDir(), "test2");
long now = System.currentTimeMillis();
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
sourceFile.setLastModified(now - 60000);
File targetFile = new File(base, "file.xml");
writeFile(targetFile);
targetFile.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner();
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 0, result.size());
assertFalse("expected stale source file not found in result", result.contains(sourceFile));
}
// test 3.
public void testWithDefaultConstructorShouldFindStaleSourcesBecauseOfMissingTargetFile() throws Exception
{
File base = new File(getTestBaseDir(), "test3");
long now = System.currentTimeMillis();
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner();
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 1, result.size());
assertTrue("expected stale source file not found in result", result.contains(sourceFile));
}
// test 4.
public void testWithDefaultConstructorShouldFindStaleSourcesOneBecauseOfMissingTargetAndOneBecauseOfStaleTarget() throws Exception
{
File base = new File(getTestBaseDir(), "test4");
long now = System.currentTimeMillis();
File targetFile = new File(base, "file2.xml");
writeFile(targetFile);
targetFile.setLastModified(now - 60000);
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
File sourceFile2 = new File(base, "file2.java");
writeFile(sourceFile2);
sourceFile2.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner();
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 2, result.size());
assertTrue("expected stale source file not found in result", result.contains(sourceFile));
assertTrue("expected stale source file not found in result", result.contains(sourceFile2));
}
// test 5.
public void testWithDefaultConstructorShouldFindOneStaleSourcesWithStaleTargetAndOmitUpToDateSource() throws Exception
{
File base = new File(getTestBaseDir(), "test5");
long now = System.currentTimeMillis();
// target/source (1) should result in source being included.
// write the target file first, and set the lastmod to some time in the
// past to ensure this.
File targetFile = new File(base, "file.xml");
writeFile(targetFile);
targetFile.setLastModified(now - 60000);
// now write the source file, and set the lastmod to now.
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
sourceFile.setLastModified(now);
// target/source (2) should result in source being omitted.
// write the source file first, and set the lastmod to some time in the
// past to ensure this.
File sourceFile2 = new File(base, "file2.java");
writeFile(sourceFile2);
sourceFile2.setLastModified(now - 60000);
// now write the target file, with lastmod of now.
File targetFile2 = new File(base, "file2.xml");
writeFile(targetFile2);
targetFile2.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner();
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 1, result.size());
assertTrue("expected stale source file not found in result", result.contains(sourceFile));
}
// test 6.
public void testConstructedWithMsecsShouldReturnOneSourceFileOfTwoDueToLastMod() throws Exception
{
File base = new File(getTestBaseDir(), "test6");
long now = System.currentTimeMillis();
File targetFile = new File(base, "file.xml");
writeFile(targetFile);
// should be within the threshold of lastMod for stale sources.
targetFile.setLastModified(now - 8000);
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
// modified 'now' for comparison with the above target file.
sourceFile.setLastModified(now);
File targetFile2 = new File(base, "file2.xml");
writeFile(targetFile2);
targetFile2.setLastModified(now - 12000);
File sourceFile2 = new File(base, "file2.java");
writeFile(sourceFile2);
// modified 'now' for comparison to above target file.
sourceFile2.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner(10000);
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 1, result.size());
assertTrue("expected stale source file not found in result", result.contains(sourceFile2));
assertFalse("expected stale source file not found in result", result.contains(sourceFile));
}
// test 7.
public void testConstructedWithMsecsIncludesAndExcludesShouldReturnOneSourceFileOfThreeDueToIncludePattern() throws Exception
{
File base = new File(getTestBaseDir(), "test7");
long now = System.currentTimeMillis();
File targetFile = new File(base, "file.xml");
writeFile(targetFile);
// should be within the threshold of lastMod for stale sources.
targetFile.setLastModified(now - 12000);
File sourceFile = new File(base, "file.java");
writeFile(sourceFile);
// modified 'now' for comparison with the above target file.
sourceFile.setLastModified(now);
File targetFile2 = new File(base, "file2.xml");
writeFile(targetFile2);
targetFile2.setLastModified(now - 12000);
File sourceFile2 = new File(base, "file2.java");
writeFile(sourceFile2);
// modified 'now' for comparison to above target file.
sourceFile2.setLastModified(now);
File targetFile3 = new File(base, "file3.xml");
writeFile(targetFile3);
targetFile3.setLastModified(now - 12000);
File sourceFile3 = new File(base, "file3.java");
writeFile(sourceFile3);
// modified 'now' for comparison to above target file.
sourceFile3.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner(0, Collections.singleton("*3.java"), Collections.EMPTY_SET);
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 1, result.size());
assertFalse("expected stale source file not found in result", result.contains(sourceFile));
assertFalse("unexpected stale source file found in result", result.contains(sourceFile2));
assertTrue("unexpected stale source file found in result", result.contains(sourceFile3));
}
// test 8.
public void testConstructedWithMsecsIncludesAndExcludesShouldReturnTwoSourceFilesOfThreeDueToExcludePattern() throws Exception
{
File base = new File(getTestBaseDir(), "test8");
long now = System.currentTimeMillis();
File targetFile = new File(base, "fileX.xml");
writeFile(targetFile);
// should be within the threshold of lastMod for stale sources.
targetFile.setLastModified(now - 12000);
File sourceFile = new File(base, "fileX.java");
writeFile(sourceFile);
// modified 'now' for comparison with the above target file.
sourceFile.setLastModified(now);
File targetFile2 = new File(base, "file2.xml");
writeFile(targetFile2);
targetFile2.setLastModified(now - 12000);
File sourceFile2 = new File(base, "file2.java");
writeFile(sourceFile2);
// modified 'now' for comparison to above target file.
sourceFile2.setLastModified(now);
File targetFile3 = new File(base, "file3.xml");
writeFile(targetFile3);
targetFile3.setLastModified(now - 12000);
File sourceFile3 = new File(base, "file3.java");
writeFile(sourceFile3);
// modified 'now' for comparison to above target file.
sourceFile3.setLastModified(now);
SuffixMapping mapping = new SuffixMapping(".java", ".xml");
StaleSourceScanner scanner = new StaleSourceScanner(0, Collections.singleton("**/*"), Collections.singleton("*X.*"));
scanner.addSourceMapping(mapping);
Set result = scanner.getIncludedSources(base, base);
assertEquals("wrong number of stale sources returned.", 2, result.size());
assertFalse("unexpected stale source file found in result", result.contains(sourceFile));
assertTrue("expected stale source not file found in result", result.contains(sourceFile2));
assertTrue("expected stale source not file found in result", result.contains(sourceFile3));
}
private File getTestBaseDir()
{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL markerResource = cl.getResource(TESTFILE_DEST_MARKER_FILE);
File basedir = null;
if(markerResource != null)
{
File marker = new File(markerResource.getPath());
basedir = marker.getParentFile().getAbsoluteFile();
}
else
{
// punt.
System.out.println("Cannot find marker file: \'" + TESTFILE_DEST_MARKER_FILE + "\' in classpath. Using '.' for basedir.");
basedir = new File(".").getAbsoluteFile();
}
return basedir;
}
private void writeFile(File file) throws IOException
{
FileWriter fWriter = null;
try
{
File parent = file.getParentFile();
if(!parent.exists())
{
parent.mkdirs();
}
file.deleteOnExit();
fWriter = new FileWriter(file);
fWriter.write("This is just a test file.");
}
finally
{
IOUtil.close(fWriter);
}
}
}

View File

@ -2,20 +2,22 @@
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.
*
* Licensed 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.plugin.util.scan.InclusionScanException;
import org.apache.maven.plugin.util.scan.SourceInclusionScanner;
import org.apache.maven.plugin.util.scan.StaleSourceScanner;
import org.apache.maven.plugin.util.scan.mapping.SuffixMapping;
import org.codehaus.plexus.compiler.Compiler;
import org.codehaus.plexus.compiler.CompilerConfiguration;
import org.codehaus.plexus.compiler.CompilerError;
@ -23,42 +25,35 @@
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
* @version $Id$
* @goal compile
* @requiresDependencyResolution
* @description Compiles application sources
* @parameter name="compileSourceRoots"
* type="java.util.List"
* required="true"
* validator=""
* expression="#project.compileSourceRoots"
* description=""
* @parameter name="outputDirectory"
* type="String"
* required="true"
* validator=""
* expression="#project.build.outputDirectory"
* description=""
* @parameter name="classpathElements"
* type="List"
* required="true"
* validator=""
* expression="#project.compileClasspathElements"
* description=""
* @parameter name="debug"
* type="boolean"
* required="false"
* validator=""
* expression="#maven.compiler.debug"
* description="Whether to include debugging information in the compiled class files; the default value is false"
* @parameter name="compileSourceRoots" type="java.util.List" required="true" validator=""
* expression="#project.compileSourceRoots" description=""
* @parameter name="outputDirectory" type="String" required="true" validator=""
* expression="#project.build.outputDirectory" description=""
* @parameter name="classpathElements" type="List" required="true" validator=""
* expression="#project.compileClasspathElements" description=""
* @parameter name="debug" type="boolean" required="false" validator=""
* expression="#maven.compiler.debug" description="Whether to include debugging
* information in the compiled class files; the default value is false"
* @todo change debug parameter type to Boolean
* @parameter name="source" type="String" required="false" expression="#source" validator="" description="The -source argument for the Java compiler"
* @parameter name="target" type="String" required="false" expression="#target" validator="" description="The -target argument for the Java compiler"
* @parameter name="source" type="String" required="false" expression="#source" validator=""
* description="The -source argument for the Java compiler"
* @parameter name="target" type="String" required="false" expression="#target" validator=""
* description="The -target argument for the Java compiler"
* @parameter name="staleMillis" type="long" required="false" expression="#lastModGranularityMs"
* validator="" description="The granularity in milliseconds of the last modification
* date for testing whether a source needs recompilation"
* @todo change staleMillis parameter type to Long
*/
public class CompilerMojo
@ -79,6 +74,9 @@ public class CompilerMojo
private String target;
// TODO: Use long when supported
private String staleMillis = "0";
public void execute()
throws PluginExecutionException
{
@ -99,11 +97,18 @@ public void execute()
compilerConfiguration.setClasspathEntries( classpathElements );
compilerConfiguration.setSourceLocations( compileSourceRoots );
Set staleSources = computeStaleSources();
if ( staleSources != null && !staleSources.isEmpty() )
{
compilerConfiguration.setSourceFiles( staleSources );
}
if ( source != null )
{
compilerConfiguration.addCompilerOption( "-source", source );
}
if ( target != null )
{
compilerConfiguration.addCompilerOption( "-target", target );
@ -143,8 +148,55 @@ public void execute()
}
}
private Set computeStaleSources()
throws PluginExecutionException
{
long staleTime = 0;
if ( staleMillis != null && staleMillis.length() > 0 )
{
try
{
staleTime = Long.parseLong( staleMillis );
}
catch ( NumberFormatException e )
{
throw new PluginExecutionException( "Invalid staleMillis plugin parameter value: \'" + staleMillis
+ "\'", e );
}
}
SuffixMapping mapping = new SuffixMapping( ".java", ".class" );
SourceInclusionScanner scanner = new StaleSourceScanner( staleTime );
File outDir = new File( outputDirectory );
Set staleSources = new HashSet();
for ( Iterator it = compileSourceRoots.iterator(); it.hasNext(); )
{
String sourceRoot = (String) it.next();
File rootFile = new File( sourceRoot );
try
{
staleSources.addAll( scanner.getIncludedSources( rootFile, outDir ) );
}
catch ( InclusionScanException e )
{
throw new PluginExecutionException( "Error scanning source root: \'" + sourceRoot
+ "\' for stale files to recompile.", e );
}
}
return staleSources;
}
/**
* @todo also in ant plugin. This should be resolved at some point so that it does not need to be calculated continuously - or should the plugins accept empty source roots as is?
* @todo also in ant plugin. This should be resolved at some point so that it does not need to
* be calculated continuously - or should the plugins accept empty source roots as is?
*/
private static List removeEmptyCompileSourceRoots( List compileSourceRootsList )
{
@ -163,4 +215,4 @@ private static List removeEmptyCompileSourceRoots( List compileSourceRootsList )
}
return newCompileSourceRootsList;
}
}
}