Example #1
0
        /// <summary>
        /// Loads the snapshot package.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public string LoadSnapshotPackage(LoadPackageContext context)
        {
            var result = string.Empty;

            try
            {
                using (var snapshotObjectSpace = new ObjectSpace(context.Package.UnitOfWork))
                {
                    // create root context
                    var sourceMaps  = snapshotObjectSpace.GetObjects <SnapshotOidMap>();
                    var rootContext = new SnapshotLoadContext(context, sourceMaps);

                    context.Worker.ReportProgress(string.Format(Localizer.ObjectsFoundInSnapshot, sourceMaps.Count));

                    // restore all of object from snapshot
                    foreach (var sourceMap in sourceMaps)
                    {
                        loadSnapshotObject(rootContext, sourceMap);
                    }

                    // fix OidMap references
                    var newMaps = from c in context.ObjectSpace.ModifiedObjects.Cast <object>()
                                  where c is OidMap && ((OidMap)c).NewObject != null
                                  select c as OidMap;
                    context.ObjectSpace.CommitChanges();
                    newMaps.ToList().ForEach(x => x.FixReference());
                    snapshotPostLoad(context.ObjectSpace);
                    restoreLastLoadedNum(context, snapshotObjectSpace);
                    context.ObjectSpace.CommitChanges();
                    snapshotObjectSpace.Rollback();
                }
            }
            catch (Exception exception)
            {
                result = string.Format(Localizer.SnapshotLoadingIsFailed, exception.Message);
                context.Worker.ReportError(result);
            }

            if (string.IsNullOrEmpty(result))
            {
                if (context.Worker.CancellationPending)
                {
                    result = Localizer.LoadingAborted;
                }

                context.Worker.ReportProgress(Color.Blue, Localizer.SnapshotLoadingIs,
                                              (context.Worker.CancellationPending ? Localizer.Aborted : Localizer.Finished));
            }

            return(result);
        }
Example #2
0
        /// <summary>
        /// Loads the snapshot object.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="sourceMap">The source map.</param>
        /// <returns></returns>
        private object loadSnapshotObject(SnapshotLoadContext context, SnapshotOidMap sourceMap)
        {
            // look for existing object in app database
            var result = OidMap.FindApplicationObject(context.ObjectSpace, sourceMap, context.Package.SenderNodeId);

            // if not found then create new one
            if (result == null)
            {
                var typeInfo = context.ObjectSpace.TypesInfo.FindTypeInfo(sourceMap.Target.Target.GetType());
                result = context.ObjectSpace.CreateObject(typeInfo.Type);
            }
            // register mapping
            updateObjectMapping(context, sourceMap, result);

            // restore object's state from snapshot
            restoreSnapshotObjectState(context, (IXPObject)sourceMap.Target.Target, (IXPObject)result);
            return(result);
        }
