/// <summary>
        /// Internal method called by the StoreConflict class during RejectChangesInternal to resolve a store conflict
        /// without locking the the save sync lock.  This ultimately filters down through CancelChanges, which locks,
        /// so this method does not need to.  When it does lock, it causes a deadlock.
        /// </summary>
        /// <param name="conflict"></param>
        /// <param name="resolutionAction"></param>
        internal void ResolveStoreConflictNoLock(StoreConflict conflict, StoreConflictResolutionAction resolutionAction)
        {
            // Cache the modified entity, which may disappear depending on the resolution
            IsolatedStorageOfflineEntity visibleEntity = conflict.ModifiedEntity;

            // Respond to the resolution
            if (resolutionAction == StoreConflictResolutionAction.AcceptModifiedEntity)
            {
                ((IsolatedStorageOfflineEntity)conflict.ModifiedEntity).UpdateModifiedTickCount();
            }
            else if (resolutionAction == StoreConflictResolutionAction.AcceptStoreEntity)
            {
                _cacheData.ResolveStoreConflictByRollback(conflict.ModifiedEntity);
            }
            else
            {
                throw new ArgumentException("Invalid resolution action specified");
            }

            // Cleanup pointers to conflicts everywhere.
            visibleEntity.StoreConflict = null;
            this._storeConflicts.Remove(conflict);

            // Clearing the context will prevent the resolution from being triggered again.
            conflict.ClearContext();
        }
        public bool ContainsEntity(IsolatedStorageOfflineEntity 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);
                }
                else
                {
                    return(_atomIdSet.Contains(entity.ServiceMetadata.Id));
                }
            }
            else
            {
                if (!String.IsNullOrEmpty(entity.ServiceMetadata.Id))
                {
                    return(_atomIdSet.Contains(entity.ServiceMetadata.Id));
                }

                OfflineEntityKey key = entity.GetIdentity() as OfflineEntityKey;
                key.TypeName = entity.GetType().FullName;

                if (_pkeySet.Contains(key))
                {
                    return(true);
                }

                return(false);
            }
        }
        public void ProcessedEntity(IsolatedStorageOfflineEntity entity)
        {
            string           atomId = entity.ServiceMetadata.Id;
            OfflineEntityKey key    = entity.GetIdentity() as OfflineEntityKey;

            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);
                }
            }
        }
        private void CollectionModifiedEntityChanged(IsolatedStorageOfflineEntity entity)
        {
            Action <IsolatedStorageOfflineEntity> action = ModifiedItemChanged;

            if (action != null)
            {
                action(entity);
            }
        }
        protected void OnModifiedItemChanged(IsolatedStorageOfflineEntity changedEntity)
        {
            Action <IsolatedStorageOfflineEntity> action = ModifiedItemChanged;

            if (action != null)
            {
                action(changedEntity);
            }
        }
        protected void OnModifiedItemChanged(IsolatedStorageOfflineEntity changedEntity)
        {
            Action<IsolatedStorageOfflineEntity> action = ModifiedItemChanged;

            if (action != null)
            {
                action(changedEntity);
            }
        }
        /// <summary>
        /// Adds a new collection for the type T.
        /// </summary>
        /// <typeparam name="T">Type of entity for the new collection</typeparam>
        public void AddCollection <T>() where T : IsolatedStorageOfflineEntity
        {
            Type t = typeof(T);

            if (IsolatedStorageOfflineEntity.GetEntityKeyProperties(t).Length == 0)
            {
                throw new ArgumentException("Type: " + t.FullName + " does not have a key specified");
            }

            _collections.Add(t.FullName, t);
        }
示例#8
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, IsolatedStorageOfflineContext context)
        {
            IsolatedStorageOfflineEntity entity = Collections[conflict.LiveEntity.GetType()].AddOrUpdateSyncEntity((IsolatedStorageOfflineEntity)conflict.LiveEntity);
            SyncConflict oldConflict            = Collections[conflict.LiveEntity.GetType()].MapSyncConflict(entity, conflict, context);

            SyncConflicts.Add(conflict);

            if (oldConflict != null)
            {
                ClearSyncConflict(oldConflict, context);
            }
        }
