KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > transport > http > AxisServletBase


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "The Jakarta Project", "Ant", and "Apache Software
27  * Foundation" must not be used to endorse or promote products derived
28  * from this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54
55
56 package org.jboss.axis.transport.http;
57
58 import org.jboss.axis.AxisEngine;
59 import org.jboss.axis.AxisFault;
60 import org.jboss.axis.AxisProperties;
61 import org.jboss.axis.EngineConfiguration;
62 import org.jboss.axis.configuration.EngineConfigurationFactoryFinder;
63 import org.jboss.axis.server.AxisServer;
64 import org.jboss.axis.utils.JavaUtils;
65 import org.jboss.logging.Logger;
66
67 import javax.servlet.ServletContext JavaDoc;
68 import javax.servlet.ServletException JavaDoc;
69 import javax.servlet.http.HttpServlet JavaDoc;
70 import javax.servlet.http.HttpServletRequest JavaDoc;
71 import javax.servlet.http.HttpServletResponse JavaDoc;
72 import java.io.File JavaDoc;
73 import java.io.IOException JavaDoc;
74 import java.util.HashMap JavaDoc;
75 import java.util.Map JavaDoc;
76
77 /**
78  * Base class for servlets used in axis, has common methods
79  * to get and save the engine to a common location, currently the
80  * webapp's context, though some alternate persistence mechanism is always
81  * possible. Also has a load counter shared by all servlets; tracks the
82  * # of active http requests open to any of the subclasses.
83  *
84  * @author Steve Loughran
85  */

