javanetbridgebeanimpl.java

来自「SRI international 发布的OAA框架软件」· Java 代码 · 共 233 行

JAVA
233
字号
/* $Id: JavaNetBridgeBeanImpl.java,v 1.6 2003/10/31 17:01:22 giuli Exp $*/
/**************************************************************************
 * Copyright 2001, 2002 SRI International. All rights reserved.
 *
 * The material contained in this file is confidential and proprietary to SRI
 * International and may not be reproduced, published, or disclosed to others
 * without authorization from SRI International.
 *
 * DISCLAIMER OF WARRANTIES
 *
 * SRI International MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
 * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SRI International SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THIS SOFTWARE
 **************************************************************************/
package com.sri.sedc.javanetbridge;

import com.sri.sedc.javanetbridge.io.DataMarshalInputStream;
import com.sri.sedc.javanetbridge.io.DataMarshalOutputStream;

import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import java.util.Map;
import java.util.Hashtable;
import java.lang.reflect.Constructor;
import java.io.IOException;

/**
 * Base class for ActiveX JavaBeans.
 */
public abstract class JavaNetBridgeBeanImpl implements JavaNetBridgeBean {
    /**
     * Object database used to store object references.
     */
    protected ObjectDB objDb;
    protected boolean traceEnabled = false;
    private List callbackListeners = new Vector();
    private Map reentrantThreads = new Hashtable();
    protected RemoteProxy remoteBridge;

    public abstract String getIDString();

    public abstract String getDateString();

    public JavaNetBridgeBeanImpl() {
        objDb = JavaNetBridgeFactory.getFactory().newObjectDB();
    }

    public ObjectDB getObjectDB() {
        if (traceEnabled) traceMethod("getObjectDB");
        return objDb;
    }

    public void addObjectRef(Object obj) {
        if (traceEnabled) traceMethod("addObjectRef");
        objDb.addObjRef(obj);
    }

    public int releaseObjectRef(Object obj) {
        int ret = objDb.releaseObjRef(obj);
        if (traceEnabled) traceMethod("releaseObjectRef, ret = " + ret);
        return ret;
    }

    public void setTraceMethods(boolean traceEnabled) {
        if (traceEnabled) traceMethod("setTraceMethods(" + traceEnabled + ")");
        this.traceEnabled = traceEnabled;
    }

    public boolean getTraceMethods() {
        if (traceEnabled) traceMethod("getTraceMethods");
        return traceEnabled;
    }

    public void addCallbackEventListener(CallbackEventListener listener) {
        if (traceEnabled) traceMethod("addCallbackEventListener");
        callbackListeners.add(listener);
    }

    public void addRef(int objId) throws ObjectNotFoundException {
        int newRef = objDb.addObjRef(objDb.getObjFromId(objId));
        if (traceEnabled) traceMethod("addRef called, objId = " + objId +  ", newRef = " + newRef);
    }

    public int releaseRef(int ref) {
        int ret = objDb.releaseObjRef(ref);
        if (traceEnabled) traceMethod("release called, ref = " + ref + ", new ref count = " + ret);
        return ret;
    }

    public ObjectDB getObjectDatabase() {
        return objDb;
    }

    /**
     * Initializes the ActiveX bean. Subclasses must override this method to
     * provide any initialization required. Users of this JavaBean are expected
     * to invoke this method after creating the JavaBean.
     */
    public void init() {
        // Does nothing
    }

    public void setRemoteProxy(RemoteProxy remote) {
        this.remoteBridge = remote;
        System.out.println("Connected to remote proxy:");
        System.out.println("    " + remoteBridge.getDescription());
        System.out.println("    Build Date: " + remoteBridge.getBuildDate());
    }

    /**
     * Destroys the bean.
     */
    public void destroy() {
        objDb.clear();
        callbackListeners.clear();
    }

    private boolean debugReentrant = false;

