Beispiel #1
0
        // -----------------------------------------------------------------------------------------
        public void DetermineSourceChildren(IModelEntity Source)
        {
            if (!this.EquivalentEntities.AddNew(Source, null))
            {
                return;
            }

            // PENDING: GET ONLY THE MINIMUM OWNED AND DOMINANT OBJECTS

            foreach (var PropDef in Source.ClassDefinition.Properties)
            {
                if (!PropDef.IsStoreBoxBased)
                {
                    var ValueObject = PropDef.Read(Source);
                    if (ValueObject == null)
                    {
                        continue;
                    }

                    var ValueEntity = ValueObject as IModelEntity;
                    if (ValueEntity == null)
                    {
                        var ValueAssignment = ValueObject as MAssignment;
                        if (ValueAssignment != null)
                        {
                            ValueEntity = ValueAssignment.AssignedValue as IModelEntity;
                        }

                        /* Not required (the owner is outside the owned children and dominant dependencies)
                         * else
                         * {
                         *  var ValueOwnership = ValueObject as MOwnership;
                         *  if (ValueOwnership != null)
                         *      ValueEntity = ValueOwnership.Owner as IModelEntity;
                         * } */
                    }

                    if (ValueEntity != null)
                    {
                        DetermineSourceChildren(ValueEntity);
                    }
                    else
                    {
                        Console.WriteLine("Prop{{" + PropDef.QualifiedTechName + "}}: [" + ValueObject.ToStringAlways() + "]");
                    }
                }
            }

            // Collections are typically owned
            foreach (var CollDef in Source.ClassDefinition.Collections)
            {
                var SourceCollection = (EditableCollection)CollDef.Read(Source) as IEnumerable <object>;
                if (SourceCollection == null)
                {
                    continue;
                }

                var Index = 0;
                foreach (var Item in SourceCollection)
                {
                    var EntityItem = Item as IModelEntity;
                    if (EntityItem != null)
                    {
                        DetermineSourceChildren(EntityItem);
                    }
                    else
                    if (Item != null)
                    {
                        Console.WriteLine("CollItem{{" + CollDef.QualifiedTechName + "(" + Index.ToString() + ")}}: [" + Item.ToStringAlways() + "]");
                    }

                    Index++;
                }
            }
        }
