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:
Rüdiger Timm 2003-04-23 16:03:59 +00:00
parent dc80c49936
commit b8789bce5c

View file

@ -2,9 +2,9 @@
*
* $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
* 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.IInvokable;
import com.sun.star.lib.sandbox.generic.DispatcherAdapterBase;
import com.sun.star.bridge.XBridge;
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.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.IProtocol;
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
* then looks for it under <code>com.sun.star.lib.uno.protocols</code>.
* <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
* @see com.sun.star.lib.uno.environments.remote.IProtocol
* @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.
*/
@ -205,7 +202,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
String oid_o[] = new String[]{oid};
_java_environment.registerInterface(null, oid_o, interfaceType );
addRefHolder(interfaceType, oid);
addRefHolder(null, interfaceType, oid);
}
else {
Object object = null;
@ -284,8 +281,9 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
}
// dispose this bridge only within an error
if(!_quit && !java_remote_bridge.this._disposed)
if (!_quit) {
java_remote_bridge.this.dispose(throwable);
}
return null;
}
@ -303,8 +301,6 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
protected IEnvironment _java_environment;
protected MessageDispatcher _messageDispatcher;
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
// 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;
// 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.
*/
@ -337,10 +339,13 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
Type _type;
String _oid;
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();
synchronized(_refHolders) {
@ -350,9 +355,11 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
refHolder = new RefHolder();
refHolder._type = type;
refHolder._oid = oid;
refHolder._hardRef = obj;
_refHolders.put(oid + type, refHolder);
}
// assert refHolder._hardRef == obj;
++ refHolder._mapCount;
}
@ -506,6 +513,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
_listeners = new Vector();
_stableListeners = new Vector();
proxyFactory = new ProxyFactory(this);
// create the message dispatcher and start it
_messageDispatcher = new MessageDispatcher();
_messageDispatcher.start();
@ -564,8 +573,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
* @see com.sun.star.uno.IBridge#mapInterfaceTo
*/
public Object mapInterfaceTo(Object object, Type type) {
if(_disposed) throw new DisposedException(
"java_remote_bridge(" + this + ").mapInterfaceTo - is disposed");
checkDisposed();
String oid[] = new String[1];
@ -574,7 +582,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
oid[0] = (String)object;
else {
_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]);
@ -590,56 +598,32 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
* @see com.sun.star.uno.IBridge#mapInterfaceFrom
*/
public Object mapInterfaceFrom(Object oId, Type type) {
if(_disposed) throw new DisposedException(
"java_remote_bridge(" + this + ").mapInterfaceFrom - is disposed");
checkDisposed();
// 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();
// see if we already have object with zInterface of given oid
Object object = _java_environment.getRegisteredInterface((String)oId, type);
if(object != null) {
if(object instanceof DispatcherAdapterBase) {
DispatcherAdapterBase dispatcherAdapterBase = (DispatcherAdapterBase)object;
if(dispatcherAdapterBase.getObject() instanceof DispatcherAdapterBase) {
dispatcherAdapterBase = (DispatcherAdapterBase)dispatcherAdapterBase.getObject();
if((dispatcherAdapterBase.getObject() instanceof String)) { // is it my proxy?
try {
sendRequest(oId,
type,
"release",
null,
new Boolean[]{new Boolean(_forceSynchronous)},
new Boolean[]{new Boolean(_forceSynchronous)});
}
catch(RuntimeException runtimeException) {
throw runtimeException;
}
catch(Throwable throwable) {
throw new com.sun.star.uno.RuntimeException(getClass().getName() + ".mapInterfaceFrom - unexpected:" + throwable);
}
}
}
String oid = (String) oId;
Object object = _java_environment.getRegisteredInterface(oid, type);
if (object == null) {
object = _java_environment.registerInterface(
proxyFactory.create(oid, type), new String[] { oid }, type);
// the proxy sends a release when finalized
} else {
try {
sendRequest(oid, type, "release", null,
new Boolean[] { new Boolean(_forceSynchronous) },
new Boolean[] { new Boolean(_forceSynchronous) });
} catch (Error e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new com.sun.star.uno.RuntimeException(
getClass().getName() + ".mapInterfaceFrom - unexpected: "
+ e);
}
}
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;
}
@ -696,10 +680,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
private synchronized void dispose(Throwable throwable) {
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(!_disposing) {
_disposing = true;
if (state == STATE_ALIVE) {
state = STATE_DISPOSING;
notifyListeners();
notifyStableListeners();
@ -764,7 +746,9 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
_java_environment = 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) {
System.err.println(getClass().getName() + ".dispose - InterruptedException:" + interruptedException);
@ -838,11 +822,8 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
+ exception + " " + result);
}
// FIXME _disposed read outside of synchronized block
if (_disposed) {
throw new DisposedException("java_remote_bridge(" + this
+ ").sendReply - is disposed");
}
// FIXME checkDisposed called outside of synchronized block
checkDisposed();
try {
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);
Object result = null;
@ -870,8 +861,7 @@ public class java_remote_bridge implements IBridge, IReceiver, IRequester, XBrid
if(mustReply == null)
mustReply = new Boolean[1];
if(_disposed) throw new DisposedException(
"java_remote_bridge(" + this + ").sendRequest - is disposed");
checkDisposed();
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) {
_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;
}