// **********************************************************************
//
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
package IceInternal;
public final class RouterInfo
{
interface GetClientEndpointsCallback
{
void setEndpoints(EndpointI[] endpoints);
void setException(Ice.LocalException ex);
}
interface AddProxyCallback
{
void addedProxy();
void setException(Ice.LocalException ex);
}
RouterInfo(Ice.RouterPrx router)
{
_router = router;
assert(_router != null);
}
synchronized public void
destroy()
{
_clientEndpoints = new EndpointI[0];
_serverEndpoints = new EndpointI[0];
_adapter = null;
_identities.clear();
}
public boolean
equals(java.lang.Object obj)
{
if(this == obj)
{
return true;
}
if(obj instanceof RouterInfo)
{
return _router.equals(((RouterInfo)obj)._router);
}
return false;
}
public int
hashCode()
{
return _router.hashCode();
}
public Ice.RouterPrx
getRouter()
{
//
// No mutex lock necessary, _router is immutable.
//
return _router;
}
public EndpointI[]
getClientEndpoints()
{
synchronized(this)
{
if(_clientEndpoints != null) // Lazy initialization.
{
return _clientEndpoints;
}
}
return setClientEndpoints(_router.getClientProxy());
}
public void
getClientEndpoints(final GetClientEndpointsCallback callback)
{
EndpointI[] clientEndpoints = null;
synchronized(this)
{
clientEndpoints = _clientEndpoints;
}
if(clientEndpoints != null)
{
callback.setEndpoints(clientEndpoints);
return;
}
_router.getClientProxy_async(new Ice.AMI_Router_getClientProxy()
{
public void
ice_response(Ice.ObjectPrx clientProxy)
{
callback.setEndpoints(setClientEndpoints(clientProxy));
}
public void
ice_exception(Ice.LocalException ex)
{
if(ex instanceof Ice.CollocationOptimizationException)
{
try
{
callback.setEndpoints(getClientEndpoints());
}
catch(Ice.LocalException e)
{
callback.setException(e);
}
}
else
{
callback.setException(ex);
}
}
});
}
public EndpointI[]
getServerEndpoints()
{
synchronized(this)
{
if(_serverEndpoints != null) // Lazy initialization.
{
return _serverEndpoints;
}
}
return setServerEndpoints(_router.getServerProxy());
}
public void
addProxy(Ice.ObjectPrx proxy)
{
assert(proxy != null);
synchronized(this)
{
if(_identities.contains(proxy.ice_getIdentity()))
{
//
// Only add the proxy to the router if it's not already in our local map.
//
return;
}
}
addAndEvictProxies(proxy, _router.addProxies(new Ice.ObjectPrx[] { proxy }));
}
public boolean
addProxy(final Ice.ObjectPrx proxy, final AddProxyCallback callback)
{
assert(proxy != null);
synchronized(this)
{
if(_identities.contains(proxy.ice_getIdentity()))
{
//
// Only add the proxy to the router if it's not already in our local map.
//
return true;
}
}
_router.addProxies_async(new Ice.AMI_Router_addProxies()
{
public void
ice_response(Ice.ObjectPrx[] evictedProxies)
{
addAndEvictProxies(proxy, evictedProxies);
callback.addedProxy();
}
public void
ice_exception(Ice.LocalException ex)
{
if(ex instanceof Ice.CollocationOptimizationException)
{
try
{
addProxy(proxy);
callback.addedProxy();
}
catch(Ice.LocalException e)
{
callback.setException(ex);
}
}
else
{
callback.setException(ex);
}
}
},
new Ice.ObjectPrx[] { proxy });
return false;
}
public synchronized void
setAdapter(Ice.ObjectAdapter adapter)
{
_adapter = adapter;
}
public synchronized Ice.ObjectAdapter
getAdapter()
{
return _adapter;
}
private synchronized EndpointI[]
setClientEndpoints(Ice.ObjectPrx clientProxy)
{
if(_clientEndpoints == null)
{
if(clientProxy == null)
{
//
// If getClientProxy() return nil, use router endpoints.
//
_clientEndpoints = ((Ice.ObjectPrxHelperBase)_router).__reference().getEndpoints();
}
else
{
clientProxy = clientProxy.ice_router(null); // The client proxy cannot be routed.
//
// In order to avoid creating a new connection to the
// router, we must use the same timeout as the already
// existing connection.
//
try
{
clientProxy = clientProxy.ice_timeout(_router.ice_getConnection().timeout());
}
catch(Ice.CollocationOptimizationException ex)
{
// Ignore - collocated router.
}
_clientEndpoints = ((Ice.ObjectPrxHelperBase)clientProxy).__reference().getEndpoints();
}
}
return _clientEndpoints;
}
private synchronized EndpointI[]
setServerEndpoints(Ice.ObjectPrx serverProxy)
{
if(serverProxy == null)
{
throw new Ice.NoEndpointException();
}
serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
_serverEndpoints = ((Ice.ObjectPrxHelperBase)serverProxy).__reference().getEndpoints();
return _serverEndpoints;
}
private synchronized void
addAndEvictProxies(Ice.ObjectPrx proxy, Ice.ObjectPrx[] evictedProxies)
{
//
// Check if the proxy hasn't already been evicted by a
// concurrent addProxies call. If it's the case, don't
// add it to our local map.
//
int index = _evictedIdentities.indexOf(proxy.ice_getIdentity());
if(index >= 0)
{
_evictedIdentities.remove(index);
}
else
{
//
// If we successfully added the proxy to the router,
// we add it to our local map.
//
_identities.add(proxy.ice_getIdentity());
}
//
// We also must remove whatever proxies the router evicted.
//
for(Ice.ObjectPrx p : evictedProxies)
{
if(!_identities.remove(p.ice_getIdentity()))
{
//
// It's possible for the proxy to not have been
// added yet in the local map if two threads
// concurrently call addProxies.
//
_evictedIdentities.add(p.ice_getIdentity());
}
}
}
private final Ice.RouterPrx _router;
private EndpointI[] _clientEndpoints;
private EndpointI[] _serverEndpoints;
private Ice.ObjectAdapter _adapter;
private java.util.Set<Ice.Identity> _identities = new java.util.HashSet<Ice.Identity>();
private java.util.List<Ice.Identity> _evictedIdentities = new java.util.ArrayList<Ice.Identity>();
}