1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.time;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.text.ParseException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29 import org.hipparchus.util.FastMath;
30 import org.orekit.data.DataLoader;
31 import org.orekit.data.DataProvidersManager;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.errors.OrekitMessages;
34
35
36
37
38
39
40
41
42 public class TAIUTCDatFilesLoader implements UTCTAIOffsetsLoader {
43
44
45 public static final String DEFAULT_SUPPORTED_NAMES = "^tai-utc\\.dat$";
46
47
48 private final String supportedNames;
49
50
51
52
53 public TAIUTCDatFilesLoader(final String supportedNames) {
54 this.supportedNames = supportedNames;
55 }
56
57
58 @Override
59 public List<OffsetModel> loadOffsets() throws OrekitException {
60 final Parser parser = new Parser();
61 DataProvidersManager.getInstance().feed(supportedNames, parser);
62 return parser.getOffsets();
63 }
64
65
66 private static class Parser implements DataLoader {
67
68
69 private static final String BLANKS = "\\p{Blank}*";
70
71
72 private static final String STORAGE_START = "(";
73
74
75 private static final String STORAGE_END = ")";
76
77
78 private static final String ALTERNATIVE = "|";
79
80
81 private static final String LINE_START_REGEXP = "^" + BLANKS;
82
83
84 private static final String LINE_END_REGEXP = BLANKS + "$";
85
86
87 private static final String INTEGER_REGEXP = "[-+]?\\p{Digit}+";
88
89
90 private static final String REAL_REGEXP = "[-+]?(?:(?:\\p{Digit}+(?:\\.\\p{Digit}*)?)|(?:\\.\\p{Digit}+))(?:[eE][-+]?\\p{Digit}+)?";
91
92
93 private static final String STORED_INTEGER_FIELD = BLANKS + STORAGE_START + INTEGER_REGEXP + STORAGE_END;
94
95
96 private static final String STORED_REAL_FIELD = BLANKS + STORAGE_START + REAL_REGEXP + STORAGE_END;
97
98
99 private Pattern dataPattern;
100
101
102 private List<OffsetModel> offsets;
103
104
105
106 Parser() {
107
108
109
110
111
112
113
114
115
116
117
118 final StringBuilder builder = new StringBuilder(BLANKS + STORAGE_START);
119 for (final Month month : Month.values()) {
120 builder.append(month.getUpperCaseAbbreviation());
121 builder.append(ALTERNATIVE);
122 }
123 builder.delete(builder.length() - 1, builder.length());
124 builder.append(STORAGE_END);
125 final String monthField = builder.toString();
126
127 dataPattern = Pattern.compile(LINE_START_REGEXP +
128 STORED_INTEGER_FIELD + monthField + STORED_INTEGER_FIELD +
129 "\\p{Blank}+=JD" + STORED_REAL_FIELD +
130 "\\p{Blank}+TAI-UTC=" + STORED_REAL_FIELD +
131 "\\p{Blank}+S\\p{Blank}+\\+\\p{Blank}+\\(MJD\\p{Blank}+-" + STORED_REAL_FIELD +
132 "\\p{Blank}*\\)\\p{Blank}+X" + STORED_REAL_FIELD +
133 "\\p{Blank}*S" + LINE_END_REGEXP);
134
135 offsets = new ArrayList<OffsetModel>();
136
137 }
138
139
140
141
142 public List<OffsetModel> getOffsets() {
143 return offsets;
144 }
145
146
147 public boolean stillAcceptsData() {
148 return offsets.isEmpty();
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162 public void loadData(final InputStream input, final String name)
163 throws OrekitException, IOException, ParseException {
164
165 offsets.clear();
166
167
168 final BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
169
170
171 int lineNumber = 0;
172 DateComponents lastDate = null;
173 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
174 ++lineNumber;
175
176
177 final Matcher matcher = dataPattern.matcher(line);
178 if (matcher.matches()) {
179
180 try {
181
182 final DateComponents dc1 = new DateComponents(Integer.parseInt(matcher.group(1)),
183 Month.parseMonth(matcher.group(2)),
184 Integer.parseInt(matcher.group(3)));
185 final DateComponents dc2 = new DateComponents(DateComponents.JULIAN_EPOCH,
186 (int) FastMath.ceil(Double.parseDouble(matcher.group(4))));
187 if (!dc1.equals(dc2)) {
188 throw new OrekitException(OrekitMessages.INCONSISTENT_DATES_IN_IERS_FILE,
189 name, dc1.getYear(), dc1.getMonth(), dc1.getDay(), dc2.getMJD());
190 }
191
192 if ((lastDate != null) && dc1.compareTo(lastDate) <= 0) {
193 throw new OrekitException(OrekitMessages.NON_CHRONOLOGICAL_DATES_IN_FILE,
194 name, lineNumber);
195 }
196 lastDate = dc1;
197
198 final double offset = Double.parseDouble(matcher.group(5));
199 final double mjdRef = Double.parseDouble(matcher.group(6));
200 final double slope = Double.parseDouble(matcher.group(7));
201 offsets.add(new OffsetModel(dc1, (int) FastMath.rint(mjdRef), offset, slope));
202
203 } catch (NumberFormatException nfe) {
204 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
205 lineNumber, name, line);
206 }
207 }
208 }
209
210 if (offsets.isEmpty()) {
211 throw new OrekitException(OrekitMessages.NO_ENTRIES_IN_IERS_UTC_TAI_HISTORY_FILE, name);
212 }
213
214 }
215
216 }
217
218 }