AUTOTAG-20 make the build really incremental whenever possible
git-svn-id: https://svn.apache.org/repos/asf/tiles/autotag/trunk@1656976 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java b/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java
index 0e8316b..4859ef5 100644
--- a/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java
+++ b/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java
@@ -26,6 +26,7 @@
import java.io.OutputStream;
import java.net.URL;
import java.net.URLClassLoader;
+import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -100,15 +101,17 @@
public void execute() throws MojoExecutionException {
try {
TemplateSuite suite;
- InputStream stream = findTemplateSuiteDescriptor();
+ URLConnection templateSuite = findTemplateSuiteDescriptor();
+ long lastModified = templateSuite.getLastModified();
+ InputStream stream = templateSuite.getInputStream();
try {
XStream xstream = new XStream(new Sun14ReflectionProvider());
suite = (TemplateSuite) xstream.fromXML(stream);
} finally {
stream.close();
}
- classesOutputLocator = new MavenOutputLocator(classesOutputDirectory);
- resourcesOutputLocator = new MavenOutputLocator(resourcesOutputDirectory);
+ classesOutputLocator = new MavenOutputLocator(classesOutputDirectory, lastModified);
+ resourcesOutputLocator = new MavenOutputLocator(resourcesOutputDirectory, lastModified);
Properties props = new Properties();
InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
props.load(propsStream);
@@ -118,13 +121,11 @@
generator.generate(packageName, suite, getParameters(), getRuntimeClass(), requestClass);
if (generator.isGeneratingResources()) {
buildContext.refresh(resourcesOutputDirectory);
- Resource resource = new Resource();
- resource.setDirectory(resourcesOutputDirectory.getAbsolutePath());
- project.addResource(resource);
+ addResourceDirectory(resourcesOutputDirectory.getAbsolutePath());
}
if (generator.isGeneratingClasses()) {
buildContext.refresh(classesOutputDirectory);
- project.addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
+ addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
}
} catch (IOException e) {
throw new MojoExecutionException("error", e);
@@ -135,7 +136,38 @@
}
}
- /**
+ private void addResourceDirectory(String directory) {
+ boolean addResource = true;
+ @SuppressWarnings("unchecked")
+ List<Resource> resources = project.getResources();
+ for(Resource resource: resources) {
+ if(directory.equals(resource.getDirectory())) {
+ addResource = false;
+ }
+ }
+ if(addResource) {
+ Resource resource = new Resource();
+ resource.setDirectory(directory);
+ project.addResource(resource);
+ }
+ }
+
+ private void addCompileSourceRoot(String directory) {
+ boolean addResource = true;
+ @SuppressWarnings("unchecked")
+ List<String> roots = project.getCompileSourceRoots();
+ for(String root: roots) {
+ if(directory.equals(root)) {
+ addResource = false;
+ }
+ }
+ if(addResource) {
+ project.addCompileSourceRoot(directory);
+ }
+ }
+
+
+ /**
* Creates a template generator factory.
*
* @param velocityEngine The Velocity engine.
@@ -156,7 +188,7 @@
* @return The inputstream of the identified descriptor.
* @throws IOException If something goes wrong.
*/
- private InputStream findTemplateSuiteDescriptor() throws IOException {
+ private URLConnection findTemplateSuiteDescriptor() throws IOException {
URL[] urls = new URL[classpathElements.size()];
int i = 0;
for ( String classpathElement: classpathElements )
@@ -165,7 +197,7 @@
}
ClassLoader cl = new URLClassLoader( urls );
- return cl.getResourceAsStream(META_INF_TEMPLATE_SUITE_XML);
+ return cl.getResource(META_INF_TEMPLATE_SUITE_XML).openConnection();
}
/**
@@ -177,9 +209,11 @@
private final class MavenOutputLocator implements OutputLocator {
private File outputDirectory;
+ private long sourceLastModified;
- private MavenOutputLocator(File outputDirectory) {
+ private MavenOutputLocator(File outputDirectory, long sourceLastModified) {
this.outputDirectory = outputDirectory;
+ this.sourceLastModified = sourceLastModified;
}
@Override
@@ -189,5 +223,11 @@
target.getParentFile().mkdirs();
return buildContext.newFileOutputStream(target);
}
+
+ @Override
+ public boolean isUptodate(String resourcePath) {
+ File target = new File(outputDirectory, resourcePath);
+ return target.exists() && target.lastModified() > sourceLastModified;
+ }
}
}
diff --git a/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java b/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java
index 2a698e8..a525115 100644
--- a/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java
+++ b/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java
@@ -42,6 +42,7 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import org.apache.maven.model.Resource;
@@ -116,32 +117,58 @@
public void execute() throws MojoExecutionException {
try {
String[] fileNames = getSourceInclusionScanner().getIncludedFiles();
+ File dir = new File(outputDirectory, "META-INF");
+ if(!dir.exists()) {
+ dir.mkdirs();
+ buildContext.refresh(dir);
+ }
+ File outputFile = new File(dir, "template-suite.xml");
+ boolean uptodate = outputFile.exists();
File[] files = new File[fileNames.length];
for(int i=0; i<fileNames.length; i++) {
files[i] = new File(sourceDirectory, fileNames[i]);
+ uptodate &= buildContext.isUptodate(outputFile, files[i]);
}
- QDoxTemplateSuiteFactory factory = new QDoxTemplateSuiteFactory(files);
- factory.setSuiteName(name);
- factory.setSuiteDocumentation(documentation);
- factory.setRequestClass(requestClass);
- TemplateSuite suite = factory.createTemplateSuite();
- XStream xstream = new XStream();
- File dir = new File(outputDirectory, "META-INF");
- dir.mkdirs();
- File outputFile = new File(dir, "template-suite.xml");
- OutputStream os = buildContext.newFileOutputStream(outputFile);
- Writer writer = new OutputStreamWriter(os);
- xstream.toXML(suite, writer);
- writer.close();
- buildContext.refresh(outputDirectory);
- Resource resource = new Resource();
- resource.setDirectory(outputDirectory.getAbsolutePath());
- project.addResource(resource);
+ if(!uptodate) {
+ createDescriptor(outputFile, files);
+ }
+ addResourceDirectory(outputDirectory.getAbsolutePath());
} catch (IOException e) {
throw new MojoExecutionException("error", e);
}
}
+ private void createDescriptor(File outputFile, File[] files)
+ throws IOException {
+ QDoxTemplateSuiteFactory factory = new QDoxTemplateSuiteFactory(files);
+ factory.setSuiteName(name);
+ factory.setSuiteDocumentation(documentation);
+ factory.setRequestClass(requestClass);
+ TemplateSuite suite = factory.createTemplateSuite();
+ XStream xstream = new XStream();
+ OutputStream os = buildContext.newFileOutputStream(outputFile);
+ Writer writer = new OutputStreamWriter(os);
+ xstream.toXML(suite, writer);
+ writer.close();
+ os.close();
+ }
+
+ private void addResourceDirectory(String directory) {
+ boolean addResource = true;
+ @SuppressWarnings("unchecked")
+ List<Resource> resources = project.getResources();
+ for(Resource resource: resources) {
+ if(directory.equals(resource.getDirectory())) {
+ addResource = false;
+ }
+ }
+ if(addResource) {
+ Resource resource = new Resource();
+ resource.setDirectory(directory);
+ project.addResource(resource);
+ }
+ }
+
/**
* Creates a source inclusion scanner.
*
diff --git a/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java b/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java
index 6b5ac67..412b0c1 100644
--- a/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java
+++ b/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java
@@ -25,6 +25,7 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -79,7 +80,7 @@
mojo.buildContext = buildContext;
buildContext.refresh(isA(File.class));
- buildContext.refresh(isA(File.class));
+ expectLastCall().times(2);
expect(mojo.createTemplateGeneratorFactory(isA(VelocityEngine.class))).andReturn(factory);
expect(factory.createTemplateGenerator()).andReturn(generator);
expect(mojo.getParameters()).andReturn(params);
@@ -87,7 +88,9 @@
generator.generate(eq("my.package"), isA(TemplateSuite.class), eq(params), eq("my.package.Runtime"), eq("my.package.Request"));
expect(generator.isGeneratingClasses()).andReturn(true);
expect(generator.isGeneratingResources()).andReturn(true);
+ expect(mavenProject.getResources()).andReturn(Collections.emptyList());
mavenProject.addResource(isA(Resource.class));
+ expect(mavenProject.getCompileSourceRoots()).andReturn(Collections.emptyList());
mavenProject.addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
replay(mavenProject, buildContext, mojo, factory, generator, params);
diff --git a/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java b/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java
index cd10500..70b470c 100644
--- a/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java
+++ b/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java
@@ -37,6 +37,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.apache.commons.io.FileUtils;
@@ -91,6 +92,7 @@
mojo.requestClass = ExampleRequest.class.getName();
mojo.buildContext = buildContext;
+ expect(mavenProject.getResources()).andReturn(Collections.emptyList());
mavenProject.addResource(isA(Resource.class));
expect(buildContext.newScanner(isA(File.class))).andReturn(scanner);
scanner.setIncludes(isA(String[].class));
@@ -98,8 +100,8 @@
expect(scanner.getIncludedFiles()).andReturn(models);
File file = new File(temp, "META-INF/template-suite.xml");
file.getParentFile().mkdirs();
+ expect(buildContext.isUptodate(isA(File.class), isA(File.class))).andReturn(false).times(models.length);
expect(buildContext.newFileOutputStream(isA(File.class))).andReturn(new FileOutputStream(file));
- buildContext.refresh(isA(File.class));
replay(mavenProject, buildContext, scanner);
mojo.execute();
InputStream sis = new FileInputStream(new File(temp, "META-INF/template-suite.xml"));
diff --git a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java
index 8d25c5d..4871f6d 100644
--- a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java
+++ b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java
@@ -31,9 +31,16 @@
public class DirectoryOutputLocator implements OutputLocator {
private File directory;
+ private long sourceLastModified;
public DirectoryOutputLocator(File directory) {
this.directory = directory;
+ this.sourceLastModified = System.currentTimeMillis();
+ }
+
+ public DirectoryOutputLocator(File directory, long sourceLastModified) {
+ this.directory = directory;
+ this.sourceLastModified = sourceLastModified;
}
@Override
@@ -43,4 +50,10 @@
return new FileOutputStream(file);
}
+ @Override
+ public boolean isUptodate(String resourcePath) {
+ File file = new File(directory, resourcePath);
+ return file.exists() && file.lastModified() > sourceLastModified;
+ }
+
}
diff --git a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java
index a2c6b45..2608e1f 100644
--- a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java
+++ b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java
@@ -33,4 +33,11 @@
* @return a Writer for the file.
*/
OutputStream getOutputStream(String resourcePath) throws IOException;
+
+ /**
+ * Checks if the output is up to date.
+ * @param resourcePath the path of the file to write.
+ * @return true if the output doesn't need to be generated again.
+ */
+ boolean isUptodate(String resourcePath);
}
diff --git a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java
index 776f021..c000cd9 100644
--- a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java
+++ b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java
@@ -67,39 +67,41 @@
getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)
+ File.separator
+ getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass);
- VelocityContext context = new VelocityContext();
- context.put("packageName", packageName);
- context.put("suite", suite);
- context.put("clazz", clazz);
- context.put("stringTool", new StringTool());
- context.put("parameters", parameters);
- context.put("runtimeClass", runtimeClass);
- context.put("requestClass", requestClass);
- try {
- Template template = velocityEngine.getTemplate(getTemplatePath(
- packageName, suite, clazz, parameters, runtimeClass, requestClass));
- Writer writer = new OutputStreamWriter(outputLocator.getOutputStream(filePath));
- try {
- template.merge(context, writer);
- } finally {
- writer.close();
- }
- } catch (ResourceNotFoundException e) {
- throw new AutotagRuntimeException("Cannot find template resource",
- e);
- } catch (ParseErrorException e) {
- throw new AutotagRuntimeException(
- "The template resource is not parseable", e);
- } catch (IOException e) {
- throw new AutotagRuntimeException(
- "I/O Exception when generating file", e);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new AutotagRuntimeException(
- "Another generic exception while parsing the template resource",
- e);
- }
+ if (!outputLocator.isUptodate(filePath)) {
+ VelocityContext context = new VelocityContext();
+ context.put("packageName", packageName);
+ context.put("suite", suite);
+ context.put("clazz", clazz);
+ context.put("stringTool", new StringTool());
+ context.put("parameters", parameters);
+ context.put("runtimeClass", runtimeClass);
+ context.put("requestClass", requestClass);
+ try {
+ Template template = velocityEngine.getTemplate(getTemplatePath(
+ packageName, suite, clazz, parameters, runtimeClass, requestClass));
+ Writer writer = new OutputStreamWriter(outputLocator.getOutputStream(filePath));
+ try {
+ template.merge(context, writer);
+ } finally {
+ writer.close();
+ }
+ } catch (ResourceNotFoundException e) {
+ throw new AutotagRuntimeException("Cannot find template resource",
+ e);
+ } catch (ParseErrorException e) {
+ throw new AutotagRuntimeException(
+ "The template resource is not parseable", e);
+ } catch (IOException e) {
+ throw new AutotagRuntimeException(
+ "I/O Exception when generating file", e);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new AutotagRuntimeException(
+ "Another generic exception while parsing the template resource",
+ e);
+ }
+ }
}
/**
diff --git a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java
index b7d815b..0f96b85 100644
--- a/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java
+++ b/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java
@@ -63,33 +63,35 @@
getDirectoryName(packageName, suite, parameters)
+ File.separator
+ getFilename(packageName, suite, parameters);
- VelocityContext context = new VelocityContext();
- context.put("packageName", packageName);
- context.put("suite", suite);
- context.put("stringTool", new StringTool());
- context.put("parameters", parameters);
- try {
- Template template = velocityEngine.getTemplate(getTemplatePath(
- packageName, suite, parameters));
- Writer writer = new OutputStreamWriter(outputLocator.getOutputStream(filePath));
- try {
- template.merge(context, writer);
- } finally {
- writer.close();
- }
- } catch (ResourceNotFoundException e) {
- throw new AutotagRuntimeException("Cannot find template resource", e);
- } catch (ParseErrorException e) {
- throw new AutotagRuntimeException("The template resource is not parseable", e);
- } catch (IOException e) {
- throw new AutotagRuntimeException(
- "I/O Exception when generating file", e);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new AutotagRuntimeException(
- "Another generic exception while parsing the template resource",
- e);
+ if (!outputLocator.isUptodate(filePath)) {
+ VelocityContext context = new VelocityContext();
+ context.put("packageName", packageName);
+ context.put("suite", suite);
+ context.put("stringTool", new StringTool());
+ context.put("parameters", parameters);
+ try {
+ Template template = velocityEngine.getTemplate(getTemplatePath(
+ packageName, suite, parameters));
+ Writer writer = new OutputStreamWriter(outputLocator.getOutputStream(filePath));
+ try {
+ template.merge(context, writer);
+ } finally {
+ writer.close();
+ }
+ } catch (ResourceNotFoundException e) {
+ throw new AutotagRuntimeException("Cannot find template resource", e);
+ } catch (ParseErrorException e) {
+ throw new AutotagRuntimeException("The template resource is not parseable", e);
+ } catch (IOException e) {
+ throw new AutotagRuntimeException(
+ "I/O Exception when generating file", e);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new AutotagRuntimeException(
+ "Another generic exception while parsing the template resource",
+ e);
+ }
}
}