Ejemplo n.º 1
0
        public virtual object BuildOneInstance(NonNativeObjectInfo objectInfo)
        {
            ICache cache = GetSession().GetCache();

            // verify if the object is check to delete
            if (objectInfo.IsDeletedObject())
            {
                throw new ODBRuntimeException(NeoDatisError.ObjectIsMarkedAsDeletedForOid.AddParameter(objectInfo.GetOid()));
            }
            // Then check if object is in cache
            object o = cache.GetObjectWithOid(objectInfo.GetOid());

            if (o != null)
            {
                return(o);
            }
            Type instanceClazz = null;

            instanceClazz = classPool.GetClass(objectInfo.GetClassInfo().GetFullClassName());
            try
            {
                o = classIntrospector.NewInstanceOf(instanceClazz);
            }
            catch (System.Exception e)
            {
                throw new ODBRuntimeException(NeoDatisError.InstanciationError.AddParameter(objectInfo.GetClassInfo().GetFullClassName()), e);
            }
            // This can happen if ODB can not create the instance
            // TODO Check if returning null is correct
            if (o == null)
            {
                return(null);
            }
            // Keep the initial hash code. In some cases, when the class redefines
            // the hash code method
            // Hash code can return wrong values when attributes are not set (when
            // hash code depends on attribute values)
            // Hash codes are used as the key of the map,
            // So at the end of this method, if hash codes are different, object
            // will be removed from the cache and inserted back
            bool hashCodeIsOk    = true;
            int  initialHashCode = 0;

            try
            {
                initialHashCode = o.GetHashCode();
            }
            catch (System.Exception)
            {
                hashCodeIsOk = false;
            }
            // Adds this incomplete instance in the cache to manage cyclic reference
            if (hashCodeIsOk)
            {
                cache.AddObject(objectInfo.GetOid(), o, objectInfo.GetHeader());
            }
            ClassInfo            ci     = objectInfo.GetClassInfo();
            IOdbList <FieldInfo> fields = classIntrospector.GetAllFields(ci.GetFullClassName());

            FieldInfo          field = null;
            AbstractObjectInfo aoi   = null;
            object             value = null;

            for (int i = 0; i < fields.Count; i++)
            {
                field = fields[i];
                // Gets the id of this field
                int attributeId = ci.GetAttributeId(field.Name);
                if (OdbConfiguration.IsDebugEnabled(LogIdDebug))
                {
                    DLogger.Debug("getting field with name " + field.Name + ", attribute id is " + attributeId);
                }
                aoi = objectInfo.GetAttributeValueFromId(attributeId);
                // Check consistency
                // ensureClassCompatibily(field,
                // instanceInfo.getClassInfo().getAttributeinfo(i).getFullClassname());
                if (aoi != null && (!aoi.IsNull()))
                {
                    if (aoi.IsNative())
                    {
                        if (aoi.IsAtomicNativeObject())
                        {
                            if (aoi.IsNull())
                            {
                                value = null;
                            }
                            else
                            {
                                value = aoi.GetObject();
                            }
                        }
                        if (aoi.IsCollectionObject())
                        {
                            value = BuildCollectionInstance((CollectionObjectInfo)aoi);
                            // Manage a specific case of Set

                            /*
                             * if (typeof(Java.Util.Set).IsAssignableFrom(field.GetType()) && typeof(ICollection).IsAssignableFrom(value.GetType()))
                             * {
                             *      Java.Util.Set s = new Java.Util.HashSet();
                             *      s.AddAll((System.Collections.ICollection)value);
                             *      value = s;
                             * }*/
                        }
                        if (aoi.IsArrayObject())
                        {
                            value = BuildArrayInstance((ArrayObjectInfo)aoi);
                        }
                        if (aoi.IsMapObject())
                        {
                            value = BuildMapInstance((MapObjectInfo)aoi);
                        }
                        if (aoi.IsEnumObject())
                        {
                            value = BuildEnumInstance((EnumNativeObjectInfo)aoi, field.FieldType);
                        }
                    }
                    else
                    {
                        if (aoi.IsNonNativeObject())
                        {
                            if (aoi.IsDeletedObject())
                            {
                                if (NeoDatis.Odb.OdbConfiguration.DisplayWarnings())
                                {
                                    IError warning = NeoDatisError.AttributeReferencesADeletedObject
                                                     .AddParameter(objectInfo.GetClassInfo().GetFullClassName())
                                                     .AddParameter(objectInfo.GetOid()).AddParameter(field.Name);
                                    DLogger.Info(warning.ToString());
                                }
                                value = null;
                            }
                            else
                            {
                                value = BuildOneInstance((NonNativeObjectInfo)aoi);
                            }
                        }
                    }
                    if (value != null)
                    {
                        if (OdbConfiguration.IsDebugEnabled(LogIdDebug))
                        {
                            DLogger.Debug("Setting field " + field.Name + "(" + field.GetType().FullName + ") to " + value + " / " + value.GetType().FullName);
                        }
                        try
                        {
                            field.SetValue(o, value);
                        }
                        catch (System.Exception e)
                        {
                            throw new ODBRuntimeException(NeoDatisError.InstanceBuilderWrongObjectContainerType
                                                          .AddParameter(objectInfo.GetClassInfo().GetFullClassName())
                                                          .AddParameter(value.GetType().FullName).AddParameter(field.GetType().FullName), e);
                        }
                    }
                }
            }
            if (o != null && !OdbClassUtil.GetFullName(o.GetType()).Equals(objectInfo.GetClassInfo().GetFullClassName()))
            {
                new ODBRuntimeException(NeoDatisError.InstanceBuilderWrongObjectType
                                        .AddParameter(objectInfo.GetClassInfo().GetFullClassName())
                                        .AddParameter(o.GetType().FullName));
            }
            if (hashCodeIsOk || initialHashCode != o.GetHashCode())
            {
                // Bug (sf bug id=1875544 )detected by glsender
                // This can happen when an object has redefined its own hashcode
                // method and depends on the field values
                // Then, we have to remove object from the cache and re-insert to
                // correct map hash code
                cache.RemoveObjectWithOid(objectInfo.GetOid());
                // re-Adds instance in the cache
                cache.AddObject(objectInfo.GetOid(), o, objectInfo.GetHeader());
            }
            if (triggerManager != null)
            {
                triggerManager.ManageSelectTriggerAfter(objectInfo.GetClassInfo().GetFullClassName
                                                            (), objectInfo, objectInfo.GetOid());
            }
            if (OdbConfiguration.ReconnectObjectsToSession())
            {
                ICrossSessionCache crossSessionCache = CacheFactory.GetCrossSessionCache(engine.GetBaseIdentification().GetIdentification());
                crossSessionCache.AddObject(o, objectInfo.GetOid());
            }

            return(o);
        }