Example #1
0
 public override NeoDatis.Odb.OID WriteObjectInfo(NeoDatis.Odb.OID oid, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                  aoi, long position, bool updatePointers)
 {
     // TODO check if it must be written in transaction
     return(objectWriter.WriteNonNativeObjectInfo(oid, aoi, position, updatePointers,
                                                  true));
 }
 public virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo BuildNnoi
     (object o, NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo classInfo, NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo
     [] values, long[] attributesIdentification, int[] attributeIds, System.Collections.Generic.IDictionary
     <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects
     )
 {
     NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                                         (o, classInfo, values, attributesIdentification, attributeIds);
     if (storageEngine != null)
     {
         // for unit test purpose
         NeoDatis.Odb.Core.Transaction.ICache cache = storageEngine.GetSession(true).GetCache
                                                          ();
         // Check if object is in the cache, if so sets its oid
         NeoDatis.Odb.OID oid = cache.GetOid(o, false);
         if (oid != null)
         {
             nnoi.SetOid(oid);
             // Sets some values to the new header to keep track of the infos
             // when
             // executing NeoDatis without closing it, just committing.
             // Bug reported by Andy
             NeoDatis.Odb.Core.Layers.Layer2.Meta.ObjectInfoHeader oih = cache.GetObjectInfoHeaderFromOid
                                                                             (oid, true);
             nnoi.GetHeader().SetObjectVersion(oih.GetObjectVersion());
             nnoi.GetHeader().SetUpdateDate(oih.GetUpdateDate());
             nnoi.GetHeader().SetCreationDate(oih.GetCreationDate());
         }
     }
     return(nnoi);
 }
Example #3
0
        public override object GetObjectFromOid(NeoDatis.Odb.OID oid)
        {
            if (oid == null)
            {
                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.CanNotGetObjectFromNullOid
                                                           );
            }
            NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = GetObjectReader()
                                                                            .ReadNonNativeObjectInfoFromOid(null, oid, true, true);
            if (nnoi.IsDeletedObject())
            {
                throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.ObjectIsMarkedAsDeletedForOid
                                                           .AddParameter(oid));
            }
            object o = nnoi.GetObject();

            if (o == null)
            {
                o = GetObjectReader().GetInstanceBuilder().BuildOneInstance(nnoi);
            }
            NeoDatis.Odb.Core.Transaction.ISession lsession = GetSession(true);
            // Here oid can be different from nnoi.getOid(). This is the case when
            // the oid is an external oid. That`s why we use
            // nnoi.getOid() to put in the cache
            lsession.GetCache().AddObject(nnoi.GetOid(), o, nnoi.GetHeader());
            lsession.GetTmpCache().ClearObjectInfos();
            return(o);
        }
Example #4
0
 public virtual void StartReadingObjectInfoWithOid(NeoDatis.Odb.OID oid, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                                   objectInfo)
 {
     if (oid == null)
     {
         throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.CacheNullOid
                                                    );
     }
     object[] objects = null;
     readingObjectInfo.TryGetValue(oid, out objects);
     // TODO : use a value object instead of an array!
     if (objects == null)
     {
         // The key is the oid, the value is an array of 2 objects :
         // 1-the read count, 2-The object info
         // Here we are saying that the object with oid 'oid' is
         // being read for the first time
         object[] values = new object[] { (short)1, objectInfo };
         readingObjectInfo[oid] = values;
     }
     else
     {
         // Here the object is already being read. It is necessary to
         // increase the read count
         short currentReadCount = ((short)objects[0]);
         objects[0] = (short)(currentReadCount + 1);
     }
 }
Example #5
0
 public override NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo GetMetaObjectFromOid
     (NeoDatis.Odb.OID oid)
 {
     NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = GetObjectReader()
                                                                     .ReadNonNativeObjectInfoFromOid(null, oid, true, false);
     GetSession(true).GetTmpCache().ClearObjectInfos();
     return(nnoi);
 }
