INTEGRATION: CWS uno2 (1.27.2.1.16); FILE MERGED
2003/04/10 13:50:26 sb 1.27.2.1.16.3: #108825# In the RefHolder, keep a hard reference to the local object (the java_environment will only hold it weakly, so that a local object might be garbage-collected otherwise). 2003/04/07 08:33:33 sb 1.27.2.1.16.2: #108678# Replaced sandbox-based proxy with java.lang.reflect based one. 2003/04/04 09:13:59 sb 1.27.2.1.16.1: #108628# Always send back a release for a known object in mapInterfaceFrom (e.g., when the object is a local one mapped out via another bridge and now mapped back in); cleaned up handling of disposed bridge.
This commit is contained in:
parent
dc80c49936
commit
b8789bce5c
1 changed files with 78 additions and 78 deletions
|
@ -2,9 +2,9 @@
|
||||||
*
|
*
|
||||||
* $RCSfile: java_remote_bridge.java,v $
|
* $RCSfile: java_remote_bridge.java,v $
|
||||||
*
|
*
|
||||||
* $Revision: 1.28 $
|
* $Revision: 1.29 $
|
||||||
*
|
*
|
||||||
* last change: $Author: hr $ $Date: 2003-03-26 12:32:59 $
|
* last change: $Author: rt $ $Date: 2003-04-23 17:03:59 $
|
||||||
*
|
*
|
||||||
* The Contents of this file are made available subject to the terms of
|
* The Contents of this file are made available subject to the terms of
|
||||||
* either of the following licenses
|
* either of the following licenses
|
||||||
|
@ -81,9 +81,6 @@ import java.util.Vector;
|
||||||
import com.sun.star.lib.util.IInvokeHook;
|
import com.sun.star.lib.util.IInvokeHook;
|
||||||
import com.sun.star.lib.util.IInvokable;
|
import com.sun.star.lib.util.IInvokable;
|
||||||
|
|
||||||
import com.sun.star.lib.sandbox.generic.DispatcherAdapterBase;
|
|
||||||
|
|
||||||
|
|
||||||
import com.sun.star.bridge.XBridge;
|
import com.sun.star.bridge.XBridge;
|
||||||
import com.sun.star.bridge.XInstanceProvider;
|
import com.sun.star.bridge.XInstanceProvider;
|
||||||
|
|
||||||
|
@ -100,9 +97,6 @@ import com.sun.star.lang.DisposedException;
|
||||||
|
|
||||||
import com.sun.star.lib.sandbox.Disposable;
|
import com.sun.star.lib.sandbox.Disposable;
|
||||||
|
|
||||||
import com.sun.star.lib.uno.environments.java.IRequester;
|
|
||||||
import com.sun.star.lib.uno.environments.java.Proxy;
|
|
||||||
|
|
||||||
import com.sun.star.lib.uno.environments.remote.IMessage;
|
import com.sun.star.lib.uno.environments.remote.IMessage;
|
||||||
import com.sun.star.lib.uno.environments.remote.IProtocol;
|
import com.sun.star.lib.uno.environments.remote.IProtocol;
|
||||||
import com.sun.star.lib.uno.environments.remote.IReceiver;
|
import com.sun.star.lib.uno.environments.remote.IReceiver;
|
||||||
|
@ -133,12 +127,15 @@ import com.sun.star.uno.Any;
|
||||||
* The protocol to used is passed by name, the bridge
|
* The protocol to used is passed by name, the bridge
|
||||||
* then looks for it under <code>com.sun.star.lib.uno.protocols</code>.
|
* then looks for it under <code>com.sun.star.lib.uno.protocols</code>.
|
||||||
* <p>
|
* <p>
|
||||||
* @version $Revision: 1.28 $ $ $Date: 2003-03-26 12:32:59 $
|
* @version $Revision: 1.29 $ $ $Date: 2003-04-23 17:03:59 $
|
||||||
* @author Kay Ramme
|
* @author Kay Ramme
|
||||||
* @see com.sun.star.lib.uno.environments.remote.IProtocol
|
* @see com.sun.star.lib.uno.environments.remote.IProtocol
|
||||||
* @since UDK1.0
|
* @since UDK1.0
|
||||||
*/
|
*/
|
||||||
public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBridge, Disposable, XComponent, IStableObject {
|
public class java_remote_bridge
|
||||||
|
implements IBridge, IReceiver, RequestHandler, XBridge, Disposable,
|
||||||
|
XComponent, IStableObject
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* When set to true, enables various debugging output.
|
* When set to true, enables various debugging output.
|
||||||
*/
|
*/
|
||||||
|
@ -205,7 +202,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
String oid_o[] = new String[]{oid};
|
String oid_o[] = new String[]{oid};
|
||||||
_java_environment.registerInterface(null, oid_o, interfaceType );
|
_java_environment.registerInterface(null, oid_o, interfaceType );
|
||||||
|
|
||||||
addRefHolder(interfaceType, oid);
|
addRefHolder(null, interfaceType, oid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object object = null;
|
Object object = null;
|
||||||
|
@ -284,8 +281,9 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispose this bridge only within an error
|
// dispose this bridge only within an error
|
||||||
if(!_quit && !java_remote_bridge.this._disposed)
|
if (!_quit) {
|
||||||
java_remote_bridge.this.dispose(throwable);
|
java_remote_bridge.this.dispose(throwable);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -303,8 +301,6 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
protected IEnvironment _java_environment;
|
protected IEnvironment _java_environment;
|
||||||
protected MessageDispatcher _messageDispatcher;
|
protected MessageDispatcher _messageDispatcher;
|
||||||
protected int _life_count = 0; // determines if this bridge is alife, which is controlled by acquire and release calls
|
protected int _life_count = 0; // determines if this bridge is alife, which is controlled by acquire and release calls
|
||||||
protected boolean _disposed = false;
|
|
||||||
protected boolean _disposing = false;
|
|
||||||
|
|
||||||
protected Hashtable _refHolders; // holds descriptions for out mapped objects, so we can release
|
protected Hashtable _refHolders; // holds descriptions for out mapped objects, so we can release
|
||||||
// the outmapped objects when the bridge is to be disposed
|
// the outmapped objects when the bridge is to be disposed
|
||||||
|
@ -317,6 +313,12 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
|
|
||||||
protected IThreadPool _iThreadPool;
|
protected IThreadPool _iThreadPool;
|
||||||
|
|
||||||
|
// Variable state must only be used while synchronized on this object:
|
||||||
|
private int state = STATE_ALIVE;
|
||||||
|
private static final int STATE_ALIVE = 0;
|
||||||
|
private static final int STATE_DISPOSING = 1;
|
||||||
|
private static final int STATE_DISPOSED = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is for testing only.
|
* This method is for testing only.
|
||||||
*/
|
*/
|
||||||
|
@ -337,10 +339,13 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
Type _type;
|
Type _type;
|
||||||
String _oid;
|
String _oid;
|
||||||
int _mapCount;
|
int _mapCount;
|
||||||
|
Object _hardRef;
|
||||||
|
// keep a hard reference to the object, the java_environment will
|
||||||
|
// only hold it weakly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final void addRefHolder(Type type, String oid) {
|
final void addRefHolder(Object obj, Type type, String oid) {
|
||||||
acquire();
|
acquire();
|
||||||
|
|
||||||
synchronized(_refHolders) {
|
synchronized(_refHolders) {
|
||||||
|
@ -350,9 +355,11 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
refHolder = new RefHolder();
|
refHolder = new RefHolder();
|
||||||
refHolder._type = type;
|
refHolder._type = type;
|
||||||
refHolder._oid = oid;
|
refHolder._oid = oid;
|
||||||
|
refHolder._hardRef = obj;
|
||||||
|
|
||||||
_refHolders.put(oid + type, refHolder);
|
_refHolders.put(oid + type, refHolder);
|
||||||
}
|
}
|
||||||
|
// assert refHolder._hardRef == obj;
|
||||||
|
|
||||||
++ refHolder._mapCount;
|
++ refHolder._mapCount;
|
||||||
}
|
}
|
||||||
|
@ -506,6 +513,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
_listeners = new Vector();
|
_listeners = new Vector();
|
||||||
_stableListeners = new Vector();
|
_stableListeners = new Vector();
|
||||||
|
|
||||||
|
proxyFactory = new ProxyFactory(this);
|
||||||
|
|
||||||
// create the message dispatcher and start it
|
// create the message dispatcher and start it
|
||||||
_messageDispatcher = new MessageDispatcher();
|
_messageDispatcher = new MessageDispatcher();
|
||||||
_messageDispatcher.start();
|
_messageDispatcher.start();
|
||||||
|
@ -564,8 +573,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
* @see com.sun.star.uno.IBridge#mapInterfaceTo
|
* @see com.sun.star.uno.IBridge#mapInterfaceTo
|
||||||
*/
|
*/
|
||||||
public Object mapInterfaceTo(Object object, Type type) {
|
public Object mapInterfaceTo(Object object, Type type) {
|
||||||
if(_disposed) throw new DisposedException(
|
checkDisposed();
|
||||||
"java_remote_bridge(" + this + ").mapInterfaceTo - is disposed");
|
|
||||||
|
|
||||||
String oid[] = new String[1];
|
String oid[] = new String[1];
|
||||||
|
|
||||||
|
@ -574,7 +582,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
oid[0] = (String)object;
|
oid[0] = (String)object;
|
||||||
else {
|
else {
|
||||||
_java_environment.registerInterface(object, oid, type);
|
_java_environment.registerInterface(object, oid, type);
|
||||||
addRefHolder(type, oid[0]);
|
addRefHolder(object, type, oid[0]);
|
||||||
}
|
}
|
||||||
if(DEBUG) System.err.println("##### " + getClass() + " - mapInterfaceTo:" + object + " interface:" + type + " " + oid[0]);
|
if(DEBUG) System.err.println("##### " + getClass() + " - mapInterfaceTo:" + object + " interface:" + type + " " + oid[0]);
|
||||||
|
|
||||||
|
@ -590,56 +598,32 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
* @see com.sun.star.uno.IBridge#mapInterfaceFrom
|
* @see com.sun.star.uno.IBridge#mapInterfaceFrom
|
||||||
*/
|
*/
|
||||||
public Object mapInterfaceFrom(Object oId, Type type) {
|
public Object mapInterfaceFrom(Object oId, Type type) {
|
||||||
if(_disposed) throw new DisposedException(
|
checkDisposed();
|
||||||
"java_remote_bridge(" + this + ").mapInterfaceFrom - is disposed");
|
// TODO What happens if an exception is thrown after the call to
|
||||||
|
// acquire, but before it is guaranteed that a pairing release will be
|
||||||
|
// called eventually?
|
||||||
acquire();
|
acquire();
|
||||||
|
String oid = (String) oId;
|
||||||
// see if we already have object with zInterface of given oid
|
Object object = _java_environment.getRegisteredInterface(oid, type);
|
||||||
Object object = _java_environment.getRegisteredInterface((String)oId, type);
|
if (object == null) {
|
||||||
|
object = _java_environment.registerInterface(
|
||||||
if(object != null) {
|
proxyFactory.create(oid, type), new String[] { oid }, type);
|
||||||
if(object instanceof DispatcherAdapterBase) {
|
// the proxy sends a release when finalized
|
||||||
DispatcherAdapterBase dispatcherAdapterBase = (DispatcherAdapterBase)object;
|
} else {
|
||||||
|
try {
|
||||||
if(dispatcherAdapterBase.getObject() instanceof DispatcherAdapterBase) {
|
sendRequest(oid, type, "release", null,
|
||||||
dispatcherAdapterBase = (DispatcherAdapterBase)dispatcherAdapterBase.getObject();
|
new Boolean[] { new Boolean(_forceSynchronous) },
|
||||||
|
new Boolean[] { new Boolean(_forceSynchronous) });
|
||||||
if((dispatcherAdapterBase.getObject() instanceof String)) { // is it my proxy?
|
} catch (Error e) {
|
||||||
try {
|
throw e;
|
||||||
sendRequest(oId,
|
} catch (RuntimeException e) {
|
||||||
type,
|
throw e;
|
||||||
"release",
|
} catch (Throwable e) {
|
||||||
null,
|
throw new com.sun.star.uno.RuntimeException(
|
||||||
new Boolean[]{new Boolean(_forceSynchronous)},
|
getClass().getName() + ".mapInterfaceFrom - unexpected: "
|
||||||
new Boolean[]{new Boolean(_forceSynchronous)});
|
+ e);
|
||||||
}
|
|
||||||
catch(RuntimeException runtimeException) {
|
|
||||||
throw runtimeException;
|
|
||||||
}
|
|
||||||
catch(Throwable throwable) {
|
|
||||||
throw new com.sun.star.uno.RuntimeException(getClass().getName() + ".mapInterfaceFrom - unexpected:" + throwable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
String oid[] = new String[]{(String)oId};
|
|
||||||
|
|
||||||
// boolean virtual = false;
|
|
||||||
// if(oid[0].startsWith("virtual:")) {
|
|
||||||
// oid[0] = oid[0].substring(8);
|
|
||||||
|
|
||||||
// virtual = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
Object proxy = Proxy.create(this, oid[0], type, false, _forceSynchronous); // this proxy sends a release, when finalized
|
|
||||||
object = _java_environment.registerInterface(proxy, oid, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DEBUG) System.err.println("##### " + getClass() + " - mapInterfaceFrom:" + oId + " interface:" + type + " " + object);
|
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,10 +680,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
private synchronized void dispose(Throwable throwable) {
|
private synchronized void dispose(Throwable throwable) {
|
||||||
if(DEBUG) System.err.println("##### " + getClass().getName() + ".dispose - life count:" + _life_count);
|
if(DEBUG) System.err.println("##### " + getClass().getName() + ".dispose - life count:" + _life_count);
|
||||||
|
|
||||||
if(_disposed) throw new DisposedException("java_remote_bridge(" + this + ").dispose - is disposed");
|
if (state == STATE_ALIVE) {
|
||||||
|
state = STATE_DISPOSING;
|
||||||
if(!_disposing) {
|
|
||||||
_disposing = true;
|
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
notifyStableListeners();
|
notifyStableListeners();
|
||||||
|
@ -764,7 +746,9 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
_java_environment = null;
|
_java_environment = null;
|
||||||
_messageDispatcher = null;
|
_messageDispatcher = null;
|
||||||
|
|
||||||
_disposed = true;
|
// TODO! Is it intended that state is left as STATE_DISPOSING
|
||||||
|
// when an exception is thrown?
|
||||||
|
state = STATE_DISPOSED;
|
||||||
}
|
}
|
||||||
catch(InterruptedException interruptedException) {
|
catch(InterruptedException interruptedException) {
|
||||||
System.err.println(getClass().getName() + ".dispose - InterruptedException:" + interruptedException);
|
System.err.println(getClass().getName() + ".dispose - InterruptedException:" + interruptedException);
|
||||||
|
@ -838,11 +822,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
+ exception + " " + result);
|
+ exception + " " + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME _disposed read outside of synchronized block
|
// FIXME checkDisposed called outside of synchronized block
|
||||||
if (_disposed) {
|
checkDisposed();
|
||||||
throw new DisposedException("java_remote_bridge(" + this
|
|
||||||
+ ").sendReply - is disposed");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
synchronized (_outputStream) {
|
synchronized (_outputStream) {
|
||||||
|
@ -860,7 +841,17 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object sendRequest(Object object, Type type, String operation, Object params[], Boolean synchron[], Boolean mustReply[]) throws Throwable {
|
public Object sendRequest(String oid, Type type, String operation,
|
||||||
|
Object[] args)
|
||||||
|
throws Throwable
|
||||||
|
{
|
||||||
|
return sendRequest(
|
||||||
|
oid, type, operation, args,
|
||||||
|
_forceSynchronous ? new Boolean[] { Boolean.TRUE } : null,
|
||||||
|
_forceSynchronous ? new Boolean[] { Boolean.TRUE } : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object sendRequest(Object object, Type type, String operation, Object params[], Boolean synchron[], Boolean mustReply[]) throws Throwable {
|
||||||
if(DEBUG) System.err.println("##### " + getClass().getName() + ".sendRequest:" + object + " " + type +" " + operation + " " + synchron + " " + mustReply);
|
if(DEBUG) System.err.println("##### " + getClass().getName() + ".sendRequest:" + object + " " + type +" " + operation + " " + synchron + " " + mustReply);
|
||||||
Object result = null;
|
Object result = null;
|
||||||
|
|
||||||
|
@ -870,8 +861,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
if(mustReply == null)
|
if(mustReply == null)
|
||||||
mustReply = new Boolean[1];
|
mustReply = new Boolean[1];
|
||||||
|
|
||||||
if(_disposed) throw new DisposedException(
|
checkDisposed();
|
||||||
"java_remote_bridge(" + this + ").sendRequest - is disposed");
|
|
||||||
|
|
||||||
if(operation.equals("acquire")) acquire(); // keep this bridge alife
|
if(operation.equals("acquire")) acquire(); // keep this bridge alife
|
||||||
|
|
||||||
|
@ -948,4 +938,14 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
|
||||||
public void removeStableListener(IStableListener stableListener) {
|
public void removeStableListener(IStableListener stableListener) {
|
||||||
_stableListeners.removeElement(stableListener);
|
_stableListeners.removeElement(stableListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function must only be called while synchronized on this object:
|
||||||
|
private void checkDisposed() {
|
||||||
|
if (state == STATE_DISPOSED) {
|
||||||
|
throw new DisposedException("java_remote_bridge " + this
|
||||||
|
+ " is disposed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ProxyFactory proxyFactory;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue