Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 1999,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.greenpepper.shaded.org.apache.xmlrpc;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.EmptyStackException;
import java.util.Stack;
import java.util.Vector;
import java.util.TimeZone;
/**
* A multithreaded, reusable XML-RPC client object. Use this if you
* need a full-grown HTTP client (e.g. for Proxy and Basic Auth
* support). If you don't need that, XmlRpcClientLite may
* work better for you.
*
* @author Hannes Wallnoefer
* @author Andrew Evers
* @author Ryan Hoegg
* @version $Id: XmlRpcClient.java 350048 2005-11-30 21:49:32 +0100 (Mi, 30 Nov 2005) jochen $
*/
public class XmlRpcClient implements XmlRpcHandler
{
protected URL url;
// stored user and password for deprecated setBasicAuthentication method
private String storedUser;
private String storedPassword;
// pool of worker instances
protected Stack pool = new Stack();
protected int workers = 0;
protected int asyncWorkers = 0;
protected XmlRpcTransportFactory transportFactory;
// a queue of calls to be handled asynchronously
private CallData first, last;
/**
* The maximum number of threads which can be used concurrently, by defaut use the one defined
* in XmlRpc
*/
private int maxThreads = -1;
/**
* Construct a XML-RPC client with this URL and a specified transport
* factory.
*/
public XmlRpcClient(URL url, XmlRpcTransportFactory transportFactory)
{
this.url = url;
this.transportFactory = transportFactory;
}
/**
* Construct a XML-RPC client with this URL.
*/
public XmlRpcClient(URL url)
{
this.url = url;
if (XmlRpc.debug)
{
System.out.println("Created client to url space " + url);
}
}
/**
* Construct a XML-RPC client for the URL represented by this String.
*/
public XmlRpcClient(String url) throws MalformedURLException
{
this(new URL(url));
}
/**
* Construct a XML-RPC client for the specified hostname and port.
*/
public XmlRpcClient(String hostname, int port) throws MalformedURLException
{
this(new URL("http://" + hostname + ':' + port + "/RPC2"));
}
/**
* Set the MaxThreads for this Client
*/
public void setMaxThreads(int maxThreads)
{
this.maxThreads = maxThreads;
}
/**
* Get the MaxThreads for this Client
*/
public int getMaxThreads()
{
if (maxThreads == -1)
return (XmlRpc.getMaxThreads());
return (maxThreads);
}
/**
* Return the URL for this XML-RPC client.
*/
public URL getURL()
{
return url;
}
/**
* Sets Authentication for this client. This will be sent as Basic
* Authentication header to the server as described in
*
* http://www.ietf.org/rfc/rfc2617.txt.
*
* This method has been deprecated. Furthermore, it has no
* effect on the overloads for execute and executeAsync that
* use an XmlRpcClientRequest or an XmlRpcTransport.
*
* @deprecated Authentication is now handled by each XmlRpcTransport
*
* @see DefaultXmlRpcTransport
* @see LiteXmlRpcTransport
* @see CommonsXmlRpcTransport
*/
public void setBasicAuthentication(String user, String password)
{
/*
* Store for use in execute and executeAsync
*
* Will be unnecessary once this method is removed.
*/
storedUser = user;
storedPassword = password;
}
/**
* Generate an XML-RPC request and send it to the server. Parse the result
* and return the corresponding Java object.
*
* @exception XmlRpcException: If the remote host returned a fault message.
* @exception IOException: If the call could not be made because of lower
* level problems.
*/
public Object execute(String method, Vector params)
throws XmlRpcException, IOException
{
/* Setting user and password on transport if setBasicAuthentication was
* used and there is no XmlRpcTransportFactory. As setBasicAuthentication
* is deprecated, this should be removed in a future version.
*/
if ((storedUser != null) && (storedPassword != null) && (transportFactory == null))
{
DefaultXmlRpcTransport transport = createDefaultTransport();
transport.setBasicAuthentication(storedUser, storedPassword);
return execute(new XmlRpcRequest(method, params), transport);
}
else
{
return execute(new XmlRpcRequest(method, params));
}
}
public Object execute(XmlRpcClientRequest request)
throws XmlRpcException, IOException
{
return execute(request, createTransport());
}
public Object execute(XmlRpcClientRequest request, XmlRpcTransport transport)
throws XmlRpcException, IOException
{
XmlRpcClientWorker worker = getWorker(false);
try
{
Object retval = worker.execute(request, transport);
return retval;
}
finally
{
releaseWorker(worker, false);
}
}
/**
* Generate an XML-RPC request and send it to the server in a new thread.
* This method returns immediately.
* If the callback parameter is not null, it will be called later to handle
* the result or error when the call is finished.
*/
public void executeAsync(String method, Vector params,
AsyncCallback callback)
{
XmlRpcRequest request = new XmlRpcRequest(method, params);
if ((storedUser != null) && (storedPassword != null) && (transportFactory == null))
{
DefaultXmlRpcTransport transport = createDefaultTransport();
transport.setBasicAuthentication(storedUser, storedPassword);
executeAsync(request, callback, transport);
}
else
{
executeAsync(request, callback);
}
}
public void executeAsync(XmlRpcClientRequest request,
AsyncCallback callback)
{
executeAsync(request, callback, null);
}
public void executeAsync(XmlRpcClientRequest request,
AsyncCallback callback, XmlRpcTransport transport)
{
CallData call = new CallData(request, callback, transport);
// if at least 4 threads are running, don't create any new ones,
// just enqueue the request.
if (asyncWorkers >= 4)
{
enqueue(call);
return;
}
XmlRpcClientWorker worker = null;
try
{
new XmlRpcClientAsyncThread(getWorker(true), call).start();
}
catch(IOException iox)
{
// make a queued worker that doesn't run immediately
enqueue(call);
}
}
class XmlRpcClientAsyncThread extends Thread
{
protected XmlRpcClientWorker worker;
protected CallData call;
protected XmlRpcClientAsyncThread(XmlRpcClientWorker worker, CallData initialCall)
{
this.worker = worker;
this.call = initialCall;
}
public void run()
{
try
{
if (call == null)
call = dequeue();
while (call != null)
{
executeAsync(call.request, call.callback, call.transport);
call = dequeue();
}
}
finally
{
releaseWorker(worker, true);
}
}
/**
* Execute an XML-RPC call and handle asyncronous callback.
*/
void executeAsync(XmlRpcClientRequest request, AsyncCallback callback, XmlRpcTransport transport)
{
Object res = null;
try
{
if (transport == null)
{
transport = createTransport();
}
res = worker.execute(request, transport);
// notify callback object
if (callback != null)
{
callback.handleResult(res, url, request.getMethodName());
}
}
catch(Exception x)
{
if (callback != null)
{
try
{
callback.handleError(x, url, request.getMethodName());
}
catch(Exception ignore)
{
}
}
}
}
}
/**
*
* @param async
* @return
* @throws IOException
*/
synchronized XmlRpcClientWorker getWorker(boolean async) throws IOException
{
try
{
XmlRpcClientWorker w = (XmlRpcClientWorker) pool.pop();
if (async)
{
asyncWorkers += 1;
}
else
{
workers += 1;
}
return w;
}
catch(EmptyStackException x)
{
if (workers < getMaxThreads())
{
if (async)
{
asyncWorkers += 1;
}
else
{
workers += 1;
}
return new XmlRpcClientWorker(getTimeZone());
}
throw new IOException("XML-RPC System overload");
}
}
TimeZone tz;
public void setTimeZone(TimeZone z) {
tz = z;
}
public TimeZone getTimeZone() {
return tz;
}
/**
* Release possibly big per-call object references to allow them to be
* garbage collected
*/
synchronized void releaseWorker(XmlRpcClientWorker w, boolean async)
{
if (pool.size() < 20)
{
pool.push(w);
}
if (async)
{
asyncWorkers -= 1;
}
else
{
workers -= 1;
}
}
/**
*
* @param method
* @param params
* @param callback
*/
synchronized void enqueue(CallData call)
{
if (last == null)
{
first = last = call;
}
else
{
last.next = call;
last = call;
}
}
/**
*
* @return
*/
synchronized CallData dequeue()
{
if (first == null)
{
return null;
}
CallData call = first;
if (first == last)
{
first = last = null;
}
else
{
first = first.next;
}
return call;
}
class CallData
{
XmlRpcClientRequest request;
XmlRpcTransport transport;
AsyncCallback callback;
CallData next;
/**
* Make a call to be queued and then executed by the next free async
* thread
*/
public CallData(XmlRpcClientRequest request, AsyncCallback callback, XmlRpcTransport transport)
{
this.request = request;
this.callback = callback;
this.transport = transport;
this.next = null;
}
}
protected XmlRpcTransport createTransport() throws XmlRpcClientException
{
if (transportFactory == null)
{
return createDefaultTransport();
}
return transportFactory.createTransport();
}
private DefaultXmlRpcTransport createDefaultTransport() {
return new DefaultXmlRpcTransport(url);
}
/**
* Just for testing.
*/
public static void main(String args[]) throws Exception
{
// XmlRpc.setDebug(true);
// XmlRpc.setKeepAlive(true);
try
{
String url = args[0];
String method = args[1];
Vector v = new Vector();
for (int i = 2; i < args.length; i++)
{
try
{
v.addElement(new Integer(Integer.parseInt(args[i])));
}
catch(NumberFormatException nfx)
{
v.addElement(args[i]);
}
}
XmlRpcClient client = new XmlRpcClient(url);
try
{
System.out.println(client.execute(method, v));
}
catch(Exception ex)
{
System.err.println("Error: " + ex.getMessage());
}
}
catch(Exception x)
{
System.err.println(x);
System.err.println("Usage: java com.greenpepper.shaded.org.apache.xmlrpc.XmlRpcClient "
+ " ....");
System.err.println("Arguments are sent as integers or strings.");
}
}
}