KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > server > http > ServerHTTPUtils


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

57
58 package org.apache.soap.server.http;
59
60 import java.io.*;
61 import java.util.*;
62 import java.lang.reflect.*;
63 import javax.servlet.* ;
64 import javax.servlet.http.*;
65 import javax.xml.parsers.*;
66 import org.w3c.dom.*;
67 import org.apache.soap.*;
68 import org.apache.soap.server.*;
69 import org.apache.soap.util.*;
70 import org.apache.soap.util.xml.*;
71 import org.apache.soap.rpc.SOAPContext;
72 import org.apache.soap.encoding.SOAPMappingRegistry;
73 import javax.activation.*;
74 import javax.mail.*;
75 import javax.mail.internet.*;
76 import org.apache.soap.transport.EnvelopeEditor;
77
78 /**
79  * Any utility stuff for HTTP SOAP stuff.
80  *
81  * @author Sanjiva Weerawarana
82  */

83 public class ServerHTTPUtils {
84   private static final String JavaDoc SERVICE_MANAGER_ID = "serviceManager";
85   private static final String JavaDoc SCRIPT_CLASS = "com.ibm.bsf.BSFManager";
86   private static final String JavaDoc SCRIPT_INVOKER =
87     "org.apache.soap.server.InvokeBSF";
88   private static final String JavaDoc SERVLET_CLASSLOADER = "servletClassLoader";
89
90   /**
91    * Look up the service manager or create it from the context. NOTE:
92    * this approach may not work if this servlet is put in a webapp
93    * that is marked distributed .. the servlet context is unique only
94    * per JVM. In that case we'll have to use an external database
95    * to store this webapp-global attribute.
96    */

97   public static ServiceManager getServiceManagerFromContext(ServletContext context,
98                                                             String JavaDoc configFilename) {
99     Object JavaDoc o;
100     if ( context != null ) {
101       synchronized (context) {
102         o = context.getAttribute(SERVICE_MANAGER_ID);
103         if (o == null) {
104           o = new ServiceManager(context, configFilename);
105           context.setAttribute (SERVICE_MANAGER_ID, o);
106         }
107       }
108     }
109     else {
110       o = new ServiceManager( null, configFilename );
111     }
112     return (ServiceManager) o;
113   }
114
115   /**
116    * Equivalent to: getServiceManagerFromContext(context, null)
117    */

118   public static ServiceManager getServiceManagerFromContext(ServletContext context) {
119     return getServiceManagerFromContext(context, null);
120   }
121
122   /**
123    * Retrieves the ClassLoader from the ServletContext, if one is registered.
124    */

125   public static ClassLoader JavaDoc getServletClassLoaderFromContext(ServletContext context) {
126     if (context != null) {
127       Object JavaDoc o;
128
129       synchronized (context) {
130         o = context.getAttribute(SERVLET_CLASSLOADER);
131       }
132       
133       return (ClassLoader JavaDoc) o;
134     } else {
135       return null;
136     }
137   }
138
139   /**
140    * Registers the ClassLoader into the ServletContext.
141    */

142   public static void setServletClassLoaderIntoContext(ServletContext context,
143                                                                    ClassLoader JavaDoc cl) {
144     synchronized (context) {
145       context.setAttribute(SERVLET_CLASSLOADER, cl);
146     }
147   }
148
149   /**
150    * If the fileName is absolute, a file representing it is returned.
151    * Otherwise, a File is returned which represents the file relative
152    * to the servlet's docBase. If ServletContext.getRealPath(fileName)
153    * returns null, a File is returned which represents the file
154    * relative to the current working directory.
155    * Note: Uses ServletContext.getRealPath(fileName).
156    */

157   public static File getFileFromNameAndContext(String JavaDoc fileName,
158                                                ServletContext context) {
159     File file = new File(fileName);
160
161     if (!file.isAbsolute())
162     {
163       if (context != null)
164       {
165         String JavaDoc realFileName = context.getRealPath(fileName);
166
167         if (realFileName != null)
168         {
169           file = new File(realFileName);
170         }
171       }
172     }
173
174     return file;
175   }
176
177   /**
178    * Read in stuff from the HTTP request stream and return the envelope.
179    * Returns null (and sets the error on the response stream) if a
180    * transport level thing is wrong and throws a SOAPException if a
181    * SOAP level thing is wrong.
182    *
183    * @return Envelope containing the SOAP envelope found in the request
184    *
185    * @exception SOAPException if a SOAP level thing goes wrong
186    * @exception IOException if something fails while sending an
187    * error response
188    */

189   public static Envelope readEnvelopeFromRequest (DocumentBuilder xdb,
190                                                   String JavaDoc contentType,
191                                                   int contentLength,
192                                                   InputStream requestStream,
193                                                   EnvelopeEditor editor,
194                                                   HttpServletResponse res,
195                                                   SOAPContext ctx)
196        throws SOAPException, IOException {
197     try {
198         return ServerUtils.readEnvelopeFromInputStream (xdb, requestStream,
199                                                         contentLength,
200                                                         contentType, editor,
201                                                         ctx);
202     } catch (IllegalArgumentException JavaDoc e) {
203       String JavaDoc msg = e.getMessage ();
204       res.sendError (res.SC_BAD_REQUEST, "Error unmarshalling envelope: " +
205                      msg);
206       return null;
207     } catch (MessagingException me) {
208       res.sendError (res.SC_BAD_REQUEST, "Error unmarshalling envelope: " +
209                      me);
210       return null;
211     }
212   }
213
214   /**
215    * Return the target object that services the service with the
216    * given ID. Depending on the deployment information of the
217    * service, the object's lifecycle is also managed here.
218    */

219   public static Object JavaDoc getTargetObject (ServiceManager serviceManager,
220                                  DeploymentDescriptor dd,
221                                  String JavaDoc targetID,
222                                  HttpServlet thisServlet,
223                                  HttpSession session,
224                                  SOAPContext ctxt,
225                                  ServletContext context)
226        throws SOAPException {
227     int scope = dd.getScope ();
228     byte providerType = dd.getProviderType ();
229     String JavaDoc className;
230     Object JavaDoc targetObject = null;
231     if (providerType == DeploymentDescriptor.PROVIDER_JAVA ||
232         providerType == DeploymentDescriptor.PROVIDER_USER_DEFINED) {
233       className = dd.getProviderClass ();
234     } else {
235       // for scripts, we need a new BSF manager basically
236
className = SCRIPT_CLASS;
237     }
238       
239     // determine the scope and lock object to use to manage the lifecycle
240
// of the service providing object
241
Object JavaDoc scopeLock = null;
242     if (scope == DeploymentDescriptor.SCOPE_REQUEST) {
243       scopeLock = thisServlet; // no need to register .. create, use and dink
244
} else if (scope == DeploymentDescriptor.SCOPE_SESSION) {
245       scopeLock = session;
246     } else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
247       scopeLock = context;
248     } else {
249       throw new SOAPException (Constants.FAULT_CODE_SERVER,
250                                "Service uses deprecated object scope " +
251                                "'page': inform provider of error");
252     }
253
254     // create the object if necessary
255
boolean freshObject = false;
256     
257     // find the target object on which the requested method should
258
// be invoked
259
if (targetID.equals (ServerConstants.SERVICE_MANAGER_SERVICE_NAME)) {
260       targetObject = serviceManager;
261     } else {
262       // locate (or create) the target object and invoke the method
263
if ( scopeLock == null ) scopeLock = className ; // Just pick something
264
synchronized (scopeLock) {
265         if (scopeLock == session) {
266           // targetObject = session.getAttribute (targetID);
267
targetObject = session.getValue (targetID);
268         } else if (scopeLock == context) {
269           targetObject = context.getAttribute (targetID);
270         } else {
271           targetObject = null;
272         }
273         if (targetObject == null) {
274           try {
275             Class JavaDoc c = ctxt.loadClass(className);
276
277             if (dd.getIsStatic ()) {
278               targetObject = c;
279             } else {
280               targetObject = c.newInstance ();
281             }
282             freshObject = true;
283
284             // remember the created instance if the scope is not REQUEST;
285
// in that case the object is to be thrown away after handling
286
// the request
287
if (scopeLock == session) {
288               session.putValue (targetID, targetObject);
289               // session.setAttribute (targetID, targetObject);
290
} else if (scopeLock == context) {
291               context.setAttribute (targetID, targetObject);
292             }
293           } catch (Exception JavaDoc e) {
294             String JavaDoc msg;
295             if (providerType == DeploymentDescriptor.PROVIDER_JAVA ||
296                 providerType == DeploymentDescriptor.PROVIDER_USER_DEFINED) {
297               msg = "Unable to resolve target object: " + e.getMessage ();
298             } else {
299               msg = "Unable to load BSF: script services not available " +
300                 "without BSF: " + e.getMessage ();
301             }
302             throw new SOAPException (
303               Constants.FAULT_CODE_SERVER_BAD_TARGET_OBJECT_URI, msg, e);
304           }
305         }
306       }
307     }
308
309     // if script provider type and first time to it, then load and
310
// exec the script
311
if ((providerType != DeploymentDescriptor.PROVIDER_JAVA &&
312          providerType != DeploymentDescriptor.PROVIDER_USER_DEFINED)
313         && freshObject) {
314       // find the class that provides the BSF services (done
315
// this way via reflection to avoid a static dependency on BSF)
316
Class JavaDoc bc = null;
317       try {
318         bc = ctxt.loadClass(SCRIPT_INVOKER);
319       } catch (Exception JavaDoc e) {
320         String JavaDoc msg = "Unable to load BSF invoker (" + SCRIPT_INVOKER + ")" +
321           ": script services not available without BSF: " + e.getMessage ();
322         throw new SOAPException (Constants.FAULT_CODE_SERVER, msg, e);
323       }
324
325         // get the script string to exec
326
String JavaDoc script = dd.getScriptFilenameOrString ();
327       if (providerType == DeploymentDescriptor.PROVIDER_SCRIPT_FILE) {
328         String JavaDoc fileName = context.getRealPath (script);
329         try {
330           script = IOUtils.getStringFromReader (new FileReader (fileName));
331         } catch (Exception JavaDoc e) {
332           String JavaDoc msg = "Unable to load script file (" + fileName + ")" +
333             ": " + e.getMessage ();
334           throw new SOAPException (Constants.FAULT_CODE_SERVER, msg, e);
335         }
336       }
337
338       // exec it
339
Class JavaDoc[] sig = {DeploymentDescriptor.class,
340                      Object JavaDoc.class,
341                      String JavaDoc.class};
342       try {
343         Method m = MethodUtils.getMethod (bc, "init", sig, true);
344         m.invoke (null, new Object JavaDoc[] {dd, targetObject, script});
345       } catch (InvocationTargetException ite) {
346         Throwable JavaDoc te = ite.getTargetException();
347         if (te instanceof SOAPException)
348           throw (SOAPException)te;
349         String JavaDoc msg = "Unable to invoke init method of script invoker: " + te;
350         throw new SOAPException (Constants.FAULT_CODE_SERVER, msg, te);
351       } catch (Exception JavaDoc e) {
352         String JavaDoc msg = "Unable to invoke init method of script invoker: " + e;
353         throw new SOAPException (Constants.FAULT_CODE_SERVER, msg, e);
354       }
355     }
356
357     return targetObject;
358   }
359
360   /**
361    * Return the soap mapping registry instance from the servlet context.
362    * If one isn't there, then create one and store it in there and then
363    * return it.
364    */

365   public static SOAPMappingRegistry
366        getSMRFromContext (ServletContext context) {
367     SOAPMappingRegistry smr = null;
368     synchronized (context) {
369       smr =
370     (SOAPMappingRegistry) context.getAttribute ("__cached_servlet_SMR__");
371       if (smr == null) {
372     smr = new SOAPMappingRegistry ();
373     context.setAttribute ("__cached_servlet_SMR__", smr);
374       }
375     }
376     return smr;
377   }
378 }
379
Popular Tags