Ejemplo n.º 1
0
 public MetaDefinition PopulateFrom(MetaDefinition SourceElement,
                                    IMModelClass DirectOwner          = null,
                                    ECloneOperationScope CloningScope = ECloneOperationScope.Slight,
                                    params string[] MemberNames)
 {
     return(this.ClassDefinitor.PopulateInstance(this, SourceElement, DirectOwner, CloningScope, false, true, MemberNames));
 }
        /// <summary>
        /// Indicates whether for this memeber a Clone operation should be performed in the specified Scope and for the specified Source,
        /// plus the CloningScope to use (which might be a new one).
        /// </summary>
        public Tuple <bool, ECloneOperationScope> IsCloneableFor(ECloneOperationScope CloningScope, IMModelClass Source)
        {
            var IsCloneable = false;
            var Evaluate    = true;

            if (this.ForcedOwnershipIndicator != null)
            {
                var Value = this.ForcedOwnershipIndicator.Read(Source);
                if (Value is bool && (bool)Value)
                {
                    IsCloneable  = true;
                    CloningScope = ECloneOperationScope.Deep;
                    Evaluate     = false;
                }
            }

            if (Evaluate)
            {
                // IMPORTANT TO BE NOTICED...
                // First, evaluate the special case of external collections, which must clone its head.
                // If no cloning of collection-heads are required, then the member should be a property storing the collection.
                // Example: ModelPropertyDefinitor<TEntity, EditableCollection<TItem>> instead of ModelListDefinitor<TEntity, TItem>
                if (this.Membership == EEntityMembership.External &&
                    this is MModelCollectionDefinitor)
                {
                    IsCloneable  = true;
                    CloningScope = ECloneOperationScope.Slight;
                }
                else
                // Notice that slight-scope also considers collection-heads
                if (CloningScope == ECloneOperationScope.Slight)
                {
                    IsCloneable = (this.Membership == EEntityMembership.InternalCoreExclusive ||
                                   this is MModelCollectionDefinitor);
                }
                else
                // NOTE: In core-scope consider for collections to do their items cloning with shallow-scope.
                if (CloningScope == ECloneOperationScope.Core)
                {
                    IsCloneable = (this.Membership == EEntityMembership.InternalCoreExclusive);
                }
                else
                {
                    // For deep-scope also consider the bulk content.
                    IsCloneable = (this.Membership == EEntityMembership.InternalCoreExclusive ||
                                   this.Membership == EEntityMembership.InternalBulk);
                }
            }

            var Result = Tuple.Create <bool, ECloneOperationScope>(IsCloneable, CloningScope);

            return(Result);
        }
        AssignInstanceController <TModelEntity>(TModelEntity EntityInstance,
                                                Func <TModelEntity, TModelEntity, IEnumerable <object>, bool> PreApply = null,
                                                ECloneOperationScope CloningScope = ECloneOperationScope.Slight)
            where TModelEntity : class, IModelEntity, IModelClass <TModelEntity>
        {
            var Result = (EntityInstanceController <TModelEntity>)EntityInstance.Controller;

            if (Result == null)
            {
                Result = new EntityInstanceController <TModelEntity>(EntityInstance, PreApply, CloningScope);
                EntityInstance.Controller = Result;
            }
            else
            {
                Result.PreApply     = PreApply;
                Result.CloningScope = CloningScope;
            }

            return(Result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public MEntityInstanceController(IModelEntity EntityInstance, ECloneOperationScope CloningScope)
        {
            General.ContractRequiresNotNull(EntityInstance);

            this.ControlledInstance = EntityInstance;
            this.EntityEditor       = EntityInstance.EditEngine;

            // Centralizes store-boxes references
            // IMPORTANT: The EntityEditor is used because exists while calling Constructors. So, do not use MainEditedEntity (Composition).
            foreach (var PropDef in EntityInstance.ClassDefinition.Properties.Where(prop => prop.IsStoreBoxBased))
            {
                PropDef.GetStoreBoxContainer(EntityInstance).CentralizeReferencesIn(EntityEditor.GlobalId);
            }

            this.CloningScope = CloningScope;

            this.ExistenceStatus       = EExistenceStatus.Created;
            this.ControlledProperties  = new ReadOnlyDictionary <string, MPropertyController>(this.ControlledProperties_);
            this.ControlledCollections = new ReadOnlyDictionary <string, MCollectionController>(this.ControlledCollections_);
            this.Errors = new ReadOnlyDictionary <string, string>(this.Errors_);
        }
Ejemplo n.º 5
0
 public override object CreateCopy(ECloneOperationScope CloningScope, IMModelClass DirectOwner)
 {
     return(this.CreateClone(CloningScope, DirectOwner));
 }
Ejemplo n.º 6
0
 public new FormalPresentationElement CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((FormalPresentationElement)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 7
0
        public FormalElement PopulateFrom(FormalElement SourceElement, IMModelClass TargetOwner = null, ECloneOperationScope CloningScope = ECloneOperationScope.Slight, params string[] MemberNames)
        {
            var Result = this.ClassDefinitor.PopulateInstance(this, SourceElement, TargetOwner, CloningScope);

            // For clones create a non-already "running" version.
            if (SourceElement.Version != null)
            {
                Result.Version = new VersionCard(SourceElement.Version.Creator, SourceElement.Version.Annotation);
            }

            return(Result);
        }
Ejemplo n.º 8
0
 public MarkerAssignment CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((MarkerAssignment)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 9
0
 public new AttachmentAppearance CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((AttachmentAppearance)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 10
0
        private static void PopulateProperties(TModelClass Target, TModelClass Source, IMModelClass TargetOwner,
                                               ECloneOperationScope CloningScope, bool IsForCloning, MModelPropertyDefinitor[] TargetProperties)
        {
            foreach (var PropDef in TargetProperties)
            {
                var SourceValue = PropDef.Read(Source);

                /*T if (//T PropDef.TechName.EndsWith("LinkRoleDef") ||
                 *  PropDef.TechName == "OwnerRelationshipDef")
                 *  Console.WriteLine("debug!"); */

                /*T if (PropDef.TechName == "ForegroundBrush")
                 * {
                 *  Console.WriteLine("Populating prop ForegroundBrush >>>>>>>>>>>>>>>>>>>>>");
                 *  Console.WriteLine("SourceEnt: {0}, TargetEnt: {1}", Source.GetHashCode(), Target.GetHashCode());
                 *  if (PropDef.IsStoreBoxBased)
                 *  {
                 *      Console.WriteLine("StoreBox-Source: {0}", PropDef.GetStoreBoxContainer(Source).GetHashCode());
                 *      Console.WriteLine("StoreBox-Target: {0}", PropDef.GetStoreBoxContainer(Target).GetHashCode());
                 *  }
                 *  Console.WriteLine("SourceVal: HC={0}", SourceValue.GetHashCode());
                 *  var TarVal = PropDef.Read(Target);
                 *  TarVal = TarVal.NullDefault("<NULL>");
                 *  Console.WriteLine("TargetVal: HC={0} (to be overwritten)", TarVal.GetHashCode());
                 *  Console.WriteLine("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
                 * } */

                var DoClone = PropDef.IsCloneableFor(CloningScope, Source);

                if (SourceValue is IMModelClass && DoClone.Item1)
                {
                    //T PopulationLevel++;
                    SourceValue = ((IMModelClass)SourceValue).CreateCopy(DoClone.Item2, Target);
                    //T PopulationLevel--;
                }

                if (PropDef.ReferencesOwner.HasValue && TargetOwner != null)
                {
                    // NOTE: See ModelFixes.ModelRev7_FixOwnerReferences method, which resulted in this piece of code for reassign Owners.
                    var SourceOwnership = SourceValue as MOwnership;
                    var Owner           = (SourceOwnership == null ? SourceValue : SourceOwnership.Owner);

                    if (Owner != null && Owner.GetType() == TargetOwner.GetType())
                    {
                        if (SourceOwnership != null)
                        {
                            SourceValue = SourceOwnership.CreateClone(TargetOwner);
                        }
                        else
                        {
                            SourceValue = TargetOwner;
                        }
                    }
                }

                // Refinements...
                // Needed because the initial clone only has duplicated the root properties (shallow copy)
                if (IsForCloning)
                {
                    var SourceAssignment = SourceValue as MAssignment;
                    if (SourceAssignment != null)
                    {
                        if (SourceAssignment.IsLocal && (SourceAssignment.AssignedValue is IMModelClass) && DoClone.Item1)
                        {
                            SourceAssignment = ((IMModelClass)SourceAssignment.AssignedValue).CreateCopy(DoClone.Item2, Target).Assign(true);
                        }
                        else
                        {
                            SourceAssignment = ((MAssignment)SourceValue).CreateClone();
                        }

                        SourceValue = SourceAssignment;
                    }

                    if (PropDef.IsStoreBoxBased)
                    {
                        var ClonedStore = PropDef.GetStoreBoxContainer(Target).CreateClone();
                        PropDef.SetStoreBoxBaseContainer(Target, ClonedStore);
                    }
                }

                PropDef.Write(Target, SourceValue);
            }
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Returns a copy of this collection for the specified target instance, indicating whether to do a deep-copy and with the supplied name.
 /// </summary>
 public abstract EditableCollection DuplicateFor(IModelEntity TargetInstance, IMModelClass DirectOwner, ECloneOperationScope CloningScope = ECloneOperationScope.Slight, string Name = null);
Ejemplo n.º 12
0
 public ContainedDetail CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((ContainedDetail)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 13
0
 public abstract object CreateCopy(ECloneOperationScope CloningScope, IMModelClass DirectOwner);
Ejemplo n.º 14
0
 public new VisualConnectorsFormat CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((VisualConnectorsFormat)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 15
0
 public new MetaCategory <TMetaDefinitor> CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((MetaCategory <TMetaDefinitor>) this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
 public new RelationshipDefinition CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((RelationshipDefinition)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 17
0
 public new LinkDetailDesignator CreateClone(ECloneOperationScope CloningScope, IMModelClass DirectOwner, bool AsActive = true)
 {
     return(this.ClassDefinitor.PopulateInstance((LinkDetailDesignator)this.MemberwiseClone(), this, DirectOwner, CloningScope, true, AsActive));
 }
Ejemplo n.º 18
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);
        }