com.openteach.diamond.provider.impl.DefaultServiceProvider.java Source code

Java tutorial

Introduction

Here is the source code for com.openteach.diamond.provider.impl.DefaultServiceProvider.java

Source

/**
 * Copyright 2013 openteach
 *
 *  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.openteach.diamond.provider.impl;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.openteach.diamond.common.exception.DiamondException;
import com.openteach.diamond.metadata.ServiceMetadata;
import com.openteach.diamond.provider.AbstractServiceProvider;
import com.openteach.diamond.service.MethodInvoker;

/**
 * 
 * @author sihai
 *
 */
public class DefaultServiceProvider extends AbstractServiceProvider {

    /**
     * ?class
     */
    private transient Class<?> interfaceClass = null;

    /**
     * ???
     */
    private transient Object target;

    /**
     * 
     */
    private transient MethodInvoker methodInvoker;

    /**
     * ?????
     *     public void ${name}_callback(Object invokeContext, Object appResponse, Throwable t);
     * ?HSFcallbackHandler
     * ????HSFSpringConsumerBean
     */
    private transient Object callbackHandler;

    /**
     * ?invokeContextThreadLocal
     * ???
     */
    private transient ThreadLocal<Serializable> invokeContext = new ThreadLocal<Serializable>();

    /**
     * 
     */
    private Map<String, Method> methodMap;

    /**
     * 
     * @param metadata
     */
    public DefaultServiceProvider(ServiceMetadata metadata) {
        super(metadata);
    }

    @Override
    public void initialize() {
        super.initialize();
        if (null == metadata) {
            throw new IllegalArgumentException("metadata must not be null");
        }
        if (null == metadata.getInterfaceName() || null == target) {
            throw new IllegalArgumentException("Please set targetInterfaceName and target");
        }
        try {
            interfaceClass = Class.forName(metadata.getInterfaceName());
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException(
                    String.format("Can not load interface:%s", metadata.getInterfaceName()), e);
        }

        if (!interfaceClass.isInstance(target)) {
            throw new IllegalArgumentException(
                    String.format("Target must implements interface:%s", metadata.getInterfaceName()));
        }
        Method[] methods = interfaceClass.getDeclaredMethods();
        methodMap = new HashMap<String, Method>(methods.length);
        for (Method m : methods) {
            methodMap.put(getKey(m), m);
        }

        generateMethodInvoker();
    }

    @Override
    public void destroy() {
        super.destroy();
        methodMap.clear();
    }

    @Override
    public MethodInvoker getMethodInvoker() {
        return methodInvoker;
    }

    @Override
    public Object invoke(String methodName, String[] parameterTypes, Object... args) throws DiamondException {
        String key = getKey(methodName, parameterTypes);
        Method method = methodMap.get(key);
        if (null == method) {
            throw new DiamondException(String.format("Can not found method:%s, key:%s", methodName, key));
        }
        try {
            return method.invoke(target, args);
        } catch (IllegalArgumentException e) {
            throw new DiamondException(e);
        } catch (IllegalAccessException e) {
            throw new DiamondException(e);
        } catch (InvocationTargetException e) {
            throw new DiamondException(e);
        }
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    /**
      * ThreadLocal??ThreadLocal.set()HSF??
      * ?ReliableCallback?
      * @return
      */
    public ThreadLocal<Serializable> getInvokeContext() {
        return invokeContext;
    }

    public void setInvokeContext(ThreadLocal<Serializable> invokeContext) {
        this.invokeContext = invokeContext;
    }

    public Object getCallbackHandler() {
        return callbackHandler;
    }

    public void setCallbackHandler(Object callbackHandler) {
        this.callbackHandler = callbackHandler;
    }

    /**
     * 
     */
    private void generateMethodInvoker() {
        methodInvoker = new MethodInvoker() {

            @Override
            public Object invoke(String method, String[] parameterTypes, Object[] args) throws DiamondException {
                return DefaultServiceProvider.this.invoke(method, parameterTypes, args);
            }

        };
    }

    /**
     * 
     * @param method
     * @return
     */
    private String getKey(Method method) {
        Class[] cs = method.getParameterTypes();
        String[] names = new String[cs.length + 1];
        names[0] = method.getName();
        for (int i = 0; i < cs.length; i++) {
            names[i + 1] = cs[i].getName();
        }
        return StringUtils.join(names, "-");
    }

    /**
     * 
     * @param methodName
     * @param parameterTypes
     */
    private String getKey(String methodName, String[] parameterTypes) {
        return String.format("%s-%s", methodName, StringUtils.join(parameterTypes, "-"));
    }
}