Save This Page
Home » struts-2.1.8.1-src » org.apache » struts2 » views » freemarker » [javadoc | source]
    1   /*
    2    * $Id: PortletFreemarkerResult.java 768802 2009-04-26 21:34:14Z nilsga $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
   10    * with the License.  You may obtain a copy of the License at
   11    *
   12    *  http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing,
   15    * software distributed under the License is distributed on an
   16    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   17    * KIND, either express or implied.  See the License for the
   18    * specific language governing permissions and limitations
   19    * under the License.
   20    */
   21   
   22   package org.apache.struts2.views.freemarker;
   23   
   24   import java.io.IOException;
   25   import java.io.Writer;
   26   import java.util.Locale;
   27   
   28   import javax.portlet.ActionResponse;
   29   import javax.portlet.PortletException;
   30   import javax.portlet.PortletRequestDispatcher;
   31   import javax.servlet.ServletContext;
   32   import javax.servlet.http.HttpServletRequest;
   33   import javax.servlet.http.HttpServletResponse;
   34   
   35   import org.apache.struts2.ServletActionContext;
   36   import org.apache.struts2.dispatcher.StrutsResultSupport;
   37   import org.apache.struts2.portlet.PortletActionConstants;
   38   import org.apache.struts2.portlet.context.PortletActionContext;
   39   import org.apache.struts2.views.util.ResourceUtil;
   40   
   41   import com.opensymphony.xwork2.ActionInvocation;
   42   import com.opensymphony.xwork2.inject.Inject;
   43   import com.opensymphony.xwork2.util.ValueStack;
   44   
   45   import freemarker.template.Configuration;
   46   import freemarker.template.ObjectWrapper;
   47   import freemarker.template.Template;
   48   import freemarker.template.TemplateException;
   49   import freemarker.template.TemplateModel;
   50   import freemarker.template.TemplateModelException;
   51   
   52   /**
   53    */
   54   public class PortletFreemarkerResult extends StrutsResultSupport implements PortletActionConstants{
   55   
   56       private static final long serialVersionUID = -5570612389289887543L;
   57   
   58       protected ActionInvocation invocation;
   59   
   60       protected Configuration configuration;
   61   
   62       protected ObjectWrapper wrapper;
   63       protected FreemarkerManager freemarkerManager;
   64   
   65       /*
   66        * Struts results are constructed for each result execeution
   67        *
   68        * the current context is availible to subclasses via these protected fields
   69        */
   70       protected String location;
   71   
   72       private String pContentType = "text/html";
   73   
   74       public PortletFreemarkerResult() {
   75           super();
   76       }
   77   
   78       public PortletFreemarkerResult(String location) {
   79           super(location);
   80       }
   81       
   82       @Inject
   83       public void setFreemarkerManager(FreemarkerManager mgr) {
   84           this.freemarkerManager = mgr;
   85       }
   86   
   87       public void setContentType(String aContentType) {
   88           pContentType = aContentType;
   89       }
   90   
   91       /**
   92        * allow parameterization of the contentType the default being text/html
   93        */
   94       public String getContentType() {
   95           return pContentType;
   96       }
   97   
   98       /**
   99        * Execute this result, using the specified template location. <p/>The
  100        * template location has already been interoplated for any variable
  101        * substitutions <p/>this method obtains the freemarker configuration and
  102        * the object wrapper from the provided hooks. It them implements the
  103        * template processing workflow by calling the hooks for preTemplateProcess
  104        * and postTemplateProcess
  105        */
  106       public void doExecute(String location, ActionInvocation invocation)
  107               throws IOException, TemplateException, PortletException {
  108           if (PortletActionContext.isEvent()) {
  109               executeActionResult(location, invocation);
  110           } else if (PortletActionContext.isRender()) {
  111               executeRenderResult(location, invocation);
  112           }
  113       }
  114   
  115       /**
  116        * @param location
  117        * @param invocation
  118        */
  119       private void executeActionResult(String location,
  120                                        ActionInvocation invocation) {
  121           ActionResponse res = PortletActionContext.getActionResponse();
  122           // View is rendered outside an action...uh oh...
  123   		invocation.getInvocationContext().getSession().put(RENDER_DIRECT_LOCATION, location);
  124           res.setRenderParameter(PortletActionConstants.ACTION_PARAM, "freemarkerDirect");
  125           res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext
  126                   .getRequest().getPortletMode().toString());
  127   
  128       }
  129   
  130       /**
  131        * @param location
  132        * @param invocation
  133        * @throws TemplateException
  134        * @throws IOException
  135        * @throws TemplateModelException
  136        */
  137       private void executeRenderResult(String location,
  138                                        ActionInvocation invocation) throws TemplateException, IOException,
  139               TemplateModelException, PortletException {
  140           this.location = location;
  141           this.invocation = invocation;
  142           this.configuration = getConfiguration();
  143           this.wrapper = getObjectWrapper();
  144   
  145           HttpServletRequest req = ServletActionContext.getRequest();
  146   
  147           if (!location.startsWith("/")) {
  148               String base = ResourceUtil.getResourceBase(req);
  149               location = base + "/" + location;
  150           }
  151   
  152           Template template = configuration.getTemplate(location, deduceLocale());
  153           TemplateModel model = createModel();
  154           // Give subclasses a chance to hook into preprocessing
  155           if (preTemplateProcess(template, model)) {
  156               try {
  157                   // Process the template
  158                   PortletActionContext.getRenderResponse().setContentType(pContentType);
  159                   template.process(model, getWriter());
  160               } finally {
  161                   // Give subclasses a chance to hook into postprocessing
  162                   postTemplateProcess(template, model);
  163               }
  164           }
  165       }
  166   
  167       /**
  168        * This method is called from {@link #doExecute(String, ActionInvocation)}
  169        * to obtain the FreeMarker configuration object that this result will use
  170        * for template loading. This is a hook that allows you to custom-configure
  171        * the configuration object in a subclass, or to fetch it from an IoC
  172        * container. <p/><b>The default implementation obtains the configuration
  173        * from the ConfigurationManager instance. </b>
  174        */
  175       protected Configuration getConfiguration() throws TemplateException {
  176           return freemarkerManager.getConfiguration(
  177                   ServletActionContext.getServletContext());
  178       }
  179   
  180       /**
  181        * This method is called from {@link #doExecute(String, ActionInvocation)}
  182        * to obtain the FreeMarker object wrapper object that this result will use
  183        * for adapting objects into template models. This is a hook that allows you
  184        * to custom-configure the wrapper object in a subclass. <p/><b>The default
  185        * implementation returns {@link Configuration#getObjectWrapper()}</b>
  186        */
  187       protected ObjectWrapper getObjectWrapper() {
  188           return configuration.getObjectWrapper();
  189       }
  190   
  191       /**
  192        * The default writer writes directly to the response writer.
  193        */
  194       protected Writer getWriter() throws IOException {
  195           return PortletActionContext.getRenderResponse().getWriter();
  196       }
  197   
  198       /**
  199        * Build the instance of the ScopesHashModel, including JspTagLib support
  200        * <p/>Objects added to the model are <p/>
  201        * <ul>
  202        * <li>Application - servlet context attributes hash model
  203        * <li>JspTaglibs - jsp tag lib factory model
  204        * <li>Request - request attributes hash model
  205        * <li>Session - session attributes hash model
  206        * <li>request - the HttpServletRequst object for direct access
  207        * <li>response - the HttpServletResponse object for direct access
  208        * <li>stack - the OgnLValueStack instance for direct access
  209        * <li>ognl - the instance of the OgnlTool
  210        * <li>action - the action itself
  211        * <li>exception - optional : the JSP or Servlet exception as per the
  212        * servlet spec (for JSP Exception pages)
  213        * <li>struts - instance of the StrutsUtil class
  214        * </ul>
  215        */
  216       protected TemplateModel createModel() throws TemplateModelException {
  217           ServletContext servletContext = ServletActionContext
  218                   .getServletContext();
  219           HttpServletRequest request = ServletActionContext.getRequest();
  220           HttpServletResponse response = ServletActionContext.getResponse();
  221           ValueStack stack = ServletActionContext.getContext()
  222                   .getValueStack();
  223           return freemarkerManager.buildTemplateModel(stack,
  224                   invocation.getAction(), servletContext, request, response,
  225                   wrapper);
  226       }
  227   
  228       /**
  229        * Returns the locale used for the
  230        * {@link Configuration#getTemplate(String, Locale)}call. The base
  231        * implementation simply returns the locale setting of the configuration.
  232        * Override this method to provide different behaviour,
  233        */
  234       protected Locale deduceLocale() {
  235           return configuration.getLocale();
  236       }
  237   
  238       /**
  239        * the default implementation of postTemplateProcess applies the contentType
  240        * parameter
  241        */
  242       protected void postTemplateProcess(Template template, TemplateModel data)
  243               throws IOException {
  244       }
  245   
  246       /**
  247        * Called before the execution is passed to template.process(). This is a
  248        * generic hook you might use in subclasses to perform a specific action
  249        * before the template is processed. By default does nothing. A typical
  250        * action to perform here is to inject application-specific objects into the
  251        * model root
  252        *
  253        * @return true to process the template, false to suppress template
  254        *         processing.
  255        */
  256       protected boolean preTemplateProcess(Template template, TemplateModel model)
  257               throws IOException {
  258           Object attrContentType = template.getCustomAttribute("content_type");
  259   
  260           if (attrContentType != null) {
  261               ServletActionContext.getResponse().setContentType(
  262                       attrContentType.toString());
  263           } else {
  264               String contentType = getContentType();
  265   
  266               if (contentType == null) {
  267                   contentType = "text/html";
  268               }
  269   
  270               String encoding = template.getEncoding();
  271   
  272               if (encoding != null) {
  273                   contentType = contentType + "; charset=" + encoding;
  274               }
  275   
  276               ServletActionContext.getResponse().setContentType(contentType);
  277           }
  278   
  279           return true;
  280       }
  281   }
  282   

Save This Page
Home » struts-2.1.8.1-src » org.apache » struts2 » views » freemarker » [javadoc | source]