KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > blojsom > extension > xmlrpc > BlojsomXMLRPCServlet


1 /**
2  * Copyright (c) 2003-2006, David A. Czarnecki
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this list of conditions and the
9  * following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
11  * following disclaimer in the documentation and/or other materials provided with the distribution.
12  * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
13  * endorse or promote products derived from this software without specific prior written permission.
14  * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
15  * without prior written permission of David A. Czarnecki.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21  * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */

31 package org.blojsom.extension.xmlrpc;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.xmlrpc.XmlRpc;
36 import org.apache.xmlrpc.XmlRpcServer;
37 import org.blojsom.blog.Blog;
38 import org.blojsom.extension.xmlrpc.handler.APIHandler;
39 import org.blojsom.fetcher.Fetcher;
40 import org.blojsom.fetcher.FetcherException;
41 import org.blojsom.servlet.ServletConfigFactoryBean;
42 import org.blojsom.util.BlojsomConstants;
43 import org.blojsom.util.BlojsomUtils;
44 import org.springframework.context.support.ClassPathXmlApplicationContext;
45
46 import javax.servlet.ServletConfig JavaDoc;
47 import javax.servlet.ServletException JavaDoc;
48 import javax.servlet.http.HttpServlet JavaDoc;
49 import javax.servlet.http.HttpServletRequest JavaDoc;
50 import javax.servlet.http.HttpServletResponse JavaDoc;
51 import java.io.IOException JavaDoc;
52 import java.io.OutputStream JavaDoc;
53 import java.io.PrintWriter JavaDoc;
54 import java.io.UnsupportedEncodingException JavaDoc;
55 import java.net.HttpURLConnection JavaDoc;
56 import java.util.Iterator JavaDoc;
57 import java.util.Properties JavaDoc;
58
59
60 /**
61  * Blojsom XML-RPC Servlet
62  * <p/>
63  * This servlet uses the Jakarta XML-RPC Library (http://ws.apache.org/xmlrpc)
64  *
65  * @author Mark Lussier
66  * @author David Czarnecki
67  * @since blojsom 3.0
68  * @version $Id: BlojsomXMLRPCServlet.java,v 1.2 2006/03/24 19:04:41 czarneckid Exp $
69  */

