Source code: jreceiver/common/rpc/xmlrpc/XmlRpcServlet.java
1 /* $Header: /cvsroot/jreceiver/jreceiver/src/jreceiver/common/rpc/xmlrpc/XmlRpcServlet.java,v 1.4 2003/04/27 23:14:32 reedesau Exp $ */
2
3 package jreceiver.common.rpc.xmlrpc;
4
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.OutputStream;
8 import java.io.Writer;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.StringTokenizer;
12 import javax.servlet.ServletException;
13 import javax.servlet.http.HttpServlet;
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16
17 import org.xml.sax.InputSource;
18 import org.xml.sax.SAXException;
19 import org.xml.sax.XMLReader;
20 import org.xml.sax.helpers.XMLReaderFactory;
21
22 import org.apache.commons.codec.binary.Base64;
23 import org.apache.commons.digester.Digester;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.xmlrpc.XmlRpc;
27 import org.apache.xmlrpc.XmlRpcServer;
28
29 import jreceiver.util.HelperFile;
30
31 /**
32 * Provide XML-RPC Services in a servlet container
33 *
34 * @author Reed Esau
35 * @version $Revision: 1.4 $ $Date: 2003/04/27 23:14:32 $
36 */
37 public class XmlRpcServlet extends HttpServlet {
38
39 static final String DEFAULT_SAX2_DRIVER = "com.bluecast.xml.Piccolo";
40
41 /**
42 */
43 public void init() throws ServletException {
44
45 log.debug("init: XML-RPC Servlet");
46
47 try {
48 String sax_driver = getInitParameter("sax-driver");
49 if (sax_driver == null)
50 sax_driver = DEFAULT_SAX2_DRIVER;
51
52 XmlRpc.setDriver(sax_driver);
53
54 String debug = getInitParameter("debug");
55 if (debug != null && debug.equals("true"))
56 XmlRpc.setDebug(true);
57
58 xmlrpc_server = new XmlRpcServer();
59 //web_server = new WebServer(port);
60
61 String filename = getInitParameter("handlers");
62 if (filename != null) {
63 List handler_list = getHandlerList(sax_driver, filename);
64 if (handler_list == null)
65 throw new ServletException("unable to load handler list");
66 if (log.isDebugEnabled())
67 log.debug("init: handler_list size=" + handler_list.size());
68 addHandlers( handler_list );
69 }
70 else {
71 log.error("handlers context-param not found");
72 }
73
74 //start listening
75 //web_server.start();
76 }
77 catch (IOException e) {
78 throw new ServletException("io-problem initing rpc engine", e);
79 }
80 catch (SAXException e) {
81 throw new ServletException("sax-problem initing rpc engine", e);
82 }
83 catch (ClassNotFoundException e) {
84 throw new ServletException("class-problem initing rpc engine", e);
85 }
86 catch (InstantiationException e) {
87 throw new ServletException("instantiation-problem initing rpc engine", e);
88 }
89 catch (IllegalAccessException e) {
90 throw new ServletException("access-problem initing rpc engine", e);
91 }
92 }
93
94 /**
95 */
96 public void doPost(HttpServletRequest req, HttpServletResponse res)
97 throws ServletException, IOException {
98
99 //get authorization header from request
100 String auth = req.getHeader("Authorization");
101 if (auth == null || !auth.toLowerCase().startsWith("basic"))
102 throw new ServletException("basic authorization required");
103
104 //get encoded user_id and password
105 String password_base64 = auth.substring(6);
106 String password_cleartext = new String(Base64.decodeBase64(password_base64.getBytes()));
107
108 //split decoded user_id and password
109 StringTokenizer userAndPass = new StringTokenizer(password_cleartext,":");
110 String user_id = userAndPass.nextToken();
111 String password = userAndPass.nextToken();
112
113 byte[] result = xmlrpc_server.execute(req.getInputStream(), user_id, password);
114 //byte[] result = xmlrpc_server.execute(req.getInputStream());
115
116 res.setContentType("text/xml");
117 res.setContentLength(result.length);
118 OutputStream output = res.getOutputStream();
119 output.write(result);
120 output.flush();
121 }
122
123
124 /**
125 */
126 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
127 Writer writer = resp.getWriter();
128 writer.write("You've reached: " + this.getClass().getName());
129 }
130
131 //
132 // RPC Handler Initialization
133 //
134
135 static final String LIST = "java.util.ArrayList";
136 static final String HANDLER = "jreceiver.common.rpc.xmlrpc.XmlRpcServlet$Handler";
137
138 /**
139 * Digest an XML list of handlers via SAX
140 *
141 * <pre>
142 * <handlers>
143 * <handler>
144 * <name>drivers</name>
145 * <class>jreceiver.common.rpc.xmlrpc.DriversHandler</class>
146 * </handler>
147 * <handler>
148 * <name>players</name>
149 * <class>jreceiver.common.rpc.xmlrpc.PlayersHandler</class>
150 * </handler>
151 * [etc...]
152 * </handlers>
153 * </pre>
154 */
155 List getHandlerList(String sax_driver, String filename)
156 throws IOException, SAXException, ServletException {
157
158 InputStream is = null;
159 try {
160 is = getServletContext().getResourceAsStream( filename );
161 if (is == null) {
162 log.error("addHandlers: cannot find " + filename);
163 throw new ServletException("unable to acquire handlers configuration");
164 }
165
166 log.debug("getHandlerList: sax_driver=" + sax_driver);
167
168 XMLReader xml_reader = XMLReaderFactory.createXMLReader(sax_driver);
169 if (xml_reader == null)
170 throw new ServletException("unable to create xml_reader to read handler list");
171
172 // create digester, configure it, and digest the XML to a list
173 Digester digester = new Digester(xml_reader);
174 digester.addObjectCreate("handlers", LIST);
175 digester.addObjectCreate("handlers/handler", HANDLER);
176 digester.addSetNext("handlers/handler", "add", HANDLER);
177 digester.addCallMethod("handlers/handler/name", "setName", 0);
178 digester.addCallMethod("handlers/handler/class", "setClazz", 0);
179 digester.parse( new InputSource(is) ); // populate the list
180
181 return(List)digester.getRoot();
182 }
183 catch (IOException e) {
184 log.error("addHandlers: unable to install handlers for " + filename, e);
185 throw e;
186 }
187 finally {
188 HelperFile.safeClose(is);
189 }
190 }
191
192 /**
193 * loads each handler specified in the list
194 */
195 void addHandlers(List handlers)
196 throws ClassNotFoundException, InstantiationException, IllegalAccessException {
197 Iterator it = handlers.iterator();
198 while (it.hasNext()) {
199 Handler handler = (Handler)it.next();
200 if (log.isInfoEnabled())
201 log.info("registering " + handler);
202 Class c = Class.forName( handler.getClazz() );
203
204 xmlrpc_server.addHandler( handler.getName(), c.newInstance() );
205 //web_server.addHandler( handler.getName(), c.newInstance() );
206 }
207 }
208
209 //
210 // internal class used in Digestion of handler XML
211 //
212
213 public static class Handler {
214 String m_name;
215 String m_clazz;
216 public void setName(String name) {
217 m_name = name;
218 }
219 public String getName() {
220 return m_name;
221 }
222 public void setClazz(String clazz) {
223 m_clazz = clazz;
224 }
225 public String getClazz() {
226 return m_clazz;
227 }
228 public String toString() {
229 return new StringBuffer()
230 .append("Handler: [name=").append(m_name)
231 .append(" clazz=").append(m_clazz).append(']').toString();
232 }
233 }
234
235 //
236 // internal data members
237 //
238
239 /**
240 *
241 */
242 private XmlRpcServer xmlrpc_server = null;
243 //private WebServer web_server = null;
244
245 /**
246 * logging object
247 */
248 protected static Log log = LogFactory.getLog(XmlRpcServlet.class);
249 }
250
251 /*
252 JRECEIVER MODIFIED BSD LICENSE
253
254 Copyright (c) 2001-2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
255
256 Redistribution and use in source and binary forms, with or without
257 modification, are permitted provided that the following conditions are
258 met:
259
260 Redistributions of source code must retain the above copyright notice,
261 this list of conditions and the following disclaimer.
262
263 Redistributions in binary form must reproduce the above copyright notice,
264 this list of conditions and the following disclaimer in the documentation
265 and/or other materials provided with the distribution.
266
267 Neither the name of the JReceiver Project
268 (http://jreceiver.sourceforge.net) nor the names of its contributors may
269 be used to endorse or promote products derived from this software without
270 specific prior written permission.
271
272 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
273 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
274 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
275 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
276 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
277 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
278 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
279 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
280 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
282 POSSIBILITY OF SUCH DAMAGE.
283 */
284