Beispiel #2
0
        // ---------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Fixes any Unique-Element duplicated Global-Id.
        /// </summary>
        private static bool ModelRev8_FixDuplicatedGlobalIds(Composition TargetCompo, string Route = null, IList <IMModelClass> ExaminedInstances = null,
                                                             IMModelClass Target = null)
        {
            if (Route == null)
            {
                Route = "\\\\";
            }

            if (ExaminedInstances == null)
            {
                ExaminedInstances = new List <IMModelClass>();
            }

            if (Target == null)
            {
                Target = TargetCompo;
            }

            if (ExaminedInstances.Contains(Target))
            {
                return(false);
            }

            ExaminedInstances.Add(Target);

            Route = Route + Target.ToHashCodeAndString() + "~";

            var PropertyDefs = Target.ClassDefinition.Properties;

            foreach (var PropDef in PropertyDefs)
            {
                var Value     = PropDef.Read(Target);
                var PropValue = (Value is MOwnership
                                 ? ((MOwnership)Value).Owner
                                 : (Value is MAssignment
                                    ? ((MAssignment)Value).AssignedValue
                                    : Value)) as IMModelClass;

                if (PropValue != null)
                {
                    ModelRev8_FixDuplicatedGlobalIds(TargetCompo, Route + PropDef.TechName + "=", ExaminedInstances, PropValue);
                }
            }

            var CollectionDefs = Target.ClassDefinition.Collections;

            foreach (var CollDef in CollectionDefs)
            {
                var Collection = (EditableCollection)CollDef.Read(Target);

                var CollList = Collection as IList;

                if (CollList != null)
                {
                    var Duplicates = new List <UniqueElement>();

                    var Index = -1;
                    foreach (var Item in CollList)
                    {
                        Index++;

                        var CollItem = (Item is MOwnership
                                         ? ((MOwnership)Item).Owner
                                         : (Item is MAssignment
                                            ? ((MAssignment)Item).AssignedValue
                                            : Item)) as IMModelClass;

                        if (CollItem != null)
                        {
                            var ItemId = CollDef.TechName + "[" + Index.ToString() + "]=" + CollItem.ToHashCodeAndString() + "\\";

                            if (Item is UniqueElement)
                            {
                                var Items = ((IEnumerable <object>)CollList).CastAs <UniqueElement, object>();
                                if (Items.Any(item => item != Item && item.GlobalId == ((UniqueElement)Item).GlobalId))
                                {
                                    Duplicates.Add((UniqueElement)Item);
                                    //T Console.WriteLine("%" + Route + ItemId + "=" + ((UniqueElement)Item).GlobalId.ToString() + (Item is FormalElement ? (((FormalElement)Item).Version != null ? "::" + ((FormalElement)Item).Version.Creation.ToString("yyyyMMdd.hhmmss") : "") : ""));
                                }
                            }

                            ModelRev8_FixDuplicatedGlobalIds(TargetCompo, ItemId,
                                                             ExaminedInstances, CollItem);
                        }
                    }

                    foreach (var Duplicate in Duplicates.Skip(1))
                    {
                        Duplicate.GlobalId = Guid.NewGuid();
                    }
                }
                else
                {
                    var CollDict = Collection as IDictionary;

                    if (CollDict != null)
                    {
                        var Duplicates = new List <UniqueElement>();

                        var Index = -1;
                        foreach (var Key in CollDict.Keys)
                        {
                            Index++;

                            var CollKey = (Key is MOwnership
                                             ? ((MOwnership)Key).Owner
                                             : (Key is MAssignment
                                                ? ((MAssignment)Key).AssignedValue
                                                : Key)) as IMModelClass;

                            if (CollKey != null)
                            {
                                var ItemId = CollDef.TechName + "[" + Index.ToString() + "]K=" + CollKey.ToHashCodeAndString() + "\\";

                                if (CollKey is UniqueElement)
                                {
                                    var Items = ((IEnumerable <object>)CollList).CastAs <UniqueElement, object>();
                                    if (Items.Any(item => item != CollKey && item.GlobalId == ((UniqueElement)CollKey).GlobalId))
                                    {
                                        Duplicates.Add((UniqueElement)CollKey);
                                        //T Console.WriteLine("%" + Route + ItemId + "=" + ((UniqueElement)CollKey).GlobalId.ToString() + (CollKey is FormalElement ? (((FormalElement)CollKey).Version != null ? "::" + ((FormalElement)CollKey).Version.Creation.ToString("yyyyMMdd.hhmmss") : "") : ""));
                                    }
                                }

                                ModelRev8_FixDuplicatedGlobalIds(TargetCompo, ItemId,
                                                                 ExaminedInstances, CollKey);
                            }
                        }

                        Index = -1;
                        foreach (var Value in CollDict.Values)
                        {
                            Index++;

                            var CollValue = (Value is MOwnership
                                             ? ((MOwnership)Value).Owner
                                             : (Value is MAssignment
                                                ? ((MAssignment)Value).AssignedValue
                                                : Value)) as IMModelClass;

                            if (CollValue != null)
                            {
                                var ItemId = CollDef.TechName + "[" + Index.ToString() + "]V=" + CollValue.ToHashCodeAndString() + "\\";

                                if (CollValue is UniqueElement)
                                {
                                    var Items = ((IEnumerable <object>)CollList).CastAs <UniqueElement, object>();
                                    if (Items.Any(item => item != CollValue && item.GlobalId == ((UniqueElement)CollValue).GlobalId))
                                    {
                                        Duplicates.Add((UniqueElement)CollValue);
                                        //T Console.WriteLine("%" + Route + ItemId + "=" + ((UniqueElement)CollValue).GlobalId.ToString() + (CollValue is FormalElement ? (((FormalElement)CollValue).Version != null ? "::" + ((FormalElement)CollValue).Version.Creation.ToString("yyyyMMdd.hhmmss") : "") : ""));
                                    }
                                }

                                ModelRev8_FixDuplicatedGlobalIds(TargetCompo, ItemId,
                                                                 ExaminedInstances, CollValue);
                            }
                        }

                        foreach (var Duplicate in Duplicates.Skip(1))
                        {
                            Duplicate.GlobalId = Guid.NewGuid();
                        }
                    }
                }
            }

            return(true);
        }