70 public class BlojsomXMLRPCServlet extends HttpServlet JavaDoc {
71
72     protected Log _logger = LogFactory.getLog(BlojsomXMLRPCServlet.class);
73
74     protected String JavaDoc[] BLOJSOM_CONFIGURATION_FILES = {"blojsom-xmlrpc.xml"};
75
76     protected static final int XMLRPC_DISABLED = 4000;
77     protected static final String JavaDoc XMLRPC_DISABLED_MESSAGE = "XML-RPC disabled for the requested blog";
78     protected static final String JavaDoc XMLRPC_ACCEPTS_ONLY_POSTS_MESSAGE = "XML-RPC server only accepts POST requests.";
79
80     protected ClassPathXmlApplicationContext _classPathXmlApplicationContext;
81
82     /**
83      * Construct a new Blojsom XML-RPC servlet instance
84      */

85     public BlojsomXMLRPCServlet() {
86     }
87
88     /**
89      * Initialize the blojsom XML-RPC servlet
90      *
91      * @param servletConfig Servlet configuration information
92      * @throws ServletException If there is an error initializing the servlet
93      */

94     public void init(ServletConfig JavaDoc servletConfig) throws ServletException JavaDoc {
95         super.init(servletConfig);
96
97         ServletConfigFactoryBean.setServletConfig(servletConfig);
98
99         _classPathXmlApplicationContext = new ClassPathXmlApplicationContext(BLOJSOM_CONFIGURATION_FILES);
100         servletConfig.getServletContext().setAttribute(BlojsomConstants.BLOJSOM_XMLRPC_APPLICATION_CONTEXT, _classPathXmlApplicationContext);
101
102         // Set the default encoding for the XmlRpc classes to UTF-8
103
XmlRpc.setEncoding(BlojsomConstants.UTF8);
104
105         if (_logger.isDebugEnabled()) {
106             _logger.debug("blojsom XML-RPC: All Your Blog Are Belong To Us");
107         }
108     }
109
110     /**
111      * Configure the XML-RPC server for the given blog
112      *
113      * @param httpServletRequest {@link HttpServletRequest}
114      * @param httpServletResponse {@link HttpServletResponse}
115      * @param blogId Blog ID
116      * @return {@link XmlRpcServer} instance with handlers configured for the given blog
117      */

118     protected XmlRpcServer configureXMLRPCServer(HttpServletRequest JavaDoc httpServletRequest, HttpServletResponse JavaDoc httpServletResponse, String JavaDoc blogId) {
119         XmlRpcServer xmlRpcServer = new XmlRpcServer();
120
121         Fetcher fetcher = (Fetcher) _classPathXmlApplicationContext.getBean("fetcher");
122
123         Blog blog;
124         try {
125             blog = fetcher.loadBlog(blogId);
126         } catch (FetcherException e) {
127             if (_logger.isErrorEnabled()) {
128                 _logger.error(e);
129             }
130
131             return null;
132         }
133
134         if (blog.getProperty(BlojsomConstants.USE_DYNAMIC_BLOG_URLS) != null) {
135             BlojsomUtils.resolveDynamicBaseAndBlogURL(httpServletRequest, blog, blogId);
136         }
137
138         // Check to see if XML-RPC is enabled for the blog
139
if (!blog.getXmlrpcEnabled().booleanValue()) {
140             if (_logger.isErrorEnabled()) {
141                 _logger.error(XMLRPC_DISABLED_MESSAGE);
142             }
143
144             return null;
145         }
146
147         Properties JavaDoc xmlrpcProperties = (Properties JavaDoc) _classPathXmlApplicationContext.getBean("xmlrpcProperties");
148         String JavaDoc defaultXMLRPCHandler = xmlrpcProperties.getProperty(BlojsomXMLRPCConstants.DEFAULT_XMLRPC_HANDLER_KEY);
149         xmlrpcProperties.remove(BlojsomXMLRPCConstants.DEFAULT_XMLRPC_HANDLER_KEY);
150
151         Iterator JavaDoc handlerIterator = xmlrpcProperties.keySet().iterator();
152         while (handlerIterator.hasNext()) {
153             String JavaDoc handlerName = (String JavaDoc) handlerIterator.next();
154             APIHandler apiHandler = (APIHandler) _classPathXmlApplicationContext.getBean(handlerName);
155             apiHandler.setProperties((Properties JavaDoc) _classPathXmlApplicationContext.getBean("defaultProperties"));
156             apiHandler.setHttpServletRequest(httpServletRequest);
157             apiHandler.setHttpServletResponse(httpServletResponse);
158             apiHandler.setBlog(blog);
159
160             xmlRpcServer.addHandler(handlerName, apiHandler);
161
162             if (defaultXMLRPCHandler != null && defaultXMLRPCHandler.equals(handlerName)) {
163                 if (_logger.isDebugEnabled()) {
164                     _logger.debug("Added default XML-RPC handler: " + apiHandler.getClass().getName() + " for blog: " + blog.getBlogId());
165                 }
166                 xmlRpcServer.addHandler(BlojsomXMLRPCConstants.DEFAULT_XMLRPC_HANDLER_KEY, apiHandler);
167             }
168
169             if (_logger.isDebugEnabled()) {
170                 _logger.debug("Added [" + handlerName + "] API Handler : " + apiHandler.getClass().getName() + " for blog: " + blog.getBlogId());
171             }
172         }
173
174         return xmlRpcServer;
175     }
176
177     /**
178      * Service an XML-RPC request by passing the request to the proper handler
179      *
180      * @param httpServletRequest Request
181      * @param httpServletResponse Response
182      * @throws ServletException If there is an error processing the request
183      * @throws IOException If there is an error during I/O
184      */

185     protected void service(HttpServletRequest JavaDoc httpServletRequest, HttpServletResponse JavaDoc httpServletResponse) throws ServletException JavaDoc, IOException JavaDoc {
186         try {
187             httpServletRequest.setCharacterEncoding(BlojsomConstants.UTF8);
188         } catch (UnsupportedEncodingException JavaDoc e) {
189             _logger.error(e);
190         }
191         
192         if (!"post".equalsIgnoreCase(httpServletRequest.getMethod())) {
193             httpServletResponse.setContentType("text/html; charset=UTF-8");
194             httpServletResponse.setContentLength(XMLRPC_ACCEPTS_ONLY_POSTS_MESSAGE.length());
195             httpServletResponse.setStatus(HttpURLConnection.HTTP_BAD_METHOD);
196             PrintWriter JavaDoc printWriter = httpServletResponse.getWriter();
197             printWriter.print(XMLRPC_ACCEPTS_ONLY_POSTS_MESSAGE);
198             printWriter.flush();
199         } else {
200             // Determine the appropriate blog from the URL
201
String JavaDoc blogId = BlojsomUtils.getBlogFromPath(httpServletRequest.getPathInfo());
202             if (BlojsomUtils.checkNullOrBlank(blogId) || "/".equals(blogId)) {
203                 httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Requested blog not found: " + blogId);
204
205                 return;
206             }
207
208             // Make sure that the blog exists in the system
209
XmlRpcServer xmlRpcServer = configureXMLRPCServer(httpServletRequest, httpServletResponse, blogId);
210             if (xmlRpcServer == null) {
211                 httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Unable to load blog: " + blogId);
212
213                 return;
214             }
215
216             byte[] result = xmlRpcServer.execute(httpServletRequest.getInputStream());
217             httpServletResponse.setContentType("text/xml; charset=UTF-8");
218             httpServletResponse.setContentLength(result.length);
219             OutputStream JavaDoc os = httpServletResponse.getOutputStream();
220             os.write(result);
221             os.flush();
222         }
223     }
224
225     /**
226      * Called when removing the servlet from the servlet container
227      */

228     public void destroy() {
229         super.destroy();
230
231         _classPathXmlApplicationContext.destroy();
232
233         if (_logger.isDebugEnabled()) {
234             _logger.debug("blojsom XML-RPC destroyed");
235         }
236     }
237 }
238
Popular Tags