示例#9
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, IsolatedStorageOfflineContext context)
        {
            IsolatedStorageOfflineEntity entity = Collections[error.LiveEntity.GetType()].AddOrUpdateSyncEntity((IsolatedStorageOfflineEntity)error.LiveEntity);
            SyncError oldError = Collections[error.LiveEntity.GetType()].MapSyncError(entity, error, context);

            SyncErrors.Add(error);

            if (oldError != null)
            {
                ClearSyncError(oldError, context);
            }
        }
        /// <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(IsolatedStorageOfflineEntity entity)
        {
            PropertyInfo[] propInfos = GetEntityProperties();

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

            CopyODataPropertiesToThis(entity);
            this._entityMetadata.IsTombstone = entity._entityMetadata.IsTombstone;
        }
        /// <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 IsolatedStorageOfflineEntity GetOriginal()
        {
            IsolatedStorageOfflineEntity original = null;

            lock (_syncRoot)
            {
                if (this.EntityState == OfflineEntityState.Modified &&
                    this._original != null)
                {
                    original = (IsolatedStorageOfflineEntity)Activator.CreateInstance(this.GetType());

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

            return(original);
        }
        /// <summary>
        /// Copies the properties from the entity to the snapshot
        /// </summary>
        /// <param name="entity">Entity from which to copy properties</param>
        private OfflineEntitySnapshot GetSnapshotFromEntity(IsolatedStorageOfflineEntity entity)
        {
            OfflineEntitySnapshot snapshot = new OfflineEntitySnapshot();

            PropertyInfo[] properties = GetEntityProperties();

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

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

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

            foreach (var property in _original.Properties)
            {
                PropertyInfo propInfo = type.GetProperty(property.Key);

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

            // Get the internal properties
            entity._entityMetadata = _original.Metadata;
            entity.EntityState     = _original.EntityState;
            entity.TickCount       = _original.TickCount;
        }
        /// <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(IsolatedStorageOfflineEntity 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;
                }
            }
        }
 public abstract void AddSerializedEntity(IsolatedStorageOfflineEntity entity);
示例#16
0
 public void ResolveStoreConflictByRollback(IsolatedStorageOfflineEntity entity)
 {
 }
 public abstract void ResolveConflictByRollback(IsolatedStorageOfflineEntity entity);
 public abstract void ClearSyncError(IsolatedStorageOfflineEntity entity);
 /// <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(IsolatedStorageOfflineEntity entity)
 {
     this._entityMetadata.Id = entity._entityMetadata.Id;
     this._entityMetadata.EditUri = entity._entityMetadata.EditUri;
     this._entityMetadata.ETag = entity._entityMetadata.ETag;
 }
 /// <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(IsolatedStorageOfflineEntity entity)
 {
     this._entityMetadata.Id      = entity._entityMetadata.Id;
     this._entityMetadata.EditUri = entity._entityMetadata.EditUri;
     this._entityMetadata.ETag    = entity._entityMetadata.ETag;
 }
        /// <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(IsolatedStorageOfflineEntity 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;
                }
            }
        }
 public abstract SyncConflict MapSyncConflict(IsolatedStorageOfflineEntity entity, SyncConflict conflict, IsolatedStorageOfflineContext context);
示例#23
0
 public void AddSerializedDownloadItem(IsolatedStorageOfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Unmodified;
     // Pass the entity to the collection
     Collections[entity.GetType()].AddOrUpdateSyncEntity(entity);
 }
示例#24
0
        /// <summary>
        /// Method called by the context to resolve a conflict with StoreItemWins
        /// </summary>
        /// <param name="entity"></param>
        public void ResolveStoreConflictByRollback(IsolatedStorageOfflineEntity entity)
        {
            Type type = entity.GetType();

            Collections[type].ResolveConflictByRollback(entity);
        }
