View Javadoc

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