private Ice.ObjectFactory loadObjectFactory(string id) { Ice.ObjectFactory factory = null; try { Type c = AssemblyUtil.findType(instance_, typeToClass(id)); if(c == null) { return null; } // // Ensure the class is instantiable. // if(!c.IsAbstract && !c.IsInterface) { Ice.ObjectFactory dynamicFactory = new DynamicObjectFactory(c); // // We will try to install the dynamic factory, but // another thread may install a factory first. // while(factory == null) { try { instance_.servantFactoryManager().add(dynamicFactory, id); factory = dynamicFactory; } catch(Ice.AlreadyRegisteredException) { // // Another thread already installed the // factory, so try to obtain it. It's // possible (but unlikely) that the // factory will have already been removed, // in which case the return value will be // null and the while loop will attempt to // install the dynamic factory again. // factory = instance_.servantFactoryManager().find(id); } } } } catch(Exception ex) { Ice.NoObjectFactoryException e = new Ice.NoObjectFactoryException(ex); e.type = id; throw e; } return factory; }
public virtual void readObject(IPatcher patcher) { Ice.Object v = null; if(_readEncapsStack == null) // Lazy initialization { _readEncapsStack = _readEncapsCache; if(_readEncapsStack != null) { _readEncapsCache = _readEncapsCache.next; } else { _readEncapsStack = new ReadEncaps(); } } if(_readEncapsStack.patchMap == null) // Lazy initialization { _readEncapsStack.patchMap = new Hashtable(); _readEncapsStack.unmarshaledMap = new Hashtable(); _readEncapsStack.typeIdMap = new Hashtable(); } int index = readInt(); if(patcher != null) { if(index == 0) { patcher.patch(null); return; } if(index < 0) { int i = -index; IceUtilInternal.LinkedList patchlist = (IceUtilInternal.LinkedList)_readEncapsStack.patchMap[i]; if(patchlist == null) { // // We have no outstanding instances to be patched // for this index, so make a new entry in the // patch map. // patchlist = new IceUtilInternal.LinkedList(); _readEncapsStack.patchMap[i] = patchlist; } // // Append a patcher for this instance and see if we // can patch the instance. (The instance may have been // unmarshaled previously.) // patchlist.Add(patcher); patchReferences(null, i); return; } } if(index < 0) { throw new Ice.MarshalException("Invalid class instance index"); } string mostDerivedId = readTypeId(); string id = mostDerivedId; while(true) { // // If we slice all the way down to Ice::Object, we throw // because Ice::Object is abstract. // if(id == Ice.ObjectImpl.ice_staticId()) { Ice.NoObjectFactoryException ex = new Ice.NoObjectFactoryException(); ex.type = mostDerivedId; throw ex; } // // Try to find a factory registered for the specific // type. // Ice.ObjectFactory userFactory = instance_.servantFactoryManager().find(id); if(userFactory != null) { v = userFactory.create(id); } // // If that fails, invoke the default factory if one // has been registered. // if(v == null) { userFactory = instance_.servantFactoryManager().find(""); if(userFactory != null) { v = userFactory.create(id); } } // // Last chance: check whether the class is // non-abstract and dynamically instantiate it using // reflection. // if(v == null) { userFactory = loadObjectFactory(id); if(userFactory != null) { v = userFactory.create(id); } } if(v == null) { if(_sliceObjects) { // // Performance sensitive, so we use lazy // initialization for tracing. // if(_traceSlicing == -1) { _traceSlicing = instance_.traceLevels().slicing; _slicingCat = instance_.traceLevels().slicingCat; } if(_traceSlicing > 0) { TraceUtil.traceSlicing("class", id, _slicingCat, instance_.initializationData().logger); } skipSlice(); // Slice off this derived part -- we don't understand it. id = readTypeId(); // Read next id for next iteration. continue; } else { Ice.NoObjectFactoryException ex = new Ice.NoObjectFactoryException(); ex.type = id; throw ex; } } int i = index; _readEncapsStack.unmarshaledMap[i] = v; // // Record each object instance so that // readPendingObjects can invoke ice_postUnmarshal // after all objects have been unmarshaled. // if(_objectList == null) { _objectList = new ArrayList(); } _objectList.Add(v); v.read__(this, false); patchReferences(i, null); return; } }
internal virtual void patchReferences(object instanceIndex, object patchIndex) { // // Called whenever we have unmarshaled a new instance or // an index. The instanceIndex is the index of the // instance just unmarshaled and patchIndex is the index // just unmarshaled. (Exactly one of the two parameters // must be null.) Patch any pointers in the patch map with // the new address. // Debug.Assert( ((object)instanceIndex != null && (object)patchIndex == null) || ((object)instanceIndex == null && (object)patchIndex != null)); IceUtilInternal.LinkedList patchlist; Ice.Object v; if((object)instanceIndex != null) { // // We have just unmarshaled an instance -- check if // something needs patching for that instance. // patchlist = (IceUtilInternal.LinkedList)_readEncapsStack.patchMap[instanceIndex]; if(patchlist == null) { return; // We don't have anything to patch for the instance just unmarshaled. } v = (Ice.Object)_readEncapsStack.unmarshaledMap[instanceIndex]; patchIndex = instanceIndex; } else { // // We have just unmarshaled an index -- check if we // have unmarshaled the instance for that index yet. // v = (Ice.Object)_readEncapsStack.unmarshaledMap[patchIndex]; if(v == null) { return; // We haven't unmarshaled the instance for this index yet. } patchlist = (IceUtilInternal.LinkedList)_readEncapsStack.patchMap[patchIndex]; } Debug.Assert(patchlist != null && patchlist.Count > 0); Debug.Assert(v != null); // // Patch all references that refer to the instance. // foreach(IPatcher patcher in patchlist) { try { patcher.patch(v); } catch(InvalidCastException ex) { // // TODO: Fix this (also for C++ and Java): // NoObjectFactoryException is misleading because // the type sent by the sender is incompatible // with what is expected. This really should be a // MarshalException. // Ice.NoObjectFactoryException nof = new Ice.NoObjectFactoryException(ex); nof.type = patcher.type(); throw nof; } } // // Clear out the patch map for that index -- there is // nothing left to patch for that index for the time // being. // _readEncapsStack.patchMap.Remove(patchIndex); }