KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > AxisEngine


1 /*
2  * Copyright 2001-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 package org.apache.axis;
18
19 import org.apache.axis.components.logger.LogFactory;
20 import org.apache.axis.encoding.TypeMappingRegistry;
21 import org.apache.axis.encoding.TypeMappingImpl;
22 import org.apache.axis.handlers.BasicHandler;
23 import org.apache.axis.handlers.soap.SOAPService;
24 import org.apache.axis.session.Session;
25 import org.apache.axis.session.SimpleSession;
26 import org.apache.axis.utils.JavaUtils;
27 import org.apache.axis.utils.Messages;
28 import org.apache.axis.utils.cache.ClassCache;
29 import org.apache.commons.logging.Log;
30
31 import javax.xml.namespace.QName JavaDoc;
32 import javax.xml.rpc.server.ServiceLifecycle JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Enumeration JavaDoc;
35 import java.util.Hashtable JavaDoc;
36
37
38 /**
39  * An <code>AxisEngine</code> is the base class for AxisClient and
40  * AxisServer. Handles common functionality like dealing with the
41  * handler/service registries and loading properties.
42  *
43  * @author Glen Daniels (gdaniels@apache.org)
44  * @author Glyn Normington (glyn@apache.org)
45  */

46 public abstract class AxisEngine extends BasicHandler
47 {
48     /**
49      * The <code>Log</code> for all message logging.
50      */

51     protected static Log log =
52         LogFactory.getLog(AxisEngine.class.getName());
53
54     // Engine property names
55
public static final String JavaDoc PROP_XML_DECL = "sendXMLDeclaration";
56     public static final String JavaDoc PROP_DEBUG_LEVEL = "debugLevel";
57     public static final String JavaDoc PROP_DEBUG_FILE = "debugFile";
58     public static final String JavaDoc PROP_DOMULTIREFS = "sendMultiRefs";
59     public static final String JavaDoc PROP_DISABLE_PRETTY_XML = "disablePrettyXML";
60     public static final String JavaDoc PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION = "enableNamespacePrefixOptimization";
61     public static final String JavaDoc PROP_PASSWORD = "adminPassword";
62     public static final String JavaDoc PROP_SYNC_CONFIG = "syncConfiguration";
63     public static final String JavaDoc PROP_SEND_XSI = "sendXsiTypes";
64     public static final String JavaDoc PROP_ATTACHMENT_DIR = "attachments.Directory";
65     public static final String JavaDoc PROP_ATTACHMENT_IMPLEMENTATION = "attachments.implementation" ;
66     public static final String JavaDoc PROP_ATTACHMENT_CLEANUP = "attachment.DirectoryCleanUp";
67     public static final String JavaDoc PROP_DEFAULT_CONFIG_CLASS = "axis.engineConfigClass";
68     public static final String JavaDoc PROP_SOAP_VERSION = "defaultSOAPVersion";
69     public static final String JavaDoc PROP_SOAP_ALLOWED_VERSION = "singleSOAPVersion";
70     public static final String JavaDoc PROP_TWOD_ARRAY_ENCODING = "enable2DArrayEncoding";
71     public static final String JavaDoc PROP_XML_ENCODING = "axis.xmlEncoding";
72     public static final String JavaDoc PROP_XML_REUSE_SAX_PARSERS = "axis.xml.reuseParsers";
73     public static final String JavaDoc PROP_BYTE_BUFFER_BACKING = "axis.byteBuffer.backing";
74     public static final String JavaDoc PROP_BYTE_BUFFER_CACHE_INCREMENT = "axis.byteBuffer.cacheIncrement";
75     public static final String JavaDoc PROP_BYTE_BUFFER_RESIDENT_MAX_SIZE = "axis.byteBuffer.residentMaxSize";
76     public static final String JavaDoc PROP_BYTE_BUFFER_WORK_BUFFER_SIZE = "axis.byteBuffer.workBufferSize";
77     public static final String JavaDoc PROP_EMIT_ALL_TYPES = "emitAllTypesInWSDL";
78     /**
79      * Set this property to 'true' when you want Axis to avoid soap encoded
80      * types to work around a .NET problem where it wont accept soap encoded
81      * types for a (soap encoded!) array.
82      */

83     public static final String JavaDoc PROP_DOTNET_SOAPENC_FIX = "dotNetSoapEncFix";
84     /** Compliance with WS-I Basic Profile. */
85     public static final String JavaDoc PROP_BP10_COMPLIANCE = "ws-i.bp10Compliance";
86
87     public static final String JavaDoc DEFAULT_ATTACHMENT_IMPL="org.apache.axis.attachments.AttachmentsImpl";
88
89     public static final String JavaDoc ENV_ATTACHMENT_DIR = "axis.attachments.Directory";
90     public static final String JavaDoc ENV_SERVLET_REALPATH = "servlet.realpath";
91     public static final String JavaDoc ENV_SERVLET_CONTEXT = "servletContext";
92
93     // Default admin. password
94
private static final String JavaDoc DEFAULT_ADMIN_PASSWORD = "admin";
95
96
97     /** Our go-to guy for configuration... */
98     protected EngineConfiguration config;
99
100     /** Has the user changed the password yet? True if they have. */
101     protected boolean _hasSafePassword = false;
102
103     /**
104      * Should we save the engine config each time we modify it? True if we
105      * should.
106      */

107     protected boolean shouldSaveConfig = false;
108
109     /** Java class cache. */
110     protected transient ClassCache classCache = new ClassCache();
111
112     /**
113      * This engine's Session. This Session supports "application scope"
114      * in the Apache SOAP sense... if you have a service with "application
115      * scope", have it store things in this Session.
116      */

117     private Session session = new SimpleSession();
118
119     /**
120      * What actor URIs hold for the entire engine? Find them here.
121      */

122     private ArrayList JavaDoc actorURIs = new ArrayList JavaDoc();
123
124     /**
125      * Thread local storage used for locating the active message context.
126      * This information is only valid for the lifetime of this request.
127      */

128     private static ThreadLocal JavaDoc currentMessageContext = new ThreadLocal JavaDoc();
129
130     /**
131      * Set the active message context.
132      *
133      * @param mc - the new active message context.
134      */

135     protected static void setCurrentMessageContext(MessageContext mc) {
136         currentMessageContext.set(mc);
137     }
138
139     /**
140      * Get the active message context.
141      *
142      * @return the current active message context
143      */

144     public static MessageContext getCurrentMessageContext() {
145         return (MessageContext) currentMessageContext.get();
146     }
147
148     /**
149      * Construct an AxisEngine using the specified engine configuration.
150      *
151      * @param config the EngineConfiguration for this engine
152      */

153     public AxisEngine(EngineConfiguration config)
154     {
155         this.config = config;
156         init();
157     }
158
159     /**
160      * Initialize the engine. Multiple calls will (may?) return the engine to
161      * the intialized state.
162      */

163     public void init() {
164         if (log.isDebugEnabled()) {
165             log.debug("Enter: AxisEngine::init");
166         }
167
168         // The SOAP/XSD stuff is in the default TypeMapping of the TypeMappingRegistry.
169
//getTypeMappingRegistry().setParent(SOAPTypeMappingRegistry.getSingletonDelegate());
170

171         try {
172             config.configureEngine(this);
173         } catch (Exception JavaDoc e) {
174             throw new InternalException(e);
175         }
176
177         /*Set the default attachment implementation */
178         setOptionDefault(PROP_ATTACHMENT_IMPLEMENTATION,
179                          AxisProperties.getProperty("axis." + PROP_ATTACHMENT_IMPLEMENTATION ));
180
181         setOptionDefault(PROP_ATTACHMENT_IMPLEMENTATION, DEFAULT_ATTACHMENT_IMPL);
182
183         // Check for the property "dotnetsoapencfix" which will turn
184
// off soap encoded types to work around a bug in .NET where
185
// it wont accept soap encoded array types.
186
final Object JavaDoc dotnet = getOption(PROP_DOTNET_SOAPENC_FIX);
187         if (JavaUtils.isTrue(dotnet)) {
188             // This is a static property of the type mapping
189
// that will ignore SOAPENC types when looking up
190
// QNames of java types.
191
TypeMappingImpl.dotnet_soapenc_bugfix = true;
192         }
193
194         if (log.isDebugEnabled()) {
195             log.debug("Exit: AxisEngine::init");
196         }
197
198     }
199
200     /**
201      * Cleanup routine removes application scoped objects.
202      *
203      * There is a small risk of this being called more than once
204      * so the cleanup should be designed to resist that event.
205      */

206     public void cleanup() {
207         super.cleanup();
208
209         // Let any application-scoped service objects know that we're going
210
// away...
211
Enumeration JavaDoc keys = session.getKeys();
212         if (keys != null) {
213             while (keys.hasMoreElements()) {
214                 String JavaDoc key = (String JavaDoc)keys.nextElement();
215                 Object JavaDoc obj = session.get(key);
216                 if (obj != null && obj instanceof ServiceLifecycle JavaDoc) {
217                     ((ServiceLifecycle JavaDoc)obj).destroy();
218                 }
219                 session.remove(key);
220             }
221         }
222     }
223
224     /** Write out our engine configuration.
225      */

226     public void saveConfiguration()
227     {
228         if (!shouldSaveConfig)
229             return;
230
231         try {
232             config.writeEngineConfig(this);
233         } catch (Exception JavaDoc e) {
234             log.error(Messages.getMessage("saveConfigFail00"), e);
235         }
236     }
237
238     /**
239      * Get the <code>EngineConfiguration</code> used throughout this
240      * <code>AxisEngine</code> instance.
241      *
242      * @return the engine configuration instance
243      */

244     public EngineConfiguration getConfig() {
245         return config;
246     }
247
248     /**
249      * Discover if this <code>AxisEngine</code> has a safe password.
250      *
251      * @return true if it is safe, false otherwise
252      */

253     public boolean hasSafePassword()
254     {
255         return _hasSafePassword;
256     }
257
258     /**
259      * Set the administration password.
260      *
261      * @param pw the literal value of the password as a <code>String</code>
262      */

263     public void setAdminPassword(String JavaDoc pw)
264     {
265         setOption(PROP_PASSWORD, pw);
266         _hasSafePassword = true;
267         saveConfiguration();
268     }
269
270     /**
271      * Set the flag that controls if the configuration should be saved.
272      *
273      * @param shouldSaveConfig true if the configuration should be changed,
274      * false otherwise
275      */

276     public void setShouldSaveConfig(boolean shouldSaveConfig)
277     {
278         this.shouldSaveConfig = shouldSaveConfig;
279     }
280
281     // fixme: could someone who knows double-check I've got the semantics of
282
// this right?
283
/**
284      * Get the <code>Handler</code> for a particular local name.
285      *
286      * @param name the local name of the request type
287      * @return the <code>Handler</code> for this request type
288      * @throws AxisFault
289      */

290     public Handler getHandler(String JavaDoc name) throws AxisFault
291     {
292         try {
293             return config.getHandler(new QName JavaDoc(null, name));
294         } catch (ConfigurationException e) {
295             throw new AxisFault(e);
296         }
297     }
298
299     // fixme: could someone who knows double-check I've got the semantics of
300
// this right?
301
/**
302      * Get the <code>SOAPService</code> for a particular local name.
303      *
304      * @param name the local name of the request type
305      * @return the <code>SOAPService</code> for this request type
306      * @throws AxisFault
307      */

308     public SOAPService getService(String JavaDoc name) throws AxisFault
309     {
310         try {
311             return config.getService(new QName JavaDoc(null, name));
312         } catch (ConfigurationException e) {
313             try {
314                 return config.getServiceByNamespaceURI(name);
315             } catch (ConfigurationException e1) {
316                 throw new AxisFault(e);
317             }
318         }
319     }
320
321     /**
322      * Get the <code>Handler</code> that implements the transport for a local
323      * name.
324      *
325      * @param name the local name to fetch the transport for
326      * @return a <code>Handler</code> for this local name
327      * @throws AxisFault
328      */

329     public Handler getTransport(String JavaDoc name) throws AxisFault
330     {
331         try {
332             return config.getTransport(new QName JavaDoc(null, name));
333         } catch (ConfigurationException e) {
334             throw new AxisFault(e);
335         }
336     }
337
338     /**
339      * Get the <code>TypeMappingRegistry</code> for this axis engine.
340      *
341      * @return the <code>TypeMappingRegistry</code> if possible, or null if
342      * there is any error resolving it
343      */

344     public TypeMappingRegistry getTypeMappingRegistry()
345     {
346         TypeMappingRegistry tmr = null;
347         try {
348             tmr = config.getTypeMappingRegistry();
349         } catch (ConfigurationException e) {
350             log.error(Messages.getMessage("axisConfigurationException00"), e);
351         }
352
353         return tmr;
354     }
355
356     /**
357      * Get the global request <code>Handler</code>.
358      *
359      * @return the <code>Handler</code> used for global requests
360      * @throws ConfigurationException
361      */

362     public Handler getGlobalRequest()
363         throws ConfigurationException
364     {
365         return config.getGlobalRequest();
366     }
367
368     /**
369      * Get the global respones <code>Handler</code>.
370      *
371      * @return the <code>Handler</code> used for global responses
372      * @throws ConfigurationException
373      */

374     public Handler getGlobalResponse()
375         throws ConfigurationException
376     {
377         return config.getGlobalResponse();
378     }
379
380     // fixme: publishing this as ArrayList prevents us moving to another
381
// List impl later
382
/**
383      * Get a list of actor URIs that hold for the entire engine.
384      *
385      * @return an <code>ArrayList</code> of all actor URIs as
386      * <code>Strings</code>
387      */

388     public ArrayList JavaDoc getActorURIs()
389     {
390         return (ArrayList JavaDoc)actorURIs.clone();
391     }
392
393     /**
394      * Add an actor by uri that will hold for the entire engine.
395      *
396      * @param uri a <code>String</code> giving the uri of the actor to add
397      */

398     public void addActorURI(String JavaDoc uri)
399     {
400         actorURIs.add(uri);
401     }
402
403     /**
404      * Remove an actor by uri that will hold for the entire engine.
405      *
406      * @param uri a <code>String</code> giving the uri of the actor to remove
407      */

408     public void removeActorURI(String JavaDoc uri)
409     {
410         actorURIs.remove(uri);
411     }
412
413     /**
414      * Client engine access.
415      * <p>
416      * An AxisEngine may define another specific AxisEngine to be used
417      * by newly created Clients. For instance, a server may
418      * create an AxisClient and allow deployment to it. Then
419      * the server's services may access the AxisClient's deployed
420      * handlers and transports.
421      *
422      * @return an <code>AxisEngine</code> that is the client engine
423      */

424
425     public abstract AxisEngine getClientEngine ();
426
427    /**
428     * Administration and management APIs
429     *
430     * These can get called by various admin adapters, such as JMX MBeans,
431     * our own Admin client, web applications, etc...
432     *
433     */

434
435     /**
436      * List of options which should be converted from Strings to Booleans
437      * automatically. Note that these options are common to all XML
438      * web services.
439      */

440     private static final String JavaDoc [] BOOLEAN_OPTIONS = new String JavaDoc [] {
441                         PROP_DOMULTIREFS, PROP_SEND_XSI, PROP_XML_DECL,
442                         PROP_DISABLE_PRETTY_XML,
443                         PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION
444     };
445
446     /**
447      * Normalise the engine's options.
448      * <p>
449      * Convert boolean options from String to Boolean and default
450      * any ommitted boolean options to TRUE. Default the admin.
451      * password.
452      *
453      * @param handler the <code>Handler</code> to normalise; instances of
454      * <code>AxisEngine</code> get extra data normalised
455      */

456     public static void normaliseOptions(Handler handler) {
457         // Convert boolean options to Booleans so we don't need to use
458
// string comparisons. Default is "true".
459

460         for (int i = 0; i < BOOLEAN_OPTIONS.length; i++) {
461             Object JavaDoc val = handler.getOption(BOOLEAN_OPTIONS[i]);
462             if (val != null) {
463                 if (val instanceof Boolean JavaDoc)
464                     continue;
465                 if (JavaUtils.isFalse(val)) {
466                     handler.setOption(BOOLEAN_OPTIONS[i], Boolean.FALSE);
467                     continue;
468                 }
469             } else {
470                 if (!(handler instanceof AxisEngine))
471                     continue;
472             }
473             // If it was null or not "false"...
474
handler.setOption(BOOLEAN_OPTIONS[i], Boolean.TRUE);
475         }
476
477         // Deal with admin password's default value.
478
if (handler instanceof AxisEngine) {
479             AxisEngine engine = (AxisEngine)handler;
480             if (!engine.setOptionDefault(PROP_PASSWORD,
481                                          DEFAULT_ADMIN_PASSWORD)) {
482                 engine.setAdminPassword(
483                         (String JavaDoc)engine.getOption(PROP_PASSWORD));
484             }
485         }
486     }
487
488     /**
489      * (Re-)load the global options from the registry.
490      *
491      * @throws ConfigurationException
492      */

493     public void refreshGlobalOptions() throws ConfigurationException {
494         Hashtable JavaDoc globalOptions = config.getGlobalOptions();
495         if (globalOptions != null)
496             setOptions(globalOptions);
497
498         normaliseOptions(this);
499
500         // fixme: If we change actorURIs to List, this copy constructor can
501
// go away...
502
actorURIs = new ArrayList JavaDoc(config.getRoles());
503     }
504
505     /**
506      * Get the <code>Session</code> object associated with the application
507      * session.
508      *
509      * @return a <code>Session</code> scoped to the application
510      */

511     public Session getApplicationSession () {
512         return session;
513     }
514
515     /**
516      * Get the <code>ClassCache</code> associated with this engine.
517      *
518      * @return the class cache
519      */

520     public ClassCache getClassCache() {
521         return classCache;
522     }
523
524 }
525
Popular Tags