Beispiel #3
0
        /// <summary>
        /// Fixes references to owner, which are not pointing to the real ones (resulting of old-buggy cloning operation).
        /// </summary>
        private static bool ModelRev7_ApplyFixOwnerReferences(Composition TargetCompo, string Route, IList <IMModelClass> ExaminedInstances,
                                                              List <Tuple <IMModelClass, MModelPropertyDefinitor, object> > Fixes,
                                                              IMModelClass Target, IMModelClass DirectOwner = null, int Level = 0)
        {
            if (ExaminedInstances.Contains(Target))
            {
                return(false);
            }

            ExaminedInstances.Add(Target);

            Route = Route + Target.ToHashCodeAndString() + "~";

            var PropertyDefs = Target.ClassDefinition.Properties;

            foreach (var PropDef in PropertyDefs)
            {
                var Value     = PropDef.Read(Target);
                var PropValue = (Value is MOwnership
                                 ? ((MOwnership)Value).Owner
                                 : (Value is MAssignment
                                    ? ((MAssignment)Value).AssignedValue
                                    : Value)) as IMModelClass;

                if (PropValue != null)
                {
                    if (PropDef.ReferencesOwner.HasValue && DirectOwner != null)
                    {
                        var Change = ModelRev7_EvaluateOwnershipDisconnection(TargetCompo, Target, Route, DirectOwner, PropValue);

                        if (Change)
                        {
                            // PENDING: Ensure there is only one claiming owner
                            // (not needed if THE-WHOLE-PROCESS is invoked by 2nd time without generating new changes)

                            object Referencer = null;
                            var    IsValid    = true; // just until all type-validations are implemented

                            Referencer = (Value is MOwnership
                                            ? (object)(((MOwnership)Value).CreateClone(DirectOwner))
                                            : (Value is MAssignment
                                                ? (object)(((MAssignment)Value).CreateClone(DirectOwner))
                                                : DirectOwner));

                            // Ensure coherence per each treated type
                            var TableOwner = DirectOwner as Table;
                            var TableRefer = PropValue as Table;
                            if (TableOwner != null)
                            {
                                if (TableOwner.AssignedDesignator.Value != TableRefer.AssignedDesignator.Value)
                                {
                                    IsValid = false;
                                }
                            }

                            /* var RelDefOwner = DirectOwner as RelationshipDefinition;
                             * var RelDefRefer = PropValue as RelationshipDefinition;
                             * if (IsValid && RelDefOwner != null)
                             * {
                             * // validate for reldef
                             * IsValid = true;
                             * } */

                            if (Referencer != null && IsValid)
                            {
                                Fixes.Add(Tuple.Create(Target, PropDef, Referencer));
                                //T Console.WriteLine("TYPES of Target=[{0}], NewRef=[{1}]", Target.GetType().Name, Referencer.GetType().Name);
                            }
                        }
                    }

                    if (PropDef.Membership != EEntityMembership.External)
                    {
                        ModelRev7_ApplyFixOwnerReferences(TargetCompo, Route + PropDef.TechName + "=", ExaminedInstances, Fixes,
                                                          PropValue, (PropDef.Membership == EEntityMembership.External ? null : Target), Level + 1);
                    }
                }
            }

            var CollectionDefs = Target.ClassDefinition.Collections;

            foreach (var CollDef in CollectionDefs)
            {
                if (CollDef.Membership == EEntityMembership.External)
                {
                    continue;
                }

                var Collection = (EditableCollection)CollDef.Read(Target);

                var CollList = Collection as IList;

                if (CollList != null)
                {
                    var Index = -1;
                    foreach (var Item in CollList)
                    {
                        Index++;

                        var CollItem = (Item is MOwnership
                                         ? ((MOwnership)Item).Owner
                                         : (Item is MAssignment
                                            ? ((MAssignment)Item).AssignedValue
                                            : Item)) as IMModelClass;

                        if (CollItem != null)
                        {
                            ModelRev7_ApplyFixOwnerReferences(TargetCompo, Route + CollDef.TechName + "[" + Index.ToString() + "]=", ExaminedInstances, Fixes,
                                                              CollItem, (CollDef.Membership == EEntityMembership.External ? null : Target), Level + 1);
                        }
                    }
                }
                else
                {
                    var CollDict = Collection as IDictionary;

                    if (CollDict != null)
                    {
                        var Index = -1;
                        foreach (var Key in CollDict.Keys)
                        {
                            Index++;

                            var CollKey = (Key is MOwnership
                                             ? ((MOwnership)Key).Owner
                                             : (Key is MAssignment
                                                ? ((MAssignment)Key).AssignedValue
                                                : Key)) as IMModelClass;

                            if (CollKey != null)
                            {
                                ModelRev7_ApplyFixOwnerReferences(TargetCompo, Route + CollDef.TechName + "[" + Index.ToString() + "]K=", ExaminedInstances, Fixes,
                                                                  CollKey, (CollDef.Membership == EEntityMembership.External ? null : Target), Level + 1);
                            }
                        }

                        Index = -1;
                        foreach (var Value in CollDict.Values)
                        {
                            Index++;

                            var CollValue = (Value is MOwnership
                                             ? ((MOwnership)Value).Owner
                                             : (Value is MAssignment
                                                ? ((MAssignment)Value).AssignedValue
                                                : Value)) as IMModelClass;

                            if (CollValue != null)
                            {
                                ModelRev7_ApplyFixOwnerReferences(TargetCompo, Route + CollDef.TechName + "[" + Index.ToString() + "]V=", ExaminedInstances, Fixes,
                                                                  CollValue, (CollDef.Membership == EEntityMembership.External ? null : Target), Level + 1);
                            }
                        }
                    }
                }
            }

            return(true);
        }
