示例#1
0
        /// <summary>In case of items with same remote ids, some new exchange items resolved as apply to remote.
        /// In case there is no activity metadata, conflict resolved as apply to local.</summary>
        /// <param name="syncItem">Sync entity instance.</param>
        /// <param name="itemMetaData">Metadata instance.</param>
        /// <param name="localStoreId">Local storage id.</param>
        /// <returns>Sync conflict resoluton for sync item.</returns>
        public override SyncConflictResolution ResolveConflict(IRemoteItem syncItem,
                                                               ItemMetadata itemMetaData, Guid localStoreId)
        {
            if (syncItem.Action == SyncAction.CreateRecurringMaster)
            {
                return(SyncConflictResolution.ApplyToLocal);
            }
            bool isActivityExists = itemMetaData.Any(item => item.SyncSchemaName == "Activity");

            if (!isActivityExists)
            {
                return(SyncConflictResolution.ApplyToLocal);
            }
            if (_userConnection.GetIsFeatureEnabled("ResolveConflictsByContent"))
            {
                var appointment = syncItem as ExchangeAppointment;
                if (appointment.Action == SyncAction.Delete)
                {
                    return(SyncConflictResolution.ApplyToRemote);
                }
                Exchange.Appointment remoteItem = appointment.Item as Exchange.Appointment;
                appointment.LoadItemProperties(remoteItem);
                string oldActivityHash = GetActivityHashFromMetadata(itemMetaData);
                if (!appointment.IsAppointmentChanged(remoteItem, oldActivityHash, _userConnection))
                {
                    return(SyncConflictResolution.ApplyToRemote);
                }
            }
            SyncConflictResolution result = base.ResolveConflict(syncItem, itemMetaData, localStoreId);

            return(result);
        }
示例#2
0
        protected override void ExecuteDirectory(string directoryPath, SearchContext context)
        {
            bool secondExists = Directory.Exists(Options.Target);

            if (secondExists)
            {
                _destinationPaths = new HashSet <string>(FileSystemHelpers.Comparer);
            }

            try
            {
                _isSecondToFirst = false;

                if (ConflictResolution == SyncConflictResolution.FirstWins &&
                    !secondExists)
                {
                    CreateDirectory(Options.Target);
                }

                base.ExecuteDirectory(directoryPath, context);
            }
            finally
            {
                _isSecondToFirst = true;
            }

            if (secondExists)
            {
                _ignoredPaths     = _destinationPaths;
                _destinationPaths = null;

                string secondDirectory = directoryPath;
                directoryPath = Options.Target;

                Options.Paths  = ImmutableArray.Create(new PathInfo(directoryPath, PathOrigin.None));
                Options.Target = secondDirectory;

                if (ConflictResolution == SyncConflictResolution.FirstWins)
                {
                    ConflictResolution = SyncConflictResolution.SecondWins;
                }
                else if (ConflictResolution == SyncConflictResolution.SecondWins)
                {
                    ConflictResolution = SyncConflictResolution.FirstWins;
                }

                base.ExecuteDirectory(directoryPath, context);
            }

            _ignoredPaths = null;
        }
        /// <summary>
        /// Utility for invoking user code for conflict interceptors
        /// </summary>
        /// <param name="context">The context to pass as parameter to user code</param>
        /// <param name="mergedVersion">The merged version for Merge resolution</param>
        /// <param name="entityType">Entity type of the conflict being raised</param>
        /// <returns>Actual resolution picked by user</returns>
        internal SyncConflictResolution?InvokeConflictInterceptor(SyncConflictContext context, Type entityType, out IOfflineEntity mergedVersion)
        {
            SyncInterceptorsInfoWrapper wrapper = null;

            if (this.SyncInterceptors.TryGetValue(context.ScopeName, out wrapper))
            {
                // Look for unfiltered Conflict and if that is null then look for filtered one.
                // Its an error to have both unfiltered and filtered ConflictInterceptor so both cannot be set.
                MethodInfo methodInfo = wrapper.ConflictInterceptor ?? wrapper.GetConflictInterceptor(entityType);
                if (methodInfo != null)
                {
                    object[] inputParams = new object[] { context, null };
                    SyncConflictResolution resolution = (SyncConflictResolution)InvokeUserInterceptorMethod(methodInfo, OperationContext.Current.InstanceContext.GetServiceInstance(), inputParams);
                    // Merged version is in the second parameter which is passed by reference. Look it up
                    mergedVersion = (IOfflineEntity)inputParams[1];
                    return(resolution);
                }
            }
            mergedVersion = null;
            return(null);
        }
示例#4
0
        /// <summary>
        /// Called to add a Sync conflict item
        /// </summary>
        /// <param name="winningEntry">the winning entity</param>
        /// <param name="winningEntryTempId">the winning entity's tempId</param>
        /// <param name="losingEntry">The losing entity</param>
        /// <param name="losingEntryTempId">The losing entity's tempId</param>
        /// <param name="resolution">The conflict resolution aplied by the server</param>
        public virtual void AddConflictItem(IOfflineEntity winningEntry, string winningEntryTempId, IOfflineEntity losingEntry, string losingEntryTempId, SyncConflictResolution resolution)
        {
            if (winningEntry == null)
            {
                throw new ArgumentNullException("winningEntry");
            }

            if (losingEntry == null)
            {
                throw new ArgumentNullException("losingEntry");
            }
            WriteItemInternal(winningEntry, winningEntryTempId, losingEntry /*conflicting*/, losingEntryTempId, resolution.ToString() /*desc*/, true /*isconflict*/, false /*emitMetadataOnly*/);
        }
示例#5
0
        /// <summary>
        /// Called to add a Sync conflict item
        /// </summary>
        /// <param name="winningEntry">the winning entity</param>
        /// <param name="winningEntryTempId">the winning entity's tempId</param>
        /// <param name="losingEntry">The losing entity</param>
        /// <param name="losingEntryTempId">The losing entity's tempId</param>
        /// <param name="resolution">The conflict resolution aplied by the server</param>
        public virtual void AddConflictItem(IOfflineEntity winningEntry, string winningEntryTempId, IOfflineEntity losingEntry, string losingEntryTempId, SyncConflictResolution resolution)
        {
            if (winningEntry == null)
            {
                throw new ArgumentNullException("winningEntry");
            }

            if (losingEntry == null)
            {
                throw new ArgumentNullException("losingEntry");
            }
            WriteItemInternal(winningEntry, winningEntryTempId, losingEntry/*conflicting*/, losingEntryTempId, resolution.ToString() /*desc*/, true/*isconflict*/, false/*emitMetadataOnly*/);
        }