Home » tiles-2.2.1-src » org.apache.tiles.freemarker.renderer » [javadoc | source]

    1   /*
    2    * $Id: FreeMarkerAttributeRenderer.java 821299 2009-10-03 12:15:05Z apetrelli $
    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.tiles.freemarker.renderer;
   23   
   24   import java.io.IOException;
   25   import java.util.Enumeration;
   26   import java.util.HashMap;
   27   import java.util.Map;
   28   
   29   import javax.servlet.ServletConfig;
   30   import javax.servlet.ServletContext;
   31   import javax.servlet.ServletException;
   32   import javax.servlet.http.HttpServletRequest;
   33   import javax.servlet.http.HttpServletResponse;
   34   
   35   import org.apache.tiles.Attribute;
   36   import org.apache.tiles.context.TilesRequestContext;
   37   import org.apache.tiles.freemarker.FreeMarkerTilesException;
   38   import org.apache.tiles.freemarker.servlet.TilesFreemarkerServlet;
   39   import org.apache.tiles.impl.InvalidTemplateException;
   40   import org.apache.tiles.renderer.impl.AbstractTypeDetectingAttributeRenderer;
   41   import org.apache.tiles.servlet.context.ExternalWriterHttpServletResponse;
   42   import org.apache.tiles.servlet.context.ServletTilesRequestContext;
   43   import org.apache.tiles.servlet.context.ServletUtil;
   44   import org.apache.tiles.util.IteratorEnumeration;
   45   
   46   /**
   47    * FreeMarker renderer for rendering FreeMarker templates as Tiles attributes.
   48    * It is only usable under a Servlet environment, because it uses
   49    * {@link TilesFreemarkerServlet} internally to forward the request.<br/>
   50    * To initialize it correctly, call {@link #setParameter(String, String)} for all the
   51    * parameters that you want to set, and then call {@link #commit()}.
   52    *
   53    * @version $Rev: 821299 $ $Date: 2009-10-03 14:15:05 +0200 (sab, 03 ott 2009) $
   54    * @since 2.2.0
   55    */
   56   public class FreeMarkerAttributeRenderer extends AbstractTypeDetectingAttributeRenderer {
   57   
   58       /**
   59        * The servlet that is used to forward the request to.
   60        */
   61       private AttributeValueFreemarkerServlet servlet;
   62   
   63       /**
   64        * The initialization parameters.
   65        */
   66       private Map<String, String> params = new HashMap<String, String>();
   67   
   68       /**
   69        * Sets a parameter for the internal servlet.
   70        *
   71        * @param key The name of the parameter.
   72        * @param value The value of the parameter.
   73        * @since 2.2.0
   74        */
   75       public void setParameter(String key, String value) {
   76           params.put(key, value);
   77       }
   78   
   79       /**
   80        * Commits the parameters and makes this renderer ready for the use.
   81        *
   82        * @since 2.2.0
   83        */
   84       public void commit() {
   85           servlet = new AttributeValueFreemarkerServlet();
   86           try {
   87               servlet.init(new InitParamsServletConfig());
   88           } catch (ServletException e) {
   89               throw new FreeMarkerTilesException(
   90                       "Cannot initialize internal servlet", e);
   91           }
   92       }
   93   
   94       /** {@inheritDoc} */
   95       @Override
   96       public void write(Object value, Attribute attribute,
   97               TilesRequestContext request) throws IOException {
   98           if (value != null) {
   99               if (value instanceof String) {
  100                   ServletTilesRequestContext servletRequest = ServletUtil.getServletRequest(request);
  101                   HttpServletRequest httpRequest = servletRequest.getRequest();
  102                   HttpServletResponse httpResponse = servletRequest.getResponse();
  103                   servlet.setValue((String) value);
  104                   try {
  105                       servlet.doGet(httpRequest,
  106                               new ExternalWriterHttpServletResponse(httpResponse,
  107                                       request.getPrintWriter()));
  108                   } catch (ServletException e) {
  109                       throw new FreeMarkerTilesException("Exception when rendering a FreeMarker attribute", e);
  110                   }
  111               } else {
  112                   throw new InvalidTemplateException(
  113                           "Cannot render a template that is not a string: "
  114                                   + value.toString());
  115               }
  116           } else {
  117               throw new InvalidTemplateException("Cannot render a null template");
  118           }
  119       }
  120   
  121       /** {@inheritDoc} */
  122       public boolean isRenderable(Object value, Attribute attribute,
  123               TilesRequestContext request) {
  124           if (value instanceof String) {
  125               String string = (String) value;
  126               return string.startsWith("/") && string.endsWith(".ftl");
  127           }
  128           return false;
  129       }
  130   
  131       /**
  132        * Extends {@link TilesFreemarkerServlet} to use the attribute value as the template name.
  133        *
  134        * @since 2.2.0
  135        */
  136       private static class AttributeValueFreemarkerServlet extends TilesFreemarkerServlet {
  137   
  138           /**
  139            * Holds the value that should be used as the template name.
  140            */
  141           private ThreadLocal<String> valueHolder = new ThreadLocal<String>();
  142   
  143           /**
  144            * Sets the value to use as the template name.
  145            *
  146            * @param value The template name.
  147            * @since 2.2.0
  148            */
  149           public void setValue(String value) {
  150               valueHolder.set(value);
  151           }
  152   
  153           /** {@inheritDoc} */
  154           @Override
  155           protected String requestUrlToTemplatePath(HttpServletRequest request) {
  156               return valueHolder.get();
  157           }
  158       }
  159   
  160       /**
  161        * Implements {@link ServletConfig} to initialize the internal servlet using parameters
  162        * set through {@link FreeMarkerAttributeRenderer#setParameter(String, String)}.
  163        *
  164        * @version $Rev: 821299 $ $Date: 2009-10-03 14:15:05 +0200 (sab, 03 ott 2009) $
  165        * @since 2.2.0
  166        */
  167       private class InitParamsServletConfig implements ServletConfig {
  168   
  169           /** {@inheritDoc} */
  170           public String getInitParameter(String name) {
  171               return params.get(name);
  172           }
  173   
  174           /** {@inheritDoc} */
  175           @SuppressWarnings("unchecked")
  176           public Enumeration getInitParameterNames() {
  177               return new IteratorEnumeration(params.keySet().iterator());
  178           }
  179   
  180           /** {@inheritDoc} */
  181           public ServletContext getServletContext() {
  182               return ServletUtil.getServletContext(applicationContext);
  183           }
  184   
  185           /** {@inheritDoc} */
  186           public String getServletName() {
  187               return "FreeMarker Attribute Renderer";
  188           }
  189       }
  190   }

Home » tiles-2.2.1-src » org.apache.tiles.freemarker.renderer » [javadoc | source]