Beispiel #4
0
        private static void ModelRev7_FindLocationsOf(IList <IMModelClass> ExaminedInstances, string Route, ref List <string> Results,
                                                      IMModelClass Target, IMModelClass SearchedObject)
        {
            if (ExaminedInstances == null)
            {
                ExaminedInstances = new List <IMModelClass>();
            }

            if (ExaminedInstances.Contains(Target))
            {
                return;
            }

            if (Target == SearchedObject)
            {
                Results.Add(Route + Target.ToHashCodeAndString());
            }

            ExaminedInstances.Add(Target);

            Route = Route + Target.ToHashCodeAndString() + "~";

            var PropertyDefs = Target.ClassDefinition.Properties;

            foreach (var PropDef in PropertyDefs)
            {
                var Value     = PropDef.Read(Target);
                var PropValue = (Value is MOwnership
                                 ? ((MOwnership)Value).Owner
                                 : (Value is MAssignment
                                    ? ((MAssignment)Value).AssignedValue
                                    : Value)) as IMModelClass;

                if (PropValue != null)
                {
                    ModelRev7_FindLocationsOf(ExaminedInstances, Route + PropDef.TechName + "=",
                                              ref Results, PropValue, SearchedObject);
                }
            }

            var CollectionDefs = Target.ClassDefinition.Collections;

            foreach (var CollDef in CollectionDefs)
            {
                var Collection = (EditableCollection)CollDef.Read(Target);

                var CollList = Collection as IList;

                if (CollList != null)
                {
                    var Index = -1;
                    foreach (var Item in CollList)
                    {
                        Index++;

                        var CollItem = (Item is MOwnership
                                         ? ((MOwnership)Item).Owner
                                         : (Item is MAssignment
                                            ? ((MAssignment)Item).AssignedValue
                                            : Item)) as IMModelClass;

                        if (CollItem != null)
                        {
                            ModelRev7_FindLocationsOf(ExaminedInstances, Route + CollDef.TechName + "[" + Index.ToString() + "]=" + CollItem.ToHashCodeAndString() + "\\",
                                                      ref Results, CollItem, SearchedObject);
                        }
                    }
                }
                else
                {
                    var CollDict = Collection as IDictionary;

                    if (CollDict != null)
                    {
                        var Index = -1;
                        foreach (var Key in CollDict.Keys)
                        {
                            Index++;

                            var CollKey = (Key is MOwnership
                                             ? ((MOwnership)Key).Owner
                                             : (Key is MAssignment
                                                ? ((MAssignment)Key).AssignedValue
                                                : Key)) as IMModelClass;

                            if (CollKey != null)
                            {
                                ModelRev7_FindLocationsOf(ExaminedInstances, Route + CollDef.TechName + "[" + Index.ToString() + "]K=" + CollKey.ToHashCodeAndString() + "\\",
                                                          ref Results, CollKey, SearchedObject);
                            }
                        }

                        Index = -1;
                        foreach (var Value in CollDict.Values)
                        {
                            Index++;

                            var CollValue = (Value is MOwnership
                                             ? ((MOwnership)Value).Owner
                                             : (Value is MAssignment
                                                ? ((MAssignment)Value).AssignedValue
                                                : Value)) as IMModelClass;

                            if (CollValue != null)
                            {
                                ModelRev7_FindLocationsOf(ExaminedInstances, Route + CollDef.TechName + "[" + Index.ToString() + "]V=" + CollValue.ToHashCodeAndString() + "\\",
                                                          ref Results, CollValue, SearchedObject);
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Populates properties of a target model instance, plus returning it, with these from the supplied one.
        /// </summary>
        /// <param name="Target">Target model instance for which populate/overwrite property values.</param>
        /// <param name="Source">Source model instance from which get property values.</param>
        ///
        /// <param name="TargetOwner">Model instance owning the Target (intended to update owner references of the Source).</param>
        /// <param name="CloningScope">Indicates to make a copy of the populated value through the dependant object hierarchy.</param>
        /// <param name="IsForCloning">Indicates whether the population will be performed on a clone.</param>  // See below
        /// <param name="AsActive">Indicates whether the new clone will be active (i.e. will notify changes and store them for undo/redo).</param>
        /// <param name="MemberNames">Optional explicit member names to be populated (when empty, all members are populated).</param>
        /// <returns>The populated target model instance.</returns>
        public TModelClass PopulateInstance(TModelClass Target, TModelClass Source, IMModelClass TargetOwner,
                                            ECloneOperationScope CloningScope = ECloneOperationScope.Slight,
                                            bool IsForCloning = false, bool AsActive = true, params string[] MemberNames)
        {
            General.ContractRequiresNotNull(Target, Source);

            if (!AsActive)
            {
                MModelClassDefinitor.RegisterPassiveInstance(Target);
            }

            /*T
             * var SouCD = Source.ClassDefinition;
             * var TarCD = Target.ClassDefinition;
             * var AreEq = (SouCD == TarCD);
             *
             * string PopulatingKind = null;
             *
             * var PopulatingPrefix = " ".Replicate(PopulationLevel * 2);
             *
             * if (Target is IMModelEntityAgent)
             *  PopulatingKind = "ENT->AGT";
             * else
             *  PopulatingKind = "AGT->ENT";
             *
             * Console.WriteLine(PopulatingPrefix + "AT-POPULATE (" + PopulatingKind + ")... Source=[{0}:{1}], Target=[{2}:{3}], ClassDefsAreEqual=[{4}], Scope={5}, Members={6}",
             *                SouCD, Source.GetHashCode(), TarCD, Target.GetHashCode(), AreEq, CloningScope,
             *                (MemberNames == null || MemberNames.Length < 1 ? "<ALL>" : MemberNames.GetConcatenation(null,";"))); */

            if (!Target.ClassDefinition.DeclaringType.InheritsFrom(this.DeclaringType))
            {
                throw new UsageAnomaly("The supplied Target instance is not defined by this model class definitor",
                                       new DataWagon("target-ClassDef", this).Add("Target instance", Target));
            }

            if (!this.IsCompatibleClassDefinition(Source.ClassDefinition))
            {
                throw new UsageAnomaly("Cannot populate a model class instance from an incompatible one (must be of the same type or descendant of it)",
                                       new DataWagon("target-ClassDef", this).Add("source-ClassDef", Source.ClassDefinition));
            }

            // Determine properties to be populated
            var TargetProperties = (MemberNames == null || MemberNames.Length < 1
                                    ? Source.ClassDefinition.Properties    // IMPORTANT: Do not use 'this.Collections' (that way descendants members are not considered!)
                                    : Source.ClassDefinition.Properties.Where(prop => prop.TechName.IsOneOf(MemberNames)));

            // First, populate relevant properties, such as owner referencers
            var InitialProperties = TargetProperties.Where(prop => prop.ReferencesOwner.HasValue).ToArray();

            // PENDING: Treat Sub-Owners properly (reappoint cloned references to the cloned sub-owners, not to the original ones)
            PopulateProperties(Target, Source, (CloningScope == ECloneOperationScope.DeepAndEquivalent ? null : TargetOwner),
                               CloningScope, IsForCloning, InitialProperties);

            // Second, populate all collections (some of the remaining properties depends on some of them)
            var TargetCollections = (MemberNames == null || MemberNames.Length < 1
                                     ? Source.ClassDefinition.Collections   // IMPORTANT: Do not use 'this.Collections' (that way descendants members are not considered!)
                                     : Source.ClassDefinition.Collections.Where(coll => coll.TechName.IsOneOf(MemberNames))).ToArray();

            foreach (var CollDef in TargetCollections)
            {
                var TargetCollection = (EditableCollection)CollDef.Read(Target);
                var SourceCollection = (EditableCollection)CollDef.Read(Source);

                /*T if (TargetCollection != null && TargetCollection.Name == "MarkerDefinitions")
                 * {
                 *  Console.WriteLine(CallingPrefix + "........................................................................");
                 *  Console.WriteLine(CallingPrefix + "MarkerDefs are the same: {0}", TargetCollection.IsEqual(SourceCollection));
                 *  Console.WriteLine(CallingPrefix + "Source: HC={0}, ItemsCnt={1}", SourceCollection.GetHashCode(), SourceCollection.Count);
                 *  Console.WriteLine(CallingPrefix + "Target: HC={0}, ItemsCnt={1}", TargetCollection.GetHashCode(), TargetCollection.Count);
                 * } */

                /*T if (TargetCollection != null && TargetCollection.Name == "TextFormats")
                 * {
                 *  Console.WriteLine("Populating coll TextFormats >>>>>>>>>>>>>>>>>>>>>");
                 *  Console.WriteLine("SourceEnt: {0}, TargetEnt: {1}", Source.GetHashCode(), Target.GetHashCode());
                 *  Console.WriteLine("TextFormats are the same: {0}", TargetCollection.IsEqual(SourceCollection));
                 *  Console.WriteLine("SourceColl: HC={0}, ItemsCnt={1}", SourceCollection.GetHashCode(), SourceCollection.Count);
                 *  Console.WriteLine("TargetColl: HC={0}, ItemsCnt={1}", TargetCollection.GetHashCode(), TargetCollection.Count);
                 *  Console.WriteLine("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
                 * } */

                if (SourceCollection == null)
                {
                    CollDef.Write(Target, SourceCollection);
                    continue;
                }

                // IMPORTANT: Remember that SourceCollection, if not cloned,
                // will still be pointing to its original Variating-Instance.

                var DoClone = CollDef.IsCloneableFor(CloningScope, Source);
                if (DoClone.Item1)
                {
                    //T PopulationLevel++;
                    CollDef.Write(Target, SourceCollection.DuplicateFor(Target as IModelEntity, Target, DoClone.Item2));
                    //T PopulationLevel--;
                }
                else
                {
                    CollDef.Write(Target, SourceCollection);    //? Consider: TargetCollection.UpdateContentFrom(SourceCollection);
                }
            }

            // Third, populate the remaining properties (remember that some of these depend on collections)
            var RemainingProperties = TargetProperties.Where(prop => !prop.ReferencesOwner.HasValue).ToArray();

            PopulateProperties(Target, Source, (CloningScope == ECloneOperationScope.DeepAndEquivalent ? null : TargetOwner),
                               CloningScope, IsForCloning, RemainingProperties);

            if (CloningScope != ECloneOperationScope.DeepAndEquivalent)
            {
                // Generate new GUID for Unique-Element's Global-Id.
                var TargetElement = Target as UniqueElement;
                if (TargetElement != null)
                {
                    TargetElement.GlobalId = Guid.NewGuid();
                }
            }

            return(Target);
        }