View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.services.remoting.xmlrpc;
16  
17  import org.figure8.join.core.setup.BootstrapUtil;
18  import org.figure8.join.core.setup.BootstrapManager;
19  import org.figure8.join.util.LogUtil;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.xmlrpc.XmlRpcServer;
23  import org.springframework.web.context.WebApplicationContext;
24  
25  import javax.servlet.ServletException;
26  import javax.servlet.http.HttpServlet;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.io.OutputStream;
33  /**
34   * This is a servlet that initialized a <code>XmlRpcServer</code> if required conditions
35   * are present. It retrieves the "xmlRpcHandler" component from a {@link WebApplicationContext}
36   * as a handler for XmlRpcServer.
37   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
38   * @version $Revision: 1.1 $
39   */
40  public class XmlRpcServlet extends HttpServlet{
41  
42     // Static -------------------------------------------------------------------
43  
44     /** Get a commons logger. */
45     private static final Log log = LogUtil.getLog(XmlRpcServlet.class);
46  
47     
48     // Attributes ---------------------------------------------------------------
49  
50     /** The wrapped Xml-rpc server that processes request */
51     private XmlRpcServer xmlrpc = null;
52  
53  
54     // Override of HttpServlet --------------------------------------------------
55  
56     /**
57      * Service a GET method Http call.
58      * @param request The container Http request wrapper
59      * @param response The container Http rseponse wrapper
60      * @throws ServletException if iniatilization of Xml-Rpc service fails
61      * @throws IOException if input or outputstream cannot be read/written/closed
62      */
63     protected void doGet(HttpServletRequest request, HttpServletResponse response)
64           throws ServletException, IOException{
65        // Do the same thing as post...
66        doPost(request, response);
67     }
68  
69     /**
70      * Service a POST method Http call.
71      * @param request The container Http request wrapper
72      * @param response The container Http rseponse wrapper
73      * @throws ServletException if iniatilization of Xml-Rpc service fails
74      * @throws IOException if input or outputstream cannot be read/written/closed
75      */
76     protected void doPost(HttpServletRequest request, HttpServletResponse response)
77           throws ServletException, IOException{
78        
79        // Initialize the XmlRpc server if necessary.
80        if (xmlrpc == null){
81           log.info("XmlRpc service is not yet initialized, launch initialization...");
82           setupXmlRpcServer();  
83           log.info("XmlRpc service is now initialized");
84        }
85        
86        // Service the request after having traced its origin.
87        if (log.isDebugEnabled())
88           log.debug("Servicing a XmlRpc request coming from " + request.getRemoteAddr() + " on " + request.getRequestURI());
89        
90        try{
91           serviceXmlRpcRequest(request, response);
92        }
93        catch (IOException ioe){
94           // Just log to keep a trace before propagating.
95           log.warn("IOException while servicing a XmlRpc request: " + ioe.getMessage());
96           throw ioe;
97        }
98     }
99  
100 
101    // Protected ----------------------------------------------------------------
102    
103    /**
104     * Service the request using the XmlRpcServer.
105     * @param request The container Http request wrapper
106     * @param response The container Http rseponse wrapper
107     * @throws IOException if input or outputstream cannot be read/written/closed
108     */
109    protected void serviceXmlRpcRequest(HttpServletRequest request, HttpServletResponse response)
110          throws IOException{
111       
112       // Process request input stream by XmlRpc handler.
113       InputStream is = request.getInputStream();
114       byte result[] = xmlrpc.execute(is);
115       is.close();
116       
117       // Write result on response output stream.
118       response.setContentType("text/xml");
119       response.setContentLength(result.length);
120       OutputStream out = response.getOutputStream();
121       out.write(result);
122       out.flush();  
123    }
124    
125    /**
126     * Setup the Xml-Rpc server if application setup is complete
127     * and we are on synchronous side of it.
128     * @throws ServletException if conditions are not present or initialization of XmlRpc handler fails
129     */
130    protected void setupXmlRpcServer() throws ServletException{
131       
132       // First, ensure that setup is complete.
133       BootstrapManager manager = BootstrapUtil.getBootstrapManager();
134       if (!manager.isSetupComplete()){
135          log.error("Application is not yet setup. Do not start XmlRpcServer");
136          throw new ServletException("You must setup Join before using Xml-Rpc service");
137       }
138       // Then, ensure that we are on synchronous side of application.
139       if (!manager.isSynchronousSide()){
140          log.error("Not the synchronous side of application. Do not start XmlRpcServer");  
141          throw new ServletException("You cannot use Xml-Rpc service on asynchronous side of Join");
142       }
143       
144       // Finally, we can try rerieving an appropriate request handler.
145       XmlRpcHandler handler = null;
146       try{
147          String wacAttributeName = getInitParameter("wacAttributeName");
148          WebApplicationContext wac = (WebApplicationContext)getServletContext().getAttribute(wacAttributeName);
149          handler = (XmlRpcHandler)wac.getBean("xmlRpcHandler");
150       }
151       catch (Exception e){
152          // Log and propagate as a servlet exception.
153          log.error("Exception when trying to retrieve xmlRpcHandler");
154          log.error("Here's the details message: " + e.getMessage());
155          throw new ServletException("Exception while initializing Join Xml-Rpc services");
156       }
157       // Start server and register.
158       xmlrpc = new XmlRpcServer();
159       xmlrpc.addHandler("join", handler);
160    }
161 }