2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

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  
18  package org.apache.shale.test.mock;
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  import java.util.ArrayList;
26  import java.util.Enumeration;
27  import java.util.HashSet;
28  import java.util.Hashtable;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Set;
32  
33  import javax.servlet.RequestDispatcher;
34  import javax.servlet.Servlet;
35  import javax.servlet.ServletContext;
36  import javax.servlet.ServletContextAttributeEvent;
37  import javax.servlet.ServletContextAttributeListener;
38  import javax.servlet.ServletException;
39  
40  
41  /***
42   * <p>Mock implementation of <code>ServletContext</code>.</p>
43   *
44   * <p><strong>WARNING</strong> - Before you can get meaningful results from
45   * calls to the <code>getResource()</code>, <code>getResourceAsStream()</code>,
46   * <code>getResourcePaths()</code>, or <code>getRealPath()</code> methods,
47   * you must configure the <code>documentRoot</code> property, passing in a
48   * <code>File</code> object pointing at a directory that simulates a
49   * web application structure.</p>
50   *
51   * $Id$
52   */
53  
54  public class MockServletContext implements ServletContext {
55  
56  
57  
58      // ----------------------------------------------------- Mock Object Methods
59  
60  
61      /***
62       * <p>Add a new listener instance that should be notified about
63       * attribute changes.</p>
64       *
65       * @param listener Listener to be added
66       */
67      public void addAttributeListener(ServletContextAttributeListener listener) {
68          attributeListeners.add(listener);
69      }
70  
71  
72      /***
73       * <p>Add a context initialization parameter to the set of
74       * parameters recognized by this instance.</p>
75       *
76       * @param name Parameter name
77       * @param value Parameter value
78       */
79      public void addInitParameter(String name, String value) {
80          parameters.put(name, value);
81      }
82  
83  
84      /***
85       * <p>Add a new MIME type mapping to the set of mappings
86       * recognized by this instance.</p>
87       *
88       * @param extension Extension to check for (without the period)
89       * @param contentType Corresponding content type
90       */
91      public void addMimeType(String extension, String contentType) {
92          mimeTypes.put(extension, contentType);
93      }
94  
95  
96      /***
97       * <p>Set the document root for <code>getRealPath()</code>
98       * resolution.  This parameter <strong>MUST</strong> represent
99       * a directory.</p>
100      *
101      * @param documentRoot The new base directory
102      */
103     public void setDocumentRoot(File documentRoot) {
104         this.documentRoot = documentRoot;
105     }
106 
107 
108     // ------------------------------------------------------ Instance Variables
109 
110 
111     private List attributeListeners = new ArrayList();
112     private Hashtable attributes = new Hashtable();
113     private File documentRoot = null;
114     private Hashtable mimeTypes = new Hashtable();
115     private Hashtable parameters = new Hashtable();
116 
117 
118     // -------------------------------------------------- ServletContext Methods
119 
120 
121     /*** {@inheritDoc} */
122     public Object getAttribute(String name) {
123 
124         return attributes.get(name);
125 
126     }
127 
128 
129     /*** {@inheritDoc} */
130     public Enumeration getAttributeNames() {
131 
132         return attributes.keys();
133 
134     }
135 
136 
137     /*** {@inheritDoc} */
138     public ServletContext getContext(String uripath) {
139 
140         throw new UnsupportedOperationException();
141 
142     }
143 
144     /*** {@inheritDoc} */
145     public String getContextPath() {
146 
147         throw new UnsupportedOperationException();
148 
149     }
150 
151 
152     /*** {@inheritDoc} */
153     public String getInitParameter(String name) {
154 
155         return (String) parameters.get(name);
156 
157     }
158 
159 
160     /*** {@inheritDoc} */
161     public Enumeration getInitParameterNames() {
162 
163         return parameters.keys();
164 
165     }
166 
167 
168     /*** {@inheritDoc} */
169     public int getMajorVersion() {
170 
171         return 2;
172 
173     }
174 
175 
176     /*** {@inheritDoc} */
177     public String getMimeType(String path) {
178 
179         int period = path.lastIndexOf('.');
180         if (period < 0) {
181             return null;
182         }
183         String extension = path.substring(period + 1);
184         return (String) mimeTypes.get(extension);
185 
186     }
187 
188 
189     /*** {@inheritDoc} */
190     public int getMinorVersion() {
191 
192         return 4;
193 
194     }
195 
196 
197     /*** {@inheritDoc} */
198     public RequestDispatcher getNamedDispatcher(String name) {
199 
200         throw new UnsupportedOperationException();
201 
202     }
203 
204 
205     /*** {@inheritDoc} */
206     public String getRealPath(String path) {
207 
208         if (documentRoot != null) {
209             if (!path.startsWith("/")) {
210                 throw new IllegalArgumentException("The specified path ('"
211                         + path + "') does not start with a '/' character");
212             }
213             File resolved = new File(documentRoot, path.substring(1));
214             try {
215                 return resolved.getCanonicalPath();
216             } catch (IOException e) {
217                 return resolved.getAbsolutePath();
218             }
219         } else {
220             return null;
221         }
222 
223     }
224 
225 
226     /*** {@inheritDoc} */
227     public RequestDispatcher getRequestDispatcher(String path) {
228 
229         throw new UnsupportedOperationException();
230 
231     }
232 
233 
234     /*** {@inheritDoc} */
235     public URL getResource(String path) throws MalformedURLException {
236 
237         if (documentRoot != null) {
238             if (!path.startsWith("/")) {
239                 throw new MalformedURLException("The specified path ('"
240                         + path + "') does not start with a '/' character");
241             }
242             File resolved = new File(documentRoot, path.substring(1));
243             if (resolved.exists()) {
244                 return resolved.toURL();
245             } else {
246                 return null;
247             }
248         } else {
249             return null;
250         }
251 
252     }
253 
254 
255     /*** {@inheritDoc} */
256     public InputStream getResourceAsStream(String path) {
257 
258         try {
259             URL url = getResource(path);
260             if (url != null) {
261                 return url.openStream();
262             }
263         } catch (Exception e) {
264             ;
265         }
266         return null;
267 
268     }
269 
270 
271     /*** {@inheritDoc} */
272     public Set getResourcePaths(String path) {
273 
274         if (documentRoot == null) {
275             return null;
276         }
277 
278         // Enforce the leading slash restriction
279         if (!path.startsWith("/")) {
280             throw new IllegalArgumentException("The specified path ('"
281                     + path + "') does not start with a '/' character");
282         }
283 
284         // Locate the File node for this path's directory (if it exists)
285         File node = new File(documentRoot, path.substring(1));
286         if (!node.exists()) {
287             return null;
288         }
289         if (!node.isDirectory()) {
290             return null;
291         }
292 
293         // Construct a Set containing the paths to the contents of this directory
294         Set set = new HashSet();
295         String[] files = node.list();
296         if (files == null) {
297             return null;
298         }
299         for (int i = 0; i < files.length; i++) {
300             String subfile = path + files[i];
301             File subnode = new File(node, files[i]);
302             if (subnode.isDirectory()) {
303                 subfile += "/";
304             }
305             set.add(subfile);
306         }
307 
308         // Return the completed set
309         return set;
310 
311     }
312 
313 
314     /*** {@inheritDoc} */
315     public Servlet getServlet(String name) throws ServletException {
316 
317         throw new UnsupportedOperationException();
318 
319     }
320 
321 
322     /*** {@inheritDoc} */
323     public String getServletContextName() {
324 
325         return "MockServletContext";
326 
327     }
328 
329 
330     /*** {@inheritDoc} */
331     public String getServerInfo() {
332 
333         return "MockServletContext";
334 
335     }
336 
337 
338     /*** {@inheritDoc} */
339     public Enumeration getServlets() {
340 
341         throw new UnsupportedOperationException();
342 
343     }
344 
345 
346     /*** {@inheritDoc} */
347     public Enumeration getServletNames() {
348 
349         throw new UnsupportedOperationException();
350 
351     }
352 
353 
354     /*** {@inheritDoc} */
355     public void log(String message) {
356 
357         System.out.println(message);
358 
359     }
360 
361 
362     /*** {@inheritDoc} */
363     public void log(Exception exception, String message) {
364 
365         System.out.println(message);
366         exception.printStackTrace();
367 
368     }
369 
370 
371     /*** {@inheritDoc} */
372     public void log(String message, Throwable exception) {
373 
374         System.out.println(message);
375         exception.printStackTrace();
376 
377     }
378 
379 
380     /*** {@inheritDoc} */
381     public void removeAttribute(String name) {
382 
383         if (attributes.containsKey(name)) {
384             Object value = attributes.remove(name);
385             fireAttributeRemoved(name, value);
386         }
387 
388     }
389 
390 
391     /*** {@inheritDoc} */
392     public void setAttribute(String name, Object value) {
393 
394         if (name == null) {
395             throw new IllegalArgumentException("Attribute name cannot be null");
396         }
397         if (value == null) {
398             removeAttribute(name);
399             return;
400         }
401         if (attributes.containsKey(name)) {
402             Object oldValue = attributes.get(name);
403             attributes.put(name, value);
404             fireAttributeReplaced(name, oldValue);
405         } else {
406             attributes.put(name, value);
407             fireAttributeAdded(name, value);
408         }
409 
410     }
411 
412 
413     // --------------------------------------------------------- Private Methods
414 
415 
416     /***
417      * <p>Fire an attribute added event to interested listeners.</p>
418      *
419      * @param key Attribute whose value has been added
420      * @param value The new value
421      */
422     private void fireAttributeAdded(String key, Object value) {
423         if (attributeListeners.size() < 1) {
424             return;
425         }
426         ServletContextAttributeEvent event =
427                 new ServletContextAttributeEvent(this, key, value);
428         Iterator listeners = attributeListeners.iterator();
429         while (listeners.hasNext()) {
430             ServletContextAttributeListener listener =
431                     (ServletContextAttributeListener) listeners.next();
432             listener.attributeAdded(event);
433         }
434     }
435 
436 
437     /***
438      * <p>Fire an attribute removed event to interested listeners.</p>
439      *
440      * @param key Attribute whose value has been removed
441      * @param value The value that was removed
442      */
443     private void fireAttributeRemoved(String key, Object value) {
444         if (attributeListeners.size() < 1) {
445             return;
446         }
447         ServletContextAttributeEvent event =
448                 new ServletContextAttributeEvent(this, key, value);
449         Iterator listeners = attributeListeners.iterator();
450         while (listeners.hasNext()) {
451             ServletContextAttributeListener listener =
452                     (ServletContextAttributeListener) listeners.next();
453             listener.attributeRemoved(event);
454         }
455     }
456 
457 
458     /***
459      * <p>Fire an attribute replaced event to interested listeners.</p>
460      *
461      * @param key Attribute whose value has been replaced
462      * @param value The original value
463      */
464     private void fireAttributeReplaced(String key, Object value) {
465         if (attributeListeners.size() < 1) {
466             return;
467         }
468         ServletContextAttributeEvent event =
469                 new ServletContextAttributeEvent(this, key, value);
470         Iterator listeners = attributeListeners.iterator();
471         while (listeners.hasNext()) {
472             ServletContextAttributeListener listener =
473                     (ServletContextAttributeListener) listeners.next();
474             listener.attributeReplaced(event);
475         }
476     }
477 
478 
479 }