javanetbridgeinteropclass.cs
来自「SRI international 发布的OAA框架软件」· CS 代码 · 共 301 行
CS
301 行
using System;
using System.Collections;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using jnb.java.lang;
namespace jnb.com.sri.sedc.javanetbridge
{
public abstract class JavaNetBridgeInteropClass
{
protected Hashtable callbackMap = new Hashtable();
protected Hashtable objectDatabase = new Hashtable();
protected CSharpDataMarshalOutputStream dout;
protected CSharpDataMarshalInputStream din;
protected CSharpDataMarshalOutputStream callbackout;
protected CSharpDataMarshalInputStream callbackin;
protected const byte METHOD_INVOKE_GOOD_RET = (byte)0;
protected const byte METHOD_INVOKE_VOID_RET = (byte)1;
protected const byte METHOD_INVOKE_EXCEPTION = (byte)2;
protected const byte INVOKE_INDICATOR = (byte)3;
protected const byte CALLBACK_INDICATOR = (byte)4;
protected const byte INVOKE_REENTRANT_INDICATOR = (byte)5;
protected JavaNetBridgeBean bean;
Mutex objectDatabaseLock = new Mutex();
Mutex methodInvokeLock = new Mutex();
private static IPAddress connectAddress = IPAddress.Loopback;
private static int connectPort = 4016;
protected static bool reentrant = true;
private static bool started = false;
private Hashtable reentrantThreads = new Hashtable();
private Hashtable reentrantThreadIds = new Hashtable();
private int reentrantThreadId = 0;
public Hashtable getCallbackMap()
{
return callbackMap;
}
public void handleSocketException(System.Net.Sockets.SocketException ex)
{
throw ex;
}
public abstract String getIDString();
public abstract String getDateString();
public void initUsingSocket()
{
started = true;
Socket connection = new Socket(AddressFamily.Unspecified, SocketType.Stream,
ProtocolType.Tcp);
connection.Connect(new IPEndPoint(connectAddress, connectPort));
Socket callbackConnection = new Socket(AddressFamily.Unspecified, SocketType.Stream,
ProtocolType.Tcp);
callbackConnection.Connect(new IPEndPoint(connectAddress, connectPort));
dout = new CSharpDataMarshalOutputStreamImpl(connection);
din = new CSharpDataMarshalInputStreamImpl(connection);
callbackout = new CSharpDataMarshalOutputStreamImpl(callbackConnection);
callbackin = new CSharpDataMarshalInputStreamImpl(callbackConnection);
dout.write(getIDString());
dout.write(getDateString());
dout.write("New");
int id = din.readInt();
callbackout.write(getIDString());
callbackout.write(getDateString());
callbackout.write("AttachCallback");
callbackout.write(id);
// Start a thread to receive callback notifications
Thread callbackThread = new Thread(new ThreadStart(readCallbacks));
callbackThread.Start();
if (reentrant) {
// Start a thread to receive the results of method calls
Thread readReturnThread = new Thread(new ThreadStart(readMethodReturns));
readReturnThread.Start();
}
}
public static IPAddress getConnectAddress()
{
return connectAddress;
}
public static void setConnectAddress(IPAddress address)
{
if (started) {
throw new Exception("setConnectAddress: The connection to the dotnetproxy has already been initiated. Cannot set the proxy host.");
}
connectAddress = address;
}
public static bool isReentrant() {
return reentrant;
}
public static void setReentrant(bool isreentrant) {
if (started) {
throw new Exception("setConnectPort: The connection to the dotnetproxy has already been initiated. Cannot set reeentrant to " + reentrant);
}
reentrant = isreentrant;
}
public static int getConnectPort()
{
return connectPort;
}
public static void setConnectPort(int port)
{
if (started) {
throw new Exception("setConnectPort: The connection to the dotnetproxy has already been initiated. Cannot set the proxy port.");
}
connectPort = port;
}
public abstract Object newCSharpObjectForJavaObject(JavaObjectId id, bool addRef, String defaultClassName);
public Object getCSharpObjectForJavaObject(JavaObjectId id, bool addRefOnNew, String defaultClassName)
{
objectDatabaseLock.WaitOne();
try
{
Object ret = objectDatabase[id.getId()];
if (ret != null)
{
ret = ((WeakReference)ret).Target;
}
if (ret != null)
{
return ret;
}
else
{
if (objectDatabase.Contains(id.getId()))
{
objectDatabase.Remove(id.getId());
}
ret = newCSharpObjectForJavaObject(id, addRefOnNew, defaultClassName);
objectDatabase.Add(id.getId(), new WeakReference(ret));
return ret;
}
}
finally
{
objectDatabaseLock.ReleaseMutex();
}
}
public void notifyCallbackFromPool(Object callbackId) {
notifyCallback((int)callbackId);
}
public void notifyCallback(int callbackId)
{
notifyCallback(new CallbackParams_StubImpl(new JavaObjectId(callbackId,
CallbackParams_StubImpl.JAVA_CLASS_NAME), false));
}
void readCallbacks()
{
while (true)
{
byte indicator = callbackin.readByte();
if (indicator == CALLBACK_INDICATOR)
{
int callBackObjId = callbackin.readInt();
if (!reentrant) {
notifyCallback(callBackObjId);
} else {
ThreadPool.QueueUserWorkItem(new WaitCallback(notifyCallbackFromPool), callBackObjId);
}
}
}
}
public void methodCallLock()
{
methodInvokeLock.WaitOne();
}
public void methodCallRelease()
{
methodInvokeLock.ReleaseMutex();
}
private Thread reeentrantMethodReturnReader;
private volatile int currentThreadId;
private Object reentrantLock = new Object();
private bool waitingForRead = false;
void readMethodReturns() {
reeentrantMethodReturnReader = Thread.CurrentThread;
while (true)
{
currentThreadId = din.readInt();
// There should be a thread waiting for the results. If there is not, then
// this may indicate a fatal error.
if (reentrantThreadIds.Contains(currentThreadId)) {
Object threadObj = reentrantThreadIds[currentThreadId];
lock (threadObj) {
Monitor.Pulse(threadObj);
waitingForRead = true;
}
// Wait for the thread to finish reading the results...
lock (reentrantLock) {
if (waitingForRead) {
Monitor.Wait(reentrantLock);
waitingForRead = false;
}
}
} else {
Console.Error.WriteLine("Error: received unknown thread id: " + currentThreadId);
}
}
}
protected void notifyMethodReturnRead() {
lock (reentrantLock) {
waitingForRead = false;
Monitor.Pulse(reentrantLock);
}
}
protected int registerReentrantThread() {
Thread currentThread = Thread.CurrentThread;
// If there is no thread id associated with this thread, assign a new id
if (!reentrantThreads.Contains(currentThread)) {
reentrantThreadId++;
reentrantThreads[currentThread] = reentrantThreadId;
reentrantThreadIds[reentrantThreadId] = currentThread;
}
return (int)reentrantThreads[currentThread];
}
protected void waitForMethodResponse() {
Thread currentThread = Thread.CurrentThread;
lock (currentThread) {
bool needsSuspend = true;
lock (reentrantLock) {
if (waitingForRead) {
// Return thread is waiting on reentrantLock. If it is waiting for this thread,
// then there is no need to suspend.
int currentId = currentThreadId;
int threadId = (int)reentrantThreads[Thread.CurrentThread];
if (threadId == currentId) {
needsSuspend = false;
}
}
}
if (needsSuspend) {
Monitor.Wait(currentThread);
}
}
}
public void notifyCallback(CallbackParams cparams)
{
try
{
int sourceId = cparams.getSource();
if (callbackMap.Contains(sourceId))
{
((CSharpCallbackImpl)callbackMap[sourceId]).doCallback(cparams);
}
}
finally
{
bean.notifyCallbackDone(cparams);
}
}
public JavaObjectId newCallback(String javaCallbackClass)
{
return new JavaObjectId(bean.newCallback(javaCallbackClass), javaCallbackClass);
}
public void readAndThrowSocketException()
{
try
{
String className = din.readString();
String message = din.readString();
throw new System.Exception("Java Invocation Exception: " +
className + ": " + message + ", Calling stack trace is: " +
new System.Diagnostics.StackTrace());
}
catch (System.Net.Sockets.SocketException ex)
{
handleSocketException(ex);
}
}
public void registerCallback(CSharpCallbackImpl impl, JavaObjectId id)
{
callbackMap.Add(id.getId(), impl);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?