Example #6
0
 public virtual object GetCurrentInstance(NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                          nnoi)
 {
     //FIXME no need
     if (nnoi.GetObject() != null)
     {
         return(nnoi.GetObject());
     }
     return(instanceBuilder.BuildOneInstance(nnoi));
 }
		private void StoreNewObjectReference(long positionToUpdateReference, NonNativeObjectInfo
			 oi2, int objectRecursionLevel, string attributeName)
		{
			NewNonNativeObjectAction nnnoa = new 
				NewNonNativeObjectAction(positionToUpdateReference
				, oi2, objectRecursionLevel, attributeName);
			newObjectMetaRepresentations.Add(nnnoa);
			nbChanges++;
		}
        /// <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>Checks if something in the Map has changed, if yes, stores the change</summary>
		/// <param name="nnoi1">
		/// The first Object meta representation (nnoi =
		/// NonNativeObjectInfo)
		/// </param>
		/// <param name="nnoi2">The second object meta representation</param>
		/// <param name="fieldIndex">The field index that this map represents</param>
		/// <param name="moi1">The Meta representation of the map 1 (moi = MapObjectInfo)</param>
		/// <param name="moi2">The Meta representation of the map 2</param>
		/// <param name="objectRecursionLevel"></param>
		/// <returns>true if the 2 map representations are different</returns>
		private bool ManageMapChanges(NonNativeObjectInfo
			 nnoi1, NonNativeObjectInfo nnoi2, int fieldId
			, MapObjectInfo moi1, MapObjectInfo
			 moi2, int objectRecursionLevel)
		{
            if (true)
            {
                return true;
            }
			IDictionary<AbstractObjectInfo
				, AbstractObjectInfo> map1 = moi1.GetMap();
			IDictionary<AbstractObjectInfo
				, AbstractObjectInfo> map2 = moi2.GetMap();
			if (map1.Count != map2.Count)
			{
				System.Text.StringBuilder buffer = new System.Text.StringBuilder();
				buffer.Append("Map size has changed oldsize=").Append(map1.Count).Append("/newsize="
					).Append(map2.Count);
				StoreChangedObject(nnoi1, nnoi2, fieldId, moi1, moi2, buffer.ToString(), objectRecursionLevel
					);
				return true;
			}
			IEnumerator<AbstractObjectInfo
				> keys1 = map1.Keys.GetEnumerator();
			IEnumerator<AbstractObjectInfo
				> keys2 = map2.Keys.GetEnumerator();
			AbstractObjectInfo key1 = null;
			AbstractObjectInfo key2 = null;
			AbstractObjectInfo value1 = null;
			AbstractObjectInfo value2 = null;
			int index = 0;
			while (keys1.MoveNext())
			{
                keys2.MoveNext();
				key1 = keys1.Current;
				key2 = keys2.Current;
				bool keysHaveChanged = this.HasChanged(key1, key2, objectRecursionLevel);
				if (keysHaveChanged)
				{
					StoreChangedObject(nnoi1, nnoi2, fieldId, key1, key2, "Map key index " + index + 
						" has changed", objectRecursionLevel);
					return true;
				}
				value1 = map1[key1];
				value2 = map2[key2];
				bool valuesHaveChanged = this.HasChanged(value1, value2, objectRecursionLevel);
				if (valuesHaveChanged)
				{
					StoreChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "Map value index " + index
						 + " has changed", objectRecursionLevel);
					return true;
				}
				index++;
			}
			return false;
		}
		/// <summary>
		/// Checks if something in the Collection has changed, if yes, stores the
		/// change
		/// </summary>
		/// <param name="nnoi1">
		/// The first Object meta representation (nnoi =
		/// NonNativeObjectInfo)
		/// </param>
		/// <param name="nnoi2">The second object meta representation</param>
		/// <param name="fieldIndex">The field index that this collection represents</param>
		/// <param name="coi1">
		/// The Meta representation of the collection 1 (coi =
		/// CollectionObjectInfo)
		/// </param>
		/// <param name="coi2">The Meta representation of the collection 2</param>
		/// <param name="objectRecursionLevel"></param>
		/// <returns>true if 2 collection representation are different</returns>
		private bool ManageCollectionChanges(NonNativeObjectInfo
			 nnoi1, NonNativeObjectInfo nnoi2, int fieldId
			, CollectionObjectInfo coi1, CollectionObjectInfo
			 coi2, int objectRecursionLevel)
		{
			ICollection<AbstractObjectInfo
				> collection1 = coi1.GetCollection();
			ICollection<AbstractObjectInfo
				> collection2 = coi2.GetCollection();
			if (collection1.Count != collection2.Count)
			{
				System.Text.StringBuilder buffer = new System.Text.StringBuilder();
				buffer.Append("Collection size has changed oldsize=").Append(collection1.Count).Append
					("/newsize=").Append(collection2.Count);
				StoreChangedObject(nnoi1, nnoi2, fieldId, coi1, coi2, buffer.ToString(), objectRecursionLevel
					);
				return true;
			}
			System.Collections.IEnumerator iterator1 = collection1.GetEnumerator();
			System.Collections.IEnumerator iterator2 = collection2.GetEnumerator();
			AbstractObjectInfo value1 = null;
			AbstractObjectInfo value2 = null;
			int index = 0;
			while (iterator1.MoveNext())
			{
                iterator2.MoveNext();
                value1 = (AbstractObjectInfo)iterator1.Current;
				value2 = (AbstractObjectInfo)iterator2.Current;
				bool hasChanged = this.HasChanged(value1, value2, objectRecursionLevel);
				if (hasChanged)
				{
					// We consider collection has changed only if object are
					// different, If objects are the same instance, but something in
					// the object has changed, then the collection has not
					// changed,only the object
					if (value1.IsNonNativeObject() && value2.IsNonNativeObject())
					{
						NonNativeObjectInfo nnoia = (NonNativeObjectInfo
							)value1;
						NonNativeObjectInfo nnoib = (NonNativeObjectInfo
							)value2;
						if (nnoia.GetOid() != null && !nnoia.GetOid().Equals(nnoi2.GetOid()))
						{
							// Objects are not the same instance -> the collection
							// has changed
							StoreChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "List element index " +
								 index + " has changed", objectRecursionLevel);
						}
					}
					else
					{
						supportInPlaceUpdate = false;
						nbChanges++;
					}
					//storeChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "List element index " + index + " has changed", objectRecursionLevel);
					return true;
				}
				index++;
			}
			return false;
		}
		private void StoreChangedObject(NonNativeObjectInfo
			 aoi1, NonNativeObjectInfo aoi2, int fieldId
			, AbstractObjectInfo oldValue, AbstractObjectInfo
			 newValue, string message, int objectRecursionLevel)
		{
			if (aoi1 != null && aoi2 != null)
			{
				if (aoi1.GetOid() != null && aoi1.GetOid().Equals(aoi2.GetOid()))
				{
					changedObjectMetaRepresentations.Add(aoi2);
					changes.Add(new ChangedObjectInfo(aoi1
						.GetClassInfo(), aoi2.GetClassInfo(), fieldId, oldValue, newValue, message, objectRecursionLevel
						));
					// also the max recursion level
					if (objectRecursionLevel > maxObjectRecursionLevel)
					{
						maxObjectRecursionLevel = objectRecursionLevel;
					}
					nbChanges++;
				}
				else
				{
					newObjects.Add(aoi2.GetObject());
					string fieldName = aoi1.GetClassInfo().GetAttributeInfoFromId(fieldId).GetName();
					// keep track of the position where the reference must be
					// updated - use aoi1 to get position, because aoi2 do not have position defined yet
					long positionToUpdateReference = aoi1.GetAttributeDefinitionPosition(fieldId);
					StoreNewObjectReference(positionToUpdateReference, aoi2, objectRecursionLevel, fieldName
						);
				}
			}
			else
			{
				//newObjectMetaRepresentations.add(aoi2);
				NeoDatis.Tool.DLogger.Info("Non native object with null object");
			}
		}
		public virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo BuildNnoi
			(object o, NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo classInfo, NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo
			[] values, long[] attributesIdentification, int[] attributeIds, System.Collections.Generic.IDictionary
			<object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects
			)
		{
			NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
				(o, classInfo, values, attributesIdentification, attributeIds);
			if (storageEngine != null)
			{
				// for unit test purpose
				NeoDatis.Odb.Core.Transaction.ICache cache = storageEngine.GetSession(true).GetCache
					();
				// Check if object is in the cache, if so sets its oid
				NeoDatis.Odb.OID oid = cache.GetOid(o, false);
				if (oid != null)
				{
					nnoi.SetOid(oid);
					// Sets some values to the new header to keep track of the infos
					// when
					// executing NeoDatis without closing it, just committing.
					// Bug reported by Andy
					NeoDatis.Odb.Core.Layers.Layer2.Meta.ObjectInfoHeader oih = cache.GetObjectInfoHeaderFromOid
						(oid, true);
					nnoi.GetHeader().SetObjectVersion(oih.GetObjectVersion());
					nnoi.GetHeader().SetUpdateDate(oih.GetUpdateDate());
					nnoi.GetHeader().SetCreationDate(oih.GetCreationDate());
				}
			}
			return nnoi;
		}
