View Javadoc
1 package org.apache.turbine.services.xmlrpc; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import helma.xmlrpc.WebServer; 58 import helma.xmlrpc.XmlRpc; 59 import helma.xmlrpc.XmlRpcClient; 60 import helma.xmlrpc.XmlRpcException; 61 import helma.xmlrpc.XmlRpcServer; 62 import helma.xmlrpc.secure.SecureWebServer; 63 import java.io.IOException; 64 import java.io.InputStream; 65 import java.net.InetAddress; 66 import java.net.Socket; 67 import java.net.URL; 68 import java.util.Iterator; 69 import java.util.Vector; 70 import javax.servlet.ServletConfig; 71 import org.apache.commons.configuration.Configuration; 72 import org.apache.turbine.services.InitializationException; 73 import org.apache.turbine.services.TurbineBaseService; 74 import org.apache.turbine.services.xmlrpc.util.FileTransfer; 75 import org.apache.turbine.util.Log; 76 import org.apache.turbine.util.TurbineException; 77 78 79 /*** 80 * This is a service which will make an xml-rpc call to a remote 81 * server. 82 * 83 * Here's an example of how it would be done: 84 * <blockquote><code><pre> 85 * XmlRpcService xs = 86 * (XmlRpcService)TurbineServices.getInstance() 87 * .getService(XmlRpcService.XMLRPC_SERVICE_NAME); 88 * Vector vec = new Vector(); 89 * vec.addElement(new Integer(5)); 90 * URL url = new URL("http://betty.userland.com/RPC2"); 91 * String name = (String)xs.executeRpc(url, "examples.getStateName", vec); 92 * </pre></code></blockquote> 93 * 94 * @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a> 95 * @author <a href="mailto:magnus@handtolvur.is">Magnús Þór Torfason</a> 96 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> 97 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> 98 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 99 * @version $Id: TurbineXmlRpcService.java,v 1.5 2002/07/11 16:53:22 mpoeschl Exp $ 100 */ 101 public class TurbineXmlRpcService 102 extends TurbineBaseService 103 implements XmlRpcService 104 { 105 /*** The standalone xmlrpc server. */ 106 private WebServer webserver = null; 107 108 /*** The encapsulated xmlrpc server. */ 109 private XmlRpcServer server = null; 110 111 /*** The xmlrpc client. */ 112 private XmlRpcClient client = null; 113 114 /*** The port to listen on. */ 115 private int port = 0; 116 117 /*** 118 * This function initializes the XmlRpcService. 119 */ 120 public void init(ServletConfig config) throws InitializationException 121 { 122 try 123 { 124 server = new XmlRpcServer(); 125 126 // Set the port for the service 127 port = getConfiguration().getInt("port", 0); 128 129 if(port != 0) 130 { 131 if (getConfiguration().getBoolean("secure.server", false)) 132 { 133 // Get the values for the JSSE system properties 134 // that we must set for use in the SecureWebServer 135 // and the URL https connection handler that is 136 // used in XmlRpcClient. 137 138 Configuration secureServerOptions = 139 getConfiguration().subset("secure.server.option"); 140 141 Iterator i = secureServerOptions.getKeys(); 142 143 while (i.hasNext()) 144 { 145 String option = (String) i.next(); 146 String value = secureServerOptions.getString(option); 147 148 Log.debug("JSSE option: " + option + " => " + value); 149 150 System.setProperty(option, value); 151 } 152 153 webserver = new SecureWebServer(port); 154 } 155 else 156 { 157 webserver = new WebServer(port); 158 } 159 } 160 161 // Set the XML driver to the correct SAX parser class 162 String saxParserClass = getConfiguration().getString("parser", 163 "org.apache.xerces.parsers.SAXParser"); 164 165 XmlRpc.setDriver ( saxParserClass ); 166 167 // Check if there are any handlers to register at startup 168 Iterator keys = getConfiguration().getKeys("handler"); 169 while ( keys.hasNext() ) 170 { 171 String handler = (String)keys.next(); 172 String handlerName = handler.substring(handler.indexOf(".")+1); 173 String handlerClass = getConfiguration().getString(handler); 174 registerHandler(handlerName, handlerClass); 175 } 176 177 /* 178 * Turn on paranoia for the webserver if requested. 179 */ 180 boolean stateOfParanoia = getConfiguration().getBoolean("paranoid", false); 181 182 if (stateOfParanoia) 183 { 184 webserver.setParanoid(stateOfParanoia); 185 Log.info(XmlRpcService.SERVICE_NAME + 186 ": Operating in a state of paranoia"); 187 188 /* 189 * Only set the accept/deny client lists if we 190 * are in a state of paranoia as they will just 191 * be ignored so there's no point in setting them. 192 */ 193 194 /* 195 * Set the list of clients that can connect 196 * to the xmlrpc server. The accepted client list 197 * will only be consulted if we are paranoid. 198 */ 199 Vector acceptedClients = getConfiguration().getVector("acceptClient"); 200 201 for (int i = 0; i < acceptedClients.size(); i++) 202 { 203 String acceptClient = (String) acceptedClients.get(i); 204 205 if (acceptClient != null && ! acceptClient.equals("")) 206 { 207 webserver.acceptClient(acceptClient); 208 Log.info(XmlRpcService.SERVICE_NAME + 209 ": Accepting client -> " + acceptClient); 210 } 211 } 212 213 /* 214 * Set the list of clients that can connect 215 * to the xmlrpc server. The denied client list 216 * will only be consulted if we are paranoid. 217 */ 218 Vector deniedClients = getConfiguration().getVector("denyClient"); 219 220 for (int i = 0; i < deniedClients.size(); i++) 221 { 222 String denyClient = (String) deniedClients.get(i); 223 224 if (denyClient != null && ! denyClient.equals("")) 225 { 226 webserver.denyClient(denyClient); 227 Log.info(XmlRpcService.SERVICE_NAME + 228 ": Denying client -> " + denyClient); 229 } 230 } 231 } 232 } 233 catch (Exception e) 234 { 235 throw new InitializationException 236 ("XMLRPCService failed to initialize", e); 237 } 238 239 setInit(true); 240 } 241 242 /*** 243 * Register an Object as a default handler for the service. 244 * 245 * @param handler The handler to use. 246 * @exception XmlRpcException. 247 * @exception IOException. 248 */ 249 public void registerHandler(Object handler) 250 throws XmlRpcException, 251 IOException 252 { 253 registerHandler("$default", handler); 254 } 255 256 /*** 257 * Register an Object as a handler for the service. 258 * 259 * @param handlerName The name the handler is registered under. 260 * @param handler The handler to use. 261 * @exception XmlRpcException. 262 * @exception IOException. 263 */ 264 public void registerHandler(String handlerName, 265 Object handler) 266 throws XmlRpcException, 267 IOException 268 { 269 if(webserver != null) 270 { 271 webserver.addHandler(handlerName, handler); 272 } 273 274 server.addHandler(handlerName, handler); 275 } 276 277 /*** 278 * A helper method that tries to initialize a handler and register it. 279 * The purpose is to check for all the exceptions that may occur in 280 * dynamic class loading and throw an InitializationException on 281 * error. 282 * 283 * @param handlerName The name the handler is registered under. 284 * @param handlerClass The name of the class to use as a handler. 285 * @exception TurbineException Couldn't instantiate handler. 286 */ 287 public void registerHandler(String handlerName, String handlerClass) 288 throws TurbineException 289 { 290 try 291 { 292 Object handler = Class.forName(handlerClass).newInstance(); 293 294 if(webserver != null) 295 { 296 webserver.addHandler(handlerName,handler); 297 } 298 299 server.addHandler(handlerName,handler); 300 } 301 // those two errors must be passed to the VM 302 catch( ThreadDeath t ) 303 { 304 throw t; 305 } 306 catch( OutOfMemoryError t ) 307 { 308 throw t; 309 } 310 311 catch( Throwable t ) 312 { 313 throw new TurbineException 314 ("Failed to instantiate " + handlerClass, t); 315 } 316 } 317 318 /*** 319 * Unregister a handler. 320 * 321 * @param handlerName The name of the handler to unregister. 322 */ 323 public void unregisterHandler(String handlerName) 324 { 325 if(webserver != null) 326 { 327 webserver.removeHandler(handlerName); 328 } 329 330 server.removeHandler(handlerName); 331 } 332 333 /*** 334 * Handle an XML-RPC request using the encapsulated server. 335 * 336 * You can use this method to handle a request from within 337 * a Turbine screen. 338 * 339 * @param is the stream to read request data from. 340 * @return the response body that needs to be sent to the client. 341 */ 342 public byte[] handleRequest(InputStream is) 343 { 344 return server.execute(is); 345 } 346 347 /*** 348 * Handle an XML-RPC request using the encapsulated server with user 349 * authentication. 350 * 351 * You can use this method to handle a request from within 352 * a Turbine screen. 353 * 354 * <p> Note that the handlers need to implement AuthenticatedXmlRpcHandler 355 * interface to access the authentication infomration. 356 * 357 * @param is the stream to read request data from. 358 * @param user the user that is making the request. 359 * @param password the password given by user. 360 * @return the response body that needs to be sent to the client. 361 */ 362 public byte[] handleRequest(InputStream is, String user, String password) 363 { 364 return server.execute(is, user, password); 365 } 366 367 /*** 368 * Client's interface to XML-RPC. 369 * 370 * The return type is Object which you'll need to cast to 371 * whatever you are expecting. 372 * 373 * @param url A URL. 374 * @param methodName A String with the method name. 375 * @param params A Vector with the parameters. 376 * @return An Object. 377 * @exception XmlRpcException. 378 * @exception IOException. 379 */ 380 public Object executeRpc(URL url, 381 String methodName, 382 Vector params) 383 throws TurbineException 384 { 385 try 386 { 387 XmlRpcClient client = new XmlRpcClient ( url ); 388 return client.execute(methodName, params); 389 } 390 catch (Exception e) 391 { 392 throw new TurbineException("XML-RPC call failed", e); 393 } 394 } 395 396 /*** 397 * Client's Authenticated interface to XML-RPC. 398 * 399 * The return type is Object which you'll need to cast to 400 * whatever you are expecting. 401 * 402 * @param url A URL. 403 * @param username The username to try and authenticate with 404 * @param password The password to try and authenticate with 405 * @param methodName A String with the method name. 406 * @param params A Vector with the parameters. 407 * @return An Object. 408 * @exception XmlRpcException. 409 * @exception IOException. 410 */ 411 public Object executeAuthenticatedRpc(URL url, 412 String username, 413 String password, 414 String methodName, 415 Vector params) 416 throws TurbineException 417 { 418 try 419 { 420 XmlRpcClient client = new XmlRpcClient ( url ); 421 client.setBasicAuthentication(username, password); 422 return client.execute(methodName, params); 423 } 424 catch (Exception e) 425 { 426 throw new TurbineException("XML-RPC call failed", e); 427 } 428 } 429 430 /*** 431 * Method to allow a client to send a file to a server. 432 * 433 * @param serverURL 434 * @param sourceLocationProperty 435 * @param sourceFileName 436 * @param destinationLocationProperty 437 * @param destinationFileName 438 */ 439 public void send(String serverURL, 440 String sourceLocationProperty, 441 String sourceFileName, 442 String destinationLocationProperty, 443 String destinationFileName) 444 throws Exception 445 { 446 FileTransfer.send(serverURL, 447 sourceLocationProperty, 448 sourceFileName, 449 destinationLocationProperty, 450 destinationFileName); 451 } 452 453 /*** 454 * Method to allow a client to send a file to a server that 455 * requires authentication 456 * 457 * @param serverURL 458 * @param username 459 * @param password 460 * @param sourceLocationProperty 461 * @param sourceFileName 462 * @param destinationLocationProperty 463 * @param destinationFileName 464 */ 465 public void send(String serverURL, 466 String username, 467 String password, 468 String sourceLocationProperty, 469 String sourceFileName, 470 String destinationLocationProperty, 471 String destinationFileName) 472 throws Exception 473 { 474 FileTransfer.send(serverURL, 475 username, 476 password, 477 sourceLocationProperty, 478 sourceFileName, 479 destinationLocationProperty, 480 destinationFileName); 481 } 482 483 /*** 484 * Method to allow a client to get a file to a server. 485 * 486 * @param serverURL 487 * @param sourceLocationProperty 488 * @param sourceFileName 489 * @param destinationLocationProperty 490 * @param destinationFileName 491 */ 492 public void get(String serverURL, 493 String sourceLocationProperty, 494 String sourceFileName, 495 String destinationLocationProperty, 496 String destinationFileName) 497 throws Exception 498 { 499 FileTransfer.get(serverURL, 500 sourceLocationProperty, 501 sourceFileName, 502 destinationLocationProperty, 503 destinationFileName); 504 } 505 506 /*** 507 * Method to allow a client to get a file from a server that 508 * requires authentication. 509 * 510 * @param serverURL 511 * @param username 512 * @param password 513 * @param sourceLocationProperty 514 * @param sourceFileName 515 * @param destinationLocationProperty 516 * @param destinationFileName 517 */ 518 public void get(String serverURL, 519 String username, 520 String password, 521 String sourceLocationProperty, 522 String sourceFileName, 523 String destinationLocationProperty, 524 String destinationFileName) 525 throws Exception 526 { 527 FileTransfer.get(serverURL, 528 username, 529 password, 530 sourceLocationProperty, 531 sourceFileName, 532 destinationLocationProperty, 533 destinationFileName); 534 } 535 536 /*** 537 * Method to allow a client to remove a file from 538 * the server 539 * 540 * @param serverURL 541 * @param sourceLocationProperty 542 * @param sourceFileName 543 */ 544 public void remove(String serverURL, 545 String sourceLocationProperty, 546 String sourceFileName) 547 throws Exception 548 { 549 FileTransfer.remove(serverURL, 550 sourceLocationProperty, 551 sourceFileName); 552 } 553 554 /*** 555 * Method to allow a client to remove a file from 556 * a server that requires authentication. 557 * 558 * @param serverURL 559 * @param username 560 * @param password 561 * @param sourceLocationProperty 562 * @param sourceFileName 563 */ 564 public void remove(String serverURL, 565 String username, 566 String password, 567 String sourceLocationProperty, 568 String sourceFileName) 569 throws Exception 570 { 571 FileTransfer.remove(serverURL, 572 username, 573 password, 574 sourceLocationProperty, 575 sourceFileName); 576 } 577 578 /*** 579 * Switch client filtering on/off. 580 * 581 * @param state Whether to filter clients. 582 * 583 * @see #acceptClient(java.lang.String) 584 * @see #denyClient(java.lang.String) 585 */ 586 public void setParanoid(boolean state) 587 { 588 webserver.setParanoid(state); 589 } 590 591 /*** 592 * Add an IP address to the list of accepted clients. The parameter can 593 * contain '*' as wildcard character, e.g. "192.168.*.*". You must 594 * call setParanoid(true) in order for this to have 595 * any effect. 596 * 597 * @param address The address to add to the list. 598 * 599 * @see #denyClient(java.lang.String) 600 * @see #setParanoid(boolean) 601 */ 602 public void acceptClient(String address) 603 { 604 webserver.acceptClient(address); 605 } 606 607 /*** 608 * Add an IP address to the list of denied clients. The parameter can 609 * contain '*' as wildcard character, e.g. "192.168.*.*". You must call 610 * setParanoid(true) in order for this to have any effect. 611 * 612 * @param address The address to add to the list. 613 * 614 * @see #acceptClient(java.lang.String) 615 * @see #setParanoid(boolean) 616 */ 617 public void denyClient(String address) 618 { 619 webserver.denyClient(address); 620 } 621 622 /*** 623 * Shuts down this service, stopping running threads. 624 */ 625 public void shutdown() 626 { 627 // Stop the XML RPC server. helma.xmlrpc.WebServer blocks in a call to 628 // ServerSocket.accept() until a socket connection is made. 629 webserver.shutdown(); 630 try 631 { 632 Socket interrupt = new Socket(InetAddress.getLocalHost(), port); 633 interrupt.close(); 634 } 635 catch (Exception ignored) 636 { 637 // Remotely possible we're leaving an open listener socket around. 638 } 639 640 setInit(false); 641 } 642 }

This page was automatically generated by Maven