/// <summary> /// Gets the nodes. /// </summary> /// <param name="matcher">The matcher.</param> /// <returns></returns> public List <OdcTreeNode> GetNodes(NodeMatcher matcher) { var result = new List <OdcTreeNode>(); GetNodes(result, matcher); return(result); }
public void TestIsMatch__Name() { NodeMatcher matcher = new NodeMatcher("NODE", "blah", null); Assert.True(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "blah" }, })); Assert.False(matcher.IsMatch(new ConfigNode("NODE"))); Assert.False(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "bleh" }, })); Assert.False(matcher.IsMatch(new ConfigNode("PART"))); Assert.False(matcher.IsMatch(new TestConfigNode("PART") { { "name", "blah" }, })); Assert.False(matcher.IsMatch(new TestConfigNode("PART") { { "name", "bleh" }, })); }
public void TestIsMatch() { NodeMatcher matcher = new NodeMatcher("NODE", null, null); Assert.True(matcher.IsMatch(new ConfigNode("NODE"))); Assert.False(matcher.IsMatch(new ConfigNode("PART"))); }
/// <summary> /// Gets the nodes. /// </summary> /// <param name="result">The result.</param> /// <param name="matcher">The matcher.</param> public void GetNodes(List <OdcTreeNode> result, NodeMatcher matcher) { foreach (var node in this) { if (matcher(node)) { result.Add(node); } node.ChildNodes.GetNodes(result, matcher); } }
public void TestIsMatch__Constraints() { NodeMatcher matcher = new NodeMatcher("NODE", "blah", "@FOO[bar*],#something[else]"); Assert.True(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "blah" }, { "something", "else" }, new TestConfigNode("FOO") { { "name", "barbar" }, }, })); Assert.False(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "blah" }, })); Assert.False(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "blah" }, { "something", "else" }, })); Assert.False(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "blah" }, new TestConfigNode("FOO") { { "name", "barbar" }, }, })); Assert.False(matcher.IsMatch(new TestConfigNode("NODE") { { "name", "bleh" }, { "something", "else" }, new TestConfigNode("FOO") { { "name", "barbar" }, }, })); Assert.False(matcher.IsMatch(new TestConfigNode("NADE") { { "name", "blah" }, { "something", "else" }, new TestConfigNode("FOO") { { "name", "barbar" }, }, })); }
/// <summary> /// Matches nodes of two node lists and invokes compareNode on /// each pair. /// </summary> /// <remarks> /// Also performs CHILD_LOOKUP comparisons for each node that /// couldn't be matched to one of the "other" list. /// </remarks> private ComparisonState CompareNodeLists(IEnumerable <XmlNode> allControlChildren, IEnumerable <XmlNode> controlSeq, XPathContext controlContext, IEnumerable <XmlNode> allTestChildren, IEnumerable <XmlNode> testSeq, XPathContext testContext) { ComparisonState chain = new OngoingComparisonState(this); IEnumerable <KeyValuePair <XmlNode, XmlNode> > matches = NodeMatcher.Match(controlSeq, testSeq); IList <XmlNode> controlListForXpath = new List <XmlNode>(allControlChildren); IList <XmlNode> testListForXpath = new List <XmlNode>(allTestChildren); IList <XmlNode> controlList = new List <XmlNode>(controlSeq); IList <XmlNode> testList = new List <XmlNode>(testSeq); ICollection <XmlNode> seen = new HashSet <XmlNode>(); foreach (KeyValuePair <XmlNode, XmlNode> pair in matches) { XmlNode control = pair.Key; seen.Add(control); XmlNode test = pair.Value; seen.Add(test); int controlIndexForXpath = controlListForXpath.IndexOf(control); int testIndexForXpath = testListForXpath.IndexOf(test); int controlIndex = controlList.IndexOf(control); int testIndex = testList.IndexOf(test); controlContext.NavigateToChild(controlIndexForXpath); testContext.NavigateToChild(testIndexForXpath); try { chain = chain.AndThen(new Comparison(ComparisonType.CHILD_NODELIST_SEQUENCE, control, GetXPath(controlContext), controlIndex, GetParentXPath(controlContext), test, GetXPath(testContext), testIndex, GetParentXPath(testContext))) .AndThen(() => CompareNodes(control, controlContext, test, testContext)); } finally { testContext.NavigateToParent(); controlContext.NavigateToParent(); } } return(chain .AndThen(UnmatchedControlNodes(controlListForXpath, controlList, controlContext, seen, testContext)) .AndThen(UnmatchedTestNodes(testListForXpath, testList, testContext, seen, controlContext))); }
public void Apply(LinkedList <IProtoUrlConfig> databaseConfigs, IPatchProgress progress, IBasicLogger logger) { if (databaseConfigs == null) { throw new ArgumentNullException(nameof(databaseConfigs)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } PatchContext context = new PatchContext(UrlConfig, databaseConfigs, logger, progress); for (LinkedListNode <IProtoUrlConfig> listNode = databaseConfigs.First; listNode != null; listNode = listNode.Next) { IProtoUrlConfig protoConfig = listNode.Value; try { if (!NodeMatcher.IsMatch(protoConfig.Node)) { continue; } if (loop) { logger.Info($"Looping on {UrlConfig.SafeUrl()} to {protoConfig.FullUrl}"); } do { progress.ApplyingUpdate(protoConfig, UrlConfig); listNode.Value = protoConfig = new ProtoUrlConfig(protoConfig.UrlFile, MMPatchLoader.ModifyNode(new NodeStack(protoConfig.Node), UrlConfig.config, context)); } while (loop && NodeMatcher.IsMatch(protoConfig.Node)); if (loop) { protoConfig.Node.RemoveNodes("MM_PATCH_LOOP"); } } catch (Exception ex) { progress.Exception(UrlConfig, $"Exception while applying update {UrlConfig.SafeUrl()} to {protoConfig.FullUrl}", ex); } } }
public void Apply(UrlDir.UrlFile file, IPatchProgress progress, IBasicLogger logger) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } PatchContext context = new PatchContext(UrlConfig, file.root, logger, progress); for (int i = 0; i < file.configs.Count; i++) { UrlDir.UrlConfig urlConfig = file.configs[i]; try { if (!NodeMatcher.IsMatch(urlConfig.config)) { continue; } if (loop) { logger.Info($"Looping on {UrlConfig.SafeUrl()} to {urlConfig.SafeUrl()}"); } do { progress.ApplyingUpdate(urlConfig, UrlConfig); file.configs[i] = urlConfig = new UrlDir.UrlConfig(file, MMPatchLoader.ModifyNode(new NodeStack(urlConfig.config), UrlConfig.config, context)); } while (loop && NodeMatcher.IsMatch(urlConfig.config)); if (loop) { file.configs[i].config.RemoveNodes("MM_PATCH_LOOP"); } } catch (Exception ex) { progress.Exception(UrlConfig, $"Exception while applying update {UrlConfig.SafeUrl()} to {urlConfig.SafeUrl()}", ex); } } }
public void Apply(UrlDir.UrlFile file, IPatchProgress progress, IBasicLogger logger) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } PatchContext context = new PatchContext(UrlConfig, file.root, logger, progress); // Avoid checking the new configs we are creating int count = file.configs.Count; for (int i = 0; i < count; i++) { UrlDir.UrlConfig url = file.configs[i]; try { if (!NodeMatcher.IsMatch(url.config)) { continue; } ConfigNode clone = MMPatchLoader.ModifyNode(new NodeStack(url.config), UrlConfig.config, context); if (url.config.HasValue("name") && url.config.GetValue("name") == clone.GetValue("name")) { progress.Error(UrlConfig, $"Error - when applying copy {UrlConfig.SafeUrl()} to {url.SafeUrl()} - the copy needs to have a different name than the parent (use @name = xxx)"); } else { progress.ApplyingCopy(url, UrlConfig); file.AddConfig(clone); } } catch (Exception ex) { progress.Exception(UrlConfig, $"Exception while applying copy {UrlConfig.SafeUrl()} to {url.SafeUrl()}", ex); } } }
public void Apply(LinkedList <IProtoUrlConfig> databaseConfigs, IPatchProgress progress, IBasicLogger logger) { if (databaseConfigs == null) { throw new ArgumentNullException(nameof(databaseConfigs)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } PatchContext context = new PatchContext(UrlConfig, databaseConfigs, logger, progress); for (LinkedListNode <IProtoUrlConfig> listNode = databaseConfigs.First; listNode != null; listNode = listNode.Next) { IProtoUrlConfig protoConfig = listNode.Value; try { if (!NodeMatcher.IsMatch(protoConfig.Node)) { continue; } ConfigNode clone = MMPatchLoader.ModifyNode(new NodeStack(protoConfig.Node), UrlConfig.config, context); if (protoConfig.Node.GetValue("name") is string name && name == clone.GetValue("name")) { progress.Error(UrlConfig, $"Error - when applying copy {UrlConfig.SafeUrl()} to {protoConfig.FullUrl} - the copy needs to have a different name than the parent (use @name = xxx)"); } else { progress.ApplyingCopy(protoConfig, UrlConfig); listNode = databaseConfigs.AddAfter(listNode, new ProtoUrlConfig(protoConfig.UrlFile, clone)); } }
public void Apply(UrlDir.UrlFile file, IPatchProgress progress, IBasicLogger logger) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } int i = 0; while (i < file.configs.Count) { UrlDir.UrlConfig url = file.configs[i]; try { if (NodeMatcher.IsMatch(url.config)) { progress.ApplyingDelete(url, UrlConfig); file.configs.RemoveAt(i); } else { i++; } } catch (Exception ex) { progress.Exception(UrlConfig, $"Exception while applying delete {UrlConfig.SafeUrl()} to {url.SafeUrl()}", ex); } } }
public void Apply(LinkedList <IProtoUrlConfig> databaseConfigs, IPatchProgress progress, IBasicLogger logger) { if (databaseConfigs == null) { throw new ArgumentNullException(nameof(databaseConfigs)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } LinkedListNode <IProtoUrlConfig> currentNode = databaseConfigs.First; while (currentNode != null) { IProtoUrlConfig protoConfig = currentNode.Value; try { LinkedListNode <IProtoUrlConfig> nextNode = currentNode.Next; if (NodeMatcher.IsMatch(protoConfig.Node)) { progress.ApplyingDelete(protoConfig, UrlConfig); databaseConfigs.Remove(currentNode); } currentNode = nextNode; } catch (Exception ex) { progress.Exception(UrlConfig, $"Exception while applying delete {UrlConfig.SafeUrl()} to {protoConfig.FullUrl}", ex); } } }
public IPatch CompilePatch(ProtoPatch protoPatch) { if (protoPatch == null) { throw new ArgumentNullException(nameof(protoPatch)); } INodeMatcher nodeMatcher = new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has); switch (protoPatch.command) { case Command.Edit: return(new EditPatch(protoPatch.urlConfig, nodeMatcher, protoPatch.passSpecifier)); case Command.Copy: return(new CopyPatch(protoPatch.urlConfig, nodeMatcher, protoPatch.passSpecifier)); case Command.Delete: return(new DeletePatch(protoPatch.urlConfig, nodeMatcher, protoPatch.passSpecifier)); default: throw new ArgumentException("has an invalid command for a root node: " + protoPatch.command, nameof(protoPatch)); } }
public PathedJsonSorter(SorterRequirements required, INodeFinder finder, NodeMatcher matches) : base(required) { Finder = finder; Matches = matches; }
public JsonSorter(SorterRequirements required, INodeFinder finder, INodeFinder sort_by, KeyOrValue pick, IEnumerable <string> order, bool after, NodeMatcher matches) : base(required, finder, matches) { SortBy = sort_by; Pick = pick; Order = order?.ToList(); After = after; }
public KeyMover(YamlMappingNode node) { Include = new ForwardNodeFinder(node.Go("from").ToList(x => NodeMatcher.Create(x))); Destination = node.Go("to").ToList(x => new NameNodeMatcher(x.String())).ToArray(); }