View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.portals.bridges.velocity;
    18
    19  import java.io.IOException;
    20  import java.io.PrintWriter;
    21  import java.io.UnsupportedEncodingException;
    22
    23  import javax.portlet.PortletConfig;
    24  import javax.portlet.PortletRequest;
    25  import javax.portlet.RenderResponse;
    26  import javax.servlet.http.HttpServletRequest;
    27  import javax.servlet.http.HttpServletResponse;
    28
    29  import org.apache.velocity.Template;
    30  import org.apache.velocity.context.Context;
    31  import org.apache.velocity.exception.MethodInvocationException;
    32  import org.apache.velocity.exception.ParseErrorException;
    33  import org.apache.velocity.exception.ResourceNotFoundException;
    34  import org.apache.velocity.io.VelocityWriter;
    35  import org.apache.velocity.tools.view.servlet.VelocityViewServlet;
    36  import org.apache.velocity.util.SimplePool;
    37
    38  /***
    39   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
    40   * @version $Id: BridgesVelocityViewServlet.java 517068 2007-03-12 01:44:37Z ate $
    41   */
    42  public class BridgesVelocityViewServlet extends VelocityViewServlet
    43  {
    44      public final static String PORTLET_REQUEST = "javax.portlet.request";
    45      public final static String PORTLET_RESPONSE = "javax.portlet.response";
    46      public final static String PORTLET_CONFIG = "javax.portlet.config";
    47
    48  	public static final String VELOCITY_WRITER_ATTR = "org.apache.velocity.io.VelocityWriter";
    49      /*** Cache of writers */
    50      private static SimplePool writerPool = new SimplePool(40);
    51
    52      public static final String VELOCITY_CONTEXT_ATTR = "org.apache.velocity.Context";
    53      /***
    54       * Adds the RenderRequest, RenderResponse and PortletConfig to the context
    55       *
    56       * @see org.apache.velocity.tools.view.servlet.VelocityViewServlet#handleRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context)
    57       */
    58      protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) throws Exception
    59      {
    60          PortletRequest renderRequest = (PortletRequest) request.getAttribute(PORTLET_REQUEST);
    61          RenderResponse renderResponse = (RenderResponse) request.getAttribute(PORTLET_RESPONSE);
    62          PortletConfig portletConfig = (PortletConfig) request.getAttribute(PORTLET_CONFIG);
    63
    64          if (renderRequest != null)
    65          {
    66              renderRequest.setAttribute(VELOCITY_CONTEXT_ATTR, ctx);
    67              Context portletContext = (Context)renderRequest.getAttribute(GenericVelocityPortlet.PORTLET_BRIDGE_CONTEXT);
    68              if (portletContext != null)
    69              {
    70                  // merge in portletContext
    71                  Object[] keys = portletContext.getKeys();
    72                  for (int ix = 0; ix < keys.length; ix++)
    73                  {
    74                      // is this api f'd in the head or what
    75                      ctx.put((String)keys[ix], portletContext.get((String)keys[ix]));
    76                  }
    77              }
    78
    79          }
    80
    81
    82          // standard render request and response also available in context
    83          ctx.put(PORTLET_REQUEST, renderRequest);
    84          ctx.put(PORTLET_RESPONSE, renderResponse);
    85
    86          return super.handleRequest(request, response, ctx);
    87      }
    88
    89      /***
    90       * @see org.apache.velocity.tools.view.servlet.VelocityViewServlet#mergeTemplate(org.apache.velocity.Template, org.apache.velocity.context.Context, javax.servlet.http.HttpServletResponse)
    91       */
    92      protected void mergeTemplate(Template template, Context context, HttpServletResponse response)
    93          throws
    94              ResourceNotFoundException,
    95              ParseErrorException,
    96              MethodInvocationException,
    97              IOException,
    98              UnsupportedEncodingException,
    99              Exception
    100     {
    101         PrintWriter pw = response.getWriter();
    102         VelocityWriter vw = null;
    103
    104         try
    105         {
    106             vw = (VelocityWriter) writerPool.get();
    107
    108             if (vw == null)
    109             {
    110                 vw = new VelocityWriter(pw, 4 * 1024, true);
    111             }
    112             else
    113             {
    114                 vw.recycle(pw);
    115             }
    116
    117 			// Place the VelocityWriter into the Context
    118 			context.put(VELOCITY_WRITER_ATTR, vw);
    119             template.merge(context, vw);
    120         }
    121         catch (Exception e)
    122         {
    123             throw e;
    124         }
    125         finally
    126         {
    127             try
    128             {
    129                 if (vw != null)
    130                 {
    131                     // flush and put back into the pool
    132                     // don't close to allow us to play
    133                     // nicely with others.
    134                     vw.flush();
    135                     /* This hack sets the VelocityWriter's internal ref to the
    136                      * PrintWriter to null to keep memory free while
    137                      * the writer is pooled. See bug report #18951 */
    138                     vw.recycle(null);
    139                     writerPool.put(vw);
    140                 }
    141             }
    142             catch (Exception e)
    143             {
    144                 // do nothing
    145             }
    146         }
    147     }
    148 }