Example #13
0
		public virtual void StartReadingObjectInfoWithOid(NeoDatis.Odb.OID oid, NonNativeObjectInfo
			 objectInfo)
		{
			if (oid == null)
			{
				throw new ODBRuntimeException(NeoDatisError.CacheNullOid);
			}
			object[] objects = (object[])readingObjectInfo[oid];
			if (objects == null)
			{
				// The key is the oid, the value is an array of 2 objects :
				// 1-the read count, 2-The object info
				// Here we are saying that the object with oid 'oid' is
				// being read for the first time
				object[] values = new object[] { (short)1, objectInfo };
				readingObjectInfo[oid] = values;
			}
			else
			{
				// Here the object is already being read. It is necessary to
				// increase the read count
				short currentReadCount = ((short)objects[0]);
				objects[0] = (short)(currentReadCount + 1);
			}
		}
Example #14
0
		//throw new ODBRuntimeException(Error.CACHE_IS_FULL.addParameter(objectInfoPointersCacheFromOid.size()).addParameter(OdbConfiguration.getMaxNumberOfObjectInCache()));
		public virtual void StartInsertingObjectWithOid(object o, NeoDatis.Odb.OID 
			oid, NonNativeObjectInfo nnoi)
		{
			// In this case oid can be -1,because object is beeing inserted and do
			// not have yet a defined oid.
			if (o == null)
			{
				return;
			}
			ObjectInsertingInfo oii = null;
            insertingObjects.TryGetValue(o,out oii);
			if (oii == null)
			{
				insertingObjects[o] = new ObjectInsertingInfo(oid, 1);
			}
			else
			{
				oii.level++;
			}
		}
