jdcasey 2005/03/28 21:28:08
Modified:
maven-plugins/maven-compiler-plugin/src/main/java/org/apache/maven/plugin
CompilerMojo.java
Added: maven-plugin/src/main/java/org/apache/maven/plugin/util/scan
StaleSourceScanner.java SourceInclusionScanner.java
InclusionScanException.java
AbstractSourceInclusionScanner.java
maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/mapping
SuffixMapping.java SourceMapping.java
maven-plugin/src/test/java/org/apache/maven/plugin/util/scan
StaleSourceScannerTest.java
Log:
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.
Revision Changes Path
1.1
maven-components/maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/StaleSourceScanner.java
Index: StaleSourceScanner.java
===================================================================
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();
}
}
1.1
maven-components/maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/SourceInclusionScanner.java
Index: SourceInclusionScanner.java
===================================================================
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;
}
1.1
maven-components/maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/InclusionScanException.java
Index: InclusionScanException.java
===================================================================
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 );
}
}
1.1
maven-components/maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/AbstractSourceInclusionScanner.java
Index: AbstractSourceInclusionScanner.java
===================================================================
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 );
}
}
1.1
maven-components/maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/mapping/SuffixMapping.java
Index: SuffixMapping.java
===================================================================
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;
}
}
1.1
maven-components/maven-plugin/src/main/java/org/apache/maven/plugin/util/scan/mapping/SourceMapping.java
Index: SourceMapping.java
===================================================================
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;
}
1.1
maven-components/maven-plugin/src/test/java/org/apache/maven/plugin/util/scan/StaleSourceScannerTest.java
Index: StaleSourceScannerTest.java
===================================================================
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);
}
}
}
1.25 +95 -43
maven-components/maven-plugins/maven-compiler-plugin/src/main/java/org/apache/maven/plugin/CompilerMojo.java
Index: CompilerMojo.java
===================================================================
RCS file:
/home/cvs/maven-components/maven-plugins/maven-compiler-plugin/src/main/java/org/apache/maven/plugin/CompilerMojo.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- CompilerMojo.java 22 Mar 2005 12:29:30 -0000 1.24
+++ CompilerMojo.java 29 Mar 2005 05:28:08 -0000 1.25
@@ -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:[EMAIL PROTECTED]">Jason van Zyl</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">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 @@
private String target;
+ // TODO: Use long when supported
+ private String staleMillis = "0";
+
public void execute()
throws PluginExecutionException
{
@@ -99,11 +97,18 @@
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 @@
}
}
+ 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 @@
}
return newCompileSourceRootsList;
}
-}
+}
\ No newline at end of file