1 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 ; 47 import javax.servlet.ServletException ; 48 import javax.servlet.http.HttpServlet ; 49 import javax.servlet.http.HttpServletRequest ; 50 import javax.servlet.http.HttpServletResponse ; 51 import java.io.IOException ; 52 import java.io.OutputStream ; 53 import java.io.PrintWriter ; 54 import java.io.UnsupportedEncodingException ; 55 import java.net.HttpURLConnection ; 56 import java.util.Iterator ; 57 import java.util.Properties ; 58 59 60 70 public class BlojsomXMLRPCServlet extends HttpServlet { 71 72 protected Log _logger = LogFactory.getLog(BlojsomXMLRPCServlet.class); 73 74 protected String [] BLOJSOM_CONFIGURATION_FILES = {"blojsom-xmlrpc.xml"}; 75 76 protected static final int XMLRPC_DISABLED = 4000; 77 protected static final String XMLRPC_DISABLED_MESSAGE = "XML-RPC disabled for the requested blog"; 78 protected static final String XMLRPC_ACCEPTS_ONLY_POSTS_MESSAGE = "XML-RPC server only accepts POST requests."; 79 80 protected ClassPathXmlApplicationContext _classPathXmlApplicationContext; 81 82 85 public BlojsomXMLRPCServlet() { 86 } 87 88 94 public void init(ServletConfig servletConfig) throws ServletException { 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 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 118 protected XmlRpcServer configureXMLRPCServer(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, String 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 if (!blog.getXmlrpcEnabled().booleanValue()) { 140 if (_logger.isErrorEnabled()) { 141 _logger.error(XMLRPC_DISABLED_MESSAGE); 142 } 143 144 return null; 145 } 146 147 Properties xmlrpcProperties = (Properties ) _classPathXmlApplicationContext.getBean("xmlrpcProperties"); 148 String defaultXMLRPCHandler = xmlrpcProperties.getProperty(BlojsomXMLRPCConstants.DEFAULT_XMLRPC_HANDLER_KEY); 149 xmlrpcProperties.remove(BlojsomXMLRPCConstants.DEFAULT_XMLRPC_HANDLER_KEY); 150 151 Iterator handlerIterator = xmlrpcProperties.keySet().iterator(); 152 while (handlerIterator.hasNext()) { 153 String handlerName = (String ) handlerIterator.next(); 154 APIHandler apiHandler = (APIHandler) _classPathXmlApplicationContext.getBean(handlerName); 155 apiHandler.setProperties((Properties ) _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 185 protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException , IOException { 186 try { 187 httpServletRequest.setCharacterEncoding(BlojsomConstants.UTF8); 188 } catch (UnsupportedEncodingException 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 printWriter = httpServletResponse.getWriter(); 197 printWriter.print(XMLRPC_ACCEPTS_ONLY_POSTS_MESSAGE); 198 printWriter.flush(); 199 } else { 200 String 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 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 os = httpServletResponse.getOutputStream(); 220 os.write(result); 221 os.flush(); 222 } 223 } 224 225 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 |