Example #15
0
 public override NeoDatis.Odb.OID UpdateObject(NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                               nnoi, bool forceUpdate)
 {
     return(objectWriter.UpdateNonNativeObjectInfo(nnoi, forceUpdate));
 }
		private void StoreActionSetAttributetoNull(NonNativeObjectInfo
			 nnoi, int id, int objectRecursionLevel)
		{
			nbChanges++;
			SetAttributeToNullAction action = new 
				SetAttributeToNullAction(nnoi, id);
			attributeToSetToNull.Add(action);
		}
		private void StoreArrayChange(NonNativeObjectInfo
			 nnoi, int arrayAttributeId, int arrayIndex, AbstractObjectInfo
			 value, bool supportInPlaceUpdate)
		{
			nbChanges++;
			ArrayModifyElement ame = new ArrayModifyElement
				(nnoi, arrayAttributeId, arrayIndex, value, supportInPlaceUpdate);
			arrayChanges.Add(ame);
		}
		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;
		}
		private void StoreChangedObject(NonNativeObjectInfo
			 aoi1, NonNativeObjectInfo aoi2, int fieldId
			, int objectRecursionLevel)
		{
			nbChanges++;
			if (aoi1 != null && aoi2 != null)
			{
				changes.Add(new ChangedObjectInfo(aoi1
					.GetClassInfo(), aoi2.GetClassInfo(), fieldId, aoi1.GetAttributeValueFromId(fieldId
					), aoi2.GetAttributeValueFromId(fieldId), objectRecursionLevel));
				// also the max recursion level
				if (objectRecursionLevel > maxObjectRecursionLevel)
				{
					maxObjectRecursionLevel = objectRecursionLevel;
				}
			}
			else
			{
				NeoDatis.Tool.DLogger.Info("Non native object with null object");
			}
		}
