/// <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); }
/// <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)); }