Coverage report

  %line %branch
org.apache.turbine.services.xmlrpc.TurbineXmlRpcService
0% 
0% 

 1  
 package org.apache.turbine.services.xmlrpc;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2005 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.io.InputStream;
 20  
 import java.net.InetAddress;
 21  
 import java.net.Socket;
 22  
 import java.net.URL;
 23  
 import java.net.UnknownHostException;
 24  
 import java.util.Iterator;
 25  
 import java.util.List;
 26  
 import java.util.Vector;
 27  
 
 28  
 import javax.servlet.ServletConfig;
 29  
 
 30  
 import org.apache.commons.configuration.Configuration;
 31  
 import org.apache.commons.lang.StringUtils;
 32  
 import org.apache.commons.logging.Log;
 33  
 import org.apache.commons.logging.LogFactory;
 34  
 import org.apache.turbine.services.InitializationException;
 35  
 import org.apache.turbine.services.TurbineBaseService;
 36  
 import org.apache.turbine.services.xmlrpc.util.FileTransfer;
 37  
 import org.apache.turbine.util.TurbineException;
 38  
 import org.apache.xmlrpc.WebServer;
 39  
 import org.apache.xmlrpc.XmlRpc;
 40  
 import org.apache.xmlrpc.XmlRpcClient;
 41  
 import org.apache.xmlrpc.XmlRpcServer;
 42  
 import org.apache.xmlrpc.secure.SecureWebServer;
 43  
 
 44  
 /**
 45  
  * This is a service which will make an xml-rpc call to a remote
 46  
  * server.
 47  
  *
 48  
  * Here's an example of how it would be done:
 49  
  * <blockquote><code><pre>
 50  
  * XmlRpcService xs =
 51  
  *   (XmlRpcService)TurbineServices.getInstance()
 52  
  *   .getService(XmlRpcService.XMLRPC_SERVICE_NAME);
 53  
  * Vector vec = new Vector();
 54  
  * vec.addElement(new Integer(5));
 55  
  * URL url = new URL("http://betty.userland.com/RPC2");
 56  
  * String name = (String)xs.executeRpc(url, "examples.getStateName", vec);
 57  
  * </pre></code></blockquote>
 58  
  *
 59  
  * <p>TODO: Handle XmlRpc.setDebug(boolean)</p>
 60  
  *
 61  
  * @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a>
 62  
  * @author <a href="mailto:magnus@handtolvur.is">Magnús Þór Torfason</a>
 63  
  * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
 64  
  * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
 65  
  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 66  
  * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
 67  
  * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
 68  
  * @version $Id: TurbineXmlRpcService.java 280020 2005-09-10 17:11:01Z henning $
 69  
  */
 70  0
 public class TurbineXmlRpcService
 71  
         extends TurbineBaseService
 72  
         implements XmlRpcService
 73  
 {
 74  
     /** Logging */
 75  0
     private static Log log = LogFactory.getLog(TurbineXmlRpcService.class);
 76  
 
 77  
     /**
 78  
      * Whether a version of Apache's XML-RPC library greater than 1.1
 79  
      * is available.
 80  
      */
 81  0
     protected boolean isModernVersion = false;
 82  
 
 83  
     /** The standalone xmlrpc server. */
 84  0
     protected WebServer webserver = null;
 85  
 
 86  
     /** The encapsulated xmlrpc server. */
 87  0
     protected XmlRpcServer server = null;
 88  
 
 89  
     /**
 90  
      * The address to listen on.  The default of <code>null</code>
 91  
      * indicates all network interfaces on a multi-homed host.
 92  
      */
 93  0
     private InetAddress address = null;
 94  
 
 95  
     /** The port to listen on. */
 96  0
     protected int port = 0;
 97  
 
 98  
     /**
 99  
      * This function initializes the XmlRpcService.This is
 100  
      * a zero parameter variant which queries the Turbine Servlet
 101  
      * for its config.
 102  
      *
 103  
      * @throws InitializationException Something went wrong in the init
 104  
      *         stage
 105  
      */
 106  
     public void init()
 107  
             throws InitializationException
 108  
     {
 109  0
         Configuration conf = getConfiguration();
 110  
 
 111  
         try
 112  
         {
 113  0
             server = new XmlRpcServer();
 114  
 
 115  
             // setup JSSE System properties from secure.server.options
 116  0
             Configuration secureServerOptions =
 117  
                     conf.subset("secure.server.option");
 118  
 
 119  0
             if (secureServerOptions != null)
 120  
             {
 121  0
                 setSystemPropertiesFromConfiguration(secureServerOptions);
 122  
             }
 123  
 
 124  
             // Host and port information for the WebServer
 125  0
             String addr = conf.getString("address", "0.0.0.0");
 126  0
             port = conf.getInt("port", 0);
 127  
 
 128  0
             if (port != 0)
 129  
             {
 130  0
                 if (addr != null && addr.length() > 0)
 131  
                 {
 132  
                     try
 133  
                     {
 134  0
                         address = InetAddress.getByName(addr);
 135  
                     }
 136  0
                     catch (UnknownHostException useDefault)
 137  
                     {
 138  0
                         address = null;
 139  0
                     }
 140  
                 }
 141  
 
 142  0
                 log.debug("Port: " + port + ", Address: " + address);
 143  
 
 144  0
                 if (conf.getBoolean("secure.server", false))
 145  
                 {
 146  0
                     webserver = new SecureWebServer(port, address);
 147  
                 }
 148  
                 else
 149  
                 {
 150  0
                     webserver = new WebServer(port, address);
 151  
                 }
 152  
             }
 153  
 
 154  
             // Set the XML driver to the correct SAX parser class
 155  0
             String saxParserClass =
 156  
                     conf.getString("parser", null);
 157  
 
 158  0
             if (saxParserClass != null)
 159  
             {
 160  0
                 XmlRpc.setDriver(saxParserClass);
 161  
             }
 162  
 
 163  
             // Check if there are any handlers to register at startup
 164  0
             for (Iterator keys = conf.getKeys("handler"); keys.hasNext();)
 165  
             {
 166  0
                 String handler      = (String) keys.next();
 167  0
                 String handlerName  = handler.substring(handler.indexOf('.')+1);
 168  0
                 String handlerClass = conf.getString(handler);
 169  
 
 170  0
                 log.debug("Found Handler " + handler + " as " + handlerName + " / " + handlerClass);
 171  
 
 172  0
                 registerHandler(handlerName, handlerClass);
 173  
             }
 174  
 
 175  
             // Turn on paranoia for the webserver if requested.
 176  0
             boolean stateOfParanoia =
 177  
                     conf.getBoolean("paranoid", false);
 178  
 
 179  0
             if (stateOfParanoia)
 180  
             {
 181  0
                 webserver.setParanoid(stateOfParanoia);
 182  0
                 log.info(XmlRpcService.SERVICE_NAME +
 183  
                         ": Operating in a state of paranoia");
 184  
 
 185  
                 // Only set the accept/deny client lists if we
 186  
                 // are in a state of paranoia as they will just
 187  
                 // be ignored so there's no point in setting them.
 188  
 
 189  
                 // Set the list of clients that can connect
 190  
                 // to the xmlrpc server. The accepted client list
 191  
                 // will only be consulted if we are paranoid.
 192  0
                 List acceptedClients =
 193  
                         conf.getList("acceptClient");
 194  
 
 195  0
                 for (int i = 0; i < acceptedClients.size(); i++)
 196  
                 {
 197  0
                     String acceptClient = (String) acceptedClients.get(i);
 198  
 
 199  0
                     if (StringUtils.isNotEmpty(acceptClient))
 200  
                     {
 201  0
                         webserver.acceptClient(acceptClient);
 202  0
                         log.info(XmlRpcService.SERVICE_NAME +
 203  
                                 ": Accepting client -> " + acceptClient);
 204  
                     }
 205  
                 }
 206  
 
 207  
                 // Set the list of clients that can connect
 208  
                 // to the xmlrpc server. The denied client list
 209  
                 // will only be consulted if we are paranoid.
 210  0
                 List deniedClients = conf.getList("denyClient");
 211  
 
 212  0
                 for (int i = 0; i < deniedClients.size(); i++)
 213  
                 {
 214  0
                     String denyClient = (String) deniedClients.get(i);
 215  
 
 216  0
                     if (StringUtils.isNotEmpty(denyClient))
 217  
                     {
 218  0
                         webserver.denyClient(denyClient);
 219  0
                         log.info(XmlRpcService.SERVICE_NAME +
 220  
                                 ": Denying client -> " + denyClient);
 221  
                     }
 222  
                 }
 223  
             }
 224  
             // If we have a XML-RPC JAR whose version is greater than the
 225  
             // 1.1 series, the WebServer must be explicitly start()'d.
 226  
             try
 227  
             {
 228  0
                 Class.forName("org.apache.xmlrpc.XmlRpcRequest");
 229  0
                 isModernVersion = true;
 230  0
                 webserver.start();
 231  
             }
 232  0
             catch (ClassNotFoundException ignored)
 233  
             {
 234  
                 // XmlRpcRequest does not exist in versions 1.1 and lower.
 235  
                 // Assume that our WebServer was already started.
 236  0
             }
 237  0
             log.debug(XmlRpcService.SERVICE_NAME + ": Using " +
 238  
                     "Apache XML-RPC version " +
 239  
                     (isModernVersion ?
 240  
                     "greater than 1.1" : "1.1 or lower"));
 241  
         }
 242  0
         catch (Exception e)
 243  
         {
 244  0
             String errorMessage = "XMLRPCService failed to initialize";
 245  0
             log.error(errorMessage, e);
 246  0
             throw new InitializationException(errorMessage, e);
 247  0
         }
 248  
 
 249  0
         setInit(true);
 250  0
     }
 251  
 
 252  
     /**
 253  
      * This function initializes the XmlRpcService.
 254  
      *
 255  
      * @deprecated Use init() instead.
 256  
      */
 257  
     public void init(ServletConfig config) throws InitializationException
 258  
     {
 259  0
         init();
 260  0
     }
 261  
 
 262  
     /**
 263  
      * Create System properties using the key-value pairs in a given
 264  
      * Configuration.  This is used to set system properties and the
 265  
      * URL https connection handler needed by JSSE to enable SSL
 266  
      * between XML-RPC client and server.
 267  
      *
 268  
      * @param configuration the Configuration defining the System
 269  
      * properties to be set
 270  
      */
 271  
     private void setSystemPropertiesFromConfiguration(Configuration configuration)
 272  
     {
 273  0
         for (Iterator i = configuration.getKeys(); i.hasNext();)
 274  
         {
 275  0
             String key = (String) i.next();
 276  0
             String value = configuration.getString(key);
 277  
 
 278  0
             log.debug("JSSE option: " + key + " => " + value);
 279  
 
 280  0
             System.setProperty(key, value);
 281  
         }
 282  0
     }
 283  
 
 284  
     /**
 285  
      * Register an Object as a default handler for the service.
 286  
      *
 287  
      * @param handler The handler to use.
 288  
      */
 289  
     public void registerHandler(Object handler)
 290  
     {
 291  0
         registerHandler("$default", handler);
 292  0
     }
 293  
 
 294  
     /**
 295  
      * Register an Object as a handler for the service.
 296  
      *
 297  
      * @param handlerName The name the handler is registered under.
 298  
      * @param handler The handler to use.
 299  
      */
 300  
     public void registerHandler(String handlerName,
 301  
                                 Object handler)
 302  
     {
 303  0
         if (webserver != null)
 304  
         {
 305  0
             webserver.addHandler(handlerName, handler);
 306  
         }
 307  
 
 308  0
         server.addHandler(handlerName, handler);
 309  
 
 310  0
         log.debug("Registered Handler " + handlerName + " as "
 311  
                 + handler.getClass().getName()
 312  
                 + ", Server: " + server
 313  
                 + ", Webserver: " + webserver);
 314  0
     }
 315  
 
 316  
     /**
 317  
      * A helper method that tries to initialize a handler and register it.
 318  
      * The purpose is to check for all the exceptions that may occur in
 319  
      * dynamic class loading and throw an InitializationException on
 320  
      * error.
 321  
      *
 322  
      * @param handlerName The name the handler is registered under.
 323  
      * @param handlerClass The name of the class to use as a handler.
 324  
      * @exception TurbineException Couldn't instantiate handler.
 325  
      */
 326  
     public void registerHandler(String handlerName, String handlerClass)
 327  
             throws TurbineException
 328  
     {
 329  
         try
 330  
         {
 331  0
             Object handler = Class.forName(handlerClass).newInstance();
 332  
 
 333  0
             if (webserver != null)
 334  
             {
 335  0
                 webserver.addHandler(handlerName, handler);
 336  
             }
 337  
 
 338  0
             server.addHandler(handlerName, handler);
 339  
         }
 340  
                 // those two errors must be passed to the VM
 341  0
         catch (ThreadDeath t)
 342  
         {
 343  0
             throw t;
 344  
         }
 345  0
         catch (OutOfMemoryError t)
 346  
         {
 347  0
             throw t;
 348  
         }
 349  
 
 350  0
         catch (Throwable t)
 351  
         {
 352  0
             throw new TurbineException
 353  
                     ("Failed to instantiate " + handlerClass, t);
 354  0
         }
 355  0
     }
 356  
 
 357  
     /**
 358  
      * Unregister a handler.
 359  
      *
 360  
      * @param handlerName The name of the handler to unregister.
 361  
      */
 362  
     public void unregisterHandler(String handlerName)
 363  
     {
 364  0
         if (webserver != null)
 365  
         {
 366  0
             webserver.removeHandler(handlerName);
 367  
         }
 368  
 
 369  0
         server.removeHandler(handlerName);
 370  0
     }
 371  
 
 372  
     /**
 373  
      * Handle an XML-RPC request using the encapsulated server.
 374  
      *
 375  
      * You can use this method to handle a request from within
 376  
      * a Turbine screen.
 377  
      *
 378  
      * @param is the stream to read request data from.
 379  
      * @return the response body that needs to be sent to the client.
 380  
      */
 381  
     public byte[] handleRequest(InputStream is)
 382  
     {
 383  0
         return server.execute(is);
 384  
     }
 385  
 
 386  
     /**
 387  
      * Handle an XML-RPC request using the encapsulated server with user
 388  
      * authentication.
 389  
      *
 390  
      * You can use this method to handle a request from within
 391  
      * a Turbine screen.
 392  
      *
 393  
      * <p> Note that the handlers need to implement AuthenticatedXmlRpcHandler
 394  
      * interface to access the authentication infomration.
 395  
      *
 396  
      * @param is the stream to read request data from.
 397  
      * @param user the user that is making the request.
 398  
      * @param password the password given by user.
 399  
      * @return the response body that needs to be sent to the client.
 400  
      */
 401  
     public byte[] handleRequest(InputStream is, String user, String password)
 402  
     {
 403  0
         return server.execute(is, user, password);
 404  
     }
 405  
 
 406  
     /**
 407  
      * Client's interface to XML-RPC.
 408  
      *
 409  
      * The return type is Object which you'll need to cast to
 410  
      * whatever you are expecting.
 411  
      *
 412  
      * @param url A URL.
 413  
      * @param methodName A String with the method name.
 414  
      * @param params A Vector with the parameters.
 415  
      * @return An Object.
 416  
      * @exception TurbineException
 417  
      */
 418  
     public Object executeRpc(URL url,
 419  
                              String methodName,
 420  
                              Vector params)
 421  
             throws TurbineException
 422  
     {
 423  
         try
 424  
         {
 425  0
             XmlRpcClient client = new XmlRpcClient(url);
 426  0
             return client.execute(methodName, params);
 427  
         }
 428  0
         catch (Exception e)
 429  
         {
 430  0
             throw new TurbineException("XML-RPC call failed", e);
 431  
         }
 432  
     }
 433  
 
 434  
     /**
 435  
      * Client's Authenticated interface to XML-RPC.
 436  
      *
 437  
      * The return type is Object which you'll need to cast to
 438  
      * whatever you are expecting.
 439  
      *
 440  
      * @param url A URL.
 441  
      * @param username The username to try and authenticate with
 442  
      * @param password The password to try and authenticate with
 443  
      * @param methodName A String with the method name.
 444  
      * @param params A Vector with the parameters.
 445  
      * @return An Object.
 446  
      * @throws TurbineException
 447  
      */
 448  
     public Object executeAuthenticatedRpc(URL url,
 449  
                                           String username,
 450  
                                           String password,
 451  
                                           String methodName,
 452  
                                           Vector params)
 453  
             throws TurbineException
 454  
     {
 455  
         try
 456  
         {
 457  0
             XmlRpcClient client = new XmlRpcClient(url);
 458  0
             client.setBasicAuthentication(username, password);
 459  0
             return client.execute(methodName, params);
 460  
         }
 461  0
         catch (Exception e)
 462  
         {
 463  0
             throw new TurbineException("XML-RPC call failed", e);
 464  
         }
 465  
     }
 466  
 
 467  
     /**
 468  
      * Method to allow a client to send a file to a server.
 469  
      *
 470  
      * @param serverURL
 471  
      * @param sourceLocationProperty
 472  
      * @param sourceFileName
 473  
      * @param destinationLocationProperty
 474  
      * @param destinationFileName
 475  
      * @deprecated This is not scope of the Service itself but of an
 476  
      *             application which uses the service.
 477  
      */
 478  
     public void send(String serverURL,
 479  
                      String sourceLocationProperty,
 480  
                      String sourceFileName,
 481  
                      String destinationLocationProperty,
 482  
                      String destinationFileName)
 483  
             throws TurbineException
 484  
     {
 485  0
         FileTransfer.send(serverURL,
 486  
                 sourceLocationProperty,
 487  
                 sourceFileName,
 488  
                 destinationLocationProperty,
 489  
                 destinationFileName);
 490  0
     }
 491  
 
 492  
     /**
 493  
      * Method to allow a client to send a file to a server that
 494  
      * requires authentication
 495  
      *
 496  
      * @param serverURL
 497  
      * @param username
 498  
      * @param password
 499  
      * @param sourceLocationProperty
 500  
      * @param sourceFileName
 501  
      * @param destinationLocationProperty
 502  
      * @param destinationFileName
 503  
      * @deprecated This is not scope of the Service itself but of an
 504  
      *             application which uses the service.
 505  
      */
 506  
     public void send(String serverURL,
 507  
                      String username,
 508  
                      String password,
 509  
                      String sourceLocationProperty,
 510  
                      String sourceFileName,
 511  
                      String destinationLocationProperty,
 512  
                      String destinationFileName)
 513  
             throws TurbineException
 514  
     {
 515  0
         FileTransfer.send(serverURL,
 516  
                 username,
 517  
                 password,
 518  
                 sourceLocationProperty,
 519  
                 sourceFileName,
 520  
                 destinationLocationProperty,
 521  
                 destinationFileName);
 522  0
     }
 523  
 
 524  
     /**
 525  
      * Method to allow a client to get a file from a server.
 526  
      *
 527  
      * @param serverURL
 528  
      * @param sourceLocationProperty
 529  
      * @param sourceFileName
 530  
      * @param destinationLocationProperty
 531  
      * @param destinationFileName
 532  
      * @deprecated This is not scope of the Service itself but of an
 533  
      *             application which uses the service.
 534  
      */
 535  
     public void get(String serverURL,
 536  
                     String sourceLocationProperty,
 537  
                     String sourceFileName,
 538  
                     String destinationLocationProperty,
 539  
                     String destinationFileName)
 540  
             throws TurbineException
 541  
     {
 542  0
         FileTransfer.get(serverURL,
 543  
                 sourceLocationProperty,
 544  
                 sourceFileName,
 545  
                 destinationLocationProperty,
 546  
                 destinationFileName);
 547  0
     }
 548  
 
 549  
     /**
 550  
      * Method to allow a client to get a file from a server that
 551  
      * requires authentication.
 552  
      *
 553  
      * @param serverURL
 554  
      * @param username
 555  
      * @param password
 556  
      * @param sourceLocationProperty
 557  
      * @param sourceFileName
 558  
      * @param destinationLocationProperty
 559  
      * @param destinationFileName
 560  
      * @deprecated This is not scope of the Service itself but of an
 561  
      *             application which uses the service.
 562  
      */
 563  
     public void get(String serverURL,
 564  
                     String username,
 565  
                     String password,
 566  
                     String sourceLocationProperty,
 567  
                     String sourceFileName,
 568  
                     String destinationLocationProperty,
 569  
                     String destinationFileName)
 570  
             throws TurbineException
 571  
     {
 572  0
         FileTransfer.get(serverURL,
 573  
                 username,
 574  
                 password,
 575  
                 sourceLocationProperty,
 576  
                 sourceFileName,
 577  
                 destinationLocationProperty,
 578  
                 destinationFileName);
 579  0
     }
 580  
 
 581  
     /**
 582  
      * Method to allow a client to remove a file from
 583  
      * the server
 584  
      *
 585  
      * @param serverURL
 586  
      * @param sourceLocationProperty
 587  
      * @param sourceFileName
 588  
      * @deprecated This is not scope of the Service itself but of an
 589  
      *             application which uses the service.
 590  
      */
 591  
     public void remove(String serverURL,
 592  
                        String sourceLocationProperty,
 593  
                        String sourceFileName)
 594  
             throws TurbineException
 595  
     {
 596  0
         FileTransfer.remove(serverURL,
 597  
                 sourceLocationProperty,
 598  
                 sourceFileName);
 599  0
     }
 600  
 
 601  
     /**
 602  
      * Method to allow a client to remove a file from
 603  
      * a server that requires authentication.
 604  
      *
 605  
      * @param serverURL
 606  
      * @param username
 607  
      * @param password
 608  
      * @param sourceLocationProperty
 609  
      * @param sourceFileName
 610  
      * @deprecated This is not scope of the Service itself but of an
 611  
      *             application which uses the service.
 612  
      */
 613  
     public void remove(String serverURL,
 614  
                        String username,
 615  
                        String password,
 616  
                        String sourceLocationProperty,
 617  
                        String sourceFileName)
 618  
             throws TurbineException
 619  
     {
 620  0
         FileTransfer.remove(serverURL,
 621  
                 username,
 622  
                 password,
 623  
                 sourceLocationProperty,
 624  
                 sourceFileName);
 625  0
     }
 626  
 
 627  
     /**
 628  
      * Switch client filtering on/off.
 629  
      *
 630  
      * @param state Whether to filter clients.
 631  
      *
 632  
      * @see #acceptClient(java.lang.String)
 633  
      * @see #denyClient(java.lang.String)
 634  
      */
 635  
     public void setParanoid(boolean state)
 636  
     {
 637  0
         webserver.setParanoid(state);
 638  0
     }
 639  
 
 640  
     /**
 641  
      * Add an IP address to the list of accepted clients. The parameter can
 642  
      * contain '*' as wildcard character, e.g. "192.168.*.*". You must
 643  
      * call setParanoid(true) in order for this to have
 644  
      * any effect.
 645  
      *
 646  
      * @param address The address to add to the list.
 647  
      *
 648  
      * @see #denyClient(java.lang.String)
 649  
      * @see #setParanoid(boolean)
 650  
      */
 651  
     public void acceptClient(String address)
 652  
     {
 653  0
         webserver.acceptClient(address);
 654  0
     }
 655  
 
 656  
     /**
 657  
      * Add an IP address to the list of denied clients. The parameter can
 658  
      * contain '*' as wildcard character, e.g. "192.168.*.*". You must call
 659  
      * setParanoid(true) in order for this to have any effect.
 660  
      *
 661  
      * @param address The address to add to the list.
 662  
      *
 663  
      * @see #acceptClient(java.lang.String)
 664  
      * @see #setParanoid(boolean)
 665  
      */
 666  
     public void denyClient(String address)
 667  
     {
 668  0
         webserver.denyClient(address);
 669  0
     }
 670  
 
 671  
     /**
 672  
      * Shuts down this service, stopping running threads.
 673  
      */
 674  
     public void shutdown()
 675  
     {
 676  
         // Stop the XML RPC server.
 677  0
         webserver.shutdown();
 678  
 
 679  0
         if (!isModernVersion)
 680  
         {
 681  
             // org.apache.xmlrpc.WebServer used to block in a call to
 682  
             // ServerSocket.accept() until a socket connection was made.
 683  
             try
 684  
             {
 685  0
                 Socket interrupt = new Socket(address, port);
 686  0
                 interrupt.close();
 687  
             }
 688  0
             catch (Exception notShutdown)
 689  
             {
 690  
                 // It's remotely possible we're leaving an open listener
 691  
                 // socket around.
 692  0
                 log.warn(XmlRpcService.SERVICE_NAME +
 693  
                         "It's possible the xmlrpc server was not " +
 694  
                         "shutdown: " + notShutdown.getMessage());
 695  0
             }
 696  
         }
 697  
 
 698  0
         setInit(false);
 699  0
     }
 700  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.