SimpleTimeStampedTableParser.java
- /* Copyright 2002-2013 CS Systèmes d'Information
- * Licensed to CS Systèmes d'Information (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.data;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.commons.math3.exception.util.DummyLocalizable;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.time.TimeStamped;
- /**
- * Parser for simple tables containing {@link TimeStamped time stamped} data.
- * @param <T> the type of time stamped data (i.e. parsed table rows)
- * @author Luc Maisonobe
- * @since 6.1
- */
- public class SimpleTimeStampedTableParser<T extends TimeStamped> {
- /** Interface for converting a table row into time-stamped data.
- * @param <S> the type of time stamped data (i.e. parsed table rows)
- */
- public interface RowConverter<S extends TimeStamped> {
- /** Convert a row.
- * @param rawFields raw row fields, as read from the file
- * @return converted row
- * @exception OrekitException if conversion cannot be performed
- */
- S convert(double[] rawFields) throws OrekitException;
- }
- /** Pattern for fields with real type. */
- private static final String REAL_TYPE_PATTERN =
- "[-+]?(?:(?:\\p{Digit}+(?:\\.\\p{Digit}*)?)|(?:\\.\\p{Digit}+))(?:[eE][-+]?\\p{Digit}+)?";
- /** Number of columns. */
- private final int columns;
- /** Converter for rows. */
- private final RowConverter<T> converter;
- /** Simple constructor.
- * @param columns number of columns
- * @param converter converter for rows
- */
- public SimpleTimeStampedTableParser(final int columns, final RowConverter<T> converter) {
- this.columns = columns;
- this.converter = converter;
- }
- /** Parse a stream.
- * @param stream stream containing the table
- * @param name name of the resource file (for error messages only)
- * @return parsed table
- * @exception OrekitException if stream is null or the table cannot be parsed
- */
- public List<T> parse(final InputStream stream, final String name) throws OrekitException {
- if (stream == null) {
- throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, name);
- }
- // regular lines are simply a space separated list of numbers
- final StringBuilder builder = new StringBuilder("^\\p{Space}*");
- for (int i = 0; i < columns; ++i) {
- builder.append("(");
- builder.append(REAL_TYPE_PATTERN);
- builder.append(")");
- builder.append((i < columns - 1) ? "\\p{Space}+" : "\\p{Space}*$");
- }
- final Pattern regularLinePattern = Pattern.compile(builder.toString());
- try {
- // setup the reader
- final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
- final List<T> table = new ArrayList<T>();
- for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- // replace unicode minus sign ('−') by regular hyphen ('-') for parsing
- // such unicode characters occur in tables that are copy-pasted from PDF files
- line = line.replace('\u2212', '-');
- final Matcher regularMatcher = regularLinePattern.matcher(line);
- if (regularMatcher.matches()) {
- // we have found a regular data line
- final double[] rawFields = new double[columns];
- for (int i = 0; i < columns; ++i) {
- rawFields[i] = Double.parseDouble(regularMatcher.group(i + 1));
- }
- table.add(converter.convert(rawFields));
- }
- }
- if (table.isEmpty()) {
- throw new OrekitException(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, name);
- }
- return table;
- } catch (IOException ioe) {
- throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
- }
- }
- }