public virtual object NewFullInstanceOf(System.Type clazz, NonNativeObjectInfo
			 nnoi)
		{
			string className = clazz.FullName;
			NeoDatis.Odb.Core.Layers.Layer2.Instance.FullInstantiationHelper helper = (NeoDatis.Odb.Core.Layers.Layer2.Instance.FullInstantiationHelper
				)fullInstantiationHelpers[className];
			if (helper != null)
			{
				object o = helper.Instantiate(nnoi);
				if (o != null)
				{
					return o;
				}
			}
			return null;
		}
		/// <summary>Checks if something in the Arary has changed, if yes, stores the change</summary>
		/// <param name="nnoi1">
		/// The first Object meta representation (nnoi =
		/// NonNativeObjectInfo)
		/// </param>
		/// <param name="nnoi2">The second object meta representation</param>
		/// <param name="fieldIndex">The field index that this collection represents</param>
		/// <param name="aoi1">The Meta representation of the array 1 (aoi = ArraybjectInfo)</param>
		/// <param name="aoi2">The Meta representation of the array 2</param>
		/// <param name="objectRecursionLevel"></param>
		/// <returns>true if the 2 array representations are different</returns>
		private bool ManageArrayChanges(NonNativeObjectInfo
			 nnoi1, NonNativeObjectInfo nnoi2, int fieldId
			, ArrayObjectInfo aoi1, ArrayObjectInfo
			 aoi2, int objectRecursionLevel)
		{
			object[] array1 = aoi1.GetArray();
			object[] array2 = aoi2.GetArray();
			if (array1.Length != array2.Length)
			{
				System.Text.StringBuilder buffer = new System.Text.StringBuilder();
				buffer.Append("Array size has changed oldsize=").Append(array1.Length).Append("/newsize="
					).Append(array2.Length);
				StoreChangedObject(nnoi1, nnoi2, fieldId, aoi1, aoi2, buffer.ToString(), objectRecursionLevel
					);
				supportInPlaceUpdate = false;
				return true;
			}
			AbstractObjectInfo value1 = null;
			AbstractObjectInfo value2 = null;
			// check if this array supports in place update
			bool localSupportInPlaceUpdate = ODBType.HasFixSize
				(aoi2.GetComponentTypeId());
			int index = 0;
			bool hasChanged = false;
			try
			{
				for (int i = 0; i < array1.Length; i++)
				{
					value1 = (AbstractObjectInfo)array1[i];
					value2 = (AbstractObjectInfo)array2[i];
					bool localHasChanged = this.HasChanged(value1, value2, objectRecursionLevel);
					if (localHasChanged)
					{
						StoreArrayChange(nnoi1, fieldId, i, value2, localSupportInPlaceUpdate);
						if (localSupportInPlaceUpdate)
						{
							hasChanged = true;
						}
						else
						{
							hasChanged = true;
							return hasChanged;
						}
					}
					index++;
				}
			}
			finally
			{
				if (hasChanged && !localSupportInPlaceUpdate)
				{
					supportInPlaceUpdate = false;
				}
			}
			return hasChanged;
		}
 public override object BuildOneInstance(NonNativeObjectInfo objectInfo)
 {
     return objectInfo;
 }
		private bool HasChanged(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int objectRecursionLevel)
		{
			AbstractObjectInfo value1 = null;
			AbstractObjectInfo value2 = null;
			bool hasChanged = false;
			// If the object is already being checked, return false, this second
			// check will not affect the check
            int n = 0;
            alreadyCheckingObjects.TryGetValue(nnoi2, out n);
			if (n != 0)
			{
				return false;
			}
			// Put the object in the temporary cache
			alreadyCheckingObjects[nnoi1] = 1;
			alreadyCheckingObjects[nnoi2] = 1;
			// Warning ID Start with 1 and not 0
			for (int id = 1; id <= nnoi1.GetMaxNbattributes(); id++)
			{
				value1 = nnoi1.GetAttributeValueFromId(id);
				// Gets the value by the attribute id to be sure
				// Problem because a new object info may not have the right ids ?
				// Check if
				// the new oiD is ok.
				value2 = nnoi2.GetAttributeValueFromId(id);
				if (value2 == null)
				{
					// this means the object to have attribute id
					StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel);
					hasChanged = true;
					continue;
				}
				if (value1 == null)
				{
					//throw new ODBRuntimeException("ObjectInfoComparator.hasChanged:attribute with id "+id+" does not exist on "+nnoi2);
					// This happens when this object was created with an version of ClassInfo (which has been refactored).
					// In this case,we simply tell that in place update is not supported so that the object will be rewritten with 
					// new metamodel
					supportInPlaceUpdate = false;
					continue;
				}
				// If both are null, no effect
				if (value1.IsNull() && value2.IsNull())
				{
					continue;
				}
				if (value1.IsNull() || value2.IsNull())
				{
					supportInPlaceUpdate = false;
					hasChanged = true;
					StoreActionSetAttributetoNull(nnoi1, id, objectRecursionLevel);
					continue;
				}
				if (!ClassAreCompatible(value1, value2))
				{
					if (value2 is NativeObjectInfo)
					{
						StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel);
						StoreChangedAttributeAction(new ChangedNativeAttributeAction
							(nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo
							)value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId
							(id).GetName()));
					}
					if (value2 is ObjectReference)
					{
						NonNativeObjectInfo nnoi = (NonNativeObjectInfo
							)value1;
						ObjectReference oref = (ObjectReference
							)value2;
						if (!nnoi.GetOid().Equals(oref.GetOid()))
						{
							StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel);
							int attributeIdThatHasChanged = id;
							// this is the exact position where the object reference
							// definition is stored
							long attributeDefinitionPosition = nnoi2.GetAttributeDefinitionPosition(attributeIdThatHasChanged
								);
							StoreChangedAttributeAction(new ChangedObjectReferenceAttributeAction
								(attributeDefinitionPosition, (ObjectReference
								)value2, objectRecursionLevel));
						}
						else
						{
							continue;
						}
					}
					hasChanged = true;
					continue;
				}
				if (value1.IsAtomicNativeObject())
				{
					if (!value1.Equals(value2))
					{
						// storeChangedObject(nnoi1, nnoi2, id,
						// objectRecursionLevel);
						StoreChangedAttributeAction(new ChangedNativeAttributeAction
							(nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo
							)value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId
							(id).GetName()));
						hasChanged = true;
						continue;
					}
					continue;
				}
				if (value1.IsCollectionObject())
				{
					CollectionObjectInfo coi1 = (CollectionObjectInfo)value1;
					CollectionObjectInfo coi2 = (CollectionObjectInfo)value2;
					bool collectionHasChanged = ManageCollectionChanges(nnoi1, nnoi2, id, coi1, coi2, objectRecursionLevel);
					hasChanged = hasChanged || collectionHasChanged;
					continue;
				}
				if (value1.IsArrayObject())
				{
					ArrayObjectInfo aoi1 = (ArrayObjectInfo)value1;
					ArrayObjectInfo aoi2 = (ArrayObjectInfo)value2;
					bool arrayHasChanged = ManageArrayChanges(nnoi1, nnoi2, id, aoi1, aoi2, objectRecursionLevel
						);
					hasChanged = hasChanged || arrayHasChanged;
					continue;
				}
				if (value1.IsMapObject())
				{
					MapObjectInfo moi1 = (MapObjectInfo)value1;
					MapObjectInfo moi2 = (MapObjectInfo)value2;
					bool mapHasChanged = ManageMapChanges(nnoi1, nnoi2, id, moi1, moi2, objectRecursionLevel
						);
					hasChanged = hasChanged || mapHasChanged;
					continue;
				}
				if (value1.IsEnumObject())
				{
					EnumNativeObjectInfo enoi1 = (EnumNativeObjectInfo)value1;
					EnumNativeObjectInfo enoi2 = (EnumNativeObjectInfo)value2;
					bool enumHasChanged = !enoi1.GetEnumClassInfo().GetId().Equals(enoi2.GetEnumClassInfo
						().GetId()) || !enoi1.GetEnumName().Equals(enoi2.GetEnumName());
					hasChanged = hasChanged || enumHasChanged;
					continue;
				}
				if (value1.IsNonNativeObject())
				{
					NonNativeObjectInfo oi1 = (NonNativeObjectInfo)value1;
					NonNativeObjectInfo oi2 = (NonNativeObjectInfo)value2;
					// If oids are equal, they are the same objects
					if (oi1.GetOid() != null && oi1.GetOid().Equals(oi2.GetOid()))
					{
						hasChanged = HasChanged(value1, value2, objectRecursionLevel + 1) || hasChanged;
					}
					else
					{
						// This means that an object reference has changed.
						hasChanged = true;
						// keep track of the position where the reference must be
						// updated
						long positionToUpdateReference = nnoi1.GetAttributeDefinitionPosition(id);
						StoreNewObjectReference(positionToUpdateReference, oi2, objectRecursionLevel, nnoi1
							.GetClassInfo().GetAttributeInfoFromId(id).GetName());
						objectRecursionLevel++;
						// Value2 may have change too
						AddPendingVerification(value2);
					}
					continue;
				}
			}
			int i1 = (int)alreadyCheckingObjects[nnoi1];
			int i2 = (int)alreadyCheckingObjects[nnoi2];
			if (i1 != null)
			{
				i1 = i1 - 1;
			}
			if (i2 != null)
			{
				i2 = i2 - 1;
			}
			if (i1 == 0)
			{
				alreadyCheckingObjects.Remove(nnoi1);
			}
			else
			{
				alreadyCheckingObjects.Add(nnoi1, i1);
			}
			if (i2 == 0)
			{
				alreadyCheckingObjects.Remove(nnoi2);
			}
			else
			{
				alreadyCheckingObjects.Add(nnoi2, i2);
			}
			return hasChanged;
		}
Example #24
0
 public NeoDatisDbObject(NonNativeObjectInfo nnoi)
 {
     this.nnoi = nnoi;
     Fields = nnoi.GetAttributeValues().Select(attr => attr.GetObject()).ToArray();
 }