예제 #1
0
        /// <summary>
        /// Internal method called by the StoreConflict class in order to resolve a store conflict.  This must be done
        /// because there must be some maintenance of the in-memory collections depending on the resolution of the conflict
        /// </summary>
        /// <param name="conflict">Conflict to resolve</param>
        /// <param name="resolutionAction">Resolution action.</param>
        internal void ResolveOfflineConflict(OfflineConflict conflict, SyncConflictResolutionAction resolutionAction)
        {
            using (saveSyncLock.LockObject())
            {
                // Cache the modified entity, which may disappear depending on the resolution
                OfflineEntity visibleEntity = conflict.ModifiedEntity;

                // Respond to the resolution
                switch (resolutionAction)
                {
                case SyncConflictResolutionAction.AcceptModifiedEntity:
                    conflict.ModifiedEntity.UpdateModifiedTickCount();
                    break;

                case SyncConflictResolutionAction.AcceptStoreEntity:
                    cacheData.ResolveStoreConflictByRollback(conflict.ModifiedEntity);
                    break;

                default:
                    throw new ArgumentException("Invalid resolution action specified");
                }

                // Cleanup pointers to conflicts everywhere.
                visibleEntity.OfflineConflict = null;
                offlineConflicts.Remove(conflict);

                // Clearing the c will prevent the resolution from being triggered again.
                conflict.ClearContext();
            }
        }
예제 #2
0
        public void ProcessedEntity(OfflineEntity entity)
        {
            string           atomId = entity.ServiceMetadata.Id;
            OfflineEntityKey key    = (OfflineEntityKey)entity.GetIdentity();

            key.TypeName = entity.GetType().FullName;

            if (entity.IsTombstone)
            {
                if (String.IsNullOrEmpty(atomId))
                {
                    pkeySet.Add(key);
                }
                else
                {
                    atomIdSet.Add(atomId);
                }
            }
            else
            {
                pkeySet.Add(key);

                if (!String.IsNullOrEmpty(atomId))
                {
                    atomIdSet.Add(atomId);
                }
            }
        }
예제 #3
0
        public bool ContainsEntity(OfflineEntity entity)
        {
            // If the entity is a tombstone, use the atom id
            if (entity.IsTombstone)
            {
                if (String.IsNullOrEmpty(entity.ServiceMetadata.Id))
                {
                    // if it's a tombstone and the id is null, it means it is a delete of
                    // a local insert that can be skipped, so we report it as already written
                    return(true);
                }
                return(atomIdSet.Contains(entity.ServiceMetadata.Id));
            }

            if (!String.IsNullOrEmpty(entity.ServiceMetadata.Id))
            {
                return(atomIdSet.Contains(entity.ServiceMetadata.Id));
            }

            OfflineEntityKey key = (OfflineEntityKey)entity.GetIdentity();

            key.TypeName = entity.GetType().FullName;

            return(pkeySet.Contains(key));
        }
예제 #4
0
        /// <summary>
        /// Adds a error to the list of in-memory
        /// </summary>
        /// <param name="error"></param>
        /// <param name="context">Context for the conflict is being added</param>
        public void AddSyncError(SyncError error, WinEightContext context)
        {
            OfflineEntity entity   = Collections[error.LiveEntity.GetType()].AddOrUpdateSyncEntity((OfflineEntity)error.LiveEntity);
            SyncError     oldError = Collections[error.LiveEntity.GetType()].MapSyncError(entity, error, context);

            SyncErrors.Add(error);

            if (oldError != null)
            {
                ClearSyncError(oldError, context);
            }
        }
예제 #5
0
        /// <summary>
        /// Adds a conflict to the list of in-memory
        /// </summary>
        /// <param name="conflict">Conflict to add</param>
        /// <param name="context">Context for which the conflict is being added</param>
        public void AddSyncConflict(SyncConflict conflict, WinEightContext context)
        {
            OfflineEntity entity      = Collections[conflict.LiveEntity.GetType()].AddOrUpdateSyncEntity((OfflineEntity)conflict.LiveEntity);
            SyncConflict  oldConflict = Collections[conflict.LiveEntity.GetType()].MapSyncConflict(entity, conflict, context);

            SyncConflicts.Add(conflict);

            if (oldConflict != null)
            {
                ClearSyncConflict(oldConflict, context);
            }
        }
예제 #6
0
        /// <summary>
        /// Does reflection to copy the properties from another entity to this entity
        /// </summary>
        /// <param name="entity">Entity from which to copy properties</param>
        private void CopyEntityToThis(OfflineEntity entity)
        {
            IEnumerable <PropertyInfo> propInfos = GetEntityProperties();

            object[] parameters = new object[] { };
            foreach (PropertyInfo propInfo in propInfos)
            {
                propInfo.SetMethod.Invoke(this, new[] { propInfo.GetMethod.Invoke(entity, parameters) });
            }

            CopyODataPropertiesToThis(entity);
            this.entityMetadata.IsTombstone = entity.entityMetadata.IsTombstone;
        }
