Commit 48c12282 authored by Dave Syer's avatar Dave Syer

Add support for groovy utilities in "spring jar"

Also an integration test that uses the (new)
@EnableGroovyTemplates to switch on the template conveniences
in a non-webapp

Fixes gh-990
parent 3c6dfb72
...@@ -80,5 +80,7 @@ public class JarCommandIT { ...@@ -80,5 +80,7 @@ public class JarCommandIT {
assertThat(invocation.getStandardOutput(), containsString("/static/static.txt")); assertThat(invocation.getStandardOutput(), containsString("/static/static.txt"));
assertThat(invocation.getStandardOutput(), assertThat(invocation.getStandardOutput(),
containsString("/templates/template.txt")); containsString("/templates/template.txt"));
assertThat(invocation.getStandardOutput(),
containsString("Goodbye Mama"));
} }
} }
package org.test package org.test
@EnableGroovyTemplates
@Component @Component
class Example implements CommandLineRunner { class Example implements CommandLineRunner {
...@@ -12,6 +13,7 @@ class Example implements CommandLineRunner { ...@@ -12,6 +13,7 @@ class Example implements CommandLineRunner {
println getClass().getResource('/resources/resource.txt') println getClass().getResource('/resources/resource.txt')
println getClass().getResource('/static/static.txt') println getClass().getResource('/static/static.txt')
println getClass().getResource('/templates/template.txt') println getClass().getResource('/templates/template.txt')
println template('template.txt', [world:'Mama'])
} }
} }
......
...@@ -55,7 +55,10 @@ import org.springframework.boot.cli.jar.PackagedSpringApplicationLauncher; ...@@ -55,7 +55,10 @@ import org.springframework.boot.cli.jar.PackagedSpringApplicationLauncher;
import org.springframework.boot.loader.tools.JarWriter; import org.springframework.boot.loader.tools.JarWriter;
import org.springframework.boot.loader.tools.Layout; import org.springframework.boot.loader.tools.Layout;
import org.springframework.boot.loader.tools.Layouts; 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.Assert;
import org.springframework.util.ClassUtils;
/** /**
* {@link Command} to create a self-contained executable jar file from a CLI application * {@link Command} to create a self-contained executable jar file from a CLI application
...@@ -207,6 +210,11 @@ public class JarCommand extends OptionParsingCommand { ...@@ -207,6 +210,11 @@ public class JarCommand extends OptionParsingCommand {
private void addCliClasses(JarWriter writer) throws IOException { private void addCliClasses(JarWriter writer) throws IOException {
addClass(writer, PackagedSpringApplicationLauncher.class); 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 { private void addClass(JarWriter writer, Class<?> sourceClass) throws IOException {
...@@ -215,6 +223,11 @@ public class JarCommand extends OptionParsingCommand { ...@@ -215,6 +223,11 @@ public class JarCommand extends OptionParsingCommand {
writer.writeEntry(name, stream); 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<MatchedResource> entries) private void addClasspathEntries(JarWriter writer, List<MatchedResource> entries)
throws IOException { throws IOException {
for (MatchedResource entry : entries) { for (MatchedResource entry : entries) {
...@@ -263,6 +276,8 @@ public class JarCommand extends OptionParsingCommand { ...@@ -263,6 +276,8 @@ public class JarCommand extends OptionParsingCommand {
AnnotationNode annotation = new AnnotationNode(new ClassNode(Grab.class)); AnnotationNode annotation = new AnnotationNode(new ClassNode(Grab.class));
annotation.addMember("value", new ConstantExpression("groovy")); annotation.addMember("value", new ConstantExpression("groovy"));
classNode.addAnnotation(annotation); classNode.addAnnotation(annotation);
// We only need to do it at most once
break;
} }
} }
......
/*
* 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");
}
}
...@@ -42,7 +42,8 @@ public class SpringMvcCompilerAutoConfiguration extends CompilerAutoConfiguratio ...@@ -42,7 +42,8 @@ public class SpringMvcCompilerAutoConfiguration extends CompilerAutoConfiguratio
dependencies dependencies
.ifAnyMissingClasses("org.springframework.web.servlet.mvc.Controller") .ifAnyMissingClasses("org.springframework.web.servlet.mvc.Controller")
.add("spring-boot-starter-web"); .add("spring-boot-starter-web");
dependencies.add("groovy-templates"); dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add(
"groovy-templates");
} }
@Override @Override
......
/*
* 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 {
}
org.springframework.boot.cli.compiler.autoconfigure.SpringBootCompilerAutoConfiguration 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.SpringMvcCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.SpringBatchCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.SpringBatchCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.RabbitCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.RabbitCompilerAutoConfiguration
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment