KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 2002-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
17
18 package org.apache.axis.transport.http;
19
20 import java.io.File JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import javax.servlet.ServletContext JavaDoc;
27 import javax.servlet.ServletException JavaDoc;
28 import javax.servlet.http.HttpServlet JavaDoc;
29 import javax.servlet.http.HttpServletRequest JavaDoc;
30 import javax.servlet.http.HttpServletResponse JavaDoc;
31
32 import org.apache.axis.AxisEngine;
33 import org.apache.axis.AxisFault;
34 import org.apache.axis.AxisProperties;
35 import org.apache.axis.EngineConfiguration;
36 import org.apache.axis.components.logger.LogFactory;
37 import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
38 import org.apache.axis.server.AxisServer;
39 import org.apache.axis.utils.JavaUtils;
40 import org.apache.commons.logging.Log;
41
42 /**
43  * Base class for servlets used in axis, has common methods
44  * to get and save the engine to a common location, currently the
45  * webapp's context, though some alternate persistence mechanism is always
46  * possible. Also has a load counter shared by all servlets; tracks the
47  * # of active http requests open to any of the subclasses.
48  * @author Steve Loughran
49  */

50
51 public class AxisServletBase extends HttpServlet JavaDoc {
52
53     /**
54      * per-instance cache of the axis server
55      */

56     protected AxisServer axisServer = null;
57
58     private static Log log =
59         LogFactory.getLog(AxisServlet.class.getName());
60         
61     private static boolean isDebug = false;
62
63     /**
64      * count number of service requests in progress
65      */

66     private static int loadCounter = 0;
67
68     /**
69      * and a lock
70      */

71     private static Object JavaDoc loadCounterLock = new Object JavaDoc();
72
73     /**
74      * name of the axis engine to use in the servlet context
75      */

76     protected static final String JavaDoc ATTR_AXIS_ENGINE =
77         "AxisEngine" ;
78
79     /**
80      * Cached path to our WEB-INF directory
81      */

82     private String JavaDoc webInfPath = null;
83
84     /**
85      * Cached path to our "root" dir
86      */

87     private String JavaDoc homeDir = null;
88
89     /**
90      * flag set to true for a 'production' server
91      */

92     private boolean isDevelopment;
93
94     /**
95      * property name for a production server
96      */

97     private static final String JavaDoc INIT_PROPERTY_DEVELOPMENT_SYSTEM=
98                "axis.development.system";
99
100
101     /**
102      * our initialize routine; subclasses should call this if they override it
103      */

104     public void init() throws javax.servlet.ServletException JavaDoc {
105         ServletContext JavaDoc context = getServletConfig().getServletContext();
106
107         webInfPath = context.getRealPath("/WEB-INF");
108         homeDir = context.getRealPath("/");
109
110         isDebug = log.isDebugEnabled();
111         if(log.isDebugEnabled()) log.debug("In AxisServletBase init");
112         isDevelopment= JavaUtils.isTrueExplicitly(getOption(context,
113                         INIT_PROPERTY_DEVELOPMENT_SYSTEM, null));
114
115     }
116
117     /**
118      * Destroy method is called when the servlet is going away. Pass this
119      * down to the AxisEngine to let it clean up... But don't create the
120      * engine if it hasn't already been created.
121      * @todo Fixme for multiple servlets.
122      * This has always been slightly broken
123      * (the context's copy stayed around), but now we have extracted it into
124      * a superclass it is blatantly broken.
125      */

126     public void destroy() {
127         super.destroy();
128
129         //if we have had anything to do with creating an axis server
130
if (axisServer != null) {
131             //then we lock it
132
synchronized(axisServer) {
133                 if (axisServer != null) {
134                     //clean it up
135
axisServer.cleanup();
136                     //and erase our history of it
137
axisServer =null;
138                     storeEngine(this,null);
139                 }
140             }
141         }
142     }
143
144     /**
145      * get the engine for this servlet from cache or context
146      * @return
147      * @throws AxisFault
148      */

149     public AxisServer getEngine() throws AxisFault {
150         if (axisServer == null)
151             axisServer = getEngine(this);
152         return axisServer;
153     }
154
155
156     /**
157      * This is a uniform method of initializing AxisServer in a servlet
158      * context.
159      * @todo add catch for not being able to cast the context attr to an
160      * engine and reinit the engine if so.
161      */

162     public static AxisServer getEngine(HttpServlet JavaDoc servlet) throws AxisFault
163     {
164         AxisServer engine = null;
165         if (isDebug)
166             log.debug("Enter: getEngine()");
167
168         ServletContext JavaDoc context = servlet.getServletContext();
169         synchronized (context) {
170             engine = retrieveEngine(servlet);
171             if (engine == null) {
172                 Map JavaDoc environment = getEngineEnvironment(servlet);
173
174                 // Obtain an AxisServer by using whatever AxisServerFactory is
175
// registered. The default one will just use the provider we
176
// passed in, and presumably JNDI ones will use the ServletContext
177
// to figure out a JNDI name to look up.
178
//
179
// The point of doing this rather than just creating the server
180
// manually with the provider above is that we will then support
181
// configurations where the server instance is managed by the
182
// container, and pre-registered in JNDI at deployment time. It
183
// also means we put the standard configuration pattern in one
184
// place.
185
engine = AxisServer.getServer(environment);
186 // attach the AxisServer with the current Servlet
187
engine.setName(servlet.getServletName());
188                 storeEngine(servlet, engine);
189             }
190         }
191
192         if (isDebug)
193             log.debug("Exit: getEngine()");
194
195         return engine;
196     }
197
198     /**
199      * put the engine back in to the context.
200      * @param context servlet context to use
201      * @param engine reference to the engine. If null, the engine is removed
202      */

203     private static void storeEngine(HttpServlet JavaDoc servlet, AxisServer engine) {
204         ServletContext JavaDoc context = servlet.getServletContext();
205         String JavaDoc axisServletName = servlet.getServletName();
206         if (engine == null) {
207             context.removeAttribute(axisServletName + ATTR_AXIS_ENGINE);
208             // find if there is other AxisEngine in Context
209
AxisServer server = (AxisServer) context.getAttribute(ATTR_AXIS_ENGINE);
210
211             // no other AxisEngine in ServletContext
212
if (server != null && servlet.getServletName().equals(server.getName())) {
213                 context.removeAttribute(ATTR_AXIS_ENGINE);
214             }
215         } else {
216             if (context.getAttribute(ATTR_AXIS_ENGINE) == null) {
217                 // first Axis servlet to store its AxisEngine
218
// use default name
219
context.setAttribute(ATTR_AXIS_ENGINE, engine);
220             }
221             context.setAttribute(axisServletName + ATTR_AXIS_ENGINE, engine);
222         }
223     }
224
225     /**
226      * Get an engine from the servlet context; robust againt serialization
227      * issues of hot-updated webapps. Remember than if a webapp is marked
228      * as distributed, there is more than 1 servlet context, hence more than
229      * one AxisEngine instance
230      * @param servlet
231      * @return the engine or null if either the engine couldnt be found or
232      * the attribute wasnt of the right type
233      */

234     private static AxisServer retrieveEngine(HttpServlet JavaDoc servlet) {
235         Object JavaDoc contextObject = servlet.getServletContext().getAttribute(servlet.getServletName() + ATTR_AXIS_ENGINE);
236         if (contextObject == null) {
237             // if AxisServer not found :
238
// fall back to the "default" AxisEngine
239
contextObject = servlet.getServletContext().getAttribute(ATTR_AXIS_ENGINE);
240         }
241         if (contextObject instanceof AxisServer) {
242             AxisServer server = (AxisServer) contextObject;
243             // if this is "our" Engine
244
if (server != null && servlet.getServletName().equals(server.getName())) {
245                 return server;
246             }
247             return null;
248         } else {
249             return null;
250         }
251      }
252
253     /**
254      * extract information from the servlet configuration files
255      * @param servlet
256      * @return
257      */

258     protected static Map JavaDoc getEngineEnvironment(HttpServlet JavaDoc servlet) {
259         Map JavaDoc environment = new HashMap JavaDoc();
260
261         String JavaDoc attdir= servlet.getInitParameter(AxisEngine.ENV_ATTACHMENT_DIR);
262         if (attdir != null)
263             environment.put(AxisEngine.ENV_ATTACHMENT_DIR, attdir);
264
265         ServletContext JavaDoc context = servlet.getServletContext();
266         environment.put(AxisEngine.ENV_SERVLET_CONTEXT, context);
267
268         String JavaDoc webInfPath = context.getRealPath("/WEB-INF");
269         if (webInfPath != null)
270             environment.put(AxisEngine.ENV_SERVLET_REALPATH,
271                             webInfPath + File.separator + "attachments");
272
273         EngineConfiguration config =
274             EngineConfigurationFactoryFinder.newFactory(servlet)
275                     .getServerEngineConfig();
276
277         if (config != null) {
278             environment.put(EngineConfiguration.PROPERTY_NAME, config);
279         }
280
281         return environment;
282     }
283
284
285     /**
286      * get a count of the # of services running. This is only
287      * ever an approximate number in a busy system
288      *
289      * @return The TotalServiceCount value
290      */

291
292     public static int getLoadCounter() {
293             return loadCounter;
294     }
295
296     /**
297      * thread safe lock counter increment
298      */

299     protected static void incLockCounter() {
300         synchronized(loadCounterLock) {
301             loadCounter++;
302         }
303     }
304
305     /**
306      * thread safe lock counter decrement
307      */

308     protected static void decLockCounter() {
309         synchronized(loadCounterLock) {
310             loadCounter--;
311         }
312     }
313
314     /**
315      * subclass of service method that tracks entry count; calls the
316      * parent's implementation to have the http method cracked and delegated
317      * to the doGet, doPost method.
318      * @param req request
319      * @param resp response
320      * @throws ServletException something went wrong
321      * @throws IOException something different went wrong
322      */

323     protected void service(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc resp)
324         throws ServletException JavaDoc, IOException JavaDoc {
325         incLockCounter();
326         try {
327             super.service(req, resp);
328         }
329         finally {
330             decLockCounter();
331         }
332     }
333     
334     /**
335      * extract the base of our webapp from an inbound request
336      *
337      * @param request request containing http://foobar/axis/services/something
338      * @return some URL like http://foobar:8080/axis/
339      */

340     protected String JavaDoc getWebappBase(HttpServletRequest JavaDoc request) {
341         StringBuffer JavaDoc baseURL=new StringBuffer JavaDoc(128);
342         baseURL.append(request.getScheme());
343         baseURL.append("://");
344         baseURL.append(request.getServerName());
345         if(request.getServerPort()!=80) {
346             baseURL.append(":");
347             baseURL.append(request.getServerPort());
348         }
349         baseURL.append(request.getContextPath());
350         return baseURL.toString();
351     }
352
353     /**
354      * what is the servlet context
355      * @return get the context from the servlet config
356      */

357     public ServletContext JavaDoc getServletContext() {
358         return getServletConfig().getServletContext();
359     }
360
361     /**
362      * accessor to webinf
363      * @return path to WEB-INF/ in the local filesystem
364      */

365     protected String JavaDoc getWebInfPath() {
366         return webInfPath;
367     }
368
369     /**
370      * what is the root dir of the applet?
371      * @return path of root dir
372      */

373     protected String JavaDoc getHomeDir() {
374         return homeDir;
375     }
376
377     /**
378      * Retrieve option, in order of precedence:
379      * (Managed) System property (see discovery.ManagedProperty),
380      * servlet init param, context init param.
381      * Use of system properties is discouraged in production environments,
382      * as it overrides everything else.
383      */

384     protected String JavaDoc getOption(ServletContext JavaDoc context,
385                              String JavaDoc param,
386                              String JavaDoc dephault)
387     {
388         String JavaDoc value = AxisProperties.getProperty(param);
389
390         if (value == null)
391             value = getInitParameter(param);
392
393         if (value == null)
394             value = context.getInitParameter(param);
395         try {
396             AxisServer engine = getEngine(this);
397             if (value == null && engine != null)
398                 value = (String JavaDoc) engine.getOption(param);
399         } catch (AxisFault axisFault) {
400         }
401
402         return (value != null) ? value : dephault;
403     }
404
405     /**
406      * probe for the system being 'production'
407      * @return true for a dev system.
408      */

409     public boolean isDevelopment() {
410         return isDevelopment;
411     }
412
413 }
414
Popular Tags