86
87 public class AxisServletBase extends HttpServlet JavaDoc
88 {
89
90    /**
91     * per-instance cache of the axis server
92     */

93    protected AxisServer axisServer = null;
94
95    private static Logger log = Logger.getLogger(AxisServlet.class.getName());
96
97    private static boolean isDebug = false;
98
99    /**
100     * count number of service requests in progress
101     */

102    private static int loadCounter = 0;
103
104    /**
105     * and a lock
106     */

107    private static Object JavaDoc loadCounterLock = new Object JavaDoc();
108
109    /**
110     * name of the axis engine to use in the servlet context
111     */

112    protected static final String JavaDoc ATTR_AXIS_ENGINE =
113            "AxisEngine";
114
115    /**
116     * Cached path to our WEB-INF directory
117     */

118    private String JavaDoc webInfPath = null;
119
120    /**
121     * Cached path to our "root" dir
122     */

123    private String JavaDoc homeDir = null;
124
125    /**
126     * flag set to true for a 'production' server
127     */

128    private boolean isDevelopment;
129
130    /**
131     * property name for a production server
132     */

133    private static final String JavaDoc INIT_PROPERTY_DEVELOPMENT_SYSTEM =
134            "axis.development.system";
135
136
137    /**
138     * our initialize routine; subclasses should call this if they override it
139     */

140    public void init()
141    {
142       ServletContext JavaDoc context = getServletConfig().getServletContext();
143
144       webInfPath = context.getRealPath("/WEB-INF");
145       homeDir = context.getRealPath("/");
146
147       isDebug = log.isDebugEnabled();
148       if (log.isDebugEnabled()) log.debug("In AxisServletBase init");
149       isDevelopment = JavaUtils.isTrueExplicitly(getOption(context,
150               INIT_PROPERTY_DEVELOPMENT_SYSTEM, null));
151
152    }
153
154    /**
155     * Destroy method is called when the servlet is going away. Pass this
156     * down to the AxisEngine to let it clean up... But don't create the
157     * engine if it hasn't already been created.
158     *
159     * @todo Fixme for multiple servlets.
160     * This has always been slightly broken
161     * (the context's copy stayed around), but now we have extracted it into
162     * a superclass it is blatantly broken.
163     */

164    public void destroy()
165    {
166       super.destroy();
167
168       //if we have had anything to do with creating an axis server
169
if (axisServer != null)
170       {
171          //then we lock it
172
synchronized (axisServer)
173          {
174             if (axisServer != null)
175             {
176                //clean it up
177
axisServer.cleanup();
178                //and erase our history of it
179
axisServer = null;
180                storeEngine(getServletContext(), null);
181             }
182          }
183       }
184    }
185
186    /**
187     * get the engine for this servlet from cache or context
188     *
189     * @return
190     * @throws AxisFault
191     */

192    public AxisServer getEngine() throws AxisFault
193    {
194       if (axisServer == null)
195          axisServer = getEngine(this);
196       return axisServer;
197    }
198
199
200    /**
201     * This is a uniform method of initializing AxisServer in a servlet
202     * context.
203     *
204     * @todo add catch for not being able to cast the context attr to an
205     * engine and reinit the engine if so.
206     */

207    public static AxisServer getEngine(HttpServlet JavaDoc servlet) throws AxisFault
208    {
209       AxisServer engine = null;
210       if (isDebug)
211          log.debug("Enter: getEngine()");
212
213       ServletContext JavaDoc context = servlet.getServletContext();
214       synchronized (context)
215       {
216          engine = retrieveEngine(context);
217          if (engine == null)
218          {
219             Map JavaDoc environment = getEngineEnvironment(servlet);
220
221             // Obtain an AxisServer by using whatever AxisServerFactory is
222
// registered. The default one will just use the provider we
223
// passed in, and presumably JNDI ones will use the ServletContext
224
// to figure out a JNDI name to look up.
225
//
226
// The point of doing this rather than just creating the server
227
// manually with the provider above is that we will then support
228
// configurations where the server instance is managed by the
229
// container, and pre-registered in JNDI at deployment time. It
230
// also means we put the standard configuration pattern in one
231
// place.
232
engine = AxisServer.getServer(environment);
233             storeEngine(context, engine);
234          }
235       }
236
237       if (isDebug)
238          log.debug("Exit: getEngine()");
239
240       return engine;
241    }
242
243    /**
244     * put the engine back in to the context.
245     *
246     * @param context servlet context to use
247     * @param engine reference to the engine. If null, the engine is removed
248     */

249    private static void storeEngine(ServletContext JavaDoc context, AxisServer engine)
250    {
251       if (engine == null)
252       {
253          context.removeAttribute(ATTR_AXIS_ENGINE);
254       }
255       else
256       {
257          context.setAttribute(ATTR_AXIS_ENGINE, engine);
258       }
259    }
260
261    /**
262     * Get an engine from the servlet context; robust againt serialization
263     * issues of hot-updated webapps. Remember than if a webapp is marked
264     * as distributed, there is more than 1 servlet context, hence more than
265     * one AxisEngine instance
266     *
267     * @param context
268     * @return the engine or null if either the engine couldnt be found or
269     * the attribute wasnt of the right type
270     */

271    private static AxisServer retrieveEngine(ServletContext JavaDoc context)
272    {
273       Object JavaDoc contextObject = context.getAttribute(ATTR_AXIS_ENGINE);
274       if (contextObject instanceof AxisServer)
275       {
276          return (AxisServer)contextObject;
277       }
278       else
279       {
280          return null;
281       }
282    }
283
284
285    /**
286     * extract information from the servlet configuration files
287     *
288     * @param servlet
289     * @return
290     */

291    protected static Map JavaDoc getEngineEnvironment(HttpServlet JavaDoc servlet)
292    {
293       Map JavaDoc environment = new HashMap JavaDoc();
294
295       String JavaDoc attdir = servlet.getInitParameter(AxisEngine.ENV_ATTACHMENT_DIR);
296       if (attdir != null)
297          environment.put(AxisEngine.ENV_ATTACHMENT_DIR, attdir);
298
299       ServletContext JavaDoc context = servlet.getServletContext();
300       environment.put(AxisEngine.ENV_SERVLET_CONTEXT, context);
301
302       String JavaDoc webInfPath = context.getRealPath("/WEB-INF");
303       if (webInfPath != null)
304          environment.put(AxisEngine.ENV_SERVLET_REALPATH,
305                  webInfPath + File.separator + "attachments");
306
307       EngineConfiguration config =
308               EngineConfigurationFactoryFinder.newFactory(context)
309               .getServerEngineConfig();
310
311       if (config != null)
312       {
313          environment.put(EngineConfiguration.PROPERTY_NAME, config);
314       }
315
316       return environment;
317    }
318
319
320    /**
321     * get a count of the # of services running. This is only
322     * ever an approximate number in a busy system
323     *
324     * @return The TotalServiceCount value
325     */

326
327    public static int getLoadCounter()
328    {
329       return loadCounter;
330    }
331
332    /**
333     * thread safe lock counter increment
334     */

335    protected static void incLockCounter()
336    {
337       synchronized (loadCounterLock)
338       {
339          loadCounter++;
340       }
341    }
342
343    /**
344     * thread safe lock counter decrement
345     */

346    protected static void decLockCounter()
347    {
348       synchronized (loadCounterLock)
349       {
350          loadCounter--;
351       }
352    }
353
354    /**
355     * subclass of service method that tracks entry count; calls the
356     * parent's implementation to have the http method cracked and delegated
357     * to the doGet, doPost method.
358     *
359     * @param req request
360     * @param resp response
361     * @throws ServletException something went wrong
362     * @throws IOException something different went wrong
363     */

364    protected void service(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc resp)
365            throws ServletException JavaDoc, IOException JavaDoc
366    {
367       incLockCounter();
368       try
369       {
370          super.service(req, resp);
371       }
372       finally
373       {
374          decLockCounter();
375       }
376    }
377
378    /**
379     * extract the base of our webapp from an inbound request
380     *
381     * @param request request containing http://foobar/axis/services/something
382     * @return some URL like http://foobar:8080/axis/
383     */

384    protected String JavaDoc getWebappBase(HttpServletRequest JavaDoc request)
385    {
386       StringBuffer JavaDoc baseURL = new StringBuffer JavaDoc(128);
387       baseURL.append(request.getScheme());
388       baseURL.append("://");
389       baseURL.append(request.getServerName());
390       if (request.getServerPort() != 80)
391       {
392          baseURL.append(":");
393          baseURL.append(request.getServerPort());
394       }
395       baseURL.append(request.getContextPath());
396       return baseURL.toString();
397    }
398
399    /**
400     * what is the servlet context
401     *
402     * @return get the context from the servlet config
403     */

404    public ServletContext JavaDoc getServletContext()
405    {
406       return getServletConfig().getServletContext();
407    }
408
409    /**
410     * accessor to webinf
411     *
412     * @return path to WEB-INF/ in the local filesystem
413     */

414    protected String JavaDoc getWebInfPath()
415    {
416       return webInfPath;
417    }
418
419    /**
420     * what is the root dir of the applet?
421     *
422     * @return path of root dir
423     */

424    protected String JavaDoc getHomeDir()
425    {
426       return homeDir;
427    }
428
429    /**
430     * Retrieve option, in order of precedence:
431     * (Managed) System property (see discovery.ManagedProperty),
432     * servlet init param, context init param.
433     * Use of system properties is discouraged in production environments,
434     * as it overrides everything else.
435     */

436    protected String JavaDoc getOption(ServletContext JavaDoc context,
437                               String JavaDoc param,
438                               String JavaDoc dephault)
439    {
440       String JavaDoc value = AxisProperties.getProperty(param);
441
442       if (value == null)
443          value = getInitParameter(param);
444
445       if (value == null)
446          value = context.getInitParameter(param);
447
448       return (value != null) ? value : dephault;
449    }
450
451    /**
452     * probe for the system being 'production'
453     *
454     * @return true for a dev system.
455     */

456    public boolean isDevelopment()
457    {
458       return isDevelopment;
459    }
460
461 }
462
Popular Tags