Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Code Block
/**
 * Parser for Diver *.mon files
 */
public class DiverMonTimeSeriesParser implements TextParser<TimeSeriesContentHandler> {
    private static final Logger log = Logger.getLogger(DiverMonTimeSeriesParser.class);

    /* headers are written in dutch and english */
    private enum DiverHeaderConstants {
        DUTCH_HEADER_CONSTANTS("Instrument info",
        ================================================================
 * Delft FEWS
 * ================================================================
 *
 * Project Info:  http://www.wldelft.nl/soft/fews/index.html
 * Project Lead:  Karel Heynert (karel.heynert@wldelft.nl)
 *
 * (C) Copyright 2003, by WL | Delft Hydraulics
 *                        P.O. Box 177
 *                        2600 MH  Delft
 *                        The Netherlands
 *                        http://www.wldelft.nl
 *
 * DELFT-FEWS is a sophisticated collection of modules designed
 * for building a FEWS customised to the specific requirements
 * of individual agencies. An open modelling approach allows users
 * to add their own modules in an efficient way.
 *
 * ----------------------------------------------------------------
 * DiverMonTimeSeriesParser.java
 * ----------------------------------------------------------------
 * (C) Copyright 2003, by WL | Delft Hydraulics
 *
 * Original Author:  Stephan Zuiderwijk
 */

package nl.wldelft.timeseriesparsers;


import nl.wldelft.util.StringArrayUtils;
import nl.wldelft.util.TextUtils;
import nl.wldelft.util.io.IniFile;
import nl.wldelft.util.io.LineReader;
import nl.wldelft.util.io.TextParser;
import nl.wldelft.util.timeseries.DefaultTimeSeriesHeader;
import nl.wldelft.util.timeseries.TimeSeriesContentHandler;
import org.apache.log4j.Logger;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Parser for Diver *.mon files
 */
public class DiverMonTimeSeriesParser implements TextParser<TimeSeriesContentHandler> {
    private static final Logger log = Logger.getLogger(DiverMonTimeSeriesParser.class);

    /* headers are written in dutch and english */
    private enum DiverHeaderConstants {
        DUTCH_HEADER_CONSTANTS("Instrument info",
                "Instrument info from data header", "Kanaal", "Locatie", "Identificatie", "Bereik", "Data"),
        ENGLISH_HEADER_CONSTANTS("Instrument info",
                "Instrument info from data header", "Channel", "Location", "Identification", "Range", "Data"),
        LOGGER_HEADER_CONSTANTS("Logger settings",
                "Series settings", "Channel", "Location", "Identification", "Range", "Data"),
        MIXED_HEADER_CONSTANTS("Instrument info",
                "Instrument info from data header", "Kanaal", "Location", "Identification", "Range", "Data"),
        ENGLISH_MIXED_HEADER_CONSTANTS("Instrument info",
                "Instrument info from data header", "Channel", "Location", "Identification", "Range", "Data"),
        INCOMPLETE_HEADER_CONSTANTS("Instrument info",
                "Instrument info from data header", "Kanaal", "Locatie", "Identificatie", "Bereik", "Data");

        String loggerSettings;
        String seriesSettings;
        String channel;
        String location;
        String chnlId;
        String chnlRange;
        String data;

        DiverHeaderConstants(String loggerSettings, String seriesSettings, String channel,
                String location, String chnlId, String chnlRange, String data) {
         "Instrument info from data header", "Kanaal", "Locatie", "Identificatie", "Bereik", "Data"),
this.location = location;
            ENGLISH_HEADER_CONSTANTS("Instrument info",
this.seriesSettings = seriesSettings;
            this.chnlId = chnlId;
     "Instrument info from data header", "Channel", "Location", "Identification", "Range", "Data"),
 this.chnlRange = chnlRange;
         LOGGER_HEADER_CONSTANTS("Logger settings",
   this.loggerSettings = loggerSettings;
            this.channel = channel;
      "Series  settings", "Channel", "Location", "Identification", "Range", "Data"),
  this.data = data;
       MIXED_HEADER_CONSTANTS("Instrument info", }
    }

    private LineReader reader = null;
    "Instrumentprivate infoString fromvirtualFileName data header", "Kanaal", "Location", "Identification", "Range", "Data"),= null;
    private TimeSeriesContentHandler contentHandler  MIXED_HEADER_CONSTANTSNEW("Instrument info",= null;
    private int channelCount = -1;

    @Override
    "Instrumentpublic infovoid from data header", "Kanaal", "Location", "Identification", "Range", "Data"),
        INCOMPLETE_HEADER_CONSTANTS("Instrument info",
      parse(LineReader reader, String virtualFileName, TimeSeriesContentHandler contentHandler) throws Exception {
        this.reader = reader;
        this.virtualFileName = virtualFileName;
 "Instrument info from data header", "Kanaal", "Locatie", "Identificatie", "Bereik", "Data");
 this.contentHandler = contentHandler;
        String loggerSettingsthis.contentHandler.addMissingValue(99999f);
        String seriesSettingsreader.setSkipEmptyLines(true);
        String channelparseHeaders();
        String location;
  parseData();
    }

    /**
     * StringParses chnlId;
the datarows of the diver file. Data is Stringwritten chnlRange;
as a timestamp, followed by a number of String data;
columns. Each
     * column refers DiverHeaderConstants(String loggerSettings, String seriesSettings, String channel,
       to a channel that is declared in the Series settings
     *
    String location,*/
 String chnlId, String chnlRange,private Stringvoid dataparseData() throws Exception {
        int nrOfLines   this.location = location;
= Integer.parseInt(reader.readLine().trim());

            this.seriesSettingslong lineCounter = seriesSettings0;
            this.chnlIdchar columnSeparator = chnlId'\0';
        String[] buffer =  this.chnlRange = chnlRangenew String[channelCount + 2];
        for (String line; (line = this.loggerSettings reader.readLine()) != loggerSettingsnull;) {
            if this.channel(columnSeparator == channel;
 '\0') {
             this.data = data;
 columnSeparator = line.indexOf('\t') == -1 ? ' }
'    }

  : '\t';
  private LineReader reader = null;
    private String virtualFileName = null; }
    private TimeSeriesContentHandler contentHandler = null;
    private int channelCount = -1;

if (line.startsWith("END OF DATA")) break;
      @Override
    public void parse(LineReader reader, String virtualFileName, TimeSeriesContentHandler contentHandler) throws Exception {
TextUtils.split(line, columnSeparator, buffer);
            contentHandler.setTime(contentHandler.getDefaultTimeZone(),  this.reader = reader"yyyy/MM/dd", buffer[0], "HH:mm:ss", buffer[1]);
        this.virtualFileName = virtualFileName;
  for (int i = 0; i this.contentHandler = contentHandler;
    < channelCount; i++) {
    this.contentHandler.addMissingValue(99999f);
        reader.setSkipEmptyLines(true);
    String valueText =  parseHeaders()buffer[i + 2];
        parseData();
    }

    /**
     * Parses the datarows of the diver file. Data is written as a timestamp, followed by a number of columns. Eachif (valueText == null) continue;
                valueText = valueText.replace(',', '.');
     * column refers to a channel that is declared in the Series settings contentHandler.setTimeSeriesHeader(i);
     *
     */
    private void parseData() throws Exception {
contentHandler.setValue('.', valueText);
             int nrOfLines = Integer.parseInt(reader.readLine().trim()contentHandler.applyCurrentFields();

         long lineCounter = 0;}
        char  columnSeparator = '\0' lineCounter++;
        String[] buffer = new String[channelCount + 2];
 }


        if (log.isDebugEnabled())
       for (String line; (line = readerlog.readLine()) != null;) {
            if (columnSeparator == '\0') {
  debug("Number of expected values: " + nrOfLines + " Found values: " + lineCounter);

    }

    /**
     * Parses the available channels from the *.mon file. columnSeparatorMultiple = line.indexOf('\t') == -1 ? ' ' : '\t';channels can exist in a file. Typically the number
     * of channels will be 2  }
  but files with 1 channel do exist.
     */
    private ifvoid (line.startsWith("END OF DATA")) break;parseHeaders() throws Exception {
        IniFile iniFile =  TextUtils.splitString(line, columnSeparator, bufferparseHeaderIniFile();
        DiverHeaderConstants headerConstants =  contentHandler.setTime(contentHandler.getDefaultTimeZone(), "yyyy/MM/dd", buffer[0], "HH:mm:ss", buffer[1]);
 determineLanguage(iniFile);

        String loc = for (int i = 0; i < channelCount; i++) {
     iniFile.getValue(headerConstants.loggerSettings, headerConstants.location);
        if (TextUtils.trimToNull(loc) == null) {
           String valueTextthrow = buffer[i + 2]new Exception("No location found");
        }
        ifDefaultTimeSeriesHeader (valueTextheader == new nullDefaultTimeSeriesHeader() continue;
        String[] subjects = iniFile.getSubjects();


        valueTextchannelCount = valueText.replace(',', '.');0;

        //loop over all subjects     contentHandler.setTimeSeriesHeader(i);
         of the form "Channel" + i + " from data header",
        contentHandler.setValue('.', valueText);
      //i.e. loop over the headers for all parameters.
        for  contentHandler.applyCurrentFields();
     (int i = 1; ; i++) {
       }
     String subject = headerConstants.channel.toLowerCase() + ' ' lineCounter+ i +;
 " from data header";
    }


        if (logStringArrayUtils.isDebugEnabledindexOfIgnoreCase(subjects, subject) == -1) {
                if log.debug("Number of expected values: " + nrOfLines + " Found values: " + lineCounter);

(this.channelCount == 0) {
              }

    /**
  throw new Exception("No *channel Parses the available channels from the *.mon file. Multiple channels can exist in a file. Typically the number
 identification found");
                }
    * of channels will be 2 but files with 1 channel do exist.return;
     */
    private void parseHeaders() throws}
 Exception {
        IniFile iniFile = parseHeaderIniFile();
        DiverHeaderConstants headerConstants = determineLanguage(iniFile);

// subject is found, get id and range
            String locid = iniFile.getValue(headerConstants.loggerSettingssubject, headerConstants.locationchnlId);

            if (TextUtilsid.trimToNulllength(loc) == null0) {
            throw new Exception("No location found");
        }
        DefaultTimeSeriesHeader header = new DefaultTimeSeriesHeader();
log.warn("Identification for channel: '" + subject + "' is not set in File: " + virtualFileName);
//             String[] subjectsset = iniFile.getSubjects();


dummy parameter
          channelCount = 0;

    id = "Not Defined";
 for  (int i = 1; ; i++) {
   }

         String subject = headerConstantsheader.channel.toLowerCase() + ' ' + i + " from data header"setParameterId(id);
            header.setLocationId(loc);
            if (StringArrayUtils.indexOfIgnoreCase(subjectscontentHandler.createTimeSeriesHeaderAlias(channelCount, subjectheader) == -1) {
;
            channelCount++;
        }
    }

    private ifIniFile parseHeaderIniFile(this.channelCount == 0)) throws Exception {
        List<String> headerLines = new ArrayList<String>();
        for throw(String newline; Exception("No channel identification found");
line = reader.readLine()) != null;) {
            if (line.trim().equalsIgnoreCase("[Data]")) {
      }
          BufferedReader reader = new BufferedReader(new  returnStringReader(TextUtils.join(headerLines, '\n')));
            }
    return new IniFile(reader, virtualFileName);
     // subject is found, get id and range}
            String id = iniFile.getValue(subject, headerConstants.chnlIdheaderLines.add(line);

        }

        throw ifnew (id.length() == 0) {Exception("No data found");
    }
    
    private static DiverHeaderConstants  log.warn("Identification for channel: '" + subject + "' is not set in File: " + virtualFileName);
//determineLanguage(IniFile iniFile) throws Exception {
        String[] subjects = iniFile.getSubjects();

        if (subjects.length > 0 &&  set dummy parameter
         subjects[0].equalsIgnoreCase("Logger settings")) return DiverHeaderConstants.LOGGER_HEADER_CONSTANTS;

        String subject2 = subjects.length < 2 ? "" : subjects[1];
       id =if (subject2.equalsIgnoreCase("Notchannel Defined"1")) return DiverHeaderConstants.ENGLISH_HEADER_CONSTANTS;
        if (subject2.equalsIgnoreCase("kanaal 1"))  }

   return DiverHeaderConstants.DUTCH_HEADER_CONSTANTS;
        if header(subject2.setParameterId(id);
            header.setLocationId(loc)equalsIgnoreCase("channel 1 from data header")) return DiverHeaderConstants.ENGLISH_HEADER_CONSTANTS;
        if (subject2.equalsIgnoreCase("kanaal 1  contentHandler.createTimeSeriesHeaderAlias(channelCount,from data header);
            channelCount++;")) return DiverHeaderConstants.DUTCH_HEADER_CONSTANTS;

        }
    }
if (subjects.length > 5) {
    private IniFile parseHeaderIniFile() throws Exception {
   if (subjects[4].equalsIgnoreCase("kanaal 1 from data List<String> headerLines = new ArrayList<String>()header")) return DiverHeaderConstants.MIXED_HEADER_CONSTANTS;
        for (String line; (line = reader.readLine(if (subjects[4].equalsIgnoreCase("kanaal1 from data header")) != null;) {return DiverHeaderConstants.MIXED_HEADER_CONSTANTS;
            if (line.trim()subjects[4].equalsIgnoreCase("[Data]")) {
       "channel 1 from data header")) return DiverHeaderConstants.ENGLISH_MIXED_HEADER_CONSTANTS;
         BufferedReader reader = newif BufferedReader(new StringReader(TextUtils.join(headerLines, '\n')))(subjects[4].equalsIgnoreCase("channel1 from data header")) return DiverHeaderConstants.ENGLISH_MIXED_HEADER_CONSTANTS;
        }
        return new IniFile(reader, virtualFileName);
if (subjects.length > 3) {
            if  }(subjects[2].equalsIgnoreCase("kanaal 1 from data header")) return DiverHeaderConstants.INCOMPLETE_HEADER_CONSTANTS;
         }

   headerLines.add(line);
     // the file }

format is corrupt
      throw new Exception("No data found");
    }
    
    private static DiverHeaderConstants determineLanguage(IniFile iniFile) throws Exception {
log.error("\n" + subjects.length + " strings read from the header :  " + composeMessage(subjects) +
                String[] subjects = iniFile.getSubjects();

        if (subjects.length > 0 && subjects[0].equalsIgnoreCase("Logger settings")) return DiverHeaderConstants.LOGGER_HEADER_CONSTANTS;

        String subject2 = subjects.length < 2 ? "" : subjects[1];
"\nexpected in string nr.2:  'channel 1'  or  'kanaal 1'  or  'channel 1 from data header'  or  'kanaal 1 from data header'   or" +
               if (subject2.equalsIgnoreCase("channel 1")) return DiverHeaderConstants.ENGLISH_HEADER_CONSTANTS;
        if (subject2.equalsIgnoreCase("kanaal 1")) return DiverHeaderConstants.DUTCH_HEADER_CONSTANTS;
"\nexpected in string nr.3:  'kanaal 1 from data header'   or" +
           if (subject2.equalsIgnoreCase("channel 1 from data header")) return DiverHeaderConstants.ENGLISH_HEADER_CONSTANTS;
        if (subject2.equalsIgnoreCase("kanaal 1"\nexpected in string nr.5:  'kanaal 1 from data header'  or  'kanaal1 from data header'")) return DiverHeaderConstants.DUTCH_HEADER_CONSTANTS;

        throw ifnew Exception(subjects.length > 5) {
            if (subjects[4].equalsIgnoreCase("kanaal 1 from data header")) return DiverHeaderConstants.MIXED_HEADER_CONSTANTS"File format not recognized as a valid diver (.mon) file, check the headers");
    }

    private static String  if composeMessage(subjectsString[4].equalsIgnoreCase("kanaal1 from data header")) return DiverHeaderConstants.MIXED_HEADER_CONSTANTSNEW;
 substr) {
        StringBuffer buffer  }= new StringBuffer();
        iffor (subjectsint i = 0; i < substr.length > 3; i++) {
            if (subjects[2].equalsIgnoreCase("kanaal 1 from data header")) return DiverHeaderConstants.INCOMPLETE_HEADER_CONSTANTSbuffer.append("'");
        }

    buffer.append(substr[i]);
    // the file format is corrupt
   buffer.append("'  ");
   throw new Exception("File format not recognized}
 as a valid diver (.mon) file, check the headers"return buffer.toString();
    }
}