diff --git a/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java b/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java index 82e766e9e6..04ef11ec8a 100644 --- a/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java +++ b/spring-boot-cli/src/it/java/org/springframework/boot/cli/JarCommandIT.java @@ -80,5 +80,7 @@ public class JarCommandIT { assertThat(invocation.getStandardOutput(), containsString("/static/static.txt")); assertThat(invocation.getStandardOutput(), containsString("/templates/template.txt")); + assertThat(invocation.getStandardOutput(), + containsString("Goodbye Mama")); } } diff --git a/spring-boot-cli/src/it/resources/jar-command/jar.groovy b/spring-boot-cli/src/it/resources/jar-command/jar.groovy index 7d68a5f470..ee912748d0 100644 --- a/spring-boot-cli/src/it/resources/jar-command/jar.groovy +++ b/spring-boot-cli/src/it/resources/jar-command/jar.groovy @@ -1,5 +1,6 @@ package org.test +@EnableGroovyTemplates @Component class Example implements CommandLineRunner { @@ -12,6 +13,7 @@ class Example implements CommandLineRunner { println getClass().getResource('/resources/resource.txt') println getClass().getResource('/static/static.txt') println getClass().getResource('/templates/template.txt') + println template('template.txt', [world:'Mama']) } } diff --git a/spring-boot-cli/src/it/resources/jar-command/templates/template.txt b/spring-boot-cli/src/it/resources/jar-command/templates/template.txt index e69de29bb2..ce65c33aff 100644 --- a/spring-boot-cli/src/it/resources/jar-command/templates/template.txt +++ b/spring-boot-cli/src/it/resources/jar-command/templates/template.txt @@ -0,0 +1 @@ +Goodbye ${world} \ No newline at end of file diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/jar/JarCommand.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/jar/JarCommand.java index c3661b6f10..11854907a6 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/jar/JarCommand.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/jar/JarCommand.java @@ -55,7 +55,10 @@ import org.springframework.boot.cli.jar.PackagedSpringApplicationLauncher; import org.springframework.boot.loader.tools.JarWriter; import org.springframework.boot.loader.tools.Layout; import org.springframework.boot.loader.tools.Layouts; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * {@link Command} to create a self-contained executable jar file from a CLI application @@ -207,6 +210,11 @@ public class JarCommand extends OptionParsingCommand { private void addCliClasses(JarWriter writer) throws IOException { addClass(writer, PackagedSpringApplicationLauncher.class); + Resource[] resources = new PathMatchingResourcePatternResolver().getResources("org/springframework/boot/groovy/**"); + for (Resource resource : resources) { + String url = resource.getURL().toString(); + addResource(writer, resource, url.substring(url.indexOf("org/springframework/boot/groovy/"))); + } } private void addClass(JarWriter writer, Class sourceClass) throws IOException { @@ -215,6 +223,11 @@ public class JarCommand extends OptionParsingCommand { writer.writeEntry(name, stream); } + private void addResource(JarWriter writer, Resource resource, String name) throws IOException { + InputStream stream = resource.getInputStream(); + writer.writeEntry(name, stream); + } + private void addClasspathEntries(JarWriter writer, List entries) throws IOException { for (MatchedResource entry : entries) { @@ -263,6 +276,8 @@ public class JarCommand extends OptionParsingCommand { AnnotationNode annotation = new AnnotationNode(new ClassNode(Grab.class)); annotation.addMember("value", new ConstantExpression("groovy")); classNode.addAnnotation(annotation); + // We only need to do it at most once + break; } } diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java new file mode 100644 index 0000000000..8e213f1639 --- /dev/null +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * 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. + */ + +package org.springframework.boot.cli.compiler.autoconfigure; + +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.control.customizers.ImportCustomizer; +import org.springframework.boot.cli.compiler.AstUtils; +import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; +import org.springframework.boot.cli.compiler.DependencyCustomizer; +import org.springframework.boot.groovy.EnableGroovyTemplates; +import org.springframework.boot.groovy.GroovyTemplate; + +/** + * {@link CompilerAutoConfiguration} for Groovy Templates (outside MVC). + * + * @author Dave Syer + * + * @since 1.1 + */ +public class GroovyTemplatesCompilerAutoConfiguration extends CompilerAutoConfiguration { + + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableGroovyTemplates"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies + .ifAnyMissingClasses("groovy.text.TemplateEngine") + .add("groovy-templates"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addStarImports("groovy.text"); + imports.addImports(EnableGroovyTemplates.class.getCanonicalName()); + imports.addStaticImport(GroovyTemplate.class.getName(), "template"); + } + +} diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java index 34727c3cb3..87116e4333 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java @@ -42,7 +42,8 @@ public class SpringMvcCompilerAutoConfiguration extends CompilerAutoConfiguratio dependencies .ifAnyMissingClasses("org.springframework.web.servlet.mvc.Controller") .add("spring-boot-starter-web"); - dependencies.add("groovy-templates"); + dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add( + "groovy-templates"); } @Override diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/groovy/EnableGroovyTemplates.java b/spring-boot-cli/src/main/java/org/springframework/boot/groovy/EnableGroovyTemplates.java new file mode 100644 index 0000000000..047029f826 --- /dev/null +++ b/spring-boot-cli/src/main/java/org/springframework/boot/groovy/EnableGroovyTemplates.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * 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. + */ + +package org.springframework.boot.groovy; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Pseudo annotation used to trigger {@link GroovyTemplatesAutoConfiguration}. + */ +@Target(ElementType.TYPE) +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface EnableGroovyTemplates { + +} diff --git a/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration b/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration index 30748a2c99..ef71edacaf 100644 --- a/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration +++ b/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration @@ -1,4 +1,5 @@ org.springframework.boot.cli.compiler.autoconfigure.SpringBootCompilerAutoConfiguration +org.springframework.boot.cli.compiler.autoconfigure.GroovyTemplatesCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.SpringMvcCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.SpringBatchCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.RabbitCompilerAutoConfiguration