예제 #7
0
        /// <summary>
        /// Gets the original state of the entity at the time it was last Submitted.
        /// </summary>
        /// <returns>The original entity, if the entity has been modified, null otherwise.</returns>
        public OfflineEntity GetOriginal()
        {
            OfflineEntity org = null;

            lock (syncRoot)
            {
                if (this.EntityState == OfflineEntityState.Modified &&
                    this.original != null)
                {
                    org = (OfflineEntity)Activator.CreateInstance(this.GetType());

                    FillEntityFromSnapshot(org);
                    org.IsReadOnly = true;
                }
            }

            return(org);
        }
예제 #8
0
        /// <summary>
        /// Copies the properties from the entity to the snapshot
        /// </summary>
        /// <param name="entity">Entity from which to copy properties</param>
        private OfflineEntitySnapshot GetSnapshotFromEntity(OfflineEntity entity)
        {
            OfflineEntitySnapshot      snapshot   = new OfflineEntitySnapshot();
            IEnumerable <PropertyInfo> properties = GetEntityProperties();

            // Copy data properties
            foreach (PropertyInfo property in properties)
            {
                object val = property.GetMethod.Invoke(entity, null);
                snapshot.Properties[property.Name] = val;
            }

            snapshot.TickCount   = entity.TickCount;
            snapshot.EntityState = entity.EntityState;
            snapshot.Metadata    = entity.ServiceMetadata.Clone();

            return(snapshot);
        }
예제 #9
0
        /// <summary>
        /// Uses the snapshot to fill the entity's properties
        /// </summary>
        /// <param name="entity">Entity to fill</param>
        internal void FillEntityFromSnapshot(OfflineEntity entity)
        {
            Type type = entity.GetType();

            foreach (var property in original.Properties)
            {
                PropertyInfo propInfo = type.GetTypeInfo().GetDeclaredProperty(property.Key);

                // If propInfo is null, it's an internal property
                // that will be handled later
                if (propInfo != null)
                {
                    propInfo.SetMethod.Invoke(entity, new[] { property.Value });
                }
            }

            // Get the internal properties
            entity.entityMetadata = original.Metadata;
            entity.EntityState    = original.EntityState;
            entity.TickCount      = original.TickCount;
        }
예제 #10
0
        /// <summary>
        /// Updates an entity from sync.
        /// </summary>
        /// <param name="entity">Entity with changes to update</param>
        /// <returns>Whether or not the entity is already modified</returns>
        internal void UpdateFromSync(OfflineEntity entity)
        {
            lock (syncRoot)
            {
                if (this.EntityState == OfflineEntityState.Modified)
                {
                    OfflineEntitySnapshot snapshot = GetSnapshotFromEntity(entity);
                    snapshot.IsTombstone = entity.IsTombstone;
                    snapshot.TickCount   = this.TickCount + 1;

                    this.original = snapshot;
                }
                else
                {
                    trackChanges = false;
                    // Update properties
                    CopyEntityToThis(entity);
                    trackChanges = true;
                }
            }
        }
예제 #11
0
 public abstract void ClearSyncError(OfflineEntity entity);
예제 #12
0
 public abstract void ClearSyncConflict(OfflineEntity entity);
예제 #13
0
 public abstract OfflineEntity AddOrUpdateSyncEntity(OfflineEntity entity,
                                                                    bool delayNotification);
예제 #14
0
 /// <summary>
 /// Copies OData properties that don't need to be snapshoted
 /// </summary>
 /// <param name="entity">Entity from which to copy properties</param>
 private void CopyODataPropertiesToThis(OfflineEntity entity)
 {
     this.entityMetadata.Id      = entity.entityMetadata.Id;
     this.entityMetadata.EditUri = entity.entityMetadata.EditUri;
     this.entityMetadata.ETag    = entity.entityMetadata.ETag;
 }
예제 #15
0
        /// <summary>
        /// Copies the properties from the entity to the snapshot
        /// </summary>
        /// <param name="entity">Entity from which to copy properties</param>        
        private OfflineEntitySnapshot GetSnapshotFromEntity(OfflineEntity entity)
        {
            OfflineEntitySnapshot snapshot = new OfflineEntitySnapshot();
            IEnumerable<PropertyInfo> properties = GetEntityProperties();

            // Copy data properties
            foreach (PropertyInfo property in properties)
            {
                object val = property.GetMethod.Invoke(entity, null);
                snapshot.Properties[property.Name] = val;
            }

            snapshot.TickCount = entity.TickCount;
            snapshot.EntityState = entity.EntityState;
            snapshot.Metadata = entity.ServiceMetadata.Clone();

            return snapshot;
        }
예제 #16
0
 public abstract void AddSerializedEntity(OfflineEntity entity);
예제 #17
0
 /// <summary>
 /// Copies OData properties that don't need to be snapshoted
 /// </summary>
 /// <param name="entity">Entity from which to copy properties</param>
 private void CopyODataPropertiesToThis(OfflineEntity entity)
 {
     this.entityMetadata.Id = entity.entityMetadata.Id;
     this.entityMetadata.EditUri = entity.entityMetadata.EditUri;
     this.entityMetadata.ETag = entity.entityMetadata.ETag;
 }
