private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntropectAtomicNativeArray (object array, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type) { int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array); NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo anoi = null; object[] arrayCopy = new object[length]; int typeId = 0; for (int i = 0; i < length; i++) { object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i); if (o != null) { // If object is not null, try to get the exact type typeId = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.GetFromClass(o.GetType()).GetId (); anoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, typeId); arrayCopy[i] = anoi; } else { // Else take the declared type arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type .GetId()); } } NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo (arrayCopy, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.Array, type.GetId()); return(aoi); }
public static bool TypesAreCompatible(ODBType type1, ODBType type2) { if (type1.IsArray() && type2.IsArray()) { return(TypesAreCompatible(type1.GetSubType(), type2.GetSubType())); } if (type1.GetName().Equals(type2.GetName())) { return(true); } if (type1.IsNative() && type2.IsNative()) { if (type1.IsEquivalent(type2)) { return(true); } return(false); } if (type1.IsNonNative() && type2.IsNonNative()) { return((type1.GetNativeClass() == type2.GetNativeClass()) || (type1.GetNativeClass ().IsAssignableFrom(type2.GetNativeClass()))); } return(false); }
public static bool IsNative(System.Type clazz) { ODBType tc = null; typesByName.TryGetValue(OdbClassUtil.GetFullName(clazz), out tc); if (tc != null) { return(true); } if (clazz.IsArray) { //ODBType type = new ODBType(ODBType.ARRAY.isPrimitive,ODBType.ARRAY_ID,ODBType.ARRAY.getName(),0); //type.subType = getFromClass(clazz.getComponentType()); return(true); } if (Map.superClass.IsAssignableFrom(clazz)) { return(true); } // check if it is a list if (Collection.superClass.IsAssignableFrom(clazz)) { return(true); } return(false); }
public ODBType Copy() { ODBType newType = new ODBType (isPrimitive, id, name, size); newType.subType = GetSubType(); return(newType); }
private NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo IntrospectCollection (System.Collections.ICollection collection, bool introspect, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects , NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { if (collection == null) { return(new NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo()); } // A collection that contain all meta representations of the collection // objects System.Collections.Generic.ICollection <NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo > collectionCopy = new System.Collections.Generic.List <NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo >(collection.Count); // A collection to keep references all all non native objects of the // collection // This will be used later to get all non native objects contained in an // object System.Collections.Generic.ICollection <NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > nonNativesObjects = new System.Collections.Generic.List <NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo >(collection.Count); NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null; System.Collections.IEnumerator iterator = collection.GetEnumerator(); while (iterator.MoveNext()) { object o = iterator.Current; NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null; // Null objects are not inserted in list if (o != null) { ci = GetClassInfo(OdbClassUtil.GetFullName(o.GetType())); aoi = GetObjectInfo(o, ci, introspect, alreadyReadObjects, callback); collectionCopy.Add(aoi); if (aoi.IsNonNativeObject()) { // o is not null, call the callback with it //callback.objectFound(o); // This is a non native object nonNativesObjects.Add((NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo)aoi ); } } } NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo coi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.CollectionObjectInfo (collectionCopy, nonNativesObjects); string realCollectionClassName = OdbClassUtil.GetFullName(collection.GetType()); if (realCollectionClassName.IndexOf("$") != -1) { coi.SetRealCollectionClassName(type.GetDefaultInstanciationClass().FullName); } else { coi.SetRealCollectionClassName(realCollectionClassName); } return(coi); }
public static ODBType GetFromId(int id) { ODBType odbType = typesById[id]; if (odbType == null) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.OdbTypeIdDoesNotExist .AddParameter(id)); } return(odbType); }
public override bool Equals(object obj) { if (obj == null || obj.GetType() != typeof(ODBType )) { return(false); } ODBType type = (ODBType )obj; return(GetId() == type.GetId()); }
static ODBType() { // Not used in Java, for .Net compatibility // Not used in Java, for .Net compatibility //public final static ODBType MAP = new ODBType(false,MAP_ID, "java.util.AbstractMap", 0, AbstractMap.class); NeoDatis.Tool.Wrappers.List.IOdbList <ODBType > allTypes = new NeoDatis.Tool.Wrappers.List.OdbArrayList <ODBType >(100); //// DO NOT FORGET DO ADD THE TYPE IN THIS LIST WHEN CREATING A NEW ONE!!! allTypes.Add(Null); allTypes.Add(NativeBoolean); allTypes.Add(NativeByte); allTypes.Add(NativeChar); allTypes.Add(NativeShort); allTypes.Add(NativeInt); allTypes.Add(NativeLong); allTypes.Add(NativeFloat); allTypes.Add(NativeDouble); allTypes.Add(Byte); allTypes.Add(Short); allTypes.Add(Integer); allTypes.Add(Long); allTypes.Add(Float); allTypes.Add(Double); allTypes.Add(BigDecimal); allTypes.Add(BigInteger); allTypes.Add(Character); allTypes.Add(Boolean); allTypes.Add(Date); allTypes.Add(DateSql); allTypes.Add(DateTimestamp); allTypes.Add(String); allTypes.Add(Enum); allTypes.Add(Collection); allTypes.Add(CollectionGeneric); allTypes.Add(Array); allTypes.Add(Map); allTypes.Add(Oid); allTypes.Add(ObjectOid); allTypes.Add(ClassOid); allTypes.Add(NonNative); ODBType type = null; for (int i = 0; i < allTypes.Count; i++) { type = allTypes[i]; typesByName[type.GetName()] = type; typesById[type.GetId()] = type; } }
public static ODBType GetFromClass(System.Type clazz) { string className = OdbClassUtil.GetFullName(clazz); if (NeoDatis.Tool.Wrappers.OdbClassUtil.IsEnum(clazz)) { ODBType type = new ODBType(ODBType.Enum.isPrimitive, ODBType.EnumId, ODBType.Enum.GetName(), 0); type.SetName(OdbClassUtil.GetFullName(clazz)); return(type); } // First check if it is a 'default type' ODBType tc = null; typesByName.TryGetValue(className, out tc); if (tc != null) { return(tc); } // Then check if it is a 'non default type' cacheOfTypesByName.TryGetValue(className, out tc); if (tc != null) { return(tc); } if (IsArray(clazz)) { ODBType type = new ODBType(ODBType.Array.isPrimitive, ODBType.ArrayId, ODBType.Array.GetName(), 0); type.subType = GetFromClass(clazz.GetElementType()); cacheOfTypesByName.Add(className, type); return(type); } if (IsMap(clazz)) { cacheOfTypesByName.Add(className, Map); return(Map); } // check if it is a list if (IsCollection(clazz)) { cacheOfTypesByName.Add(className, Collection); return(Collection); } nb++; ODBType nonNative = new ODBType(ODBType.NonNative.isPrimitive, NonNativeId, OdbClassUtil.GetFullName(clazz), 0); cacheOfTypesByName.Add(className, nonNative); return(nonNative); }
public static ODBType GetFromName(string fullName ) { ODBType tc = null; typesByName.TryGetValue(fullName, out tc); if (tc != null) { return(tc); } ODBType nonNative = new ODBType (ODBType.NonNative.isPrimitive, NonNativeId , fullName, 0); return(nonNative); }
private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntrospectArray(object array, bool introspect, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType valueType, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array); System.Type elementType = array.GetType().GetElementType(); NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType .GetFromClass(elementType); if (type.IsAtomicNative()) { return(IntropectAtomicNativeArray(array, type)); } if (!introspect) { return(new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])array)); } object[] arrayCopy = new object[length]; for (int i = 0; i < length; i++) { object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i); NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null; if (o != null) { ci = GetClassInfo(OdbClassUtil.GetFullName(o.GetType())); NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = GetObjectInfo(o, ci , introspect, alreadyReadObjects, callback); arrayCopy[i] = aoi; } else { arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeNullObjectInfo(); } } NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo arrayOfAoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo (arrayCopy, valueType, type.GetId()); return(arrayOfAoi); }
public void SetSubType(ODBType subType) { this.subType = subType; }
public static ODBType GetFromClass(System.Type clazz) { string className = OdbClassUtil.GetFullName(clazz); if (NeoDatis.Tool.Wrappers.OdbClassUtil.IsEnum(clazz)) { ODBType type = new ODBType(ODBType.Enum.isPrimitive, ODBType.EnumId, ODBType.Enum.GetName(), 0); type.SetName(OdbClassUtil.GetFullName(clazz)); return type; } // First check if it is a 'default type' ODBType tc = null; typesByName.TryGetValue(className, out tc); if (tc != null) { return tc; } // Then check if it is a 'non default type' cacheOfTypesByName.TryGetValue(className,out tc); if (tc != null) { return tc; } if (IsArray(clazz)) { ODBType type = new ODBType(ODBType.Array.isPrimitive, ODBType.ArrayId, ODBType.Array.GetName(), 0); type.subType = GetFromClass(clazz.GetElementType()); cacheOfTypesByName.Add(className, type); return type; } if (IsMap(clazz)) { cacheOfTypesByName.Add(className, Map); return Map; } // check if it is a list if (IsCollection(clazz)) { cacheOfTypesByName.Add(className, Collection); return Collection; } nb++; ODBType nonNative = new ODBType(ODBType.NonNative.isPrimitive, NonNativeId , OdbClassUtil.GetFullName(clazz), 0); cacheOfTypesByName.Add(className, nonNative); return nonNative; }
public static ODBType GetFromName(string fullName ) { ODBType tc = null; typesByName.TryGetValue(fullName, out tc); if (tc != null) { return tc; } ODBType nonNative = new ODBType (ODBType.NonNative.isPrimitive, NonNativeId , fullName, 0); return nonNative; }
public ODBType Copy() { ODBType newType = new ODBType (isPrimitive, id, name, size); newType.subType = GetSubType(); return newType; }
private bool IsEquivalent(ODBType type2) { return((id == IntegerId && type2.id == NativeIntId) || (type2.id == IntegerId && id == NativeIntId)); }
public static bool IsPrimitive(int odbTypeId) { return(ODBType.GetFromId(odbTypeId).isPrimitive); }
protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetNativeObjectInfoInternal (NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, object o, bool recursive , System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetId()); } else { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, type .GetId()); } } else { if (type.IsCollection()) { aoi = IntrospectCollection((System.Collections.ICollection)o, recursive, alreadyReadObjects , type, callback); } else { if (type.IsArray()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo(null); } else { // Gets the type of the elements of the array string realArrayClassName = OdbClassUtil.GetFullName(o.GetType().GetElementType()); NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aroi = null; if (recursive) { aroi = IntrospectArray(o, recursive, alreadyReadObjects, type, callback); } else { aroi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])o ); } aroi.SetRealArrayComponentClassName(realArrayClassName); aoi = aroi; } } else { if (type.IsMap()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.MapObjectInfo(null, type, type.GetDefaultInstanciationClass ().FullName); } else { MapObjectInfo moi = null; string realMapClassName = OdbClassUtil.GetFullName(o.GetType()); bool isGeneric = o.GetType().IsGenericType; if (isGeneric) { moi = new MapObjectInfo(IntrospectGenericMap((System.Collections.Generic.IDictionary <object, object>)o, recursive, alreadyReadObjects, callback), type, realMapClassName); } else { moi = new MapObjectInfo(IntrospectNonGenericMap((System.Collections.IDictionary)o, recursive, alreadyReadObjects, callback), type, realMapClassName); } if (realMapClassName.IndexOf("$") != -1) { moi.SetRealMapClassName(OdbClassUtil.GetFullName(type.GetDefaultInstanciationClass())); } aoi = moi; } } else { if (type.IsEnum()) { System.Enum enumObject = (System.Enum)o; if (enumObject == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetSize( )); } else { Type t = enumObject.GetType(); string enumClassName = enumObject == null ? null : OdbClassUtil.GetFullName(enumObject.GetType()); // Here we must check if the enum is already in the meta model. Enum must be stored in the meta // model to optimize its storing as we need to keep track of the enum class // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long // instead of the full enum class name string NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = GetClassInfo(enumClassName); string enumValue = enumObject == null ? null : enumObject.ToString(); aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.EnumNativeObjectInfo(ci, enumValue ); } } } } } } return(aoi); }
/// <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); }
public MapObjectInfo(IDictionary <AbstractObjectInfo, AbstractObjectInfo> map, ODBType type, string realMapClassName) : base(map, type) { this.realMapClassName = realMapClassName; }
public static bool TypesAreCompatible(ODBType type1, ODBType type2) { if (type1.IsArray() && type2.IsArray()) { return TypesAreCompatible(type1.GetSubType(), type2.GetSubType()); } if (type1.GetName().Equals(type2.GetName())) { return true; } if (type1.IsNative() && type2.IsNative()) { if (type1.IsEquivalent(type2)) { return true; } return false; } if (type1.IsNonNative() && type2.IsNonNative()) { return (type1.GetNativeClass() == type2.GetNativeClass()) || (type1.GetNativeClass ().IsAssignableFrom(type2.GetNativeClass())); } return false; }
private bool IsEquivalent(ODBType type2) { return (id == IntegerId && type2.id == NativeIntId) || (type2.id == IntegerId && id == NativeIntId); }
public void SetSubType(ODBType subType) { this.subType = subType; }
public MapObjectInfo(IDictionary<AbstractObjectInfo,AbstractObjectInfo> map, ODBType type, string realMapClassName) : base(map, type) { this.realMapClassName = realMapClassName; }
public virtual ClassInfoCompareResult ExtractDifferences(ClassInfo newCI, bool update) { string attributeName = null; ClassAttributeInfo cai1 = null; ClassAttributeInfo cai2 = null; Meta.ClassInfoCompareResult result = new ClassInfoCompareResult(GetFullClassName()); bool isCompatible = true; IOdbList <ClassAttributeInfo> attributesToRemove = new OdbArrayList <ClassAttributeInfo>(10); IOdbList <ClassAttributeInfo> attributesToAdd = new OdbArrayList <ClassAttributeInfo>(10); int nbAttributes = attributes.Count; for (int id = 0; id < nbAttributes; id++) { // !!!WARNING : ID start with 1 and not 0 cai1 = attributes[id]; if (cai1 == null) { continue; } attributeName = cai1.GetName(); cai2 = newCI.GetAttributeInfoFromId(cai1.GetId()); if (cai2 == null) { result.AddCompatibleChange("Field '" + attributeName + "' has been removed"); if (update) { // Simply remove the attribute from meta-model attributesToRemove.Add(cai1); } } else { if (!ODBType.TypesAreCompatible(cai1.GetAttributeType(), cai2.GetAttributeType())) { result.AddIncompatibleChange("Type of Field '" + attributeName + "' has changed : old='" + cai1.GetFullClassname() + "' - new='" + cai2.GetFullClassname() + "'"); isCompatible = false; } } } int nbNewAttributes = newCI.attributes.Count; for (int id = 0; id < nbNewAttributes; id++) { // !!!WARNING : ID start with 1 and not 0 cai2 = newCI.attributes[id]; if (cai2 == null) { continue; } attributeName = cai2.GetName(); cai1 = GetAttributeInfoFromId(cai2.GetId()); if (cai1 == null) { result.AddCompatibleChange("Field '" + attributeName + "' has been added"); if (update) { // Sets the right id of attribute cai2.SetId(maxAttributeId + 1); maxAttributeId++; // Then adds the new attribute to the meta-model attributesToAdd.Add(cai2); } } } attributes.RemoveAll(attributesToRemove); attributes.AddAll(attributesToAdd); FillAttributesMap(); return(result); }