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 }