diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..af3335f488038e83588eda2787b715aa730ef3d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +target +settings.xml + +# intellij files +*.iws +.idea/workspace.xml +.idea/ant.xml +.idea/uiDesigner.xml +.idea/libraries +.idea/dictionaries +.idea/copyright +.idea/inspectionProfiles + +# eclipse files +.project +.classpath +.settings +.externalToolBuilders/ +maven-eclipse.xml + +# OS X files +.DS_Store + +# backups +*~ diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e540a7306c4d4c11a93b9200af0d91d96415ed58 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# StringTemplate Maven Plugin + +This plugin allows you to execute [StringTemplate](http://www.stringtemplate.org/) template files during your +build. The values for templates can come from static declarations or from a Java class specified to be executed. + +For detailed instructions on how to use this plugin, please refer to the +[plugin site](http://kevinbirch.github.com/string-template-maven-plugin/). diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..3e837959ad2fecc4f50f67bcba73ec05e4604201 --- /dev/null +++ b/pom.xml @@ -0,0 +1,447 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.sonatype.oss</groupId> + <artifactId>oss-parent</artifactId> + <version>7</version> + </parent> + + <prerequisites> + <maven>3.0</maven> + </prerequisites> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <packaging>maven-plugin</packaging> + <version>1.1</version> + + <organization> + <name>The WebGuys</name> + </organization> + + <name>StringTemplate Maven Plugin</name> + <description>This plugin allows you to execute StringTemplate template files during your build. The values for + templates can come from static declarations or from a Java class specified to be executed.</description> + <inceptionYear>2011</inceptionYear> + + <url>https://github.com/kevinbirch/string-template-maven-plugin</url> + <scm> + <connection>scm:git:https://github.com/kevinbirch/string-template-maven-plugin.git</connection> + <developerConnection>scm:git:https://github.com/kevinbirch/string-template-maven-plugin.git</developerConnection> + <url>https://github.com/kevinbirch/string-template-maven-plugin</url> + <tag>string-template-maven-plugin-1.1</tag> + </scm> + + <issueManagement> + <url>https://github.com/kevinbirch/string-template-maven-plugin/issues</url> + <system>github</system> + </issueManagement> + + <licenses> + <license> + <name>MIT</name> + <url>http://www.opensource.org/licenses/mit-license.php</url> + <distribution>manual</distribution> + </license> + </licenses> + + <developers> + <developer> + <id>kmb</id> + <name>Kevin Birch</name> + <email>kmb@pobox.com</email> + <roles> + <role>architect</role> + <role>developer</role> + </roles> + </developer> + </developers> + + <contributors> + <contributor> + <name>Rob Wicke</name> + <url>https://github.com/rwicke</url> + </contributor> + </contributors> + + <dependencies> + + <dependency> + <groupId>org.antlr</groupId> + <artifactId>stringtemplate</artifactId> + <version>4.0.2</version> + </dependency> + + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>3.0.4</version> + </dependency> + + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>3.0.4</version> + </dependency> + + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact</artifactId> + <version>3.0.4</version> + </dependency> + + <dependency> + <groupId>org.sonatype.aether</groupId> + <artifactId>aether-util</artifactId> + <version>1.13.1</version> + </dependency> + + <dependency> + <groupId>org.twdata.maven</groupId> + <artifactId>mojo-executor</artifactId> + <version>2.0</version> + </dependency> + + </dependencies> + + <reporting> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>2.6</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <version>3.2</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.9</version> + <configuration> + <minmemory>128m</minmemory> + <maxmemory>512m</maxmemory> + <tagletArtifacts> + <tagletArtifact> + <groupId>org.apache.maven.plugin-tools</groupId> + <artifactId>maven-plugin-tools-javadoc</artifactId> + <version>3.2</version> + </tagletArtifact> + <tagletArtifact> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-component-javadoc</artifactId> + <version>1.5.5</version> + </tagletArtifact> + </tagletArtifacts> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-report-plugin</artifactId> + <version>2.13</version> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>versions-maven-plugin</artifactId> + <version>2.0</version> + <reportSets> + <reportSet> + <reports> + <report>dependency-updates-report</report> + <report>plugin-updates-report</report> + <report>property-updates-report</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changes-plugin</artifactId> + <version>2.8</version> + <reportSets> + <reportSet> + <reports> + <report>changes-report</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + </plugins> + </reporting> + + <build> + + <pluginManagement> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.0</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-enforcer-plugin</artifactId> + <version>1.2</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <version>3.2</version> + </plugin> + + <plugin> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-component-metadata</artifactId> + <version>1.5.5</version> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>versions-maven-plugin</artifactId> + <version>2.0</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>2.2.1</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.9</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-gpg-plugin</artifactId> + <version>1.4</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.13</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.2</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <version>2.7</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.4</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.6</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-release-plugin</artifactId> + <version>2.4</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-clean-plugin</artifactId> + <version>2.5</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>2.4</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>2.4</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.7</version> + </plugin> + + </plugins> + </pluginManagement> + + <plugins> + + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.6</source> + <target>1.6</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-enforcer-plugin</artifactId> + <executions> + <execution> + <id>enforce-build-environment</id> + <goals> + <goal>enforce</goal> + </goals> + <configuration> + <rules> + <requireMavenVersion> + <version>[3.0,)</version> + </requireMavenVersion> + <requireJavaVersion> + <version>[1.6,)</version> + </requireJavaVersion> + </rules> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <executions> + <execution> + <id>default-descriptor</id> + <phase>process-classes</phase> + <goals> + <goal>descriptor</goal> + </goals> + <configuration> + <goalPrefix>string-template</goalPrefix> + </configuration> + </execution> + <execution> + <id>generate-helpmojo</id> + <goals> + <goal>helpmojo</goal> + </goals> + <configuration> + <helpPackageName>com.webguys.maven.plugin.st</helpPackageName> + <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-component-metadata</artifactId> + <executions> + <execution> + <goals> + <goal>generate-metadata</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>versions-maven-plugin</artifactId> + <executions> + <execution> + <phase>verify</phase> + <goals> + <goal>display-dependency-updates</goal> + <goal>display-plugin-updates</goal> + <goal>display-property-updates</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar-no-fork</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <doctitle>StringTemplate Maven Plugin - ${project.version}</doctitle> + <windowtitle>StringTemplate Maven Plugin - ${project.version}</windowtitle> + <show>public</show> + <links> + <link>http://docs.oracle.com/javase/6/docs/api/</link> + </links> + </configuration> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-gpg-plugin</artifactId> + <executions> + <execution> + <id>sign-artifacts</id> + <phase>verify</phase> + <goals> + <goal>sign</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/src/changes/changes.xml b/src/changes/changes.xml new file mode 100644 index 0000000000000000000000000000000000000000..6dcd4630bba7402a80a19a636402a36e703a8958 --- /dev/null +++ b/src/changes/changes.xml @@ -0,0 +1,48 @@ +<!-- + ~ The MIT License + ~ + ~ Copyright (c) 2013 Kevin Birch <kmb@pobox.com>. Some rights reserved. + ~ + ~ Permission is hereby granted, free of charge, to any person obtaining a copy of + ~ this software and associated documentation files (the "Software"), to deal in + ~ the Software without restriction, including without limitation the rights to + ~ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + ~ of the Software, and to permit persons to whom the Software is furnished to do + ~ so, subject to the following conditions: + ~ + ~ The above copyright notice and this permission notice shall be included in all + ~ copies or substantial portions of the Software. + ~ + ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ~ SOFTWARE. + --> + +<document xmlns="http://maven.apache.org/changes/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 + http://maven.apache.org/xsd/changes-1.0.0.xsd"> + + <body> + + <release version="1.1" date="2013-01-25" description="New feature and bug fixes"> + <action dev="kmb" type="add"> + Add support <properties> configuration element for controller. + </action> + <action dev="rwicke" type="fix"> + Use File.separator instead of '/' to allow running on Windows. + </action> + </release> + + <release version="1.0" date="2012-04-02" description="First release"> + <action dev="kmb" type="add"> + Implemented initial version with basic features to render templates. + </action> + </release> + + </body> +</document> diff --git a/src/main/java/com/webguys/maven/plugin/st/Controller.java b/src/main/java/com/webguys/maven/plugin/st/Controller.java new file mode 100644 index 0000000000000000000000000000000000000000..056545f5d6f83d0fe1d80c0d7caf3ef73b72d718 --- /dev/null +++ b/src/main/java/com/webguys/maven/plugin/st/Controller.java @@ -0,0 +1,269 @@ +/* + * The MIT License + * + * Copyright (c) 2011 Kevin Birch <kmb@pobox.com>. Some rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.webguys.maven.plugin.st; + +import org.apache.maven.ProjectDependenciesResolver; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.sonatype.aether.util.artifact.JavaScopes; +import org.stringtemplate.v4.ST; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import static org.twdata.maven.mojoexecutor.MojoExecutor.*; + +public class Controller +{ + /** + * The name of the class to instantiate. + * + * @parameter + * @required + */ + private String className; + + /** + * The name of the method to invoke. + * + * @parameter + * @required + */ + private String method; + + /** + * The static properties to be provided to the controller. + * + * @parameter + */ + private Map<String, String> properties; + + /** + * Should the this controller attempt to be compiled? + * + * @parameter default-value="true" + */ + private boolean compile = true; + + /** + * @parameter default-value="1.6" + */ + private String sourceVersion = "1.6"; + + /** + * @parameter default-value="1.6" + */ + private String targetVersion = "1.6"; + + /** + * @parameter default-value="3.0" + */ + private String compilerVersion = "3.0"; + + private Object controllerInstance = null; + + public void invoke(ST st, ExecutionEnvironment executionEnvironment, ProjectDependenciesResolver dependenciesResolver, Log log) throws MojoExecutionException + { + try + { + Class controllerClass = this.findControllerClass(dependenciesResolver, executionEnvironment, log); + Method method = this.getMethod(controllerClass); + + this.applyProperties(controllerClass, this.properties, log); + Object results = this.invoke(controllerClass, method, log); + + this.applyResults(st, results); + } + catch(Exception e) + { + throw new MojoExecutionException(String.format("Unable to invoke controller: %s (%s)", this.className, e.getMessage()), e); + } + } + + private Class findControllerClass(ProjectDependenciesResolver dependenciesResolver, ExecutionEnvironment executionEnvironment, Log log) + throws MojoExecutionException, ClassNotFoundException, MalformedURLException, ArtifactResolutionException, ArtifactNotFoundException + { + try + { + return this.loadController(executionEnvironment.getMavenProject(), executionEnvironment.getMavenSession(), dependenciesResolver); + } + catch(ClassNotFoundException e) + { + if(this.compile) + { + log.info(String.format("Unable to find the class: %s. Attempting to compile it...", this.className)); + return this.compileAndLoadController(log, dependenciesResolver, executionEnvironment); + } + else + { + throw new MojoExecutionException(String.format("The class %s is not in the classpath, and compilation is not enabled.", this.className), e); + } + } + } + + private Class compileAndLoadController(Log log, ProjectDependenciesResolver dependenciesResolver, ExecutionEnvironment executionEnvironment) + throws MojoExecutionException, ClassNotFoundException, MalformedURLException, ArtifactResolutionException, ArtifactNotFoundException + { + MavenProject project = executionEnvironment.getMavenProject(); + + Set<Artifact> originalArtifacts = this.configureArtifacts(project); + this.executeCompilerPlugin(executionEnvironment, log); + Class result = this.loadController(project, executionEnvironment.getMavenSession(), dependenciesResolver); + project.setArtifacts(originalArtifacts); + return result; + } + + private Set<Artifact> configureArtifacts(MavenProject project) + { + Set<Artifact> originalArtifacts = project.getArtifacts(); + project.setArtifacts(project.getDependencyArtifacts()); + return originalArtifacts; + } + + private void executeCompilerPlugin(ExecutionEnvironment executionEnvironment, Log log) throws MojoExecutionException + { + String path = this.className.replace(".", File.separator) + ".java"; + log.info(String.format("Compiling %s...", path)); + + executeMojo( + plugin( + groupId("org.apache.maven.plugins"), + artifactId("maven-compiler-plugin"), + version(compilerVersion) + ), + goal("compile"), + configuration( + element(name("source"), sourceVersion), + element(name("target"), targetVersion), + element(name("includes"), element("include", path)) + ), + executionEnvironment + ); + } + + private Class loadController(MavenProject project, MavenSession session, ProjectDependenciesResolver dependenciesResolver) + throws MalformedURLException, ClassNotFoundException, ArtifactResolutionException, ArtifactNotFoundException + { + ArrayList<String> scopes = new ArrayList<String>(1); + scopes.add(JavaScopes.RUNTIME); + Set<Artifact> artifacts = dependenciesResolver.resolve(project, scopes, session); + + ArrayList<URL> urls = new ArrayList<URL>(); + urls.add(new File(project.getBuild().getOutputDirectory()).getAbsoluteFile().toURI().toURL()); + for(Artifact artifact : artifacts) + { + urls.add(artifact.getFile().getAbsoluteFile().toURI().toURL()); + } + + ClassLoader loader = URLClassLoader.newInstance(urls.toArray(new URL[urls.size()]), this.getClass().getClassLoader()); + return loader.loadClass(this.className); + } + + private Method getMethod(Class controllerClass) throws NoSuchMethodException, MojoExecutionException + { + Method method = controllerClass.getMethod(this.method); + + if(!method.getReturnType().isAssignableFrom(Map.class)) + { + throw new MojoExecutionException(String.format("The return type of the method %s was not of type Map<String, Object>", this.method)); + } + + return method; + } + + private void applyProperties(Class controllerClass, Map<String, String> properties, Log log) + throws IllegalAccessException, InvocationTargetException, InstantiationException + { + if(null == properties || properties.isEmpty()) + { + return; + } + + Method setProperties = null; + try + { + setProperties = controllerClass.getMethod("setProperties", Map.class); + } + catch (NoSuchMethodException ignored) + { + // ignore + } + if(null != setProperties) + { + this.invoke(controllerClass, setProperties, log, properties); + } + } + + private Object invoke(Class controllerClass, Method method, Log log, Object ... args) + throws InstantiationException, IllegalAccessException, InvocationTargetException + { + Object controller = null; + if(!Modifier.isStatic(method.getModifiers())) + { + if (null == this.controllerInstance) + { + this.controllerInstance = controllerClass.newInstance(); + } + controller = this.controllerInstance; + } + + log.info(String.format("Invoking controller method: %s.%s()", controllerClass.getName(), method.getName())); + return method.invoke(controller, args); + } + + private void applyResults(ST st, Object result) throws MojoExecutionException + { + if(null == result) + { + throw new MojoExecutionException(String.format("The result invoking %s.%s was null.", this.className, this.method)); + } + Map<Object, Object> attributes = (Map<Object, Object>) result; + + for(Entry<Object, Object> entry : attributes.entrySet()) + { + Object key = entry.getKey(); + if(!(key instanceof String)) + { + String msg = String.format("A non-String key of type %s was found in the %s.%s results.", key.getClass().getName(), this.className, this.method); + throw new MojoExecutionException(msg); + } + st.add((String)key, entry.getValue()); + } + } +} diff --git a/src/main/java/com/webguys/maven/plugin/st/StringTemplateMojo.java b/src/main/java/com/webguys/maven/plugin/st/StringTemplateMojo.java new file mode 100644 index 0000000000000000000000000000000000000000..2c5dfd344930172658716f7d956cc2dd2c2cd406 --- /dev/null +++ b/src/main/java/com/webguys/maven/plugin/st/StringTemplateMojo.java @@ -0,0 +1,130 @@ +/* + * The MIT License + * + * Copyright (c) 2011 Kevin Birch <kmb@pobox.com>. Some rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Created: 11/20/11 10:47 PM + */ + +package com.webguys.maven.plugin.st; + +import org.apache.maven.ProjectDependenciesResolver; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupDir; +import org.stringtemplate.v4.misc.ErrorBuffer; +import org.twdata.maven.mojoexecutor.MojoExecutor.ExecutionEnvironment; + +import java.io.File; +import java.util.List; + +import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment; + +/** + * Executes string template using a given controller. + * + * @goal render + */ +public class StringTemplateMojo extends AbstractMojo +{ + /** + * The Maven Project Object + * + * @parameter property="project" + * @required + * @readonly + */ + private MavenProject project; + + /** + * The Maven Session Object + * + * @parameter property="session" + * @required + * @readonly + */ + private MavenSession session; + + /** + * The Maven PluginManager Object + * + * @component + * @required + */ + private BuildPluginManager pluginManager; + + /** + * The Maven ProjectDependenciesResolver Object + * + * @component + * @required + */ + private ProjectDependenciesResolver dependenciesResolver; + + /** + * The collection of templates to render. + * @parameter + * @required + */ + private List<Template> templates; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + for(Template template : this.templates) + { + File templateDirectory = this.getTemplateDirectory(template); + + STGroup group = new STGroupDir(templateDirectory.getAbsolutePath()); + ErrorBuffer errorBuffer = new ErrorBuffer(); + group.setListener(errorBuffer); + ST st = group.getInstanceOf(template.getName()); + + if(null == st || !errorBuffer.errors.isEmpty()) + { + throw new MojoExecutionException(String.format("Unable to execute template. %n%s", errorBuffer.toString())); + } + + ExecutionEnvironment executionEnvironment = executionEnvironment(this.project, this.session, this.pluginManager); + template.invokeController(st, executionEnvironment, this.dependenciesResolver, this.getLog()); + template.installProperties(st); + + template.render(st, this.project, this.getLog()); + } + } + + private File getTemplateDirectory(Template template) + { + File templateDirectory = template.getDirectory(); + if(!templateDirectory.isAbsolute()) + { + templateDirectory = new File(this.project.getBasedir(), templateDirectory.getPath()); + } + + return templateDirectory; + } +} diff --git a/src/main/java/com/webguys/maven/plugin/st/Template.java b/src/main/java/com/webguys/maven/plugin/st/Template.java new file mode 100644 index 0000000000000000000000000000000000000000..75b6c45a642327867c996e18542e66173d3b75a9 --- /dev/null +++ b/src/main/java/com/webguys/maven/plugin/st/Template.java @@ -0,0 +1,169 @@ +/* + * The MIT License + * + * Copyright (c) 2011 Kevin Birch <kmb@pobox.com>. Some rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.webguys.maven.plugin.st; + +import org.apache.maven.ProjectDependenciesResolver; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.stringtemplate.v4.AutoIndentWriter; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.misc.ErrorBuffer; +import org.twdata.maven.mojoexecutor.MojoExecutor.ExecutionEnvironment; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +public class Template +{ + /** + * The path to the template file's parent directory. + * + * @parameter + * @required + */ + private File directory; + + /** + * The name of the template file to render. + * + * @parameter + * @required + */ + private String name; + + /** + * The path to the output file. + * + * @parameter + * @required + */ + private File target; + + /** + * The class to invoke to provide data for the template. + * + * @parameter + */ + private Controller controller; + + /** + * The static properties to be provided to the template. + * + * @parameter + */ + private Map<String, String> properties; + + public File getDirectory() + { + return directory; + } + + public String getName() + { + return name; + } + + public void invokeController(ST st, ExecutionEnvironment executionEnvironment, ProjectDependenciesResolver dependenciesResolver, Log log) throws MojoExecutionException + { + if(null != this.controller) + { + this.controller.invoke(st, executionEnvironment, dependenciesResolver, log); + } + } + + public void installProperties(ST st) + { + if(null != this.properties) + { + for(Entry<String, String> entry : this.properties.entrySet()) + { + st.add(entry.getKey(), entry.getValue()); + } + } + } + + public void render(ST st, MavenProject project, Log log) throws MojoExecutionException + { + try + { + File outputFile = this.prepareOutputFile(project.getBasedir()); + this.prepareCompilerSourceRoot(outputFile, project, log); + FileWriter fileWriter = new FileWriter(outputFile); + ErrorBuffer listener = new ErrorBuffer(); + st.write(new AutoIndentWriter(fileWriter), listener); + fileWriter.flush(); + fileWriter.close(); + + if(!listener.errors.isEmpty()) + { + throw new MojoExecutionException(listener.toString()); + } + } + catch(IOException e) + { + throw new MojoExecutionException(String.format("Unable to write output file: %s. (%s)", this.target.getAbsolutePath(), e.getMessage()), e); + } + } + + private File prepareOutputFile(File baseDirectory) throws MojoExecutionException, IOException + { + File outputFile = this.target; + if(!outputFile.isAbsolute()) + { + outputFile = new File(baseDirectory, outputFile.getPath()); + } + + if(!outputFile.exists()) + { + if(!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) + { + throw new MojoExecutionException(String.format("Unable to fully create the output directory: %s", this.target.getParentFile())); + } + if(!outputFile.createNewFile()) + { + throw new MojoExecutionException(String.format("Unable to create the output file: %s", this.target)); + } + } + + return outputFile; + } + + private void prepareCompilerSourceRoot(File file, MavenProject project, Log log) + { + String path = file.getPath(); + if(file.getName().endsWith("java") && path.contains("generated-sources")) + { + int index = path.indexOf("generated-sources") + 18; + index = path.indexOf(File.separator, index); + String sourceRoot = path.substring(0, index); + log.info("Adding compile source root: " + sourceRoot); + project.addCompileSourceRoot(sourceRoot); + } + } +} diff --git a/src/site/apt/examples/basic.apt.vm b/src/site/apt/examples/basic.apt.vm new file mode 100644 index 0000000000000000000000000000000000000000..330456735cfbf23ceffa31972d3373213b0ac89d --- /dev/null +++ b/src/site/apt/examples/basic.apt.vm @@ -0,0 +1,193 @@ + ----------------------------- + StringTemplate Plugin Example + ----------------------------- + +StringTemplate Plugin Example + + The StringTemplate Plugin uses the {{{http://www.stringtemplate.org}StringTemplate}} template engine to generate files + during your build. + +* Add the Plugin + + The following configuration shows a complete configuration example: + ++-----+ + +<project> + ... + <build> + <plugins> + ... + <plugin> + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <version>1.1</version> + <configuration> + <templates> + <template> + <directory>${basedir}/src/main/string-template</directory> + <name>voltron</name> + <target>${basedir}/target/generated-sources/string-template/com/example/application/VoltronIII.java</target> + <controller> + <className>com.example.application.util.TemplateController</className> + <method>getProperties</method> + </controller> + <properties> + <className>VoltronIII</className> + <robot>Lion</robot> + </properties> + </template> + </templates> + </configuration> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>render</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + ... +</project> + ++-----+ + + Notice the use of Maven properties and also the specification of fully qualified paths and class names. The output + file for this template is in a subdirectory of <<<target/generated-sources>>>, so the + <<<target/generated-sources/string-template>>> directory will be automatically added to the Maven compile source + paths. Thus, it will be picked up and compiled by the <<<compile>>> phase automatically (assuming that you have + associated the plugin with a phase that occurs before <<<compile>>> in the lifecycle). + + In this example, the TemplateController class is assumed to not be available on the classpath when the plugin runs, so + the plugin will compile it for you. + +* Write the Template + + In this example the template file is <<<src/main/string-template/voltron.st>>>. Generally, the name of the template + is also the name of the template file, like Java classes. This template has three parameters: <<<members>>> (assumed + to be a list), <<<robot>>> and <<<className>>> (both scalars). The <<<members>>> parameter comes from the controller, + while the others are defined statically in the <<<properties>>> element above. + + A complete StringTemplate definition for <<<src/main/string-template/voltron.st>>> follows: + ++-----+ + +voltron(members, robot, className) ::= << +package com.example.application; + +import com.example.application.<robot>; + +public class <className> implements Voltron +{ + <members:{each | private <robot> <each>; + }> + + public <className>() + { + + } + + public void initiateDocking() + { + // ... + } + + public void swordAttack() + { + // ... + } + + public void beamAttack() + { + // ... + } + + public void missileAttack() + { + // ... + } +} +>> + ++-----+ + +* Make a Controller + + In this example, a controller is used to provide dynamic input to the template. The return type of the specified + method <<must>> be of the type <<<Map\<String, Object\>>>>. The keys of this map will be treated as template + parameter names and added to the template's invocation. In this case, there is one key in the map: <"members">, which + corresponds to the <<<members>>> template parameter seen above. It is a list type, thus the use of the + StringTemplate iteration syntax. + + A complete template class definition that conforms to the above configuration follows: + ++-----+ + +package com.example.application.util; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class TemplateController +{ + public Map<String, Object> getProperties() + { + HashMap<String, Object> result = new HashMap<String, Object>(); + result.put("members", Arrays.asList("black", "red", "green", "blue", "yellow")); + + return result; + } +} + + ++-----+ + +* Enjoy Your Generated File + + The results of rendering the above template follows: + ++-----+ + +package com.example.application; + +import com.example.application.Lion; + +public class VoltronIII implements Voltron +{ + private Lion black; + private Lion red; + private Lion green; + private Lion blue; + private Lion yellow; + + public VoltronIII() + { + + } + + public void initiateDocking() + { + // ... + } + + public void swordAttack() + { + // ... + } + + public void beamAttack() + { + // ... + } + + public void missileAttack() + { + // ... + } +} + ++-----+ diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt new file mode 100644 index 0000000000000000000000000000000000000000..0cf16fd75c1a74f3230089334ea50f136ce728a2 --- /dev/null +++ b/src/site/apt/index.apt @@ -0,0 +1,28 @@ + ------------ + Introduction + ------------ + +Maven StringTemplate Plugin + + The StringTemplate Plugin uses the {{{http://www.stringtemplate.org}StringTemplate}} template engine to generate files + during your build. The generated files can be any kind of text file including Java or other source files, and can be + included into your build. + + The plugin has special support for generated Java sources files: if the output of a template is a Java source file + and it is written to a subdirectory of <<<target/generated-sources>>>, then that subdirectory will be automatically + added to the compile source paths. + +* Goals Overview + + The StringTemplate Plugin has the following goal: + + * {{{./render-mojo.html}string-template:render}} renders all of the templates specified in the configuration + +* Usage + + General instructions on how to use the StringTemplate Plugin can be found on the {{{./usage.html}usage page}}. A + complete example is given below. + +* Example + + A {{{./examples/basic.html}basic example}} is provided to illustrate the configuration. diff --git a/src/site/apt/usage.apt.vm b/src/site/apt/usage.apt.vm new file mode 100644 index 0000000000000000000000000000000000000000..00aeff06a15118253c44dc6340b14f88071151ed --- /dev/null +++ b/src/site/apt/usage.apt.vm @@ -0,0 +1,213 @@ + ----- + Usage + ----- + +Usage + + The StringTemplate Plugin uses the {{{http://www.stringtemplate.org}StringTemplate}} template engine to generate files + during your build. + +* Configuration + + The configuration looks like the following: + ++-----+ + + <build> + <plugins> + <plugin> + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <version>1.1</version> + <configuration> + <templates> + <template> + <directory>path-to-template-directory</directory> + <name>template-name</name> + <target>path-to-output-filename</target> + <controller> + <className>fully-qualified-class-name</className> + <method>method-to-invoke</method> + <properties> + <key>value</key> + </properties> + </controller> + <properties> + <name1>value1</name1> + <name2>value2</name2> + </properties> + </template> + </templates> + </configuration> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>render</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + ++-----+ + + The execution of the plugin can be under any phase, but it is recommended to use the <<<generate-sources>>> phase. + + The configuration consists of a set of <<<\<template\>>>> elements that <<must>> contain: + + [[1]] <<<\<directory\>>>> - The absolute or relative path to the directory where the template files to be processed + reside. + + [[2]] <<<\<name\>>>> - The name of the template to process. + + [[3]] <<<\<target\>>>> - The absolute or relative path to the file to write the template processing results to. + + [] + + The <<<\<template\>>>> element also <<may>> contain: + + * <<<\<controller\>>>> - This element specifies a class and method to invoke to provide computed attributes to the + template. The children elements are <<<\<className\>>>> for the fully qualified classname and <<<\<method\>>>> for + the name of the method to invoke. The method can be a static <or> instance method, the type will be automatically + detected at invocation time. The return type of the specified method <<must>> be of the type + <<<Map\<String, Object\>>>>. The keys of this map will be treated as template parameter names and added to the + template's invocation. Properties can also be passed to the controller using a <<<\<properties\>>>> section, see + below for more details. + + * <<<\<properties\>>>> - Ths element specifies a set of static name-value pairs to provide to the template. Keys are + element names and values are the text child of the element. <<N.B.>> The properties are installed into the template + after the results of the controller, so if there are any name collisions then the value type will be automatically + converted into a list type by StringTemplate. + + [] + + Generally, at least one of <<<\<controller\>>>> or <<<\<properties\>>>> will be needed for each template definition. + +* Passing Properties to the Controller + + The <<<\<controller\>>>> element can have an optional <<<\<properties\>>>> child element to pass properties from the + POM file to the controller. The format of this section is the same as any other <<<\<properties\>>>> section: + element names are keys and the text children of them are values. In order to support this, the controller <<must>> + have a (class <or> instance) method with the following signature: + ++-----+ +public void setProperties(java.util.Map) ++-----+ + + If properties are configured in the POM and this method exists (either as a class <or> instance method), it will be + invoked <<before>> the method specified in the <<<\<method\>>>> element. The keys and the values of the <<<Map>>> + parameter will both be strings. + +* Automatic Inclusion of Generated Source Paths + + If the output of a template is a Java file (ends with '.java') and it is written to a subdirectory of + <<<target/generated-sources>>>, then that subdirectory will be automatically added to the Maven project's compile + source path for that lifecycle execution. This behavior is applied for all templates, so multiple directories + could be added to the compile source path. + +* Automatic Compilation of the Controller Class + + If the class file for the controller is not available when the plugin is run, the plugin will attempt to be + compile it. It is assumed that the source for the specified controller is in the current project. If the class is + not available on the classpath, and either the source file cannot be found or cannot be compiled the build will fail. + +* Controlling the Compiler Used for Automatic Compilation of the Controller Class + + You can set the source and target Java versions that are used to automatically compile the controller class. You can + also set the version of the Maven compiler plugin that will be used. Custom values for these parameters must be + valid for their context: the source and target version must be valid for the Java compiler and the plugin version + must be a valid Maven compiler plugin version. + + The default values are: + + * Source Version - 1.6 + + * Target Version - 1.6 + + * Maven Compiler Plugin Version - 3.0 + + [] + + The following is an example of using custom settings for these parameters: + ++-----+ + + <build> + <plugins> + <plugin> + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <version>1.1</version> + <configuration> + <templates> + <template> + <directory>path-to-template-directory</directory> + <name>template-name</name> + <target>path-to-output-filename</target> + <controller> + <className>fully-qualified-class-name</className> + <method>method-to-invoke</method> + <sourceVersion>1.5</sourceVersion> + <targetVersion>1.5</targetVersion> + <compilerVersion>2.3.2</compilerVersion> + </controller> + </template> + </templates> + </configuration> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>render</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + ++-----+ + +* Disabling Automatic Compilation of Controller Classes + + You can disable this on a per-controller basis by setting the <<<\<compile\>>>> attribute to <<false>>. If the + controller class is not available on the classpath and this setting is false, and exception will be thrown by the + plugin and the build will fail. + ++-----+ + + <build> + <plugins> + <plugin> + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <version>1.1</version> + <configuration> + <templates> + <template> + <directory>path-to-template-directory</directory> + <name>template-name</name> + <target>path-to-output-filename</target> + <controller> + <className>fully-qualified-class-name</className> + <method>method-to-invoke</method> + <compile>false</compile> + </controller> + </template> + </templates> + </configuration> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>render</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + ++-----+ diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 0000000000000000000000000000000000000000..569656f321e19d2900172ca81213d8e219a22729 --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ The MIT License + ~ + ~ Copyright (c) 2013 Kevin Birch <kmb@pobox.com>. Some rights reserved. + ~ + ~ Permission is hereby granted, free of charge, to any person obtaining a copy of + ~ this software and associated documentation files (the "Software"), to deal in + ~ the Software without restriction, including without limitation the rights to + ~ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + ~ of the Software, and to permit persons to whom the Software is furnished to do + ~ so, subject to the following conditions: + ~ + ~ The above copyright notice and this permission notice shall be included in all + ~ copies or substantial portions of the Software. + ~ + ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ~ SOFTWARE. + --> + +<project xmlns="http://maven.apache.org/DECORATION/1.3.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.3.0 http://maven.apache.org/xsd/decoration-1.3.0.xsd"> + + <body> + + <links> + <item name="StringTemplate" href="http://www.stringtemplate.org"/> + </links> + + <menu name="Overview"> + <item name="Introduction" href="index.html"/> + <item name="Goals" href="plugin-info.html"/> + <item name="Usage" href="usage.html"/> + <item name="Release Notes" href="changes-report.html"/> + </menu> + + <menu name="Examples"> + <item name="Basic Usage" href="examples/basic.html"/> + </menu> + + <menu ref="reports"/> + </body> +</project> diff --git a/tests/pom.xml b/tests/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..52d10357913316f089541a014f09b13280c7d155 --- /dev/null +++ b/tests/pom.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ The MIT License + ~ + ~ Copyright (c) 2013 Kevin Birch <kmb@pobox.com>. Some rights reserved. + ~ + ~ Permission is hereby granted, free of charge, to any person obtaining a copy of + ~ this software and associated documentation files (the "Software"), to deal in + ~ the Software without restriction, including without limitation the rights to + ~ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + ~ of the Software, and to permit persons to whom the Software is furnished to do + ~ so, subject to the following conditions: + ~ + ~ The above copyright notice and this permission notice shall be included in all + ~ copies or substantial portions of the Software. + ~ + ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ~ SOFTWARE. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <groupId>com.example</groupId> + <version>1.0</version> + <artifactId>application</artifactId> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.0</version> + </plugin> + <plugin> + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <version>1.1-SNAPSHOT</version> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.6</source> + <target>1.6</target> + </configuration> + </plugin> + + <plugin> + <groupId>com.webguys</groupId> + <artifactId>string-template-maven-plugin</artifactId> + <configuration> + <templates> + <template> + <directory>${basedir}/src/main/string-template</directory> + <name>voltron</name> + <target>${basedir}/target/generated-sources/string-template/com/example/application/VoltronIII.java</target> + <controller> + <className>com.example.util.LionForceController</className> + <method>getMembers</method> + <properties> + <powerLevel>jigawats</powerLevel> + </properties> + </controller> + <properties> + <className>VoltronIII</className> + <robot>Lion</robot> + </properties> + </template> + </templates> + </configuration> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>render</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/tests/src/main/java/com/example/application/Lion.java b/tests/src/main/java/com/example/application/Lion.java new file mode 100644 index 0000000000000000000000000000000000000000..0ea74b76393be9cfcb940e951049788deb3adcff --- /dev/null +++ b/tests/src/main/java/com/example/application/Lion.java @@ -0,0 +1,19 @@ +package com.example.application; + +/** + * Created: 2013-01-23 14:28 + */ +public class Lion +{ + private String color; + + public Lion(String color) + { + this.color = color; + } + + public String getColor() + { + return color; + } +} diff --git a/tests/src/main/java/com/example/application/Voltron.java b/tests/src/main/java/com/example/application/Voltron.java new file mode 100644 index 0000000000000000000000000000000000000000..56f0269f65fa3b99e9879e07542b4da26741658e --- /dev/null +++ b/tests/src/main/java/com/example/application/Voltron.java @@ -0,0 +1,16 @@ +/** + * Created: 2013-01-23 14:25 + */ + +package com.example.application; + +public interface Voltron +{ + void initiateDocking(); + + void swordAttack(); + + void beamAttack(); + + void missileAttack(); +} diff --git a/tests/src/main/java/com/example/util/LionForceController.java b/tests/src/main/java/com/example/util/LionForceController.java new file mode 100644 index 0000000000000000000000000000000000000000..b59a6890dae64780b131b93a5bf475e50117ef10 --- /dev/null +++ b/tests/src/main/java/com/example/util/LionForceController.java @@ -0,0 +1,54 @@ +/* + * The MIT License + * + * Copyright (c) 2011 Kevin Birch <kmb@pobox.com>. Some rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.example.util; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class LionForceController +{ + private String powerLevel; + + public Map<String, Object> getMembers() + { + HashMap<String, Object> result = new HashMap<String, Object>(); + result.put("members", Arrays.asList("black", "red", "green", "blue", "yellow")); + if(null != this.powerLevel) + { + result.put("powerLevel", this.powerLevel); + } + + return result; + } + + public void setProperties(Map<String, String> properties) + { + if(properties.containsKey("powerLevel")) + { + this.powerLevel = properties.get("powerLevel"); + } + } +} diff --git a/tests/src/main/string-template/voltron.st b/tests/src/main/string-template/voltron.st new file mode 100644 index 0000000000000000000000000000000000000000..2e7e5de8e85ba86df4fcad48268737099c06c732 --- /dev/null +++ b/tests/src/main/string-template/voltron.st @@ -0,0 +1,36 @@ +voltron(members, robot, className, powerLevel) ::= << +package com.example.application; + +public class <className> implements Voltron +{ + <members:{each | private <robot> <each>; + }> + + private String powerLevel = "<powerLevel>"; + + public <className>() + { + + } + + public void initiateDocking() + { + // ... + } + + public void swordAttack() + { + // ... + } + + public void beamAttack() + { + // ... + } + + public void missileAttack() + { + // ... + } +} +>>