Example #3
0
        /// <summary>
        /// Updates the object mapping.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="sourceMap">The source map.</param>
        /// <param name="appObject">The app object.</param>
        private void updateObjectMapping(SnapshotLoadContext context,
                                         IPackageObjectReference sourceMap, object appObject)
        {
            if (context.UpdatedMapping.Contains(appObject))
            {
                return;
            }
            context.UpdatedMapping.Add(appObject);

            foreach (var mappingStr in sourceMap.KnownMapping.Split(new[] { '\n' },
                                                                    StringSplitOptions.RemoveEmptyEntries))
            {
                var mapArray = mappingStr.Split('\a');
                var nodeId   = mapArray[0];
                var objectId = mapArray[1];
                var oidMap   = OidMap.GetOidMap(appObject, nodeId);
                if (oidMap == null)
                {
                    OidMap.CreateOidMap(context.ObjectSpace, objectId, nodeId, (IXPObject)appObject);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Restores the state of the snapshot object.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="snapshotObject">The snapshot object.</param>
        /// <param name="appObject">The app object.</param>
        private void restoreSnapshotObjectState(SnapshotLoadContext context, IXPObject snapshotObject, IXPObject appObject)
        {
            if (context.RestoredObjects.Contains(snapshotObject))
            {
                return;
            }
            context.RestoredObjects.Add(snapshotObject);

            var snapClassInfo = snapshotObject.ClassInfo;
            var modelClass    = XafDeltaModule.XafApp.FindModelClass(snapClassInfo.ClassType);

            // restore non collection properties
            foreach (var snapMemberInfo in snapClassInfo.Members.Where(x => x.IsPersistent &&
                                                                       !x.IsReadOnly && !(x is ServiceField) && !x.IsKey))
            {
                // skip non snapshot members
                if (modelClass != null)
                {
                    var modelMember = modelClass.FindMember(snapMemberInfo.Name);
                    if (modelMember != null && modelMember.NonSnapshot())
                    {
                        continue;
                    }
                }

                var appMemberInfo = appObject.ClassInfo.GetMember(snapMemberInfo.Name);
                // skip unknown and readonly properties
                if (appMemberInfo == null || appMemberInfo.IsReadOnly)
                {
                    continue;
                }

                // new value grom snapshot
                var snapValue        = snapMemberInfo.GetValue(snapshotObject);
                var memberIsRestored = false;

                // XPO references
                if (snapMemberInfo.ReferenceType != null)
                {
                    // aggregated objects
                    if (snapMemberInfo.IsAggregated && snapValue != null)
                    {
                        // app current aggregate value
                        var aggrObj = appMemberInfo.GetValue(appObject);
                        // if aggregated object in app is not null
                        // then link it to snapshot object and restore state
                        if (aggrObj != null)
                        {
                            updateObjectMapping(context, context.Maps[snapValue], aggrObj);
                            restoreSnapshotObjectState(context, (IXPObject)snapValue, (IXPObject)aggrObj);
                            memberIsRestored = true;
                        }
                    }

                    if (snapValue != null && !memberIsRestored)
                    {
                        var snapOidMap = context.Maps[snapValue];
                        appMemberInfo.SetValue(appObject, loadSnapshotObject(context, snapOidMap));
                        memberIsRestored = true;
                    }
                }

                if (!memberIsRestored)
                {
                    appMemberInfo.SetValue(appObject, snapValue);
                }
            }

            // restore collections state
            foreach (var snapMemberInfo in snapClassInfo.Members.Where(x => !x.Name.EndsWith("__Links") &&
                                                                       (x.IsManyToMany || x.IsManyToManyAlias || x.IsCollection || x.IsAssociationList)))
            {
                // skip non snapshot members
                if (modelClass != null)
                {
                    var modelMember = modelClass.FindMember(snapMemberInfo.Name);
                    if (modelMember != null && modelMember.MemberInfo.FindAttribute <NonSnapshotAttribute>() != null)
                    {
                        continue;
                    }
                }

                var snapCollection = snapMemberInfo.GetValue(snapshotObject) as IList;
                var appMemberInfo  = appObject.ClassInfo.GetMember(snapMemberInfo.Name);
                var appCollection  = appMemberInfo.GetValue(appObject) as IList;
                if (snapCollection != null && appCollection != null)
                {
                    foreach (var snapElement in snapCollection)
                    {
                        if (context.Maps.ContainsKey(snapElement))
                        {
                            var appElement = loadSnapshotObject(context, context.Maps[snapElement]);
                            if (!appCollection.Contains(appElement))
                            {
                                appCollection.Add(appElement);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Updates the object mapping.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="sourceMap">The source map.</param>
        /// <param name="appObject">The app object.</param>
        private void updateObjectMapping(SnapshotLoadContext context, 
            IPackageObjectReference sourceMap, object appObject)
        {
            if(context.UpdatedMapping.Contains(appObject)) return;
            context.UpdatedMapping.Add(appObject);

            foreach (var mappingStr in sourceMap.KnownMapping.Split(new[]{'\n'},
                StringSplitOptions.RemoveEmptyEntries))
            {
                var mapArray = mappingStr.Split('\a');
                var nodeId = mapArray[0];
                var objectId = mapArray[1];
                var oidMap = OidMap.GetOidMap(appObject, nodeId);
                if(oidMap == null)
                    OidMap.CreateOidMap(context.ObjectSpace, objectId, nodeId, (IXPObject)appObject);
            }
        }
        /// <summary>
        /// Restores the state of the snapshot object.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="snapshotObject">The snapshot object.</param>
        /// <param name="appObject">The app object.</param>
        private void restoreSnapshotObjectState(SnapshotLoadContext context, IXPObject snapshotObject, IXPObject appObject)
        {
            if(context.RestoredObjects.Contains(snapshotObject)) return;
            context.RestoredObjects.Add(snapshotObject);

            var snapClassInfo = snapshotObject.ClassInfo;
            var modelClass = XafDeltaModule.XafApp.FindModelClass(snapClassInfo.ClassType);

            // restore non collection properties
            foreach (var snapMemberInfo in snapClassInfo.Members.Where(x => x.IsPersistent
                && !x.IsReadOnly && !(x is ServiceField) && !x.IsKey))
            {
                // skip non snapshot members
                if(modelClass != null)
                {
                    var modelMember = modelClass.FindMember(snapMemberInfo.Name);
                    if (modelMember != null && modelMember.NonSnapshot())
                        continue;
                }

                var appMemberInfo = appObject.ClassInfo.GetMember(snapMemberInfo.Name);
                // skip unknown and readonly properties
                if(appMemberInfo == null || appMemberInfo.IsReadOnly) continue;

                // new value grom snapshot
                var snapValue = snapMemberInfo.GetValue(snapshotObject);
                var memberIsRestored = false;

                // XPO references
                if (snapMemberInfo.ReferenceType != null)
                {
                    // aggregated objects
                    if (snapMemberInfo.IsAggregated && snapValue != null)
                    {
                        // app current aggregate value
                        var aggrObj = appMemberInfo.GetValue(appObject);
                        // if aggregated object in app is not null
                        // then link it to snapshot object and restore state
                        if (aggrObj != null)
                        {
                            updateObjectMapping(context, context.Maps[snapValue], aggrObj);
                            restoreSnapshotObjectState(context, (IXPObject)snapValue, (IXPObject)aggrObj);
                            memberIsRestored = true;
                        }
                    }

                    if (snapValue != null && !memberIsRestored)
                    {
                        var snapOidMap = context.Maps[snapValue];
                        appMemberInfo.SetValue(appObject, loadSnapshotObject(context, snapOidMap));
                        memberIsRestored = true;
                    }
                }

                if (!memberIsRestored)
                    appMemberInfo.SetValue(appObject, snapValue);
            }

            // restore collections state
            foreach (var snapMemberInfo in snapClassInfo.Members.Where(x => !x.Name.EndsWith("__Links")
                && (x.IsManyToMany || x.IsManyToManyAlias || x.IsCollection || x.IsAssociationList)))
            {
                // skip non snapshot members
                if (modelClass != null)
                {
                    var modelMember = modelClass.FindMember(snapMemberInfo.Name);
                    if (modelMember != null && modelMember.MemberInfo.FindAttribute<NonSnapshotAttribute>() != null)
                        continue;
                }

                var snapCollection = snapMemberInfo.GetValue(snapshotObject) as IList;
                var appMemberInfo = appObject.ClassInfo.GetMember(snapMemberInfo.Name);
                var appCollection = appMemberInfo.GetValue(appObject) as IList;
                if (snapCollection != null && appCollection != null)
                    foreach (var snapElement in snapCollection)
                    {
                        if (context.Maps.ContainsKey(snapElement))
                        {
                            var appElement = loadSnapshotObject(context, context.Maps[snapElement]);
                            if (!appCollection.Contains(appElement))
                                appCollection.Add(appElement);
                        }
                    }
            }
        }
        /// <summary>
        /// Loads the snapshot object.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="sourceMap">The source map.</param>
        /// <returns></returns>
        private object loadSnapshotObject(SnapshotLoadContext context, SnapshotOidMap sourceMap)
        {
            // look for existing object in app database
            var result = OidMap.FindApplicationObject(context.ObjectSpace, sourceMap, context.Package.SenderNodeId);

            // if not found then create new one
            if(result == null)
            {
                var typeInfo = context.ObjectSpace.TypesInfo.FindTypeInfo(sourceMap.Target.Target.GetType());
                result = context.ObjectSpace.CreateObject(typeInfo.Type);
            }
            // register mapping
            updateObjectMapping(context, sourceMap, result);

            // restore object's state from snapshot
            restoreSnapshotObjectState(context, (IXPObject)sourceMap.Target.Target, (IXPObject)result);
            return result;
        }
        /// <summary>
        /// Loads the snapshot package.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public string LoadSnapshotPackage(LoadPackageContext context)
        {
            var result = string.Empty;

            try
            {
                using (var snapshotObjectSpace = new ObjectSpace(context.Package.UnitOfWork))
                {
                    // create root context
                    var sourceMaps = snapshotObjectSpace.GetObjects<SnapshotOidMap>();
                    var rootContext = new SnapshotLoadContext(context, sourceMaps);

                    context.Worker.ReportProgress(string.Format(Localizer.ObjectsFoundInSnapshot, sourceMaps.Count));

                    // restore all of object from snapshot
                    foreach (var sourceMap in sourceMaps)
                        loadSnapshotObject(rootContext, sourceMap);

                    // fix OidMap references
                    var newMaps = from c in context.ObjectSpace.ModifiedObjects.Cast<object>()
                                  where c is OidMap && ((OidMap)c).NewObject != null
                                  select c as OidMap;
                    context.ObjectSpace.CommitChanges();
                    newMaps.ToList().ForEach(x => x.FixReference());
                    snapshotPostLoad(context.ObjectSpace);
                    restoreLastLoadedNum(context, snapshotObjectSpace);
                    context.ObjectSpace.CommitChanges();
                    snapshotObjectSpace.Rollback();
                }
            }
            catch (Exception exception)
            {
                result = string.Format(Localizer.SnapshotLoadingIsFailed, exception.Message);
                context.Worker.ReportError( result);
            }

            if (string.IsNullOrEmpty(result))
            {
                if (context.Worker.CancellationPending)
                    result = Localizer.LoadingAborted;

                context.Worker.ReportProgress(Color.Blue, Localizer.SnapshotLoadingIs,
                                                          (context.Worker.CancellationPending ? Localizer.Aborted : Localizer.Finished));
            }

            return result;
        }