예제 #18
0
 public abstract void ClearSyncConflict(OfflineEntity entity);
예제 #19
0
 public abstract void ClearSyncError(OfflineEntity entity);
예제 #20
0
 public abstract void ResolveConflictByRollback(OfflineEntity entity);
예제 #21
0
 public abstract SyncError MapSyncError(OfflineEntity entity, SyncError error,
                                        WinEightContext context);
예제 #22
0
 public abstract SyncConflict MapSyncConflict(OfflineEntity entity, SyncConflict conflict,
                                              WinEightContext context);
예제 #23
0
        /// <summary>
        /// Updates an entity from sync.
        /// </summary>
        /// <param name="entity">Entity with changes to update</param>
        /// <returns>Whether or not the entity is already modified</returns>
        internal void UpdateFromSync(OfflineEntity entity)
        {
            lock (syncRoot)
            {
                if (this.EntityState == OfflineEntityState.Modified)
                {
                    OfflineEntitySnapshot snapshot = GetSnapshotFromEntity(entity);
                    snapshot.IsTombstone = entity.IsTombstone;
                    snapshot.TickCount = this.TickCount + 1;

                    this.original = snapshot;
                }
                else
                {
                    trackChanges = false;
                    // Update properties
                    CopyEntityToThis(entity);
                    trackChanges = true;
                }
            }
        }
예제 #24
0
 public abstract OfflineEntity AddOrUpdateSyncEntity(OfflineEntity entity);
예제 #25
0
        /// <summary>
        /// Does reflection to copy the properties from another entity to this entity
        /// </summary>
        /// <param name="entity">Entity from which to copy properties</param>
        private void CopyEntityToThis(OfflineEntity entity)
        {
            IEnumerable<PropertyInfo> propInfos = GetEntityProperties();

            object[] parameters = new object[] { };
            foreach (PropertyInfo propInfo in propInfos)
            {
                propInfo.SetMethod.Invoke(this, new[] { propInfo.GetMethod.Invoke(entity, parameters) });
            }

            CopyODataPropertiesToThis(entity);
            this.entityMetadata.IsTombstone = entity.entityMetadata.IsTombstone;
        }
예제 #26
0
 public abstract void AddSerializedEntity(OfflineEntity entity);
예제 #27
0
        /// <summary>
        /// Uses the snapshot to fill the entity's properties
        /// </summary>
        /// <param name="entity">Entity to fill</param>
        internal void FillEntityFromSnapshot(OfflineEntity entity)
        {
            Type type = entity.GetType();
            foreach (var property in original.Properties)
            {
                PropertyInfo propInfo = type.GetTypeInfo().GetDeclaredProperty(property.Key);

                // If propInfo is null, it's an internal property
                // that will be handled later
                if (propInfo != null)
                {
                    propInfo.SetMethod.Invoke(entity, new[] { property.Value });
                }
            }

            // Get the internal properties
            entity.entityMetadata = original.Metadata;
            entity.EntityState = original.EntityState;
            entity.TickCount = original.TickCount;
        }
예제 #28
0
 public void AddSerializedLocalChange(OfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Saved;
     Collections[entity.GetType()].AddSerializedEntity(entity);
 }
예제 #29
0
        /// <summary>
        /// Method called by the context to resolve a conflict with StoreItemWins
        /// </summary>
        /// <param name="entity"></param>
        public void ResolveStoreConflictByRollback(OfflineEntity entity)
        {
            Type type = entity.GetType();

            Collections[type].ResolveConflictByRollback(entity);
        }
예제 #30
0
 public abstract SyncError MapSyncError(OfflineEntity entity, SyncError error,
                                        WinEightContext context);
예제 #31
0
 public void AddSerializedDownloadItem(OfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Unmodified;
     // Pass the entity to the collection
     Collections[entity.GetType()].AddOrUpdateSyncEntity(entity);
 }
예제 #32
0
 public abstract void ResolveConflictByRollback(OfflineEntity entity);
예제 #33
0
 public void AddSerializedDownloadItem(OfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Unmodified;
     // Pass the entity to the collection
     Collections[entity.GetType()].AddOrUpdateSyncEntity(entity);
 }
예제 #34
0
 public abstract OfflineEntity AddOrUpdateSyncEntity(OfflineEntity entity);
예제 #35
0
 public abstract OfflineEntity AddOrUpdateSyncEntity(OfflineEntity entity,
                                                     bool delayNotification);
예제 #36
0
        /// <summary>
        /// Method called by the context to resolve a conflict with StoreItemWins
        /// </summary>
        /// <param name="entity"></param>
        public void ResolveStoreConflictByRollback(OfflineEntity entity)
        {
            Type type = entity.GetType();

            Collections[type].ResolveConflictByRollback(entity);            
        }
예제 #37
0
 public abstract SyncConflict MapSyncConflict(OfflineEntity entity, SyncConflict conflict,
                                              WinEightContext context);
예제 #38
0
 public void AddSerializedLocalChange(OfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Saved;
     Collections[entity.GetType()].AddSerializedEntity(entity);
 }