View Javadoc

1   package org.apache.velocity.tools.view;
2   
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  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpServletResponse;
27  import javax.servlet.http.HttpSession;
28  import javax.servlet.ServletContext;
29  import org.apache.velocity.app.VelocityEngine;
30  import org.apache.velocity.context.Context;
31  import org.apache.velocity.tools.ToolContext;
32  import org.apache.velocity.tools.Toolbox;
33  
34  /**
35   * <p>{@link ToolContext} implementation specific to the servlet environment.</p>
36   *
37   * <p>It provides the following special features:</p>
38   * <ul>
39   *   <li>puts the request, response, session, and servlet context objects
40   *       into the Velocity context for direct access, and keeps them
41   *       read-only</li>
42   *   <li>supports a read-only toolbox of view tools</li>
43   *   <li>auto-searches servlet request attributes, session attributes and
44   *       servlet context attribues for objects</li>
45   * </ul>
46   *
47   * <p>The {@link #get(String key)} method implements the following search order
48   * for objects:</p>
49   * <ol>
50   *   <li>tool in a request scoped toolbox</li>
51   *   <li>tool in a session scoped toolbox</li>
52   *   <li>tool in a application scoped toolbox</li>
53   *   <li>request, response, session, or servlet context</li>
54   *   <li>object in the local map of objects (traditional use)</li>
55   *   <li>request attributes, session attributes, servlet context attributes</li>
56   * </ol>
57   *
58   * <p>The purpose of this class is to make it easy for web designer to work
59   * with Java servlet based web applications. They do not need to be concerned
60   * with the concepts of request, session or application attributes and the
61   * lifetime of objects in these scopes.</p>
62   *
63   * <p>Note that the put() method always puts objects into the local map
64   * and does not allow tools or servlet classes to be overridden.
65   * </p>
66   *
67   * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
68   * @author <a href="mailto:sidler@teamup.com">Gabe Sidler</a>
69   * @author Nathan Bubna
70   *
71   * @version $Id: ViewContext.java 514727 2007-03-05 16:49:03Z nbubna $
72   */
73  public class ViewToolContext extends ToolContext implements ViewContext
74  {
75      private final HttpServletRequest request;
76      private final HttpServletResponse response;
77      private final ServletContext application;
78      private final VelocityEngine velocity;
79      private String toolboxKey = DEFAULT_TOOLBOX_KEY;
80  
81      public ViewToolContext(VelocityEngine velocity,
82                             HttpServletRequest request,
83                             HttpServletResponse response,
84                             ServletContext application)
85      {
86          super(velocity);
87  
88          this.velocity = velocity;
89          this.request = request;
90          this.response = response;
91          this.application = application;
92  
93          // automagically set common tool properties
94          putToolProperties();
95      }
96  
97      protected void setToolboxKey(String key)
98      {
99          this.toolboxKey = key;
100     }
101 
102     protected void putToolProperties()
103     {
104         putToolProperty(REQUEST, getRequest());
105         if (getRequest() != null)
106         {
107             putToolProperty(LOCALE_KEY, getRequest().getLocale());
108         }
109         putToolProperty(RESPONSE, getResponse());
110         putToolProperty(SESSION, getSession());
111         putToolProperty(SERVLET_CONTEXT_KEY, getServletContext());
112         putToolProperty(PATH_KEY, ServletUtils.getPath(getRequest()));
113     }
114 
115     protected List<Toolbox> getToolboxes()
116     {
117         // this means once we find any toolbox,
118         // then we stop looking.  adding boxes to
119         // the request/session/application attributes
120         // later will not work.  once one is in, any
121         // later additions must be via addToolbox(Toolbox)
122         // or addToolboxesUnderKey(String toolboxKey)
123         if (super.getToolboxes().isEmpty())
124         {
125             addToolboxesUnderKey(this.toolboxKey);
126         }
127         return super.getToolboxes();
128     }
129 
130     protected void addToolboxesUnderKey(String toolboxKey)
131     {
132         Toolbox reqTools = (Toolbox)getRequest().getAttribute(toolboxKey);
133         if (reqTools != null)
134         {
135             addToolbox(reqTools);
136         }
137 
138         if (getSession() != null)
139         {
140             Toolbox sessTools = (Toolbox)getSession().getAttribute(toolboxKey);
141             if (sessTools != null)
142             {
143                 addToolbox(sessTools);
144             }
145         }
146 
147         Toolbox appTools = (Toolbox)getServletContext().getAttribute(toolboxKey);
148         if (appTools != null)
149         {
150             addToolbox(appTools);
151         }
152     }
153 
154     /**
155      * <p>Looks up and returns the object with the specified key.</p>
156      * <p>See the class documentation for more details.</p>
157      *
158      * @see #setUserCanOverwriteTools
159      * @see #getUserVar
160      * @see #getToolVar
161      * @param key the key of the object requested
162      * @return the requested object or null if not found
163      */
164     @Override
165     public Object get(String key)
166     {
167         boolean overwrite = getUserCanOverwriteTools();
168         Object o = overwrite ? getUserVar(key) : getToolVar(key);
169         if (o == null)
170         {
171             o = overwrite ? getToolVar(key) : getUserVar(key);
172         }
173         return o;
174     }
175 
176     /**
177      * Finds "user" set values, either in the local context
178      * or in the scoped attributes if none is in the local context.
179      * @see #internalGet
180      * @see #getAttribute
181      */
182     protected Object getUserVar(String key)
183     {
184         Object o = internalGet(key);
185         if (o != null)
186         {
187             return o;
188         }
189         return getAttribute(key);
190     }
191 
192     /**
193      * Finds the automatically provided values, either configured
194      * tools or servlet API objects (request, response, etc).
195      * @see #findTool
196      * @see #getServletApi
197      */
198     protected Object getToolVar(String key)
199     {
200         Object o = findTool(key);
201         if (o != null)
202         {
203             return o;
204         }
205         return getServletApi(key);
206     }
207 
208     /**
209      * Returns the current matching servlet request, response, session, 
210      * or servlet context instance, or null if the key matches none of those
211      * keys.
212      */
213     protected Object getServletApi(String key)
214     {
215         if (key.equals(REQUEST))
216         {
217             return request;
218         }
219         else if(key.equals(RESPONSE))
220         {
221             return response;
222         }
223         else if (key.equals(SESSION))
224         {
225             return getSession();
226         }
227         else if (key.equals(APPLICATION))
228         {
229             return application;
230         }
231         return null;
232     }
233 
234 
235     /**
236      * <p>Searches for the named attribute in request, session (if valid),
237      * and application scope(s) in order and returns the value associated
238      * or null.</p>
239      *
240      * @since VelocityTools 1.1
241      */
242     public Object getAttribute(String key)
243     {
244         Object o = request.getAttribute(key);
245         if (o == null)
246         {
247             if (getSession() != null)
248             {
249                 try
250                 {
251                     o = getSession().getAttribute(key);
252                 }
253                 catch (IllegalStateException ise)
254                 {
255                     // Handle invalidated session state
256                     o = null;
257                 }
258             }
259 
260             if (o == null)
261             {
262                 o = application.getAttribute(key);
263             }
264         }
265         return o;
266     }
267 
268 
269     /**
270      * <p>Returns the current servlet request.</p>
271      */
272     public HttpServletRequest getRequest()
273     {
274         return request;
275     }
276 
277     /**
278      * <p>Returns the current servlet response.</p>
279      */
280     public HttpServletResponse getResponse()
281     {
282         return response;
283     }
284 
285     /**
286      * <p>Returns the current session, if any.</p>
287      */
288     public HttpSession getSession()
289     {
290         return getRequest().getSession(false);
291     }
292 
293     /**
294      * <p>Returns the servlet context.</p>
295      */
296     public ServletContext getServletContext()
297     {
298         return application;
299     }
300 
301     /**
302      * <p>Returns a reference to the Velocity context (this object).</p>
303      */
304     public Context getVelocityContext()
305     {
306         return this;
307     }
308 
309     /**
310      * <p>Returns a reference to the VelocityEngine.</p>
311      */
312     public VelocityEngine getVelocityEngine()
313     {
314         return velocity;
315     }
316 
317      /**
318       * Indicates whether the specified key is in the context.
319       *
320       * @param key The key to look for.
321       * @return    Whether the key is in the context.
322       */
323      public boolean containsKey(String key)
324      {
325          return super.containsKey(key)
326            || getAttribute(key) != null
327            || key.equals(REQUEST) && request != null
328            || key.equals(RESPONSE) && response != null
329            || key.equals(SESSION) && getSession() != null
330            || key.equals(APPLICATION) && application != null;
331      }
332 
333 }