private void VisitNode(XmlElement elem, ItemReference masterRef) { var textChildren = elem.ChildNodes.OfType<XmlText>().ToList(); // Add a dependency to the relevant itemTypes if (elem.LocalName == "Item" && elem.HasAttribute("type")) { ItemType itemType; if (_metadata.ItemTypeByName(elem.Attribute("type").ToLowerInvariant(), out itemType)) { AddDependency(itemType.Reference, elem, elem, masterRef); } else { AddDependency(new ItemReference("ItemType", ItemTypeByNameWhere + elem.Attributes["type"].Value + "'") { KeyedName = elem.Attributes["type"].Value }, elem, elem, masterRef); } } // Item property node if (elem.HasAttribute("type") && textChildren.Count == 1 && !string.IsNullOrEmpty(textChildren[0].Value)) { AddDependency(ItemReference.FromItemProp(elem), elem.Parent(), elem, masterRef); } else if (elem.LocalName == "sqlserver_body" && elem.Parent().LocalName == "Item" && elem.Parent().Attribute("type") == "SQL") { var names = GetInnovatorNames(elem.InnerText) .Select(n => n.FullName.StartsWith("innovator.", StringComparison.OrdinalIgnoreCase) ? n.FullName.Substring(10).ToLowerInvariant() : n.FullName.ToLowerInvariant()) .Distinct(); ItemType itemType; ItemReference sql; foreach (var name in names) { if (_metadata.ItemTypeByName(name.Replace('_', ' '), out itemType)) { AddDependency(itemType.Reference, elem.Parent(), elem, masterRef); } else if (_metadata.SqlRefByName(name, out sql)) { AddDependency(sql, elem.Parent(), elem, masterRef); } } } else if (elem.LocalName == "data_source" && textChildren.Count == 1 && !string.IsNullOrEmpty(textChildren[0].Value)) { // Property data source dependencies var parent = elem.ParentNode as XmlElement; if (parent != null && parent.LocalName == "Item" && parent.Attribute("type") == "Property") { var keyedName = elem.Attribute("keyed_name"); var itemtype = _metadata.ItemTypes.FirstOrDefault(i => i.Reference.Unique == elem.Parent().Parent().Parent().Attribute("id") && i.IsPolymorphic); if (itemtype == null) { var dataType = parent.Element("data_type"); if (dataType != null) { switch (dataType.InnerText.ToLowerInvariant()) { case "list": case "mv_list": case "filter list": AddDependency(new ItemReference("List", textChildren[0].Value) { KeyedName = keyedName }, parent, elem, masterRef); break; case "item": AddDependency(new ItemReference("ItemType", textChildren[0].Value) { KeyedName = keyedName }, parent, elem, masterRef); break; case "sequence": AddDependency(new ItemReference("Sequence", textChildren[0].Value) { KeyedName = keyedName }, parent, elem, masterRef); break; } } } } } else if (elem != _elem && elem.LocalName == "Item" && elem.HasAttribute("type") && elem.Attribute("action", "") == "get" && (elem.HasAttribute("id") || elem.HasAttribute("where"))) { // Item queries AddDependency(ItemReference.FromFullItem(elem, true), elem.Parent().Parent(), elem.Parent(), masterRef); } else if (textChildren.Count == 1 && textChildren[0].Value.StartsWith("vault:///?fileId=", StringComparison.OrdinalIgnoreCase)) { // Vault Id references for image properties AddDependency(new ItemReference("File", textChildren[0].Value.Substring(17)), elem.Parent(), elem, masterRef); } else { if (elem != _elem && elem.LocalName == "Item" && elem.HasAttribute("type") && elem.HasAttribute("id")) { _definitions.Add(ItemReference.FromFullItem(elem, elem.Attribute("type") == "ItemType")); } var isItem = (elem.LocalName == "Item" && elem.HasAttribute("type")); ItemProperty newProp; ItemReference propRef; foreach (var child in elem.Elements()) { if (isItem) { newProp = new ItemProperty() { ItemType = elem.Attributes["type"].Value, ItemTypeId = (elem.HasAttribute("typeid") ? elem.Attributes["typeid"].Value : null), Property = child.LocalName }; if (_metadata.CustomPropertyByPath(newProp, out propRef)) { propRef = propRef.Clone(); AddDependency(propRef, elem, child, masterRef); } } VisitNode(child, masterRef); } } }
public void ProcessImport(IDataExtractor extractor, string xslt, int batchSize) { _extractor = extractor; Exception error = null; _completeDate = DateTime.MinValue; _globallyProcessed = 0; try { extractor.Reset(); using (_cts = new CancellationTokenSource()) { var opts = new ParallelOptions(); opts.CancellationToken = _cts.Token; Parallel.ForEach(GetXml(extractor, batchSize), opts, xml => { int locallyProcessed = 0; var doc = new XmlDocument(); doc.LoadXml(ArasXsltExtensions.Transform(xslt, xml, _conn.ExternalConnection)); IList<XmlElement> levelElements = new XmlElement[] { doc.DocumentElement }; while (!levelElements.Any(e => e.LocalName == "AML" || e.LocalName == "SQL" || e.LocalName == "sql" || e.LocalName == "Item")) levelElements = levelElements.Elements(e => true).ToList(); var isError = false; for (var i = 0; i < levelElements.Count; i++) { Action<int, int> progressReporter = (curr, count) => { var progress = (int)(((double)(count * i + curr) / (count * levelElements.Count)) * batchSize); if (progress > locallyProcessed) Interlocked.Add(ref _globallyProcessed, progress - locallyProcessed); locallyProcessed = progress; SignalProgress(batchSize); }; XmlNode result; switch (levelElements[i].LocalName) { case "AML": result = _conn.CallAction("ApplyAML", levelElements[i], progressReporter); break; case "SQL": case "sql": result = _conn.CallAction("ApplySQL", levelElements[i], progressReporter); break; case "Item": result = _conn.CallAction("ApplyItem", levelElements[i], progressReporter); break; default: result = null; break; } if (_conn.GetError(result) != null) { _errors.Add(new ErrorEntry() { Error = result.OuterXml, Query = xml }); isError = true; break; } } if (isError) Interlocked.Increment(ref _errorBlocks); Interlocked.Add(ref _globallyProcessed, batchSize - locallyProcessed); SignalProgress(batchSize); opts.CancellationToken.ThrowIfCancellationRequested(); }); } } catch (OperationCanceledException) { } catch (Exception ex) { error = ex; } finally { _cts = null; } _completeDate = DateTime.Now; OnActionComplete(new ActionCompleteEventArgs() { Exception = error }); }
/// <summary> /// Remove keyed_name attributes to make diffing easier /// </summary> private void RemoveKeyedNameAttributes(XmlElement node) { if (node.HasAttribute("keyed_name")) node.RemoveAttribute("keyed_name"); foreach (var elem in node.Elements()) RemoveKeyedNameAttributes(elem); }