You are viewing an old version of this page. View the current version.
Compare with Current
View Page History
Version 1
Next »
package nl.wldelft.fews.system.plugin.dataImport;
import nl.wldelft.util.TextUtils;
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 java.io.IOException;
public class WiskiTimeSeriesParser implements TextParser<TimeSeriesContentHandler> {
private LineReader reader = null;
private TimeSeriesContentHandler contentHandler = null;
private DefaultTimeSeriesHeader header = new DefaultTimeSeriesHeader();
@Override
public void parse(LineReader reader, String virtualFileName, TimeSeriesContentHandler contentHandler) throws Exception {
this.contentHandler = contentHandler;
this.contentHandler.addMissingValue(-777.0f);
this.reader = reader;
this.reader.setCommentLinePrefix('?');
this.reader.setSkipEmptyLines(true);
reader.mark(500);
String[] buffer = new String[2];
for (String line; (line = reader.readLine()) != null; reader.mark(500)) {
line = line.trim();
if (line.equals("ENDOFFILE")) return;
if (line.charAt(0) == '#') {
reader.reset();
parseHeader();
continue;
}
if (this.contentHandler.isCurrentTimeSeriesHeaderForAllTimesRejected()) continue;
TextUtils.split(line, ' ', buffer);
contentHandler.setTime(contentHandler.getDefaultTimeZone(), "yyyyMMddHHmmss", buffer[0]);
contentHandler.setValue('.', buffer[1]);
contentHandler.applyCurrentFields();
}
}
/**
* Read metadata from the #-records. Metadata block is followed by the timeseries-records
* but the timeseries-records may be also omitted. In this case the Metadata block MUST start
* with a record that begins with ## !
* <p/>
* Parse previously read metadata record, if any.
* Ignore empty records.
* The meaning of the keys is:
* SANR : location
* CNAME: parameter
* CUNIT: unit
* RINVAL: missing value
* REXCHANGE: location-parameter. Wil be used only if the metadata block does not contain keys SANR or CNAME.
* The string specified by keyword REXCHANGE represents location Id and also parameter-id (so locations Id and parameter Id equals)
*
* @return following line, or null if any error occurs, or the string "ENDOFFILE"
*/
private void parseHeader() throws IOException {
this.header.clear();
String fallbackParLoc = null;
for (String line ; (line = this.reader.readLine()) != null ; reader.mark(500)) {
line = line.trim();
if (line.charAt(0) != '#') {
reader.reset();
break;
}
String locationId = parseKeyValue("SANR", line);
if (locationId != null) header.setLocationId(locationId);
String parameterId = parseKeyValue("CNAME", line);
if (parameterId != null) header.setParameterId(parameterId);
String unit = parseKeyValue("CUNIT", line);
if (unit != null) header.setUnit(unit);
String missingValue = parseKeyValue("RINVAL", line);
if (missingValue != null) contentHandler.addMissingValue(missingValue);
String parLoc = parseKeyValue("REXCHANGE", line);
if (parLoc != null) fallbackParLoc = parLoc;
}
if (header.getParameterId() == null || header.getLocationId() == null) {
header.setParameterId(fallbackParLoc);
header.setLocationId(fallbackParLoc);
}
contentHandler.setTimeSeriesHeader(header);
}
/**
* Returns value or null if the key not found in the buffer
*/
private static String parseKeyValue(String key, String buffer) {
int keyPos = buffer.indexOf(key);
if (keyPos == -1) return null;
int endValuePos = buffer.indexOf(";*;", keyPos + key.length());
if (endValuePos == -1) endValuePos = buffer.indexOf("|*|", keyPos + key.length());
if (endValuePos == -1) return null;
return buffer.substring(keyPos + key.length(), endValuePos);
}
}