/// <summary>
        /// Build a meta representation of an object
        /// <pre>
        /// warning: When an object has two fields with the same name (a private field with the same name in a parent class, the deeper field (of the parent) is ignored!)
        /// </pre>
        /// </summary>
        /// <param name="o"></param>
        /// <param name="ci"></param>
        /// <param name="recursive"></param>
        /// <returns>The ObjectInfo</returns>
        protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetObjectInfoInternal
            (NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo nnoi, object o, NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo
            ci, bool recursive, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                                        > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback
            callback)
        {
            object value = null;

            if (o == null)
            {
                return(NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo.GetInstance());
            }
            System.Type clazz = o.GetType();
            NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType
                                                                .GetFromClass(clazz);
            string className = OdbClassUtil.GetFullName(clazz);

            if (type.IsNative())
            {
                return(GetNativeObjectInfoInternal(type, o, recursive, alreadyReadObjects,
                                                   callback));
            }
            // sometimes the clazz.getName() may not match the ci.getClassName()
            // It happens when the attribute is an interface or superclass of the
            // real attribute class
            // In this case, ci must be updated to the real class info
            if (ci != null && !clazz.FullName.Equals(ci.GetFullClassName()))
            {
                ci   = GetClassInfo(className);
                nnoi = null;
            }
            NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo mainAoi = (NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                                                )nnoi;
            bool isRootObject = false;

            if (alreadyReadObjects == null)
            {
                alreadyReadObjects = new NeoDatis.Tool.Wrappers.Map.OdbHashMap <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                                                >();
                isRootObject = true;
            }
            if (o != null)
            {
                NonNativeObjectInfo cachedNnoi = null;
                alreadyReadObjects.TryGetValue(o, out cachedNnoi);

                if (cachedNnoi != null)
                {
                    ObjectReference or = new ObjectReference(cachedNnoi);
                    return(or);
                }
                if (callback != null)
                {
                    callback.ObjectFound(o);
                }
            }
            if (mainAoi == null)
            {
                mainAoi = BuildNnoi(o, ci, null, null, null, alreadyReadObjects);
            }
            alreadyReadObjects[o] = mainAoi;
            NeoDatis.Tool.Wrappers.List.IOdbList <System.Reflection.FieldInfo> fields = classIntrospector.GetAllFields(className);
            NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo            aoi    = null;
            int attributeId = -1;

            // For all fields
            for (int i = 0; i < fields.Count; i++)
            {
                System.Reflection.FieldInfo field = fields[i];
                try
                {
                    value       = field.GetValue(o);
                    attributeId = ci.GetAttributeId(field.Name);
                    if (attributeId == -1)
                    {
                        throw new ODBRuntimeException(NeoDatisError.ObjectIntrospectorNoFieldWithName.AddParameter(ci.GetFullClassName()).AddParameter(field.Name));
                    }
                    ODBType valueType = null;
                    if (value == null)
                    {
                        // If value is null, take the type from the field type
                        // declared in the class
                        valueType = ODBType.GetFromClass(field.FieldType);
                    }
                    else
                    {
                        // Else take the real attribute type!
                        valueType = ODBType.GetFromClass(value.GetType());
                    }
                    // for native fields
                    if (valueType.IsNative())
                    {
                        aoi = GetNativeObjectInfoInternal(valueType, value, recursive, alreadyReadObjects, callback);
                        mainAoi.SetAttributeValue(attributeId, aoi);
                    }
                    else
                    {
                        //callback.objectFound(value);
                        // Non Native Objects
                        if (value == null)
                        {
                            ClassInfo clai = GetClassInfo(OdbClassUtil.GetFullName(field.GetType()));

                            aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeNullObjectInfo(clai);
                            mainAoi.SetAttributeValue(attributeId, aoi);
                        }
                        else
                        {
                            ClassInfo clai = GetClassInfo(OdbClassUtil.GetFullName(value.GetType()));
                            if (recursive)
                            {
                                aoi = GetObjectInfoInternal(null, value, clai, recursive, alreadyReadObjects, callback
                                                            );
                                mainAoi.SetAttributeValue(attributeId, aoi);
                            }
                            else
                            {
                                // When it is not recursive, simply add the object
                                // values.add(value);
                                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.InternalError
                                                                           .AddParameter("Should not enter here - ObjectIntrospector - 'simply add the object'"
                                                                                         ));
                            }
                        }
                    }
                }
                catch (System.ArgumentException e)
                {
                    throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.InternalError
                                                               .AddParameter("in getObjectInfoInternal"), e);
                }
                catch (System.MemberAccessException e)
                {
                    throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.InternalError
                                                               .AddParameter("getObjectInfoInternal"), e);
                }
            }
            if (isRootObject)
            {
                alreadyReadObjects.Clear();
                alreadyReadObjects = null;
            }
            return(mainAoi);
        }
Пример #2
0
        /// <summary>Store an object with the specific id</summary>
        /// <param name="oid"></param>
        /// <param name="@object"></param>
        /// <returns></returns>
        /// <></>
        protected virtual NeoDatis.Odb.OID InternalStore(OID oid, object o)
        {
            if (GetSession(true).IsRollbacked())
            {
                throw new ODBRuntimeException(NeoDatisError.OdbHasBeenRollbacked.AddParameter(GetBaseIdentification().ToString()));
            }
            if (o == null)
            {
                throw new ODBRuntimeException(NeoDatisError.OdbCanNotStoreNullObject);
            }
            Type clazz = o.GetType();

            if (ODBType.IsNative(clazz))
            {
                throw new ODBRuntimeException(NeoDatisError.OdbCanNotStoreNativeObjectDirectly
                                              .AddParameter(clazz.FullName).AddParameter(ODBType.GetFromClass(clazz).GetName()).AddParameter(clazz.FullName));
            }
            // The object must be transformed into meta representation
            ClassInfo ci        = null;
            string    className = OdbClassUtil.GetFullName(clazz);

            // first checks if the class of this object already exist in the
            // metamodel
            if (GetMetaModel().ExistClass(className))
            {
                ci = GetMetaModel().GetClassInfo(className, true);
            }
            else
            {
                ClassInfoList ciList = classIntrospector.Introspect(o.GetType(), true);
                // All new classes found
                objectWriter.AddClasses(ciList);
                ci = ciList.GetMainClassInfo();
            }
            // first detects if we must perform an insert or an update
            // If object is in the cache, we must perform an update, else an insert
            bool   mustUpdate = false;
            ICache cache      = GetSession(true).GetCache();

            if (o != null)
            {
                OID cacheOid = cache.IdOfInsertingObject(o);
                if (cacheOid != null)
                {
                    return(cacheOid);
                }
                // throw new ODBRuntimeException("Inserting meta representation of
                // an object without the object itself is not yet supported");
                mustUpdate = cache.ExistObject(o);
            }
            // The introspection callback is used to execute some specific task (like calling trigger, for example) while introspecting the object
            IIntrospectionCallback callback = introspectionCallbackForInsert;

            if (mustUpdate)
            {
                callback = introspectionCallbackForUpdate;
            }
            // Transform the object into an ObjectInfo
            NonNativeObjectInfo nnoi = (NonNativeObjectInfo)objectIntrospector.GetMetaRepresentation(o, ci, true, null, callback);

            // During the introspection process, if object is to be updated, then the oid has been set
            mustUpdate = nnoi.GetOid() != null;
            if (mustUpdate)
            {
                return(objectWriter.UpdateNonNativeObjectInfo(nnoi, false));
            }
            return(objectWriter.InsertNonNativeObject(oid, nnoi, true));
        }