// // Copyright (c) ZeroC, Inc. All rights reserved. // namespace IceInternal { using System.Collections.Generic; using System.Diagnostics; public sealed class ServantManager { public void addServant(Ice.Object servant, Ice.Identity ident, string facet) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. if(facet == null) { facet = ""; } Dictionary m; _servantMapMap.TryGetValue(ident, out m); if(m == null) { _servantMapMap[ident] = (m = new Dictionary()); } else { if(m.ContainsKey(facet)) { Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException(); ex.id = Ice.Util.identityToString(ident, _instance.toStringMode()); ex.kindOfObject = "servant"; if(facet.Length > 0) { ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "", _instance.toStringMode()); } throw ex; } } m[facet] = servant; } } public void addDefaultServant(Ice.Object servant, string category) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. Ice.Object obj = null; _defaultServantMap.TryGetValue(category, out obj); if(obj != null) { Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException(); ex.kindOfObject = "default servant"; ex.id = category; throw ex; } _defaultServantMap[category] = servant; } } public Ice.Object removeServant(Ice.Identity ident, string facet) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. if(facet == null) { facet = ""; } Dictionary m; _servantMapMap.TryGetValue(ident, out m); Ice.Object obj = null; if(m == null || !m.ContainsKey(facet)) { Ice.NotRegisteredException ex = new Ice.NotRegisteredException(); ex.id = Ice.Util.identityToString(ident, _instance.toStringMode()); ex.kindOfObject = "servant"; if(facet.Length > 0) { ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "", _instance.toStringMode()); } throw ex; } obj = m[facet]; m.Remove(facet); if(m.Count == 0) { _servantMapMap.Remove(ident); } return obj; } } public Ice.Object removeDefaultServant(string category) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. Ice.Object obj = null; _defaultServantMap.TryGetValue(category, out obj); if(obj == null) { Ice.NotRegisteredException ex = new Ice.NotRegisteredException(); ex.kindOfObject = "default servant"; ex.id = category; throw ex; } _defaultServantMap.Remove(category); return obj; } } public Dictionary removeAllFacets(Ice.Identity ident) { lock(this) { Debug.Assert(_instance != null); Dictionary m; _servantMapMap.TryGetValue(ident, out m); if(m == null) { Ice.NotRegisteredException ex = new Ice.NotRegisteredException(); ex.id = Ice.Util.identityToString(ident, _instance.toStringMode()); ex.kindOfObject = "servant"; throw ex; } _servantMapMap.Remove(ident); return m; } } public Ice.Object findServant(Ice.Identity ident, string facet) { lock(this) { // // This assert is not valid if the adapter dispatch incoming // requests from bidir connections. This method might be called if // requests are received over the bidir connection after the // adapter was deactivated. // //Debug.Assert(_instance != null); // Must not be called after destruction. if(facet == null) { facet = ""; } Dictionary m; _servantMapMap.TryGetValue(ident, out m); Ice.Object obj = null; if(m == null) { _defaultServantMap.TryGetValue(ident.category, out obj); if(obj == null) { _defaultServantMap.TryGetValue("", out obj); } } else { m.TryGetValue(facet, out obj); } return obj; } } public Ice.Object findDefaultServant(string category) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. Ice.Object obj = null; _defaultServantMap.TryGetValue(category, out obj); return obj; } } public Dictionary findAllFacets(Ice.Identity ident) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. Dictionary m = _servantMapMap[ident]; if(m != null) { return new Dictionary(m); } return new Dictionary(); } } public bool hasServant(Ice.Identity ident) { lock(this) { // // This assert is not valid if the adapter dispatch incoming // requests from bidir connections. This method might be called if // requests are received over the bidir connection after the // adapter was deactivated. // // //Debug.Assert(_instance != null); // Must not be called after destruction. Dictionary m; _servantMapMap.TryGetValue(ident, out m); if(m == null) { return false; } else { Debug.Assert(m.Count != 0); return true; } } } public void addServantLocator(Ice.ServantLocator locator, string category) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. Ice.ServantLocator l; _locatorMap.TryGetValue(category, out l); if(l != null) { Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException(); ex.id = IceUtilInternal.StringUtil.escapeString(category, "", _instance.toStringMode()); ex.kindOfObject = "servant locator"; throw ex; } _locatorMap[category] = locator; } } public Ice.ServantLocator removeServantLocator(string category) { lock(this) { Debug.Assert(_instance != null); // Must not be called after destruction. Ice.ServantLocator l; _locatorMap.TryGetValue(category, out l); if(l == null) { Ice.NotRegisteredException ex = new Ice.NotRegisteredException(); ex.id = IceUtilInternal.StringUtil.escapeString(category, "", _instance.toStringMode()); ex.kindOfObject = "servant locator"; throw ex; } _locatorMap.Remove(category); return l; } } public Ice.ServantLocator findServantLocator(string category) { lock(this) { // // This assert is not valid if the adapter dispatch incoming // requests from bidir connections. This method might be called if // requests are received over the bidir connection after the // adapter was deactivated. // // //Debug.Assert(_instance != null); // Must not be called after destruction. Ice.ServantLocator result; _locatorMap.TryGetValue(category, out result); return result; } } // // Only for use by Ice.ObjectAdapterI. // public ServantManager(Instance instance, string adapterName) { _instance = instance; _adapterName = adapterName; } /* ~ServantManager() { // // Don't check whether destroy() has been called. It might have // not been called if the associated object adapter was not // properly deactivated. // //lock(this) //{ //IceUtil.Assert.FinalizerAssert(_instance == null); //} } */ // // Only for use by Ice.ObjectAdapterI. // public void destroy() { Dictionary locatorMap = null; Ice.Logger logger = null; lock(this) { // // If the ServantManager has already been destroyed, we're done. // if(_instance == null) { return; } logger = _instance.initializationData().logger; _servantMapMap.Clear(); _defaultServantMap.Clear(); locatorMap = new Dictionary(_locatorMap); _locatorMap.Clear(); _instance = null; } foreach(KeyValuePair p in locatorMap) { Ice.ServantLocator locator = p.Value; try { locator.deactivate(p.Key); } catch(System.Exception ex) { string s = "exception during locator deactivation:\n" + "object adapter: `" + _adapterName + "'\n" + "locator category: `" + p.Key + "'\n" + ex; logger.error(s); } } } private Instance _instance; private readonly string _adapterName; private Dictionary > _servantMapMap = new Dictionary>(); private Dictionary _defaultServantMap = new Dictionary(); private Dictionary _locatorMap = new Dictionary(); } }