1 16 17 18 package org.apache.xmlrpc; 19 20 import java.io.IOException ; 21 import java.net.MalformedURLException ; 22 import java.net.URL ; 23 import java.util.EmptyStackException ; 24 import java.util.Stack ; 25 import java.util.Vector ; 26 27 38 public class XmlRpcClient implements XmlRpcHandler 39 { 40 protected URL url; 41 42 private String storedUser; 44 private String storedPassword; 45 46 protected Stack pool = new Stack (); 48 protected int workers = 0; 49 protected int asyncWorkers = 0; 50 protected XmlRpcTransportFactory transportFactory; 51 52 private CallData first, last; 54 55 59 private int maxThreads = -1; 60 61 62 66 public XmlRpcClient(URL url, XmlRpcTransportFactory transportFactory) 67 { 68 this.url = url; 69 this.transportFactory = transportFactory; 70 } 71 72 75 public XmlRpcClient(URL url) 76 { 77 this.url = url; 78 if (XmlRpc.debug) 79 { 80 System.out.println("Created client to url space " + url); 81 } 82 } 83 84 87 public XmlRpcClient(String url) throws MalformedURLException 88 { 89 this(new URL (url)); 90 } 91 92 95 public XmlRpcClient(String hostname, int port) throws MalformedURLException 96 { 97 this(new URL ("http://" + hostname + ':' + port + "/RPC2")); 98 } 99 100 103 public void setMaxThreads(int maxThreads) 104 { 105 this.maxThreads = maxThreads; 106 } 107 108 111 public int getMaxThreads() 112 { 113 if (maxThreads == -1) 114 return (XmlRpc.getMaxThreads()); 115 116 return (maxThreads); 117 } 118 119 122 public URL getURL() 123 { 124 return url; 125 } 126 127 143 public void setBasicAuthentication(String user, String password) 144 { 145 150 storedUser = user; 151 storedPassword = password; 152 } 153 154 162 public Object execute(String method, Vector params) 163 throws XmlRpcException, IOException 164 { 165 169 if ((storedUser != null) && (storedPassword != null) && (transportFactory == null)) 170 { 171 DefaultXmlRpcTransport transport = createDefaultTransport(); 172 transport.setBasicAuthentication(storedUser, storedPassword); 173 return execute(new XmlRpcRequest(method, params), transport); 174 } 175 else 176 { 177 return execute(new XmlRpcRequest(method, params)); 178 } 179 } 180 181 public Object execute(XmlRpcClientRequest request) 182 throws XmlRpcException, IOException 183 { 184 return execute(request, createTransport()); 185 } 186 187 public Object execute(XmlRpcClientRequest request, XmlRpcTransport transport) 188 throws XmlRpcException, IOException 189 { 190 XmlRpcClientWorker worker = getWorker(false); 191 try 192 { 193 Object retval = worker.execute(request, transport); 194 return retval; 195 } 196 finally 197 { 198 releaseWorker(worker, false); 199 } 200 } 201 207 public void executeAsync(String method, Vector params, 208 AsyncCallback callback) 209 { 210 XmlRpcRequest request = new XmlRpcRequest(method, params); 211 if ((storedUser != null) && (storedPassword != null) && (transportFactory == null)) 212 { 213 DefaultXmlRpcTransport transport = createDefaultTransport(); 214 transport.setBasicAuthentication(storedUser, storedPassword); 215 executeAsync(request, callback, transport); 216 } 217 else 218 { 219 executeAsync(request, callback); 220 } 221 } 222 223 public void executeAsync(XmlRpcClientRequest request, 224 AsyncCallback callback) 225 { 226 executeAsync(request, callback, null); 227 } 228 229 public void executeAsync(XmlRpcClientRequest request, 230 AsyncCallback callback, XmlRpcTransport transport) 231 { 232 CallData call = new CallData(request, callback, transport); 233 234 if (asyncWorkers >= 4) 237 { 238 enqueue(call); 239 return; 240 } 241 XmlRpcClientWorker worker = null; 242 try 243 { 244 new XmlRpcClientAsyncThread(getWorker(true), call).start(); 245 } 246 catch(IOException iox) 247 { 248 enqueue(call); 250 } 251 } 252 253 class XmlRpcClientAsyncThread extends Thread 254 { 255 protected XmlRpcClientWorker worker; 256 protected CallData call; 257 258 protected XmlRpcClientAsyncThread(XmlRpcClientWorker worker, CallData initialCall) 259 { 260 this.worker = worker; 261 this.call = initialCall; 262 } 263 264 public void run() 265 { 266 try 267 { 268 while (call != null) 269 { 270 call = dequeue(); 271 executeAsync(call.request, call.callback, call.transport); 272 } 273 } 274 finally 275 { 276 releaseWorker(worker, true); 277 } 278 } 279 280 283 void executeAsync(XmlRpcClientRequest request, AsyncCallback callback, XmlRpcTransport transport) 284 { 285 Object res = null; 286 try 287 { 288 if (transport == null) 289 { 290 transport = createTransport(); 291 } 292 res = worker.execute(request, transport); 293 if (callback != null) 295 { 296 callback.handleResult(res, url, request.getMethodName()); 297 } 298 } 299 catch(Exception x) 300 { 301 if (callback != null) 302 { 303 try 304 { 305 callback.handleError(x, url, request.getMethodName()); 306 } 307 catch(Exception ignore) 308 { 309 } 310 } 311 } 312 } 313 } 314 320 synchronized XmlRpcClientWorker getWorker(boolean async) throws IOException 321 { 322 try 323 { 324 XmlRpcClientWorker w = (XmlRpcClientWorker) pool.pop(); 325 if (async) 326 { 327 asyncWorkers += 1; 328 } 329 else 330 { 331 workers += 1; 332 } 333 return w; 334 } 335 catch(EmptyStackException x) 336 { 337 if (workers < getMaxThreads()) 338 { 339 if (async) 340 { 341 asyncWorkers += 1; 342 } 343 else 344 { 345 workers += 1; 346 } 347 return new XmlRpcClientWorker(); 348 } 349 throw new IOException ("XML-RPC System overload"); 350 } 351 } 352 353 357 synchronized void releaseWorker(XmlRpcClientWorker w, boolean async) 358 { 359 if (pool.size() < 20) 360 { 361 pool.push(w); 362 } 363 if (async) 364 { 365 asyncWorkers -= 1; 366 } 367 else 368 { 369 workers -= 1; 370 } 371 } 372 373 379 synchronized void enqueue(CallData call) 380 { 381 if (last == null) 382 { 383 first = last = call; 384 } 385 else 386 { 387 last.next = call; 388 last = call; 389 } 390 } 391 392 396 synchronized CallData dequeue() 397 { 398 if (first == null) 399 { 400 return null; 401 } 402 CallData call = first; 403 if (first == last) 404 { 405 first = last = null; 406 } 407 else 408 { 409 first = first.next; 410 } 411 return call; 412 } 413 414 class CallData 415 { 416 XmlRpcClientRequest request; 417 XmlRpcTransport transport; 418 AsyncCallback callback; 419 CallData next; 420 421 425 public CallData(XmlRpcClientRequest request, AsyncCallback callback, XmlRpcTransport transport) 426 { 427 this.request = request; 428 this.callback = callback; 429 this.transport = transport; 430 this.next = null; 431 } 432 } 433 434 protected XmlRpcTransport createTransport() throws XmlRpcClientException 435 { 436 if (transportFactory == null) 437 { 438 return createDefaultTransport(); 439 } 440 return transportFactory.createTransport(); 441 } 442 443 private DefaultXmlRpcTransport createDefaultTransport() { 444 return new DefaultXmlRpcTransport(url); 445 } 446 447 450 public static void main(String args[]) throws Exception 451 { 452 try 455 { 456 String url = args[0]; 457 String method = args[1]; 458 Vector v = new Vector (); 459 for (int i = 2; i < args.length; i++) 460 { 461 try 462 { 463 v.addElement(new Integer (Integer.parseInt(args[i]))); 464 } 465 catch(NumberFormatException nfx) 466 { 467 v.addElement(args[i]); 468 } 469 } 470 XmlRpcClient client = new XmlRpcClient(url); 471 try 472 { 473 System.out.println(client.execute(method, v)); 474 } 475 catch(Exception ex) 476 { 477 System.err.println("Error: " + ex.getMessage()); 478 } 479 } 480 catch(Exception x) 481 { 482 System.err.println(x); 483 System.err.println("Usage: java org.apache.xmlrpc.XmlRpcClient " 484 + "<url> <method> <arg> ...."); 485 System.err.println("Arguments are sent as integers or strings."); 486 } 487 } 488 } 489 | Popular Tags |