Package org.apache.xmlrpc.client.util

Source Code of org.apache.xmlrpc.client.util.ClientFactory

/*
* Copyright 1999,2006 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 org.apache.xmlrpc.client.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.common.TypeConverter;
import org.apache.xmlrpc.common.TypeConverterFactory;
import org.apache.xmlrpc.common.TypeConverterFactoryImpl;
import org.apache.xmlrpc.common.XmlRpcInvocationException;


/**
* <p>The {@link ClientFactory} is a useful tool for simplifying the
* use of Apache XML-RPC. The rough idea is as follows: All XML-RPC
* handlers are implemented as interfaces. The server uses the actual
* implementation. The client uses the {@link ClientFactory} to
* obtain an implementation, which is based on running XML-RPC calls.</p>
*/
public class ClientFactory {
    private final XmlRpcClient client;
    private final TypeConverterFactory typeConverterFactory;
    private boolean objectMethodLocal;

    /** Creates a new instance.
     * @param pClient A fully configured XML-RPC client, which is
     *   used internally to perform XML-RPC calls.
     * @param pTypeConverterFactory Creates instances of {@link TypeConverterFactory},
     *   which are used to transform the result object in its target representation.
     */
    public ClientFactory(XmlRpcClient pClient, TypeConverterFactory pTypeConverterFactory) {
        typeConverterFactory = pTypeConverterFactory;
        client = pClient;
    }

    /** Creates a new instance. Shortcut for
     * <pre>
     *   new ClientFactory(pClient, new TypeConverterFactoryImpl());
     * </pre>
     * @param pClient A fully configured XML-RPC client, which is
     *   used internally to perform XML-RPC calls.
     * @see TypeConverterFactoryImpl
     */
    public ClientFactory(XmlRpcClient pClient) {
        this(pClient, new TypeConverterFactoryImpl());
    }

    /** Returns the factories client.
     */
    public XmlRpcClient getClient() {
        return client;
    }

    /** Returns, whether a method declared by the {@link Object
     * Object class} is performed by the local object, rather than
     * by the server. Defaults to true.
     */
    public boolean isObjectMethodLocal() {
        return objectMethodLocal;
    }

    /** Sets, whether a method declared by the {@link Object
     * Object class} is performed by the local object, rather than
     * by the server. Defaults to true.
     */
    public void setObjectMethodLocal(boolean pObjectMethodLocal) {
        objectMethodLocal = pObjectMethodLocal;
    }

    /**
     * Creates an object, which is implementing the given interface.
     * The objects methods are internally calling an XML-RPC server
     * by using the factories client; shortcut for
     * <pre>
     *   newInstance(Thread.currentThread().getContextClassLoader(),
     *     pClass)
     * </pre>
     */
    public Object newInstance(Class pClass) {
        return newInstance(Thread.currentThread().getContextClassLoader(), pClass);
    }

    /** Creates an object, which is implementing the given interface.
     * The objects methods are internally calling an XML-RPC server
     * by using the factories client; shortcut for
     * <pre>
     *   newInstance(pClassLoader, pClass, pClass.getName())
     * </pre>
     */
    public Object newInstance(ClassLoader pClassLoader, Class pClass) {
        return newInstance(pClassLoader, pClass, pClass.getName());
    }

    /** Creates an object, which is implementing the given interface.
     * The objects methods are internally calling an XML-RPC server
     * by using the factories client.
     * @param pClassLoader The class loader, which is being used for
     *   loading classes, if required.
     * @param pClass Interface, which is being implemented.
     * @param pRemoteName Handler name, which is being used when
     *   calling the server. This is used for composing the
     *   method name. For example, if <code>pRemoteName</code>
     *   is "Foo" and you want to invoke the method "bar" in
     *   the handler, then the full method name would be "Foo.bar".
     */
    public Object newInstance(ClassLoader pClassLoader, final Class pClass, final String pRemoteName) {
       return Proxy.newProxyInstance(pClassLoader, new Class[]{pClass}, new InvocationHandler(){
            public Object invoke(Object pProxy, Method pMethod, Object[] pArgs) throws Throwable {
                if (isObjectMethodLocal()  &&  pMethod.getDeclaringClass().equals(Object.class)) {
                    return pMethod.invoke(pProxy, pArgs);
                }
                String methodName = pRemoteName + "." + pMethod.getName();
                Object result;
                try {
                    result = client.execute(methodName, pArgs);
                } catch (XmlRpcInvocationException e) {
                    Throwable t = e.linkedException;
                    if (t instanceof RuntimeException) {
                        throw t;
                    }
                    Class[] exceptionTypes = pMethod.getExceptionTypes();
                    for (int i = 0;  i < exceptionTypes.length;  i++) {
                        Class c = exceptionTypes[i];
                        if (c.isAssignableFrom(t.getClass())) {
                            throw t;
                        }
                    }
                    throw new UndeclaredThrowableException(t);
                }
                TypeConverter typeConverter = typeConverterFactory.getTypeConverter(pMethod.getReturnType());
                return typeConverter.convert(result);
            }
        });
    }
}
TOP

Related Classes of org.apache.xmlrpc.client.util.ClientFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.