code.google.nfs.rpc.server.RPCServerHandler.java Source code

Java tutorial

Introduction

Here is the source code for code.google.nfs.rpc.server.RPCServerHandler.java

Source

package code.google.nfs.rpc.server;

/**
 * nfs-rpc
 *   Apache License
 *   
 *   http://code.google.com/p/nfs-rpc (c) 2011
 */
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import code.google.nfs.rpc.Codecs;
import code.google.nfs.rpc.RequestWrapper;
import code.google.nfs.rpc.ResponseWrapper;

/**
 * Reflection RPC Server Handler 
 * 
 * @author <a href="mailto:bluedavy@gmail.com">bluedavy</a>
 */
public class RPCServerHandler implements ServerHandler {

    private static final Log LOGGER = LogFactory.getLog(RPCServerHandler.class);

    // Server Processors     key: servicename    value: service instance
    private static Map<String, Object> processors = new HashMap<String, Object>();

    // Cached Server Methods  key: instanceName#methodname$argtype_argtype
    private static Map<String, Method> cacheMethods = new HashMap<String, Method>();

    public void registerProcessor(String instanceName, Object instance) {
        processors.put(instanceName, instance);
        Class<?> instanceClass = instance.getClass();
        Method[] methods = instanceClass.getMethods();
        for (Method method : methods) {
            Class<?>[] argTypes = method.getParameterTypes();
            StringBuilder methodKeyBuilder = new StringBuilder();
            methodKeyBuilder.append(instanceName).append("#");
            methodKeyBuilder.append(method.getName()).append("$");
            for (Class<?> argClass : argTypes) {
                methodKeyBuilder.append(argClass.getName()).append("_");
            }
            cacheMethods.put(methodKeyBuilder.toString(), method);
        }
    }

    public ResponseWrapper handleRequest(final RequestWrapper request) {
        ResponseWrapper responseWrapper = new ResponseWrapper(request.getId(), request.getCodecType(),
                request.getProtocolType());
        String targetInstanceName = new String(request.getTargetInstanceName());
        String methodName = new String(request.getMethodName());
        byte[][] argTypeBytes = request.getArgTypes();
        String[] argTypes = new String[argTypeBytes.length];
        for (int i = 0; i < argTypeBytes.length; i++) {
            argTypes[i] = new String(argTypeBytes[i]);
        }
        Object[] requestObjects = null;
        Method method = null;
        try {
            Object processor = processors.get(targetInstanceName);
            if (processor == null) {
                throw new Exception("no " + targetInstanceName + " instance exists on the server");
            }
            if (argTypes != null && argTypes.length > 0) {
                StringBuilder methodKeyBuilder = new StringBuilder();
                methodKeyBuilder.append(targetInstanceName).append("#");
                methodKeyBuilder.append(methodName).append("$");
                Class<?>[] argTypeClasses = new Class<?>[argTypes.length];
                for (int i = 0; i < argTypes.length; i++) {
                    methodKeyBuilder.append(argTypes[i]).append("_");
                    argTypeClasses[i] = Class.forName(argTypes[i]);
                }
                requestObjects = new Object[argTypes.length];
                method = cacheMethods.get(methodKeyBuilder.toString());
                if (method == null) {
                    throw new Exception("no method: " + methodKeyBuilder.toString() + " find in "
                            + targetInstanceName + " on the server");
                }
                Object[] tmprequestObjects = request.getRequestObjects();
                for (int i = 0; i < tmprequestObjects.length; i++) {
                    try {
                        requestObjects[i] = Codecs.getDecoder(request.getCodecType()).decode(argTypes[i],
                                (byte[]) tmprequestObjects[i]);
                    } catch (Exception e) {
                        throw new Exception("decode request object args error", e);
                    }
                }
            } else {
                method = processor.getClass().getMethod(methodName, new Class<?>[] {});
                if (method == null) {
                    throw new Exception(
                            "no method: " + methodName + " find in " + targetInstanceName + " on the server");
                }
                requestObjects = new Object[] {};
            }
            responseWrapper.setResponse(method.invoke(processor, requestObjects));
        } catch (Exception e) {
            LOGGER.error("server handle request error", e);
            responseWrapper.setException(e);
        }
        return responseWrapper;
    }
}