Adding FreemarkerViewResolver and improving FreemarkerViewTest with JspTaglibFactory and example.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/9083de1b Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/9083de1b Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/9083de1b Branch: refs/heads/3 Commit: 9083de1ba04d9d54b80109ed86941da72337cba5 Parents: 83e896c Author: Woonsan Ko <[email protected]> Authored: Sun Jul 2 01:25:01 2017 -0400 Committer: Woonsan Ko <[email protected]> Committed: Sun Jul 2 01:25:01 2017 -0400 ---------------------------------------------------------------------- freemarker-spring/build.gradle | 40 ++++-- .../spring/web/view/AbstractFreemarkerView.java | 37 ++---- .../spring/web/view/FreemarkerView.java | 129 ++----------------- .../spring/web/view/FreemarkerViewResolver.java | 90 ++++++++++++- .../spring/web/view/PageContextServlet.java | 39 ++++++ .../web/view/PageContextServletConfig.java | 56 ++++++++ .../freemarker/spring/web/view/EchoTag.java | 55 ++++++++ .../spring/web/view/FreemarkerViewTest.java | 61 ++++++--- .../src/test/resources/WEB-INF/echo.tld | 46 +++++++ .../src/test/resources/WEB-INF/web.xml | 23 ++++ 10 files changed, 408 insertions(+), 168 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/build.gradle ---------------------------------------------------------------------- diff --git a/freemarker-spring/build.gradle b/freemarker-spring/build.gradle index 1865cc2..dce28d9 100644 --- a/freemarker-spring/build.gradle +++ b/freemarker-spring/build.gradle @@ -29,33 +29,57 @@ dependencies { compile project(":freemarker-core") compile project(":freemarker-servlet") - // TODO: what's difference between compileOnly and compile?? - compile "org.apache.geronimo.specs:geronimo-servlet_3.0_spec:1.0" - + def geronimoServletSpec3Version = "1.0" def springVersion = "4.3.9.RELEASE" - compile("org.springframework:spring-core:$springVersion") { + compileOnly "org.apache.geronimo.specs:geronimo-servlet_3.0_spec:${geronimoServletSpec3Version}" + + compileOnly("org.springframework:spring-core:$springVersion") { exclude group: "commons-logging", module: "commons-logging" } - compile("org.springframework:spring-beans:$springVersion") { + compileOnly("org.springframework:spring-beans:$springVersion") { exclude group: "commons-logging", module: "commons-logging" } - compile("org.springframework:spring-context:$springVersion") { + compileOnly("org.springframework:spring-context:$springVersion") { exclude group: "commons-logging", module: "commons-logging" } - compile("org.springframework:spring-web:$springVersion") { + compileOnly("org.springframework:spring-web:$springVersion") { exclude group: "commons-logging", module: "commons-logging" } - compile("org.springframework:spring-webmvc:$springVersion") { + compileOnly("org.springframework:spring-webmvc:$springVersion") { exclude group: "commons-logging", module: "commons-logging" } // ------------------------------------------------------------------------ // For tests + def taglibsStandardVersion = "1.2.1" + + testCompile "org.apache.geronimo.specs:geronimo-servlet_3.0_spec:${geronimoServletSpec3Version}" + + testCompile("org.springframework:spring-core:$springVersion") { + exclude group: "commons-logging", module: "commons-logging" + } + testCompile("org.springframework:spring-beans:$springVersion") { + exclude group: "commons-logging", module: "commons-logging" + } + testCompile("org.springframework:spring-context:$springVersion") { + exclude group: "commons-logging", module: "commons-logging" + } + testCompile("org.springframework:spring-web:$springVersion") { + exclude group: "commons-logging", module: "commons-logging" + } + testCompile("org.springframework:spring-webmvc:$springVersion") { + exclude group: "commons-logging", module: "commons-logging" + } testCompile("org.springframework:spring-test:$springVersion") { exclude group: "commons-logging", module: "commons-logging" } + + testCompile "javax.servlet.jsp:jsp-api:2.1" + testCompile "org.apache.taglibs:taglibs-standard-spec:${taglibsStandardVersion}" + testCompile "org.apache.taglibs:taglibs-standard-impl:${taglibsStandardVersion}" + } jar { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/AbstractFreemarkerView.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/AbstractFreemarkerView.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/AbstractFreemarkerView.java index 595ada2..38c2e3e 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/AbstractFreemarkerView.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/AbstractFreemarkerView.java @@ -32,13 +32,13 @@ import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateNotFoundException; import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper; import org.apache.freemarker.core.model.TemplateHashModel; -import org.apache.freemarker.core.model.impl.DefaultObjectWrapper; import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException; -import org.springframework.web.servlet.view.AbstractView; +import org.springframework.web.servlet.view.AbstractTemplateView; -public abstract class AbstractFreemarkerView extends AbstractView { +public abstract class AbstractFreemarkerView extends AbstractTemplateView { private Configuration configuration; + private ObjectWrapperAndUnwrapper objectWrapper; private String name; private Locale locale; private Serializable customLookupCondition; @@ -49,15 +49,17 @@ public abstract class AbstractFreemarkerView extends AbstractView { } public void setConfiguration(Configuration configuration) { - if (!(configuration.getObjectWrapper() instanceof ObjectWrapperAndUnwrapper)) { - throw new RuntimeException(AbstractFreemarkerView.class.getSimpleName() + " requires an ObjectWrapper that " - + "implements " + ObjectWrapperAndUnwrapper.class.getName() + ", but this class doesn't do that: " - + configuration.getObjectWrapper().getClass().getName()); - } - this.configuration = configuration; } + public ObjectWrapperAndUnwrapper getObjectWrapper() { + return objectWrapper; + } + + public void setObjectWrapper(ObjectWrapperAndUnwrapper objectWrapper) { + this.objectWrapper = objectWrapper; + } + public String getName() { return name; } @@ -91,9 +93,9 @@ public abstract class AbstractFreemarkerView extends AbstractView { } @Override - protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, + protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { - getTemplate().process(createModel(model, getObjectWrapperForModel(), request, response), response.getWriter()); + getTemplate().process(createModel(model, getObjectWrapper(), request, response), response.getWriter()); } protected Template getTemplate() @@ -101,19 +103,6 @@ public abstract class AbstractFreemarkerView extends AbstractView { return getConfiguration().getTemplate(getName(), getLocale(), getCustomLookupCondition(), isIgnoreMissing()); } - protected ObjectWrapperAndUnwrapper getObjectWrapperForModel() { - ObjectWrapperAndUnwrapper wrapper; - - if (configuration.isObjectWrapperSet()) { - wrapper = (ObjectWrapperAndUnwrapper) configuration.getObjectWrapper(); - } else { - // TODO: need to cache this? - wrapper = new DefaultObjectWrapper.Builder(configuration.getIncompatibleImprovements()).build(); - } - - return wrapper; - } - protected abstract TemplateHashModel createModel(Map<String, Object> map, ObjectWrapperAndUnwrapper objectWrapperForModel, HttpServletRequest request, HttpServletResponse response); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerView.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerView.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerView.java index 64b3158..2210b98 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerView.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerView.java @@ -18,17 +18,8 @@ */ package org.apache.freemarker.spring.web.view; -import java.io.IOException; -import java.util.Collections; -import java.util.Enumeration; import java.util.Map; -import javax.servlet.GenericServlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -42,38 +33,15 @@ import org.apache.freemarker.servlet.HttpRequestParametersHashModel; import org.apache.freemarker.servlet.HttpSessionHashModel; import org.apache.freemarker.servlet.ServletContextHashModel; import org.apache.freemarker.servlet.jsp.TaglibFactory; -import org.apache.freemarker.servlet.jsp.TaglibFactoryBuilder; public class FreemarkerView extends AbstractFreemarkerView { - private volatile PageContextServlet pageContextServlet; - - private volatile ServletContextHashModel servletContextModel; - - private volatile TaglibFactory taglibFactory; + private PageContextServlet pageContextServlet; + private ServletContextHashModel servletContextModel; + private TaglibFactory taglibFactory; public PageContextServlet getPageContextServlet() { - PageContextServlet servlet = pageContextServlet; - - if (servlet == null) { - synchronized (this) { - servlet = pageContextServlet; - - if (servlet == null) { - servlet = new PageContextServlet(); - - try { - servlet.init(new PageContextServletConfig(getServletContext(), getBeanName())); - } catch (ServletException e) { - // never happens... - } - - pageContextServlet = servlet; - } - } - } - - return servlet; + return pageContextServlet; } public void setPageContextServlet(PageContextServlet pageContextServlet) { @@ -81,20 +49,7 @@ public class FreemarkerView extends AbstractFreemarkerView { } public ServletContextHashModel getServletContextModel() { - ServletContextHashModel contextModel = servletContextModel; - - if (contextModel == null) { - synchronized (this) { - contextModel = servletContextModel; - - if (contextModel == null) { - contextModel = new ServletContextHashModel(getPageContextServlet(), getObjectWrapperForModel()); - servletContextModel = contextModel; - } - } - } - - return contextModel; + return servletContextModel; } public void setServletContextModel(ServletContextHashModel servletContextModel) { @@ -102,22 +57,7 @@ public class FreemarkerView extends AbstractFreemarkerView { } public TaglibFactory getTaglibFactory() { - TaglibFactory tlFactory = taglibFactory; - - if (tlFactory == null) { - synchronized (this) { - tlFactory = taglibFactory; - - if (tlFactory == null) { - tlFactory = new TaglibFactoryBuilder(getServletContext(), getObjectWrapperForModel()) - .build(); - - taglibFactory = tlFactory; - } - } - } - - return tlFactory; + return taglibFactory; } public void setTaglibFactory(TaglibFactory taglibFactory) { @@ -125,15 +65,15 @@ public class FreemarkerView extends AbstractFreemarkerView { } @Override - protected TemplateHashModel createModel(Map<String, Object> map, ObjectWrapperAndUnwrapper objectWrapperForModel, + protected TemplateHashModel createModel(Map<String, Object> map, ObjectWrapperAndUnwrapper objectWrapper, HttpServletRequest request, HttpServletResponse response) { - AllHttpScopesHashModel model = new AllHttpScopesHashModel(objectWrapperForModel, getServletContext(), request); + AllHttpScopesHashModel model = new AllHttpScopesHashModel(objectWrapper, getServletContext(), request); model.putUnlistedModel(FreemarkerServlet.KEY_APPLICATION, getServletContextModel()); model.putUnlistedModel(FreemarkerServlet.KEY_SESSION, - getHttpSessionModel(objectWrapperForModel, request, response)); + getHttpSessionModel(objectWrapper, request, response)); HttpRequestHashModel requestModel = (HttpRequestHashModel) request .getAttribute(FreemarkerServlet.ATTR_REQUEST_MODEL); @@ -141,9 +81,9 @@ public class FreemarkerView extends AbstractFreemarkerView { .getAttribute(FreemarkerServlet.ATTR_REQUEST_PARAMETERS_MODEL); if (requestModel == null || requestModel.getRequest() != request) { - requestModel = new HttpRequestHashModel(request, response, objectWrapperForModel); + requestModel = new HttpRequestHashModel(request, response, objectWrapper); request.setAttribute(FreemarkerServlet.ATTR_REQUEST_MODEL, requestModel); - requestParametersModel = new HttpRequestParametersHashModel(request, objectWrapperForModel); + requestParametersModel = new HttpRequestParametersHashModel(request, objectWrapper); } model.putUnlistedModel(FreemarkerServlet.KEY_REQUEST, requestModel); @@ -175,51 +115,4 @@ public class FreemarkerView extends AbstractFreemarkerView { return sessionModel; } - /** - * Extending {@link GenericServlet} for {@link PageContext#getPage()} in JSP Tag Library support. - */ - @SuppressWarnings("serial") - private static class PageContextServlet extends GenericServlet { - - @Override - public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - // Do nothing - } - - } - - /** - * {@link ServletConfig} for {@link PageContextServlet}. - */ - private class PageContextServletConfig implements ServletConfig { - - private ServletContext servletContext; - private String servletName; - - public PageContextServletConfig(ServletContext servletContext, String servletName) { - this.servletContext = servletContext; - this.servletName = servletName; - } - - @Override - public String getServletName() { - return servletName; - } - - @Override - public ServletContext getServletContext() { - return servletContext; - } - - @Override - public String getInitParameter(String name) { - return null; - } - - @Override - public Enumeration<String> getInitParameterNames() { - return Collections.enumeration(Collections.<String> emptySet()); - } - } - } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerViewResolver.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerViewResolver.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerViewResolver.java index 6d7ab40..ecacd42 100644 --- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerViewResolver.java +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreemarkerViewResolver.java @@ -18,9 +18,26 @@ */ package org.apache.freemarker.spring.web.view; +import javax.servlet.ServletException; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper; +import org.apache.freemarker.core.model.impl.DefaultObjectWrapper; +import org.apache.freemarker.servlet.ServletContextHashModel; +import org.apache.freemarker.servlet.jsp.TaglibFactory; +import org.apache.freemarker.servlet.jsp.TaglibFactoryBuilder; +import org.springframework.beans.factory.InitializingBean; import org.springframework.web.servlet.view.AbstractTemplateViewResolver; +import org.springframework.web.servlet.view.AbstractUrlBasedView; + +public class FreemarkerViewResolver extends AbstractTemplateViewResolver implements InitializingBean { -public class FreemarkerViewResolver extends AbstractTemplateViewResolver { + private Configuration configuration; + + private ObjectWrapperAndUnwrapper objectWrapper; + private PageContextServlet pageContextServlet; + private ServletContextHashModel servletContextModel; + private TaglibFactory taglibFactory; public FreemarkerViewResolver() { setViewClass(requiredViewClass()); @@ -32,9 +49,80 @@ public class FreemarkerViewResolver extends AbstractTemplateViewResolver { setSuffix(suffix); } + public Configuration getConfiguration() { + return configuration; + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public void afterPropertiesSet() throws Exception { + if (configuration == null) { + throw new IllegalStateException("Configuration is not set."); + } + + if (objectWrapper == null) { + if (configuration.isObjectWrapperSet()) { + if (!(configuration.getObjectWrapper() instanceof ObjectWrapperAndUnwrapper)) { + throw new RuntimeException( + FreemarkerViewResolver.class.getSimpleName() + " requires an ObjectWrapper that " + + "implements " + ObjectWrapperAndUnwrapper.class.getName() + + ", but the Configuration's ObjectWrapper doesn't do that: " + + configuration.getObjectWrapper().getClass().getName()); + } + + objectWrapper = (ObjectWrapperAndUnwrapper) configuration.getObjectWrapper(); + } else { + objectWrapper = new DefaultObjectWrapper.Builder(configuration.getIncompatibleImprovements()).build(); + } + } + + pageContextServlet = new PageContextServlet(); + + try { + pageContextServlet + .init(new PageContextServletConfig(getServletContext(), FreemarkerViewResolver.class.getName())); + } catch (ServletException e) { + // never happens... + } + + servletContextModel = new ServletContextHashModel(pageContextServlet, objectWrapper); + + taglibFactory = new TaglibFactoryBuilder(getServletContext(), objectWrapper).build(); + } + @Override protected Class<?> requiredViewClass() { return FreemarkerView.class; } + @Override + protected AbstractUrlBasedView buildView(String viewName) throws Exception { + FreemarkerView view = (FreemarkerView) super.buildView(viewName); + view.setConfiguration(configuration); + view.setObjectWrapper(objectWrapper); + view.setPageContextServlet(pageContextServlet); + view.setServletContextModel(servletContextModel); + view.setTaglibFactory(taglibFactory); + return view; + } + + protected ObjectWrapperAndUnwrapper getObjectWrapper() { + return objectWrapper; + } + + protected PageContextServlet getPageContextServlet() { + return pageContextServlet; + } + + protected ServletContextHashModel getServletContextModel() { + return servletContextModel; + } + + protected TaglibFactory getTaglibFactory() { + return taglibFactory; + } + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServlet.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServlet.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServlet.java new file mode 100644 index 0000000..94b586b --- /dev/null +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServlet.java @@ -0,0 +1,39 @@ +/* + * 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.web.view; + +import java.io.IOException; + +import javax.servlet.GenericServlet; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +/** + * <code>GenericServlet</code> to support {@link javax.servlet.jsp.PageContext#getPage()} when JspTaglibs is used. + */ +@SuppressWarnings("serial") +class PageContextServlet extends GenericServlet { + + @Override + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { + // Do nothing + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServletConfig.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServletConfig.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServletConfig.java new file mode 100644 index 0000000..0d42ba4 --- /dev/null +++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/PageContextServletConfig.java @@ -0,0 +1,56 @@ +/* + * 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.web.view; + +import java.util.Collections; +import java.util.Enumeration; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +class PageContextServletConfig implements ServletConfig { + + private ServletContext servletContext; + private String servletName; + + public PageContextServletConfig(ServletContext servletContext, String servletName) { + this.servletContext = servletContext; + this.servletName = servletName; + } + + @Override + public String getServletName() { + return servletName; + } + + @Override + public ServletContext getServletContext() { + return servletContext; + } + + @Override + public String getInitParameter(String name) { + return null; + } + + @Override + public Enumeration<String> getInitParameterNames() { + return Collections.enumeration(Collections.<String> emptySet()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/EchoTag.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/EchoTag.java b/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/EchoTag.java new file mode 100644 index 0000000..155474f --- /dev/null +++ b/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/EchoTag.java @@ -0,0 +1,55 @@ +/* + * 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.web.view; + +import java.io.IOException; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.TagSupport; + +/** + * Simple Example JSP Tag Library for unit test. + */ +@SuppressWarnings("serial") +public class EchoTag extends TagSupport { + + private String message; + + public EchoTag() { + super(); + } + + public void setMessage(String message) { + this.message = message; + } + + public int doEndTag() throws JspException { + try { + pageContext.getOut().print(message); + } catch (IOException e) { + throw new JspException("Message printing error.", e); + } + return EVAL_PAGE; + } + + public void release() { + this.message = null; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/FreemarkerViewTest.java ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/FreemarkerViewTest.java b/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/FreemarkerViewTest.java index 80fc2b3..4a6f4b1 100644 --- a/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/FreemarkerViewTest.java +++ b/freemarker-spring/src/test/java/org/apache/freemarker/spring/web/view/FreemarkerViewTest.java @@ -34,25 +34,41 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockServletContext; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; public class FreemarkerViewTest { private ServletContext servletContext; + private GenericWebApplicationContext applicationContext; private StringTemplateLoader templateLoader; - private Configuration configuration; + private FreemarkerViewResolver viewResolver; + private AtomicLong visitorCount; @Before public void setUp() throws Exception { servletContext = new MockServletContext(); - visitorCount = new AtomicLong(); - servletContext.setAttribute("visitorCount", visitorCount); + + applicationContext = new GenericWebApplicationContext(servletContext); + applicationContext.refresh(); + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext); + templateLoader = new StringTemplateLoader(); configuration = new Configuration.Builder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS) .templateLoader(templateLoader).build(); + + viewResolver = new FreemarkerViewResolver(); + viewResolver.setServletContext(servletContext); + viewResolver.setApplicationContext(applicationContext); + viewResolver.setConfiguration(configuration); + viewResolver.afterPropertiesSet(); + + visitorCount = new AtomicLong(); + servletContext.setAttribute("visitorCount", visitorCount); } @Test @@ -63,10 +79,7 @@ public class FreemarkerViewTest { templateLoader.putTemplate("hello.ftl", "Hello, ${name!\"World\"}! Visit count: ${visitCount!0}"); - FreemarkerView view = new FreemarkerView(); - view.setServletContext(servletContext); - view.setConfiguration(configuration); - view.setName("hello.ftl"); + FreemarkerView view = createFreemarkerView("hello.ftl"); int visitCount = 0; Map<String, Object> model = new HashMap<String, Object>(); @@ -100,10 +113,7 @@ public class FreemarkerViewTest { + "BTW, you're ${Application.visitorCount}th visitor. " + "(token1: ${RequestParameters['token1']!})"); - FreemarkerView view = new FreemarkerView(); - view.setServletContext(servletContext); - view.setConfiguration(configuration); - view.setName("default-model.ftl"); + FreemarkerView view = createFreemarkerView("default-model.ftl"); Map<String, Object> model = new HashMap<String, Object>(); model.put("name", "Dan"); @@ -121,16 +131,33 @@ public class FreemarkerViewTest { request.setContextPath("/mycontext"); request.setServletPath("/myservlet"); - // TODO: - templateLoader.putTemplate("taglibs.ftl", ""); + templateLoader.putTemplate("taglibs.ftl", + "<#assign e=JspTaglibs ['http://freemarker.org/jsp/example/echo'] >" + + "<#assign msg=\"Hello!\" />" + + "<@e.echo message=msg />"); - FreemarkerView view = new FreemarkerView(); - view.setServletContext(servletContext); - view.setConfiguration(configuration); - view.setName("taglibs.ftl"); + FreemarkerView view = createFreemarkerView("taglibs.ftl"); Map<String, Object> model = new HashMap<String, Object>(); MockHttpServletResponse response = new MockHttpServletResponse(); view.render(model, request, response); + assertEquals("Hello!", response.getContentAsString()); + } + + private FreemarkerView createFreemarkerView(final String name) { + FreemarkerView view = new FreemarkerView(); + + view.setServletContext(servletContext); + view.setApplicationContext(applicationContext); + view.setConfiguration(configuration); + view.setObjectWrapper(viewResolver.getObjectWrapper()); + + view.setPageContextServlet(viewResolver.getPageContextServlet()); + view.setServletContextModel(viewResolver.getServletContextModel()); + view.setTaglibFactory(viewResolver.getTaglibFactory()); + + view.setName(name); + + return view; } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/test/resources/WEB-INF/echo.tld ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/test/resources/WEB-INF/echo.tld b/freemarker-spring/src/test/resources/WEB-INF/echo.tld new file mode 100644 index 0000000..aff4d98 --- /dev/null +++ b/freemarker-spring/src/test/resources/WEB-INF/echo.tld @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + 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. +--> +<taglib xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" + version="2.1"> + + <description>Test Echo Tag Library</description> + <display-name>Test Echo Tag Library</display-name> + <tlib-version>1.2</tlib-version> + <short-name>e</short-name> + <uri>http://freemarker.org/jsp/example/echo</uri> + + <tag> + <description> + Print the message. + </description> + <name>echo</name> + <tag-class>org.apache.freemarker.spring.web.view.EchoTag</tag-class> + <body-content>JSP</body-content> + <attribute> + <description> + Message string. + </description> + <name>message</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + +</taglib> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9083de1b/freemarker-spring/src/test/resources/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/freemarker-spring/src/test/resources/WEB-INF/web.xml b/freemarker-spring/src/test/resources/WEB-INF/web.xml new file mode 100644 index 0000000..f091779 --- /dev/null +++ b/freemarker-spring/src/test/resources/WEB-INF/web.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<web-app version="3.0"> + + <display-name>Test Web Application descriptor in Apache FreeMarker Spring Framework support module</display-name> + <description>Test Web Application descriptor in Apache FreeMarker Spring Framework support module</description> + +</web-app>
