package com.chamago.bison;
import com.chamago.bison.codec.BeanCallCode;
import com.chamago.bison.codec.InterfaceCallInfo;
import com.chamago.bison.helper.BisonImpl;
import java.io.PrintStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.RemoteException;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* @author Gavin.peng
*
* 2013-10-27 下午04:08:03
× bison-client
*/
public class RemoteObjectFactory
{
private static ConcurrentHashMap<String, Object> maps = new ConcurrentHashMap();
public static Object findRemoteObject(Class<?> clsType, String group, BisonContext context)
throws RemoteException
{
Object obj = maps.get(clsType.getName() + "_" + group);
if (obj == null) {
if (context == null) {
context = BisonContext.getDefaultContext();
}
InterfaceCallInfo callInfo = new InterfaceCallInfo();
callInfo.setClassName(clsType.getName());
callInfo.setMethodName("");
ProxyCall call = new ProxyCall();
call.setGroupID(group);
//int rc = call.findRemoteInterface(callInfo, context);
//if (rc == 0) {
InvocationHandler handler = new MyInvocationHandler(context, group, clsType.getName());
obj = Proxy.newProxyInstance(clsType.getClassLoader(), new Class[] { clsType }, handler);
if (obj != null)
maps.put(clsType.getName() + "_" + group, obj);
// }
// else
// {
// throw new RemoteException("find remote interface exception code=" + rc);
// }
}
return obj;
}
public static Object findRemoteObject(Class<?> clsType, String group) throws RemoteException {
return findRemoteObject(clsType, group, null);
}
static class MyInvocationHandler
implements InvocationHandler
{
private BisonContext context;
private String group;
private String clsName;
public MyInvocationHandler(BisonContext context, String group, String clsName)
{
this.context = context;
this.group = group;
this.clsName = clsName;
}
public Object invoke(Object proxy, Method method, Object[] args) throws RemoteException
{
InterfaceCallInfo callInfo = new InterfaceCallInfo();
callInfo.setClassName(this.clsName);
callInfo.setMethodName(method.getName());
callInfo.setParamTypes(method.getParameterTypes());
callInfo.setParams(args);
RemoteObjectFactory.ProxyCall call = new RemoteObjectFactory.ProxyCall();
call.setGroupID(this.group);
int rc = call.callRemoteInterface(callInfo, this.context);
if (rc == 0) {
Object o = call.getResult();
if ((o instanceof Exception)) {
throw new RemoteException("call remote interface exception code=" + rc, (Exception)o);
}
return call.getResult();
}
throw new RemoteException("call remote interface exception code=" + rc);
}
}
static class ProxyCall extends BisonImpl
{
private InterfaceCallInfo callInfo;
private int errCode;
private boolean async = false;
private Object result;
public boolean _onReceiveMessageEvent(int errCode, Object obj)
{
try
{
this.errCode = errCode;
InterfaceCallInfo objCall = (InterfaceCallInfo)obj;
if ((objCall != null) &&
(objCall.getCallFlag() == 2)) {
this.result = objCall.getResult();
}
objCall = null;
obj = null;
releaseThread();
} catch (Exception e) {
e.printStackTrace();
this.errCode = -2;
releaseThread();
}
return true;
}
public void _onTimeOut() {
this.errCode = -1;
}
public int findRemoteInterface(InterfaceCallInfo call, BisonContext context) {
this.ready = false;
this.async = false;
this.callInfo = call;
this.callInfo.setCallFlag(1);
this.errCode = 0;
context.send_message(this);
if (!lockThread()) {
this.errCode = -1;
}
return this.errCode;
}
public int callRemoteInterface(InterfaceCallInfo callInfo) {
return callRemoteInterface(callInfo, null);
}
protected int callRemoteInterface(InterfaceCallInfo callInfo, BisonContext context)
{
this.ready = false;
this.async = false;
this.callInfo = callInfo;
this.callInfo.setCallFlag(2);
this.errCode = 0;
if (context == null) {
context = BisonContext.getDefaultContext();
}
context.send_message(this);
if (!lockThread()) {
this.errCode = -1;
}
return this.errCode;
}
public int getErrCode() {
return this.errCode;
}
public Object getResult() {
return this.result;
}
public String getMethodName() {
return "";
}
public Object getSendObject() {
return this.callInfo;
}
public boolean isAsync() {
return this.async;
}
public int getCallType() {
return BeanCallCode.INTERFACE_CALL_ID;
}
}
}