/// <returns>True if the tree was dumped, false if the root item was not included</returns> public virtual bool DumpTree(IItemData item, IConfiguration configuration = null) { using (new TransparentSyncDisabler()) { if(configuration == null) configuration = GetConfigurationForItem(item); if (configuration == null) return false; var logger = configuration.Resolve<ILogger>(); var predicate = configuration.Resolve<IPredicate>(); var serializationStore = configuration.Resolve<ITargetDataStore>(); var sourceStore = configuration.Resolve<ISourceDataStore>(); var rootReference = serializationStore.GetByPathAndId(item.Path, item.Id, item.DatabaseName); if (rootReference != null) { logger.Warn("[D] existing serialized items under {0}".FormatWith(rootReference.GetDisplayIdentifier())); serializationStore.Remove(rootReference); } logger.Info("[U] Serializing included items under root {0}".FormatWith(item.GetDisplayIdentifier())); if (!predicate.Includes(item).IsIncluded) return false; DumpTreeInternal(item, predicate, serializationStore, sourceStore, logger); } return true; }
public virtual void LoadFrom(IItemData itemData, IFieldFormatter[] fieldFormatters) { Id = itemData.Id; DatabaseName = itemData.DatabaseName; ParentId = itemData.ParentId; TemplateId = itemData.TemplateId; Path = itemData.Path; BranchId = itemData.BranchId; foreach (var field in itemData.SharedFields) { var fieldObject = new YamlFieldValue(); fieldObject.LoadFrom(field, fieldFormatters); SharedFields.Add(fieldObject); } var languages = itemData.Versions.GroupBy(x => x.Language.Name); foreach (var language in languages) { var languageObject = new YamlLanguage(); languageObject.LoadFrom(language, fieldFormatters); if(languageObject.Versions.Count > 0) Languages.Add(languageObject); } }
public SyncItem BuildSyncItem(IItemData item) { var syncItem = new SyncItem { ID = item.Id.ToString("B"), DatabaseName = item.DatabaseName, ParentID = item.ParentId.ToString("B"), Name = item.Name, BranchId = item.BranchId.ToString("B"), TemplateID = item.TemplateId.ToString("B"), ItemPath = item.Path }; //syncItem.TemplateName = item.TemplateName; foreach (var field in item.SharedFields) //TODO: ItemSynchronization.BuildSyncItem sorts the fields and versions first, should we ? { syncItem.AddSharedField(field.FieldId.ToString("B"), null/*name*/, null/*key?*/, field.Value, true); } foreach (var version in item.Versions) { var syncVersion = syncItem.AddVersion(version.Language.ToString(), version.VersionNumber.ToString(), version.VersionNumber.ToString() /*revisionid needed?*/); if (syncVersion != null) { foreach (var field in version.Fields) { syncVersion.AddField(field.FieldId.ToString("B"), null/*name*/,null /*key?*/, field.Value, true); } } } return syncItem; }
/// <returns>True if the item was dumped, false if it was not included</returns> public virtual bool DumpItem(IItemData item, IConfiguration[] configurations = null) { using (new TransparentSyncDisabler()) { if (configurations == null) configurations = GetConfigurationsForItem(item); foreach(var configuration in configurations) { if (configuration == null) return false; var predicate = configuration.Resolve<IPredicate>(); var serializationStore = configuration.Resolve<ITargetDataStore>(); CacheManager.ClearAllCaches(); // BOOM! This clears all caches before we begin; // because for a TpSync configuration we could have TpSync items in the data cache which 'taint' the reserialize // from being purely database var result = DumpItemInternal(item, predicate, serializationStore).IsIncluded; CacheManager.ClearAllCaches(); // BOOM! And we clear everything again at the end, because now // for a TpSync configuration we might have DATABASE items in cache where we want TpSync. if (!result) return false; } return true; } }
public virtual IItemData EvaluateUpdate(IItemData sourceItem, IItemData targetItem) { Assert.ArgumentNotNull(sourceItem, "sourceItemData"); _logger.Evaluated(sourceItem); return null; }
public PredicateFilteredItemData(IItemData innerItem, IPredicate predicate) : base(innerItem) { Assert.ArgumentNotNull(predicate, "predicate"); _predicate = predicate; }
public void AddTreeRetry(IItemData reference, Exception exception) { Assert.ArgumentNotNull(reference, "reference"); Assert.ArgumentNotNull(exception, "exception"); _treeFailures.Add(new Failure(reference, exception)); }
public void AddProcessedItem(IItemData itemData) { lock (_syncRoot) { _duplicateChecks.Add(CreateKey(itemData), new DuplicateIdEntry(itemData)); } }
public virtual void Renamed(IItemData sourceItem, IItemData targetItem) { Assert.ArgumentNotNull(sourceItem, "sourceItem"); Assert.ArgumentNotNull(targetItem, "targetItem"); _logger.Debug("> Name: Serialized \"{0}\", Source \"{1}\"".FormatWith(targetItem.Name, sourceItem.Name)); }
public virtual void LoadAll(IItemData[] rootItemsData, IDeserializeFailureRetryer retryer, IConsistencyChecker consistencyChecker, Action<IItemData> rootLoadedCallback = null) { Assert.ArgumentNotNull(rootItemsData, "rootItems"); Assert.IsTrue(rootItemsData.Length > 0, "No root items were passed!"); CacheManager.ClearAllCaches(); // BOOM! This clears all caches before we begin; // because for a TpSync configuration we could have TpSync items in the data cache which 'taint' the item comparisons and result in missed updates bool disableNewSerialization = UnicornDataProvider.DisableSerialization; try { UnicornDataProvider.DisableSerialization = true; using (new EventDisabler()) { foreach (var rootItem in rootItemsData) { LoadTree(rootItem, retryer, consistencyChecker); if (rootLoadedCallback != null) rootLoadedCallback(rootItem); } retryer.RetryAll(SourceDataStore, item => DoLoadItem(item, null), item => LoadTreeInternal(item, retryer, null)); } } finally { UnicornDataProvider.DisableSerialization = disableNewSerialization; } }
public void EvaluateOrphans(IItemData[] orphanItems) { Assert.ArgumentNotNull(orphanItems, "orphanItems"); EvaluatorUtility.RecycleItems(orphanItems, _sourceDataStore, item => _logger.DeletedItem(item)); foreach (var orphan in orphanItems) _logger.Evaluated(orphan); }
public virtual void Save(IItemData item) { var tree = GetTreeForPath(item.Path, item.DatabaseName); if (tree == null) throw new InvalidOperationException("No trees contained the global path " + item.Path); tree.Save(item); }
/// <summary> /// Creates a rebasing based on an item, new PARENT path, and new parent ID. Use this to rebase an individual item /// that may not yet have the right parent and path. /// </summary> public PathRebasingProxyItem(IItemData innerItem, string newParentPath, Guid newParentId) : base(innerItem) { Assert.ArgumentNotNull(innerItem, "innerItem"); Assert.ArgumentNotNull(newParentPath, "newParentPath"); _newParentPath = newParentPath; ParentId = newParentId; }
protected override void WriteItem(IItemData item, string path) { _sourceControlManager.EditPreProcessing(path); base.WriteItem(item, path); _sourceControlManager.EditPostProcessing(path); }
/// <summary> /// Creates a rebasing path based on the path and parent ID of an existing item. Use this to rebase the paths of all children, /// while leaving the root item unchanged. /// </summary> public PathRebasingProxyItem(IItemData innerItem) : base(innerItem) { Assert.ArgumentNotNull(innerItem, "innerItem"); ParentId = innerItem.ParentId; _newParentPath = innerItem.Path; _parentPathIsLiteral = true; }
public CatalogItemArgs(CatalogItemProgressType type, IMailboxData mailbox, Stack<IFolderData> folderStack, IFolderData folder, IItemData currentItem) { this.Type = type; this.Mailbox = mailbox; this.FolderStack = folderStack; this.Folder = folder; this.CurrentItem = currentItem; }
public virtual void SerializedUpdatedItem(IItemData targetItem) { Assert.ArgumentNotNull(targetItem, "targetItem"); _logger.Info("[U] {0}".FormatWith(targetItem.GetDisplayIdentifier())); _pipelineDataCollector.PushChangedItem(targetItem, ChangeType.Modified); _pipelineDataCollector.AddProcessedItem(); }
public IItemData Deserialize(IItemData serializedItemData) { Assert.ArgumentNotNull(serializedItemData, "serializedItem"); bool newItemWasCreated; var targetItem = GetOrCreateTargetItem(serializedItemData, out newItemWasCreated); var softErrors = new List<TemplateMissingFieldException>(); try { ChangeTemplateIfNeeded(serializedItemData, targetItem); RenameIfNeeded(serializedItemData, targetItem); ResetTemplateEngineIfItemIsTemplate(targetItem); UpdateFieldSharingIfNeeded(serializedItemData, targetItem); PasteSharedFields(serializedItemData, targetItem, newItemWasCreated, softErrors); ClearCaches(targetItem.Database, new ID(serializedItemData.Id)); targetItem.Reload(); ResetTemplateEngineIfItemIsTemplate(targetItem); PasteVersions(serializedItemData, targetItem, newItemWasCreated, softErrors); ClearCaches(targetItem.Database, targetItem.ID); if (softErrors.Count > 0) throw TemplateMissingFieldException.Merge(softErrors); return new ItemData(targetItem, ParentDataStore); } catch (ParentForMovedItemNotFoundException) { throw; } catch (ParentItemNotFoundException) { throw; } catch (TemplateMissingFieldException) { throw; } catch (Exception ex) { if (newItemWasCreated) { targetItem.Delete(); ClearCaches(targetItem.Database, new ID(serializedItemData.Id)); } throw new DeserializationException("Failed to paste item: " + serializedItemData.Path, ex); } }
public bool IsConsistent(IItemData itemData) { DuplicateIdEntry duplicateItemData; if(!_duplicateChecks.TryGetValue(CreateKey(itemData), out duplicateItemData)) return true; _logger.DuplicateFound(duplicateItemData, itemData); return false; }
public override void EvaluateOrphans(IItemData[] orphanItems) { Assert.ArgumentNotNull(orphanItems, "orphanItems"); foreach (var item in orphanItems) { RecycleItem(item); } }
public IItemData Convert(IItemData itemData, byte[] data) { return new ItemModel() { ItemId = itemData.ItemId, Data = data, Location = itemData.Location }; }
public CatalogFolderArgs(CatalogFolderProgressType type, IMailboxData currentMailbox, Stack<IFolderData> folderStack, IFolderData currentFolder, Process itemProcess, IItemData currentItem, Process childFolderProcess) { this.Type = type; this.CurrentMailbox = currentMailbox; this.FolderStack = folderStack; this.CurrentFolder = currentFolder; this.ItemProcess = itemProcess; this.CurrentItem = currentItem; this.ChildFolderProcess = childFolderProcess; }
public virtual void AddTreeRetry(IItemData item, Exception exception) { Assert.ArgumentNotNull(item, "reference"); Assert.ArgumentNotNull(exception, "exception"); lock (_collectionLock) { _treeFailures.Add(CreateFailure(item, exception)); } }
public void AddItemRetry(IItemData reference, Exception exception) { Assert.ArgumentNotNull(reference, "reference"); Assert.ArgumentNotNull(exception, "exception"); lock (_collectionLock) { _itemFailures.Add(new Failure(reference, exception)); } }
/// <summary> /// Deletes an item from the source data provider /// </summary> private static void RecycleItem(IItemData itemData, ISourceDataStore sourceStore, Action<IItemData> deleteMessage) { var children = sourceStore.GetChildren(itemData); RecycleItems(children, sourceStore, deleteMessage); deleteMessage(itemData); sourceStore.Remove(itemData); }
public ChangeEntry(IItemData itemData, ChangeType type) { if (itemData != null) { Id = itemData.Id; DatabaseName = itemData.DatabaseName; } ChangeType = type; }
public RainbowItem(IItemData itemData) { this.Name = itemData.Name; this.DatabaseName = itemData.DatabaseName; this.Id = itemData.Id.ToString("B"); this.BranchId = itemData.BranchId.ToString("B"); this.ItemPath = itemData.Path; this.ParentId = itemData.ParentId.ToString("B"); this.TemplateId = itemData.TemplateId.ToString("B"); this.SharedFields = itemData.SharedFields.Select(x => new RainbowField(x)).Cast<IField>().ToList().ToList(); }
/// <summary> /// Checks if a preset includes a given item /// </summary> protected PredicateResult Includes(PresetTreeRoot entry, IItemData itemData) { // check for db match if (!itemData.DatabaseName.Equals(entry.DatabaseName, StringComparison.OrdinalIgnoreCase)) return new PredicateResult(false); // check for path match if (!itemData.Path.StartsWith(entry.Path, StringComparison.OrdinalIgnoreCase)) return new PredicateResult(false); // check excludes return ExcludeMatches(entry, itemData); }
protected virtual PredicateResult ExcludeMatches(PresetTreeRoot entry, IItemData itemData) { foreach (var exclude in entry.Exclusions) { var result = exclude.Evaluate(itemData.Path); if (!result.IsIncluded) return result; } return new PredicateResult(true); }
public virtual IItemData EvaluateNewSerializedItem(IItemData newItemData) { Assert.ArgumentNotNull(newItemData, "newItem"); _logger.DeserializedNewItem(newItemData); _sourceDataStore.Save(newItemData); _logger.Evaluated(newItemData); return newItemData; }
public ItemService(IItemData itemData) { _itemData = itemData; }
public PredicateResult Evaluate(IItemData itemData) { var itemPath = PathTool.EnsureTrailingSlash(itemData.Path); // you may preserve certain children from exclusion foreach (var exception in _exceptions) { var fullPath = exception.Item1; var exceptionRule = exception.Item2; var unescapedExceptionPath = fullPath.Replace(@"\*", "*"); if (exceptionRule.IncludeChildren) { if (itemPath.StartsWith(unescapedExceptionPath, StringComparison.OrdinalIgnoreCase)) { return(new PredicateResult(true)); } } else { if (itemPath.Equals(unescapedExceptionPath, StringComparison.OrdinalIgnoreCase)) { return(new PredicateResult(true)); } } } // if the path isn't under the exclusion, it's included var unescapedWildcardFreePath = _excludeChildrenOfPath.EndsWith("/*/") ? _excludeChildrenOfPath.Substring(0, _excludeChildrenOfPath.Length - 2) : _excludeChildrenOfPath; // unescape any "\*" escapes to match a literal wildcard item so we can compare the path (we don't check this variable for * later) unescapedWildcardFreePath = unescapedWildcardFreePath.Replace(@"\*", "*"); if (!itemPath.StartsWith(unescapedWildcardFreePath, StringComparison.OrdinalIgnoreCase)) { return(new PredicateResult(true)); } // if the path EQUALS the exclusion path it's included. Because we're including the root, and excluding the children. if (itemPath.Equals(unescapedWildcardFreePath, StringComparison.OrdinalIgnoreCase)) { return(new PredicateResult(true)); } // if the path EQUALS a wildcarded exclusion path it's included. // we accomplish this by doing an equals on the parent path of both the item path and the exclusion // /foo/bar => /foo, then match against COP = /foo/* => /foo/ == TRUE, so we include it // but, /foo/bar/baz => /foo/bar, match against COP /foo/* => /foo/ == FALSE, so it is excluded if (_excludeChildrenOfPath.EndsWith("/*/")) { var itemParentPath = itemPath.Substring(0, itemPath.TrimEnd('/').LastIndexOf('/') + 1); // /foo/bar/ => /foo/ if (itemParentPath.Equals(unescapedWildcardFreePath, StringComparison.OrdinalIgnoreCase)) { return(new PredicateResult(true)); } } // the item is part of the exclusion return(new PredicateResult($"Children of {_excludeChildrenOfPath} excluded")); }
public ItemBizLogic(IItemData _dataAccess) { dataAccess = _dataAccess; }