private void processEDIObservation()

in SdmxEdiParser/src/main/java/org/sdmxsource/sdmx/ediparser/engine/reader/impl/EDIDataReaderEngineImpl.java [730:820]


    private void processEDIObservation() {
        while (true) {
            currentObsPos++;
            currentObs = null;
            if (observations == null) {
                if (obsDates != null && (obsDates.size() > currentObsPos)) {
                    //Observations is null, but this does not mean that there was not a reported date, or dates.
                    //In this case, the observation is just a date, with no reported value.  This can be the case in delete messages
                    String obsDate = obsDates.size() > currentObsPos ? obsDates.get(currentObsPos) : null;
                    currentObs = new ObservationImpl(currentKey, obsDate, null, null);
                }
            } else if (observations.length > currentObsPos) {
                String currentObsLine = observations[currentObsPos];

                //1. Set up variables
                String obsDate = obsDates.size() > currentObsPos ? obsDates.get(currentObsPos) : null;
                String obsVal = null;
                List<KeyValue> attributes = new ArrayList<KeyValue>();

                // If there is no observation, and no date, don't output anything.
                if (!ObjectUtil.validString(currentObsLine)) {
                    if (!ObjectUtil.validString(obsDate)) {
                        currentObsPos++;
                        continue;
                    }
                }

                String[] obsArr = EDIUtil.splitOnColon(currentObsLine);
                //0 = OBS_VALUE
                //1 = OBS_STATUS
                //2 = OBS_CONF
                //3 = OBS_PRE_BREAK
                obsVal = obsArr[0];

                boolean obsStatusPresent = obsArr.length > 1 && ObjectUtil.validString(obsArr[1]);
                boolean obsConfPresent = obsArr.length > 2 && ObjectUtil.validString(obsArr[2]);
                boolean obsPreBreakPresent = obsArr.length > 3 && ObjectUtil.validString(obsArr[3]);

                if (obsStatusPresent) {
                    if (hasObsStatus) {
                        attributes.add(new KeyValueImpl(obsArr[1], SDMX_EDI_ATTRIBUTES.OBS_STATUS));
                    } else {
                        throw new IllegalArgumentException("No observation attribute '" + SDMX_EDI_ATTRIBUTES.OBS_STATUS + "' present on DSD, but the data contains a value for this attribute");
                    }
                } else {
                    // If there is no OBS_STATUS and no OBS_VALUE skip to the next entry
                    if (!ObjectUtil.validString(obsVal)) {
                        continue;
                    }
                }
                if (obsConfPresent) {
                    if (hasObsConf) {
                        attributes.add(new KeyValueImpl(obsArr[2], obsConf));
                    } else {
                        throw new IllegalArgumentException("No observation attribute '" + obsConf + "' present on DSD, but the data contains a value for this attribute");
                    }
                }
                if (obsPreBreakPresent) {
                    if (hasObsPreBeak) {
                        String obsAttr = obsArr[3].equals(missingValue) ? SdmxConstants.MISSING_DATA_VALUE : obsArr[3];
                        attributes.add(new KeyValueImpl(obsAttr, obsPreBreak));
                    } else {
                        throw new IllegalArgumentException("No observation attribute '" + obsPreBreak + "' present on DSD, but the data contains a value for this attribute");
                    }
                }

                if (obsVal == null) {
                    obsVal = "";
                }
                if (obsVal.equals(missingValue)) {
                    obsVal = SdmxConstants.MISSING_DATA_VALUE;
                }
                currentObs = new ObservationImpl(currentKey, obsDate, obsVal, attributes);
            } else {
                //Check if the next key is the same as the last key
                Keyable prevKey = currentKey;
                if (moveNextKeyable()) {
                    if (inFootNoteSection) {
                        lookedAhead = true;
                        break;
                    }
                    if (currentKey.equals(prevKey)) {
                        continue;
                    }
                    lookedAhead = true;
                }
            }

            break;
        }
    }