示例#25
0
 public void AddSerializedLocalChange(IsolatedStorageOfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Saved;
     Collections[entity.GetType()].AddSerializedEntity(entity);
 }
        /// <summary>
        /// Copies the properties from the entity to the snapshot
        /// </summary>
        /// <param name="entity">Entity from which to copy properties</param>        
        private OfflineEntitySnapshot GetSnapshotFromEntity(IsolatedStorageOfflineEntity entity)
        {
            OfflineEntitySnapshot snapshot = new OfflineEntitySnapshot();
            PropertyInfo[] properties = GetEntityProperties();

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

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

            return snapshot;
        }
        /// <summary>
        /// Uses the snapshot to fill the entity's properties
        /// </summary>
        /// <param name="entity">Entity to fill</param>
        internal void FillEntityFromSnapshot(IsolatedStorageOfflineEntity entity)
        {
            Type type = entity.GetType();
            foreach (var property in _original.Properties)
            {
                PropertyInfo propInfo = type.GetProperty(property.Key);

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

            // Get the internal properties
            entity._entityMetadata = _original.Metadata;
            entity.EntityState = _original.EntityState;
            entity.TickCount = _original.TickCount;
        }
示例#28
0
        /// <summary>
        /// Method called by the context to resolve a conflict with StoreItemWins
        /// </summary>
        /// <param name="entity"></param>
        public void ResolveStoreConflictByRollback(IsolatedStorageOfflineEntity entity)
        {
            Type type = entity.GetType();

            Collections[type].ResolveConflictByRollback(entity);            
        }
 public abstract IsolatedStorageOfflineEntity AddOrUpdateSyncEntity(IsolatedStorageOfflineEntity entity);
 public abstract void ClearSyncError(IsolatedStorageOfflineEntity entity);
 public abstract SyncConflict MapSyncConflict(IsolatedStorageOfflineEntity entity, SyncConflict conflict, IsolatedStorageOfflineContext context);
 public abstract void ClearSyncConflict(IsolatedStorageOfflineEntity entity);
 public abstract void ResolveConflictByRollback(IsolatedStorageOfflineEntity entity);
示例#34
0
 public void AddSerializedDownloadItem(IsolatedStorageOfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Unmodified;
     // Pass the entity to the collection
     Collections[entity.GetType()].AddOrUpdateSyncEntity(entity);
 }
        /// <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(IsolatedStorageOfflineEntity entity)
        {
            PropertyInfo[] propInfos = GetEntityProperties();

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

            CopyODataPropertiesToThis(entity);
            this._entityMetadata.IsTombstone = entity._entityMetadata.IsTombstone;
        }
 public abstract void AddSerializedEntity(IsolatedStorageOfflineEntity entity);
 public abstract IsolatedStorageOfflineEntity AddOrUpdateSyncEntity(IsolatedStorageOfflineEntity entity, bool delayNotification);
 public abstract IsolatedStorageOfflineEntity AddOrUpdateSyncEntity(IsolatedStorageOfflineEntity entity, bool delayNotification);
 public abstract IsolatedStorageOfflineEntity AddOrUpdateSyncEntity(IsolatedStorageOfflineEntity entity);
 public abstract SyncError MapSyncError(IsolatedStorageOfflineEntity entity, SyncError error, IsolatedStorageOfflineContext context);
示例#41
0
 public void AddSerializedLocalChange(IsolatedStorageOfflineEntity entity)
 {
 }
 public abstract void ClearSyncConflict(IsolatedStorageOfflineEntity entity);
示例#43
0
 public void AddSerializedDownloadItem(IsolatedStorageOfflineEntity entity)
 {
 }
示例#44
0
 public void AddSerializedLocalChange(IsolatedStorageOfflineEntity entity)
 {
     entity.EntityState = OfflineEntityState.Saved;
     Collections[entity.GetType()].AddSerializedEntity(entity);
 }
 public abstract SyncError MapSyncError(IsolatedStorageOfflineEntity entity, SyncError error, IsolatedStorageOfflineContext context);