/// <summary> /// Retrieve and populate the <see cref="IHierarchicalCodelistMutableObject.Hierarchies"/> for the HCL with specified Primary KEY /// </summary> /// <param name="hierarchicalCodelistBean"> /// The <see cref="IHierarchicalCodelistMutableObject"/> to populate /// </param> /// <param name="sysId"> /// The HCL Mapping store Primary KEY /// </param> private void FillHierarchy(IHierarchicalCodelistMutableObject hierarchicalCodelistBean, long sysId) { // ReSharper restore SuggestBaseTypeForParameter var sysIdArtefacts = new Dictionary <long, IHierarchyMutableObject>(); var itemSqlQuery = new ItemSqlQuery(this._hierarchyQueryInfo, sysId); using (DbCommand command = this._itemCommandBuilder.Build(itemSqlQuery)) { using (IDataReader dataReader = this.MappingStoreDb.ExecuteReader(command)) { int sysIdIdx = dataReader.GetOrdinal("SYSID"); int idIdx = dataReader.GetOrdinal("ID"); int txtIdx = dataReader.GetOrdinal("TEXT"); int langIdx = dataReader.GetOrdinal("LANGUAGE"); int typeIdx = dataReader.GetOrdinal("TYPE"); while (dataReader.Read()) { long hierarchySysId = DataReaderHelper.GetInt64(dataReader, sysIdIdx); IHierarchyMutableObject artefact; if (!sysIdArtefacts.TryGetValue(hierarchySysId, out artefact)) { artefact = new HierarchyMutableCore { Id = DataReaderHelper.GetString(dataReader, idIdx) }; sysIdArtefacts.Add(hierarchySysId, artefact); } ReadLocalisedString(artefact, typeIdx, txtIdx, langIdx, dataReader); } } } this._hierarchyAnnotationRetrieverEngine.RetrieveAnnotations(sysId, sysIdArtefacts); foreach (KeyValuePair <long, IHierarchyMutableObject> sysIdArtefact in sysIdArtefacts) { long hid = sysIdArtefact.Key; IHierarchyMutableObject artefact = sysIdArtefact.Value; this.FillLevel(artefact, hid); this.FillCodeRef(artefact, hid); hierarchicalCodelistBean.AddHierarchies(artefact); } }
/// <summary> /// Writes the hierarchy. /// </summary> /// <param name="hierarchy"> /// The hierarchy. /// </param> private void WriteHierarchy(IHierarchyMutableObject hierarchy) { this.WriteStartElement(this.DefaultNS, ElementNameTable.Hierarchy); this.WriteIdentifiableArtefactAttributes(hierarchy); ////TryWriteAttribute(AttributeNameTable.version, hierarchy.Version); ////TryWriteAttribute(AttributeNameTable.validFrom, hierarchy.ValidFrom); ////TryWriteAttribute(AttributeNameTable.validTo, hierarchy.ValidTo); ////TryWriteAttribute(AttributeNameTable.isFinal, hierarchy.FinalStructure); this.WriteIdentifiableArtefactContent(hierarchy); foreach (ICodeRefMutableObject codeRef in hierarchy.HierarchicalCodeObjects) { this.TraverseCodeRefTree(codeRef); } ILevelMutableObject current = hierarchy.ChildLevel; int order = 1; while (current != null) { this.WriteLevel(current, order++); current = current.ChildLevel; } this.WriteAnnotations(ElementNameTable.Annotations, hierarchy.Annotations); this.WriteEndElement(); }
/// <summary> /// Handles the HierarchicalCodelist element child elements /// </summary> /// <param name="parent"> /// The parent IHierarchicalCodelistMutableObject object /// </param> /// <param name="localName"> /// The name of the current xml element /// </param> /// <returns> /// The <see cref="StructureReaderBaseV20.ElementActions"/>. /// </returns> private ElementActions HandleChildElements(IHierarchicalCodelistMutableObject parent, object localName) { ElementActions actions = null; if (NameTableCache.IsElement(localName, ElementNameTable.CodelistRef)) { var codelistRefMutableCore = new CodelistRefMutableCore(); parent.AddCodelistRef(codelistRefMutableCore); this._currentCodelistRef = codelistRefMutableCore; IReferenceInfo reference = new ReferenceInfo(SdmxStructureEnumType.CodeList); this._currentReference = reference; actions = this.BuildElementActions(codelistRefMutableCore, DoNothingComplex, HandleTextChildElement); } else if (NameTableCache.IsElement(localName, ElementNameTable.Hierarchy)) { var hc = new HierarchyMutableCore(); ParseAttributes(hc, this.Attributes); this._currentHierarchy = hc; //// TODO java 0.9.9 no isFinal ////hc.IsFinal = Helper.TrySetFromAttribute(this.Attributes, AttributeNameTable.isFinal, hc.IsFinal); parent.AddHierarchies(hc); actions = this.AddNameableAction(hc, this.HandleChildElements); } return actions; }
/// <summary> /// Handles the Hierarchy element child elements /// </summary> /// <param name="parent"> /// The parent IHierarchyMutableObject object /// </param> /// <param name="localName"> /// The name of the current xml element /// </param> /// <returns> /// The <see cref="StructureReaderBaseV20.ElementActions"/>. /// </returns> private ElementActions HandleChildElements(IHierarchyMutableObject parent, object localName) { ElementActions actions = null; if (NameTableCache.IsElement(localName, ElementNameTable.CodeRef)) { ICodeRefMutableObject cr = new CodeRefMutableCore(); ParseAttributes(cr, this.Attributes); parent.AddHierarchicalCode(cr); actions = this.BuildElementActions(cr, HandleChildElements, this.HandleTextChildElement); } else if (NameTableCache.IsElement(localName, ElementNameTable.Level)) { ILevelMutableObject level = new LevelMutableCore(); ParseAttributes(level, this.Attributes); actions = this.AddNameableAction(level, HandleChildElements, this.HandleTextChildElement); } return actions; }
/// <summary> /// Build level ref. /// </summary> /// <param name="levelRef">The level reference.</param> /// <param name="hierarchyMutableObject">The hierarchy mutable object.</param> /// <returns>The <see cref="IEnumerable{String}" />.</returns> private static IEnumerable<string> BuildLevelRef(string levelRef, IHierarchyMutableObject hierarchyMutableObject) { var hierarchy = hierarchyMutableObject; var level = hierarchy.ChildLevel; while (!level.Id.Equals(levelRef)) { yield return level.Id; level = level.ChildLevel; } yield return level.Id; }
/// <summary> /// Setups the hierarchy levels. /// </summary> /// <param name="levelMutableObjects">The level mutable objects.</param> /// <param name="currentHierarchy">The current hierarchy.</param> private static void SetupHierarchyLevels(SortedList<int, ILevelMutableObject> levelMutableObjects, IHierarchyMutableObject currentHierarchy) { ILevelMutableObject previous = null; foreach (KeyValuePair<int, ILevelMutableObject> levelMutableObject in levelMutableObjects) { if (previous == null) { currentHierarchy.FormalLevels = true; currentHierarchy.ChildLevel = levelMutableObject.Value; previous = levelMutableObject.Value; } else { previous.ChildLevel = levelMutableObject.Value; previous = levelMutableObject.Value; } } }
/// <summary> /// Setups the code reference levels. /// </summary> /// <param name="currentHierarchy">The current hierarchy.</param> private static void SetupCodeRefLevels(IHierarchyMutableObject currentHierarchy) { if (currentHierarchy.ChildLevel != null) { var stack = new Stack<ICodeRefMutableObject>(currentHierarchy.HierarchicalCodeObjects); while (stack.Count != 0) { var currentCode = stack.Pop(); if (!string.IsNullOrWhiteSpace(currentCode.LevelReference)) { currentCode.LevelReference = string.Join(".", BuildLevelRef(currentCode.LevelReference, currentHierarchy)); } foreach (var codeRefMutableObject in currentCode.CodeRefs) { stack.Push(codeRefMutableObject); } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////// ////////////BUILD FROM MUTABLE OBJECT ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="HierarchyCore"/> class. /// </summary> /// <param name="parent"> /// The parent. /// </param> /// <param name="hierarchy"> /// The hierarchy. /// </param> /// <exception cref="SdmxSemmanticException"> /// Throws Validate exception. /// </exception> public HierarchyCore(IHierarchicalCodelistObject parent, IHierarchyMutableObject hierarchy) : base(hierarchy, parent) { // LEVELS MUST BE SET BEFORE ANYTHING ELSE this._hasFormalLevels = hierarchy.FormalLevels; if (hierarchy.ChildLevel != null) { this._level = new LevelCore(this, hierarchy.ChildLevel); } this._codeRefs = new List<IHierarchicalCode>(); if (hierarchy.HierarchicalCodeObjects != null) { foreach (ICodeRefMutableObject currentCoderef in hierarchy.HierarchicalCodeObjects) { this._codeRefs.Add(new HierarchicalCodeCore(currentCoderef, this)); } } try { this.Validate(); } catch (SdmxSemmanticException ex) { throw new SdmxSemmanticException(ex, ExceptionCode.ObjectStructureConstructionError, this.Urn); } catch (Exception th) { throw new SdmxException(th, ExceptionCode.ObjectStructureConstructionError, this.Urn); } }
/// <summary> /// Retrieve and populate the <see cref="IHierarchyMutableObject.ChildLevel"/> for the HIERARCHY with specified Primary KEY /// </summary> /// <param name="hierarchy"> /// the <see cref="IHierarchyMutableObject"/> to populate /// </param> /// <param name="sysId"> /// The HIERARCHY Mapping store Primary KEY /// </param> private void FillLevel(IHierarchyMutableObject hierarchy, long sysId) { var sysIdArtefacts = new Dictionary <long, ILevelMutableObject>(); // holds the next level id to level id map. It contains all but the first level (with order == 1) var orderChain = new Dictionary <long, long>(); using (DbCommand command = this._itemCommandBuilder.Build(new ItemSqlQuery(this._levelQueryInfo, sysId))) { using (IDataReader dataReader = this.MappingStoreDb.ExecuteReader(command)) { int sysIdIdx = dataReader.GetOrdinal("SYSID"); int idIdx = dataReader.GetOrdinal("ID"); int parentIdx = dataReader.GetOrdinal("PARENT"); int txtIdx = dataReader.GetOrdinal("TEXT"); int langIdx = dataReader.GetOrdinal("LANGUAGE"); int typeIdx = dataReader.GetOrdinal("TYPE"); while (dataReader.Read()) { long levelId = DataReaderHelper.GetInt64(dataReader, sysIdIdx); ILevelMutableObject artefact; if (!sysIdArtefacts.TryGetValue(levelId, out artefact)) { artefact = new LevelMutableCore { Id = DataReaderHelper.GetString(dataReader, idIdx) }; long nextLevelId = DataReaderHelper.GetInt64(dataReader, parentIdx); // TODO CodingType when MSDB supports it if (nextLevelId > long.MinValue) { orderChain[levelId] = nextLevelId; } sysIdArtefacts.Add(levelId, artefact); } ReadLocalisedString(artefact, typeIdx, txtIdx, langIdx, dataReader); } } } this._levelAnnotationRetrieverEngine.RetrieveAnnotations(sysId, sysIdArtefacts); foreach (KeyValuePair <long, ILevelMutableObject> level in sysIdArtefacts) { long nextLevelId; if (orderChain.TryGetValue(level.Key, out nextLevelId)) { ILevelMutableObject nextLevel; if (sysIdArtefacts.TryGetValue(nextLevelId, out nextLevel)) { nextLevel.ChildLevel = level.Value; } } else { hierarchy.ChildLevel = level.Value; //// TODO FIXME common api sets this to true for SDMX v2.0 input if levels exist. hierarchy.FormalLevels = true; } } }
/// <summary> /// Retrieve and populate the <see cref="IHierarchyMutableObject.HierarchicalCodeObjects"/> for the HIERARCHY with specified Primary KEY /// </summary> /// <param name="artefact"> /// The <see cref="IHierarchyMutableObject"/> instance to populate /// </param> /// <param name="hid"> /// The Hierarchy Mapping store Primary KEY /// </param> private void FillCodeRef(IHierarchyMutableObject artefact, long hid) { IDictionary <long, ICodeRefMutableObject> allItems = new ListDictionary <long, ICodeRefMutableObject>(); var childItems = new Dictionary <long, long>(); using (DbCommand command = this._itemCommandBuilder.Build(new ItemSqlQuery(this._codeRefQueryInfo, hid))) { using (IDataReader dataReader = this.MappingStoreDb.ExecuteReader(command)) { int sysIdIdx = dataReader.GetOrdinal("SYSID"); int idIdx = dataReader.GetOrdinal("CODE_ID"); int parentIdx = dataReader.GetOrdinal("PARENT"); int nodeAliasIdIdx = dataReader.GetOrdinal("NodeAliasID"); //// TODO check how to set the version (it seems supported in v2.1) int levelRefIdx = dataReader.GetOrdinal("LEVEL_REF"); int clidIdx = dataReader.GetOrdinal("CLID"); int clversionIdx = dataReader.GetOrdinal("CLVERSION"); int clagencyIdx = dataReader.GetOrdinal("CLAGENCY"); int validFromIdx = dataReader.GetOrdinal("VALID_FROM"); int validToIdx = dataReader.GetOrdinal("VALID_TO"); while (dataReader.Read()) { var codeRef = new CodeRefMutableCore { CodelistAliasRef = BuildCodelistRefAlias( DataReaderHelper.GetString(dataReader, clidIdx), DataReaderHelper.GetString(dataReader, clagencyIdx), DataReaderHelper.GetString(dataReader, clversionIdx)), Id = DataReaderHelper.GetString(dataReader, nodeAliasIdIdx), CodeId = DataReaderHelper.GetString(dataReader, idIdx) }; if (artefact.ChildLevel != null) { var levelRef = DataReaderHelper.GetString(dataReader, levelRefIdx); ILevelMutableObject currentLevel = artefact.ChildLevel; var normalizedLevel = GetNormalizedLevel(currentLevel, levelRef); codeRef.LevelReference = normalizedLevel; } if (string.IsNullOrWhiteSpace(codeRef.Id)) { codeRef.Id = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", codeRef.CodelistAliasRef.Replace('@', '_'), '_', codeRef.CodeId); } DateTime?validFrom = DataReaderHelper.GetStringDate(dataReader, validFromIdx); if (validFrom != null) { codeRef.ValidFrom = validFrom.Value; } DateTime?validTo = DataReaderHelper.GetStringDate(dataReader, validToIdx); if (validTo != null) { codeRef.ValidTo = validTo.Value; } long sysId = DataReaderHelper.GetInt64(dataReader, sysIdIdx); long parentItemId = DataReaderHelper.GetInt64(dataReader, parentIdx); if (parentItemId > long.MinValue) { childItems.Add(sysId, parentItemId); } allItems.Add(sysId, codeRef); } } } this._hierarchalCodeAnnotationRetrieverEngine.RetrieveAnnotations(hid, allItems); ICollection <KeyValuePair <long, ICodeRefMutableObject> > collection = allItems; foreach (KeyValuePair <long, ICodeRefMutableObject> item in collection) { long sysId = item.Key; ICodeRefMutableObject codeRef = item.Value; long parentItemId; if (childItems.TryGetValue(sysId, out parentItemId)) { // has parent ICodeRefMutableObject parent = allItems[parentItemId]; parent.AddCodeRef(codeRef); } else { // add only root elements artefact.AddHierarchicalCode(codeRef); } } }