    public void waitNextInvokeMarshalling(DataMarshalInputStream in, DataMarshalOutputStream out) throws Exception {
        byte indicator = in.readByte();
        if (indicator == INVOKE_INDICATOR) {
            int methodId = in.readInt();
            try {
                synchronized (this) {
                    invokeMethod(methodId, readMethodParams(methodId, in), out, -1);
                }
            } catch (UnsupportedMethodIdException ex) {
                // Fatal error because the data stream could be corrupted
                throw ex;
            } catch (Throwable ex) {
                ex.printStackTrace();
                synchronized (out) {
                    out.write(METHOD_INVOKE_EXCEPTION);
                    out.write(ex.getClass().getName());
                    out.write(ex.getMessage());
                    out.flush();
                }
            }
        } else if (indicator == INVOKE_REENTRANT_INDICATOR) {
            if (!debugReentrant) {
                System.out.println("Client supports reentrant capability.");
                debugReentrant = true;
            }
            int threadId = in.readInt();
            int methodId = in.readInt();
            // Is there a thread running for the current threadId? If not,
            // then start a thread which will poll a queue for invoking the
            // methods which originated on the csharp thread.
            ReentrantThreadHandler handler = (ReentrantThreadHandler)reentrantThreads.get(new Integer(threadId));
            if (handler == null) {
                handler = JavaNetBridgeFactory.getFactory().newReentrantThreadHandler(this, out, threadId);
                reentrantThreads.put(new Integer(threadId), handler);
                handler.start();
            }
            handler.queueMethodCall(methodId, readMethodParams(methodId, in));
        } else {
            throw new IOException("Read unsupported indicator from data stream: " + indicator);
        }
    }

    private Class[] callBackConstructorParams = { JavaNetBridgeBeanImpl.class };
    public int newCallback(String javaCallbackClass) throws Exception {
        if (traceEnabled) traceMethod("newCallback: " + javaCallbackClass);
        Class cls = Class.forName(javaCallbackClass);
        Constructor constructor = cls.getConstructor(callBackConstructorParams);
        CallbackImpl callback = (CallbackImpl)constructor.newInstance(new Object[] {this} );
        // XXX Callbacks should actually be weaak references. WHen a callback garbage collects,
        // then the other app should be notified that the object no longer exists. This is
        // not implemented.
        int objId = objDb.addObjRef(callback);
        callback.setObjectId(objId);
        return objId;
    }

    public void removeCallbackEventListener(CallbackEventListener listener) {
        callbackListeners.remove(listener);
    }

    public Object triggerCallback(CallbackParams params) {
        try {
            int objId = objDb.addObjRef(params);
            // XXXXXX The case where a callback occurs on the calling thread is not handled.
            // This can result in deadlock and the callback should really be done asynchronously for this case.
            for (Iterator itr = callbackListeners.iterator(); itr.hasNext();) {
                CallbackEventListener callbackEventListener = (CallbackEventListener) itr.next();
                synchronized (params) {
                    callbackEventListener.notifyCallback(objId);
                    params.wait();
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        return params.getReturn();
    }

    public void notifyCallbackDone(int paramsId) throws ObjectNotFoundException {
        Object paramsObj = objDb.getObjFromId(paramsId);
        notifyCallbackDone((CallbackParams)paramsObj);
    }

    public void notifyCallbackDone(CallbackParams params) {
        if (traceEnabled) traceMethod("notifyCallbackDone: " + params.getSource());
        synchronized (params) {
            params.notify();
        }
    }

    protected void traceMethod(String msg) {
        System.out.println("Oaa2JavaNet:methodTrace: " + msg);
    }

    public int getAXBridgeBean() {
        return objDb.addObjRef(this);
    }

    public String getJavaClassName(int objRef) throws ObjectNotFoundException {
        return objDb.getObjFromId(objRef).getClass().getName();
    }

    public void system_setProperty(String propName, String propValue) {
        if (traceEnabled) traceMethod("system_setProperty called, propName = \"" + propName +
                "\", propValue = " + propValue + "\"");
        System.setProperty(propName, propValue);
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?