/// <summary> /// Recursively called for each message (structure or data) in an Edi Document. Each time this is called a /// <see cref="IEdiDocumentPosition"/> is stored in the IEdiMetadata /// </summary> /// <param name="metadata"> /// The metadata. /// </param> /// <param name="currentnum"> /// The current number . /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> private int ValidateMessageInterchangeHeader(IEdiMetadata metadata, int currentnum) { int segmentStart = this._ediReader.LineNumber; EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.MessageIdentification, true); string[] splitOnPlus = EDIUtil.SplitOnPlus(this._currentLine, 2); string messageIdentification = splitOnPlus[0]; if (!splitOnPlus[1].Equals("GESMES:2:1:E6")) { throw new ArgumentException("Expecting GESMES:2:1:E6 but was " + splitOnPlus[1]); } this.ReadNextLine(); EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.MessageFunction, true); MessageFunction messageFunction = MessageFunctionExtension.GetFromEdiStr(this._currentLine); // Fifth Line is the message agency this.ReadNextLine(); EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.MessageAgency, true); string messageAgency = this._currentLine; // Sixth Line is the receiving agency this.ReadNextLine(); EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.ReceivingAgency, true); string recievingAgency = this._currentLine; IParty sendingAgency = this.ProcessMessageSender(); int documentStart = this._ediReader.LineNumber; if (messageFunction.IsData()) { this.DetermineDatasetMetadata(); metadata.ReportingBegin = this._reportingBegin; metadata.ReportingEnd = this._reportingEnd; } bool inRecursive = false; IList<IKeyValue> datasetAttributes = new List<IKeyValue>(); while (this._currentLine != null) { try { this.ReadNextLine(); if (!messageFunction.IsData()) { if (this._ediReader.LineType.IsDataSegment()) { documentStart = this._ediReader.LineNumber + 1; throw new SdmxSyntaxException("Message function is " + messageFunction.GetEdiString() + " but message contains a data segment. Line number : " + documentStart); } } else if (!messageFunction.IsStructure()) { if (this._ediReader.LineType.IsStructureSegment()) { throw new SdmxSyntaxException("Message function is " + messageFunction.GetEdiString() + " but message contains a structure segment"); } } // Check For Any Dataset Attributes And Store Them if (messageFunction.IsData()) { if (this._ediReader.LineType == EdiPrefix.DatasetAttributeScope) { int scope = int.Parse(this._ediReader.CurrentLine); // 1 = dataset, 4=mix of dimensions, 5=observation if (scope == 1) { this.ReadNextLine(); EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.DatasetDataAttribute, true); while (true) { this.ReadNextLine(); if (this._ediReader.LineType != EdiPrefix.DatasetAttributeCoded && this._ediReader.LineType != EdiPrefix.DatasetAttributeUncoded) { this._ediReader.MoveBackLine(); break; } string attributeConceptId = this._ediReader.CurrentLine; string attributeValue = null; if (this._ediReader.LineType == EdiPrefix.DatasetAttributeCoded) { // Move to the code value Line this.AssertMoveNext(); // If the current line is the attribute value then store it, otherwise if (EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.CodeValue, false)) { attributeValue = this._ediReader.CurrentLine; } else { this._ediReader.MoveBackLine(); } } else if (this._ediReader.LineType == EdiPrefix.DatasetAttributeUncoded) { string compositeValue = string.Empty; while (true) { // Move to the next line and see if it is Free Text this.AssertMoveNext(); if (EDIUtil.AssertPrefix(this._ediReader, EdiPrefix.String, false)) { compositeValue += this._ediReader.ParseTextString(); } else { break; } } attributeValue = compositeValue; this._ediReader.MoveBackLine(); } datasetAttributes.Add(new KeyValueImpl(attributeValue, attributeConceptId)); } } } } if (this._ediReader.LineType.IsEndMessageAdministration()) { if (this._ediReader.IsBackLine) { this._ediReader.MoveNext(); } string[] splitMessAdminOnPlus = EDIUtil.SplitOnPlus(this._currentLine, 2); string numLinesString = splitMessAdminOnPlus[0]; int numLines = EDIUtil.ParseStringAsInt(numLinesString); int segmentCount = this._ediReader.LineNumber - segmentStart + 1; if (segmentCount != numLines) { throw new SdmxSemmanticException("Expected segment count '" + numLines + "' does not match actual segment count '" + segmentCount + "'"); } IEdiDocumentPosition documentPosition = new EdiDocumentPosition( documentStart, this._ediReader.LineNumber, messageFunction.IsStructure(), this._datasetId, messageAgency, sendingAgency, recievingAgency, this._datasetAction, this._keyFamilyIdentifier, this._missingValue, this._datasetPreperation, this._reportingPeriod, datasetAttributes); metadata.AddDocumentIndex(documentPosition); string messageRef = splitMessAdminOnPlus[1]; if (!messageIdentification.Equals(messageRef)) { throw new SdmxSemmanticException("Message ref expected to be '" + messageIdentification + "' but was '" + messageRef + "'"); } // Either we have another message identification or an end message this.ReadNextLine(); if (this._ediReader.LineType.IsMessageIdentification()) { inRecursive = true; return this.ValidateMessageInterchangeHeader(metadata, ++currentnum); } return currentnum; } } catch (SdmxException th) { if (inRecursive) { throw; } throw new SdmxException("Error while trying to validate Edi Message:" + messageIdentification, th); } } throw new SdmxSyntaxException("Message identification" + EdiPrefix.MessageIdentification + " is not terminated with an end identification " + EdiPrefix.EndMessageAdministration); }
/// <summary> /// Initializes a new instance of the <see cref="EdiAbstractPositionalReader"/> class. /// </summary> /// <param name="dataFile"> /// The data file. /// </param> /// <param name="documentPosition"> /// The document position. /// </param> /// <param name="ediMetadata"> /// The edi metadata. /// </param> public EdiAbstractPositionalReader(IReadableDataLocation dataFile, IEdiDocumentPosition documentPosition, IEdiMetadata ediMetadata) : base(dataFile) { this._ediMetadata = ediMetadata; this._documentPosition = documentPosition; }
/// <summary> /// Initializes a new instance of the <see cref="EdiDataReader"/> class. /// </summary> /// <param name="dataFile"> /// The data file. /// </param> /// <param name="documentPosition"> /// The document position. /// </param> /// <param name="ediMetadata"> /// The EDI metadata. /// </param> public EdiDataReader(IReadableDataLocation dataFile, IEdiDocumentPosition documentPosition, IEdiMetadata ediMetadata) : base(dataFile, documentPosition, ediMetadata) { this._documentPosition = documentPosition; }
/// <summary> /// Initializes a new instance of the <see cref="EdiWorkspace"/> class. /// </summary> /// <param name="ediDocument"> /// The EDI document. /// </param> /// <param name="writeableDataLocationFactory"> /// The writable Data Location Factory. /// </param> /// <param name="ediParseEngine"> /// The EDI Parse Engine. /// </param> public EdiWorkspace(IReadableDataLocation ediDocument, IWriteableDataLocationFactory writeableDataLocationFactory, IEdiParseEngine ediParseEngine) { this._ediMetadata = ediParseEngine.ParseEDIMessage(ediDocument); IFileReader fr = new FileReaderImpl(ediDocument, EdiConstants.EndOfLineRegEx, EdiConstants.CharsetEncoding); foreach (var documentPosition in this._ediMetadata.DocumentIndex) { int start = documentPosition.StartLine; this._writeableDataLocation = writeableDataLocationFactory.GetTemporaryWriteableDataLocation(); using (TextWriter osw = new StreamWriter(this._writeableDataLocation.OutputStream, EdiConstants.CharsetEncoding)) { while (fr.MoveNext()) { int idx = fr.LineNumber; // If this next line is within the bounds of the start and end location then write the current line to the writer if (idx >= start) { string line = fr.CurrentLine; Write(osw, line + EdiConstants.EndTag); // WriteLineSeparator(osw); // Keep going until we encounter the end segment indicator if (line.StartsWith(EdiPrefix.EndMessageAdministration.ToString())) { break; } } } osw.Flush(); } if (documentPosition.IsData) { IEdiDataDocument dataDocument = new EdiDataDocument(this._writeableDataLocation, documentPosition, this._ediMetadata); this._dataDocuments.Add(dataDocument); this._keyFamilyReferences.Add(dataDocument.DataReader.DataSetHeaderObject.DataStructureReference.StructureReference.MaintainableReference); } else { ////IEdiStructureDocument doc = new EDIStructureDocumentImpl(wdl, documentPosition, this._ediMetadata); ////this._beans.Add(doc.SdmxObjects); this._writeableDataLocation.Close(); } } this.CreateHeader(); }
/// <summary> /// Initializes a new instance of the <see cref="EdiDataDocument"/> class. /// </summary> /// <param name="documentUri"> /// The document URI. /// </param> /// <param name="documentPosition"> /// The document position. /// </param> /// <param name="ediMetadata"> /// The EDI metadata. /// </param> public EdiDataDocument(IReadableDataLocation documentUri, IEdiDocumentPosition documentPosition, IEdiMetadata ediMetadata) { this._dataLocation = documentUri; this._documentPosition = documentPosition; this._ediMetadata = ediMetadata; }