Author: musachy Date: Tue Jun 26 20:29:53 2007 New Revision: 551022 URL: http://svn.apache.org/viewvc?view=rev&rev=551022 Log: WW-1808 Support Freemarker template_exception_handler=rethrow * new attribute "writeIfCompleted" was added to FreeMarkerResult which if set to true will write to the stream only when there isn't any error processing the template (false by default)
Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/ struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/someFreeMarkerFile.ftl Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java?view=diff&rev=551022&r1=551021&r2=551022 ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java (original) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java Tue Jun 26 20:29:53 2007 @@ -335,8 +335,10 @@ public SimpleHash buildTemplateModel(ValueStack stack, Object action, ServletContext servletContext, HttpServletRequest request, HttpServletResponse response, ObjectWrapper wrapper) { ScopesHashModel model = buildScopesHashModel(servletContext, request, response, wrapper, stack); populateContext(model, stack, action, request, response); - for (String prefix : tagLibraries.keySet()) { - model.put(prefix, tagLibraries.get(prefix).getFreemarkerModels(stack, request, response)); + if (tagLibraries != null) { + for (String prefix : tagLibraries.keySet()) { + model.put(prefix, tagLibraries.get(prefix).getFreemarkerModels(stack, request, response)); + } } return model; } Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java?view=diff&rev=551022&r1=551021&r2=551022 ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java (original) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java Tue Jun 26 20:29:53 2007 @@ -20,6 +20,7 @@ */ package org.apache.struts2.views.freemarker; +import java.io.CharArrayWriter; import java.io.IOException; import java.io.Writer; import java.util.Locale; @@ -42,6 +43,7 @@ import freemarker.template.ObjectWrapper; import freemarker.template.Template; import freemarker.template.TemplateException; +import freemarker.template.TemplateExceptionHandler; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; @@ -78,6 +80,10 @@ * not be parsed for Ognl expressions.</li> * * <li><b>contentType</b> - defaults to "text/html" unless specified.</li> + * + * <li><b>writeIfCompleted</b> - false by default, write to stream only if there isn't any error + * processing the template. Setting template_exception_handler=rethrow in freemarker.properties + * will have the same effect.</li> * * </ul> * @@ -102,7 +108,7 @@ protected ObjectWrapper wrapper; protected FreemarkerManager freemarkerManager; private Writer writer; - + private boolean writeIfCompleted = false; /* * Struts results are constructed for each result execution * @@ -165,7 +171,20 @@ if (preTemplateProcess(template, model)) { try { // Process the template - template.process(model, getWriter()); + Writer writer = getWriter(); + if (isWriteIfCompleted() || configuration.getTemplateExceptionHandler() == TemplateExceptionHandler.RETHROW_HANDLER) { + CharArrayWriter charArrayWriter = new CharArrayWriter(); + try { + template.process(model, charArrayWriter); + charArrayWriter.flush(); + charArrayWriter.writeTo(writer); + } finally { + if (charArrayWriter != null) + charArrayWriter.close(); + } + } else { + template.process(model, writer); + } } finally { // Give subclasses a chance to hook into postprocessing postTemplateProcess(template, model); @@ -295,5 +314,19 @@ } return true; + } + + /** + * @return true write to the stream only when template processing completed successfully (false by default) + */ + public boolean isWriteIfCompleted() { + return writeIfCompleted; + } + + /** + * Writes to the stream only when template processing completed successfully + */ + public void setWriteIfCompleted(boolean writeIfCompleted) { + this.writeIfCompleted = writeIfCompleted; } } Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java?view=auto&rev=551022 ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java (added) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java Tue Jun 26 20:29:53 2007 @@ -0,0 +1,119 @@ +/* + * $Id$ + * + * 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.struts2.views.freemarker; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsStatics; +import org.apache.struts2.views.jsp.StrutsMockHttpServletResponse; +import org.apache.struts2.views.jsp.StrutsMockServletContext; +import org.springframework.mock.web.MockHttpServletRequest; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.mock.MockActionInvocation; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; + +/** + * Test case for FreeMarkerResult. + * + */ +public class FreeMarkerResultTest extends TestCase { + + ValueStack stack; + MockActionInvocation invocation; + ActionContext context; + StrutsMockHttpServletResponse response; + PrintWriter writer; + StringWriter stringWriter; + StrutsMockServletContext servletContext; + private FreemarkerManager mgr; + private MockHttpServletRequest request; + + public void testWriteIfCompleted() throws Exception { + FreemarkerResult result = new FreemarkerResult(); + result.setLocation("someFreeMarkerFile.ftl"); + result.setFreemarkerManager(mgr); + result.setWriteIfCompleted(true); + + try { + result.execute(invocation); + assertTrue(false); + } catch (Exception e) { + assertEquals(0, stringWriter.getBuffer().length()); + } + } + + public void testWithoutWriteIfCompleted() throws Exception { + FreemarkerResult result = new FreemarkerResult(); + result.setLocation("someFreeMarkerFile.ftl"); + result.setFreemarkerManager(mgr); + + try { + result.execute(invocation); + assertTrue(false); + } catch (Exception e) { + assertTrue(stringWriter.getBuffer().length() > 0); + } + } + + protected void setUp() throws Exception { + super.setUp(); + mgr = new FreemarkerManager(); + mgr.setEncoding("UTF-8"); + stringWriter = new StringWriter(); + writer = new PrintWriter(stringWriter); + response = new StrutsMockHttpServletResponse(); + response.setWriter(writer); + request = new MockHttpServletRequest(); + servletContext = new StrutsMockServletContext(); + stack = ValueStackFactory.getFactory().createValueStack(); + context = new ActionContext(stack.getContext()); + context.put(StrutsStatics.HTTP_RESPONSE, response); + context.put(StrutsStatics.HTTP_REQUEST, request); + context.put(StrutsStatics.SERVLET_CONTEXT, servletContext); + ServletActionContext.setServletContext(servletContext); + ServletActionContext.setRequest(request); + ServletActionContext.setResponse(response); + servletContext.setAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY, null); + invocation = new MockActionInvocation(); + invocation.setStack(stack); + invocation.setInvocationContext(context); + servletContext.setRealPath(FreeMarkerResultTest.class.getResource( + "someFreeMarkerFile.ftl").getFile()); + } + + protected void tearDown() throws Exception { + stack = null; + invocation = null; + context = null; + response = null; + writer = null; + stringWriter = null; + servletContext = null; + + super.tearDown(); + } +} Added: struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/someFreeMarkerFile.ftl URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/someFreeMarkerFile.ftl?view=auto&rev=551022 ============================================================================== --- struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/someFreeMarkerFile.ftl (added) +++ struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/someFreeMarkerFile.ftl Tue Jun 26 20:29:53 2007 @@ -0,0 +1,3 @@ +Text + +<#if something>out</#if> \ No newline at end of file