FREEMARKER-54: Adding SpringResourceTemplateLoader and test
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a571c24f Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a571c24f Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a571c24f Branch: refs/heads/3 Commit: a571c24f6fc9544e164eeaf71347044b3fe88182 Parents: 18ee8a0 Author: Woonsan Ko <[email protected]> Authored: Sat Jun 17 23:44:46 2017 -0400 Committer: Woonsan Ko <[email protected]> Committed: Sat Jun 17 23:44:46 2017 -0400 ---------------------------------------------------------------------- .../SpringResourceTemplateLoader.java | 123 +++++++++++++++++++ .../SpringResourceTemplateLoaderTest.java | 82 +++++++++++++ .../META-INF/templates/sub1/sub2/t.ftl | 1 + 3 files changed, 206 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a571c24f/freemarker-spring/src/main/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoader.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoader.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoader.java new file mode 100644 index 0000000..a327bab --- /dev/null +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoader.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.freemarker.spring.templateresolver; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Objects; + +import org.apache.freemarker.core._CoreLogs; +import org.apache.freemarker.core.templateresolver.TemplateLoader; +import org.apache.freemarker.core.templateresolver.TemplateLoaderSession; +import org.apache.freemarker.core.templateresolver.TemplateLoadingResult; +import org.apache.freemarker.core.templateresolver.TemplateLoadingSource; +import org.slf4j.Logger; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +/** + * A {@link TemplateLoader} that uses Spring Framework <code>Resource</code>s which are resolved by locations. + */ +public class SpringResourceTemplateLoader implements TemplateLoader, ResourceLoaderAware { + + private static final Logger LOG = _CoreLogs.TEMPLATE_RESOLVER; + + private ResourceLoader resourceLoader; + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @Override + public TemplateLoaderSession createSession() { + return null; + } + + @Override + public TemplateLoadingResult load(String name, TemplateLoadingSource ifSourceDiffersFrom, + Serializable ifVersionDiffersFrom, TemplateLoaderSession session) throws IOException { + if (resourceLoader == null) { + throw new IllegalStateException("Spring Framework ResourceLoader was not set."); + } + + Resource resource = resourceLoader.getResource(name); + + if (!resource.exists()) { + return TemplateLoadingResult.NOT_FOUND; + } + + ResourceTemplateLoadingSource source = new ResourceTemplateLoadingSource(resource); + + Long version = null; + + try { + long lmd = resource.lastModified(); + if (lmd != -1) { + version = lmd; + } + } catch (IOException e) { + if (LOG.isDebugEnabled()) { + LOG.debug("The last modified timestamp of the resource at '{}' may not be resolved. {}", name, + e.toString()); + } + } + + if (ifSourceDiffersFrom != null && ifSourceDiffersFrom.equals(source) + && Objects.equals(ifVersionDiffersFrom, version)) { + return TemplateLoadingResult.NOT_MODIFIED; + } + + return new TemplateLoadingResult(source, version, resource.getInputStream(), null); + } + + @Override + public void resetState() { + // Does nothing + } + + @SuppressWarnings("serial") + private static class ResourceTemplateLoadingSource implements TemplateLoadingSource { + + private final Resource resource; + + ResourceTemplateLoadingSource(Resource resource) { + this.resource = resource; + } + + @Override + public int hashCode() { + return resource.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return resource.equals(((ResourceTemplateLoadingSource) obj).resource); + } + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a571c24f/freemarker-spring/src/test/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoaderTest.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/test/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoaderTest.java b/freemarker-spring/src/test/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoaderTest.java new file mode 100644 index 0000000..23f604e --- /dev/null +++ b/freemarker-spring/src/test/java/org/apache/freemarker/spring/templateresolver/SpringResourceTemplateLoaderTest.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.freemarker.spring.templateresolver; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.TemplateNotFoundException; +import org.apache.freemarker.test.TestConfigurationBuilder; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.GenericApplicationContext; + +public class SpringResourceTemplateLoaderTest { + + private static final String TEMPLATE_BASE_PATH = "classpath:META-INF/templates/"; + + private GenericApplicationContext appContext; + private SpringResourceTemplateLoader templateLoader; + private Configuration cfg; + + @Before + public void setUp() throws IOException { + appContext = new GenericApplicationContext(); + templateLoader = new SpringResourceTemplateLoader(); + templateLoader.setResourceLoader(appContext); + cfg = new TestConfigurationBuilder().templateLoader(templateLoader).build(); + } + + @After + public void tearDown() throws Exception { + if (appContext.isActive()) { + appContext.stop(); + appContext.destroy(); + appContext.close(); + } + } + + @Test + public void testSuccessful() throws Exception { + for (int i = 0; i < 2; i++) { + assertEquals("foo", cfg.getTemplate(TEMPLATE_BASE_PATH + "sub1/sub2/t.ftl").toString()); + } + } + + @Test + public void testNotFound() throws Exception { + for (int i = 0; i < 2; i++) { + try { + cfg.getTemplate(TEMPLATE_BASE_PATH + "sub1X/sub2/t.ftl"); + fail(); + } catch (TemplateNotFoundException e) { + assertThat(e.getMessage(), containsString("sub1X")); + assertNull(e.getCause()); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a571c24f/freemarker-spring/src/test/resources/META-INF/templates/sub1/sub2/t.ftl ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/test/resources/META-INF/templates/sub1/sub2/t.ftl b/freemarker-spring/src/test/resources/META-INF/templates/sub1/sub2/t.ftl new file mode 100644 index 0000000..1910281 --- /dev/null +++ b/freemarker-spring/src/test/resources/META-INF/templates/sub1/sub2/t.ftl @@ -0,0 +1 @@ +foo \ No newline at end of file
