2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

1   /* 
2    * ========================================================================
3    * 
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * 
19   * ========================================================================
20   */
21  package org.apache.cactus.server;
22  
23  import java.io.InputStream;
24  
25  import java.lang.reflect.Constructor;
26  
27  import java.net.MalformedURLException;
28  import java.net.URL;
29  
30  import java.util.Enumeration;
31  import java.util.Hashtable;
32  import java.util.Vector;
33  
34  import javax.servlet.RequestDispatcher;
35  import javax.servlet.Servlet;
36  import javax.servlet.ServletContext;
37  import javax.servlet.ServletException;
38  
39  import org.apache.cactus.util.ChainedRuntimeException;
40  
41  /**
42   * Abstract wrapper around <code>ServletContext</code>. This class provides
43   * a common implementation of the wrapper for the different servlet API. In
44   * addition to implementing the <code>ServletContext</code> interface it
45   * provides additional features helpful for writing unit tests. More
46   * specifically the <code>getRequestDispatcher()</code> method is overrided
47   * to return an request dispatcher wrapper. In addition logs generated by
48   * calls to the <code>log()</code> methods can be retrieved and asserted by
49   * calling the <code>getLogs()</code> method.
50   *
51   * @version $Id: AbstractServletContextWrapper.java 292559 2005-09-29 21:36:43Z kenney $
52   */
53  public abstract class AbstractServletContextWrapper implements ServletContext
54  {
55      /**
56       * The original servlet context object.
57       */
58      protected ServletContext originalContext;
59  
60      /**
61       * List of parameters set using the <code>setInitParameter()</code> method.
62       */
63      protected Hashtable initParameters;
64      
65      /**
66       * The logs resulting from calling the <code>log()</code> methods.
67       */
68      private Vector logs = new Vector();
69  
70      // Constructors  -------------------------------------------------------
71  
72      /**
73       * @param theOriginalContext the original servlet context object
74       */
75      public AbstractServletContextWrapper(ServletContext theOriginalContext)
76      {
77          this.originalContext = theOriginalContext;
78          this.initParameters = new Hashtable();
79      }
80      /**
81       * @param theOriginalContext object 
82       * @return AbstractServletContextWrapper
83       */
84      public static AbstractServletContextWrapper newInstance(ServletContext
85          theOriginalContext)
86      {
87          try
88          {
89              Class clazz = Class.forName(
90                  "org.apache.cactus.server.ServletContextWrapper");
91              Object[] args = new Object[] {theOriginalContext};
92  
93              Constructor constructor = clazz.getConstructor(new Class[] {
94                  ServletContext.class });
95  
96              return (AbstractServletContextWrapper) 
97                  constructor.newInstance(args);
98          }
99          catch (Throwable t)
100         {
101             throw new ChainedRuntimeException(
102                 "Failed to create ServletContextWrapper", t);
103         }
104     }
105 
106     // New methods ---------------------------------------------------------
107 
108     /**
109      * @return the original unmodified config object
110      * @since 1.6
111      */
112     public ServletContext getOriginalContext()
113     {
114         return this.originalContext;
115     }
116     
117     /**
118      * Sets a parameter as if it were set in the <code>web.xml</code> file
119      * (using the &lt;context-param&gt; element).
120      *
121      * @param theName the parameter's name
122      * @param theValue the parameter's value
123      */
124     public void setInitParameter(String theName, String theValue)
125     {
126         this.initParameters.put(theName, theValue);
127     }
128     
129     /**
130      * Returns all the text logs that have been generated using the
131      * <code>log()</code> methods so that it is possible to easily assert the
132      * content of the logs. This method does not return the exceptions or
133      * throwable sent for logging; it only returns the messages.
134      *
135      * @return the logs as a vector of strings (each string contains the
136      *         message that was sent for logging).
137      */
138     public Vector getLogs()
139     {
140         return this.logs;
141     }
142     
143     // Overridden methods --------------------------------------------------
144 
145     /**
146      * {@inheritDoc}
147      * @see ServletContext#setAttribute(String, Object)
148      */
149     public void setAttribute(String theName, Object theAttribute)
150     {
151         this.originalContext.setAttribute(theName, theAttribute);
152     }
153 
154     /**
155      * {@inheritDoc}
156      * @see ServletContext#removeAttribute(String)
157      */
158     public void removeAttribute(String theName)
159     {
160         this.originalContext.removeAttribute(theName);
161     }
162 
163     /**
164      * Intercept the log call and add the message to an internal vector of
165      * log messages that can then later be retrieved and asserted by the
166      * test case writer. Note that the throwable is not saved.
167      *
168      * @param theMessage a <code>String</code> that describes the error or
169      *        exception
170      * @param theCause the <code>Throwable</code> error or exception
171      *
172      * @see #getLogs()
173      * @see ServletContext#log(String, Throwable)
174      */
175     public void log(String theMessage, Throwable theCause)
176     {
177         if (theMessage != null)
178         {
179             this.logs.addElement(theMessage);
180         }
181 
182         this.originalContext.log(theMessage, theCause);
183     }
184 
185     /**
186      * Intercept the log call and add the message to an internal vector of
187      * log messages that can then later be retrieved and asserted by the
188      * test case writer. Note that the throwable is not saved.
189      *
190      * @param theMessage a <code>String</code> that describes the error or
191      *        exception
192      *
193      * @see #getLogs()
194      * @see ServletContext#log(String)
195      */
196     public void log(String theMessage)
197     {
198         if (theMessage != null)
199         {
200             this.logs.addElement(theMessage);
201         }
202 
203         this.originalContext.log(theMessage);
204     }
205 
206     /**
207      * Intercept the log call and add the message to an internal vector of
208      * log messages that can then later be retrieved and asserted by the
209      * test case writer. Note that the throwable is not saved.
210      *
211      * @param theException the exception to log
212      * @param theMessage a <code>String</code> that describes the error or
213      *        exception
214      *
215      * @see #getLogs()
216      * @see ServletContext#log(Exception, String)
217      *
218      * @deprecated As of Java Servlet API 2.1, use
219      *             {@link #log(String message, Throwable throwable)} instead.
220      *             This method was originally defined to write an exception's
221      *             stack trace and an explanatory error message to the servlet
222      *             log file.
223      */
224     public void log(Exception theException, String theMessage)
225     {
226         if (theMessage != null)
227         {
228             this.logs.addElement(theMessage);
229         }
230 
231         this.originalContext.log(theException, theMessage);
232     }
233 
234     /**
235      * {@inheritDoc}
236      * @see ServletContext#getServlets()
237      */
238     public Enumeration getServlets()
239     {
240         return this.originalContext.getServlets();
241     }
242 
243     /**
244      * {@inheritDoc}
245      * @see ServletContext#getServletNames()
246      */
247     public Enumeration getServletNames()
248     {
249         return this.originalContext.getServletNames();
250     }
251 
252     /**
253      * {@inheritDoc}
254      * @see ServletContext#getServlet(String)
255      */
256     public Servlet getServlet(String theName) throws ServletException
257     {
258         return this.originalContext.getServlet(theName);
259     }
260 
261     /**
262      * {@inheritDoc}
263      * @see ServletContext#getServerInfo()
264      */
265     public String getServerInfo()
266     {
267         return this.originalContext.getServerInfo();
268     }
269 
270     /**
271      * {@inheritDoc}
272      * @see ServletContext#getResourceAsStream(String)
273      */
274     public InputStream getResourceAsStream(String thePath)
275     {
276         return this.originalContext.getResourceAsStream(thePath);
277     }
278 
279     /**
280      * {@inheritDoc}
281      * @see ServletContext#getResource(String)
282      */
283     public URL getResource(String thePath) throws MalformedURLException
284     {
285         return this.originalContext.getResource(thePath);
286     }
287 
288     /**
289      * @param thePath a string specifying the pathname to the resource
290      * @return our request dispatcher wrapper
291      * @see ServletContext#getRequestDispatcher(String)
292      */
293     public RequestDispatcher getRequestDispatcher(String thePath)
294     {
295         RequestDispatcher wrappedDispatcher = null;
296 
297         RequestDispatcher originalDispatcher = 
298             this.originalContext.getRequestDispatcher(thePath);
299 
300         if (originalDispatcher != null)
301         {
302             wrappedDispatcher = 
303                 new RequestDispatcherWrapper(originalDispatcher);
304         }
305 
306         return wrappedDispatcher;
307     }
308 
309     /**
310      * @param theName a string specifying the name of a servlet to wrap
311      * @return our request dispatcher wrapper or null if the servlet cannot
312      *         be found.
313      * @see ServletContext#getNamedDispatcher(String)
314      */
315     public RequestDispatcher getNamedDispatcher(String theName)
316     {
317         RequestDispatcher wrappedDispatcher = null;
318 
319         RequestDispatcher originalDispatcher = 
320             this.originalContext.getNamedDispatcher(theName);
321 
322         if (originalDispatcher != null)
323         {
324             wrappedDispatcher = 
325                 new RequestDispatcherWrapper(originalDispatcher);
326         }
327 
328         return wrappedDispatcher;
329     }
330 
331     /**
332      * {@inheritDoc}
333      * @see ServletContext#getRealPath(String)
334      */
335     public String getRealPath(String thePath)
336     {
337         return this.originalContext.getRealPath(thePath);
338     }
339 
340     /**
341      * {@inheritDoc}
342      * @see ServletContext#getMinorVersion()
343      */
344     public int getMinorVersion()
345     {
346         return this.originalContext.getMinorVersion();
347     }
348 
349     /**
350      * {@inheritDoc}
351      * @see ServletContext#getMimeType(String)
352      */
353     public String getMimeType(String theFilename)
354     {
355         return this.originalContext.getMimeType(theFilename);
356     }
357 
358     /**
359      * {@inheritDoc}
360      * @see ServletContext#getMajorVersion()
361      */
362     public int getMajorVersion()
363     {
364         return this.originalContext.getMajorVersion();
365     }
366 
367     /**
368      * @return the union of the parameters defined in the Redirector
369      *         <code>web.xml</code> file and the one set using the
370      *         <code>setInitParameter()</code> method.
371      */
372     public Enumeration getInitParameterNames()
373     {
374         Vector names = new Vector();
375 
376         // Add parameters that were added using setInitParameter()
377         Enumeration en = this.initParameters.keys();
378 
379         while (en.hasMoreElements())
380         {
381             String value = (String) en.nextElement();
382 
383             names.add(value);
384         }
385 
386         // Add parameters from web.xml
387         en = this.originalContext.getInitParameterNames();
388 
389         while (en.hasMoreElements())
390         {
391             String value = (String) en.nextElement();
392 
393             // Do not add parameters that have been overriden by calling
394             // the setInitParameter() method.
395             if (!names.contains(value))
396             {
397                 names.add(value);
398             }
399         }
400 
401         return names.elements();
402     }
403 
404     /**
405      * @param theName the name of the parameter's value to return
406      * @return the value of the parameter, looking for it first in the list of
407      *         parameters set using the <code>setInitParameter()</code> method
408      *         and then in those set in <code>web.xml</code>.
409      */
410     public String getInitParameter(String theName)
411     {
412         // Look first in the list of parameters set using the
413         // setInitParameter() method.
414         String value = (String) this.initParameters.get(theName);
415 
416         if (value == null)
417         {
418             value = this.originalContext.getInitParameter(theName);
419         }
420 
421         return value;
422     }
423     
424     /**
425      * @param theUripath a String specifying the context path of another web
426      *        application in the container
427      * @return our servlet context wrapper
428      * @see ServletContext#getContext(String)
429      */
430     public ServletContext getContext(String theUripath)
431     {
432         ServletContext context = AbstractServletContextWrapper.newInstance(
433             this.originalContext.getContext(theUripath));
434 
435         return context;
436     }
437 
438     /**
439      * {@inheritDoc}
440      * @see ServletContext#getAttributeNames()
441      */
442     public Enumeration getAttributeNames()
443     {
444         return this.originalContext.getAttributeNames();
445     }
446 
447     /**
448      * {@inheritDoc}
449      * @see ServletContext#getAttribute(String)
450      */
451     public Object getAttribute(String theName)
452     {
453         return this.originalContext.getAttribute(theName);
454     }
455 }