comparison flys-backend/src/main/java/org/dive4elements/river/importer/parsers/HYKParser.java @ 5828:dfb26b03b179

Moved directories to org.dive4elements.river
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 11:53:11 +0200
parents flys-backend/src/main/java/de/intevation/flys/importer/parsers/HYKParser.java@36edf9a71cbd
children 18619c1e7c2a
comparison
equal deleted inserted replaced
5827:e308d4ecd35a 5828:dfb26b03b179
1 package de.intevation.flys.importer.parsers;
2
3 import de.intevation.artifacts.common.utils.FileTools;
4
5 import de.intevation.flys.importer.ImportHYK;
6 import de.intevation.flys.importer.ImportHYKEntry;
7 import de.intevation.flys.importer.ImportHYKFormation;
8 import de.intevation.flys.importer.ImportHYKFlowZone;
9 import de.intevation.flys.importer.ImportHYKFlowZoneType;
10
11 import java.io.File;
12 import java.io.IOException;
13 import java.io.FileInputStream;
14 import java.io.InputStreamReader;
15 import java.io.LineNumberReader;
16
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.Date;
20 import java.util.Calendar;
21
22 import java.math.BigDecimal;
23
24 import org.apache.log4j.Logger;
25
26 public class HYKParser
27 {
28 private static Logger log = Logger.getLogger(HYKParser.class);
29
30 public interface Callback {
31 boolean hykAccept(File file);
32 void hykParsed(HYKParser parser);
33 } // interface Callback
34
35 public static enum State {
36 LINE_1, LINE_2, LINE_3, LINE_4, LINE_5, LINE_6
37 };
38
39 private static final String ENCODING = "ISO-8859-1";
40
41 protected Map<String, ImportHYKFlowZoneType> flowZoneTypes;
42
43 protected ImportHYK hyk;
44
45 public HYKParser() {
46 flowZoneTypes = new HashMap<String, ImportHYKFlowZoneType>();
47 }
48
49 public ImportHYK getHYK() {
50 return hyk;
51 }
52
53 private static Date yearToDate(Integer year) {
54 if (year == null) {
55 return null;
56 }
57 Calendar cal = Calendar.getInstance();
58 cal.set(year, 0, 1, 12, 0, 0);
59 long ms = cal.getTimeInMillis();
60 cal.setTimeInMillis(ms - ms%1000);
61 return cal.getTime();
62 }
63
64 public boolean parse(File file) {
65
66 boolean debug = log.isDebugEnabled();
67
68 log.info("Parsing HYK file '" + file + "'");
69
70 LineNumberReader in = null;
71
72 String description =
73 file.getParentFile().getName() + "/" + file.getName();
74
75 hyk = new ImportHYK(null, description);
76
77 try {
78 in =
79 new LineNumberReader(
80 new InputStreamReader(
81 new FileInputStream(file), ENCODING));
82
83 String line;
84
85 State state = State.LINE_1;
86
87 int numFormations = 0;
88
89 BigDecimal km = null;
90 BigDecimal top = null;
91 BigDecimal bottom = null;
92 BigDecimal distanceVL = null;
93 BigDecimal distanceHF = null;
94 BigDecimal distanceVR = null;
95
96 Integer year = null;
97 int numZones = 0;
98
99 ImportHYKFlowZoneType [] fzts = null;
100 BigDecimal [] coords = null;
101 int coordPos = 0;
102
103 ImportHYKEntry entry = null;
104 ImportHYKFormation formation = null;
105
106 while ((line = in.readLine()) != null) {
107
108 if (line.startsWith("*") || line.startsWith("----")) {
109 continue;
110 }
111
112 line = line.trim();
113
114 if (state != State.LINE_5 && line.length() == 0) {
115 continue;
116 }
117
118 String [] parts = line.split("\\s+");
119
120 if (debug) {
121 log.debug("'" + line + "': " + state);
122 }
123
124 switch (state) {
125 case LINE_1:
126 if (parts.length < 2) {
127 log.error("HYK 1: not enough elements in line " +
128 in.getLineNumber());
129 return false;
130 }
131
132 if (parts.length == 2) {
133 // no year given
134 year = null;
135 }
136 else {
137 try {
138 year = Integer.valueOf(parts[1]);
139 }
140 catch (NumberFormatException nfe) {
141 log.error(
142 "year is not an integer in line " +
143 in.getLineNumber());
144 return false;
145 }
146 }
147 try {
148 km = new BigDecimal(parts[0]);
149 numFormations = Integer.parseInt(
150 parts[parts.length > 2 ? 2 : 1]);
151 }
152 catch (NumberFormatException nfe) {
153 log.error(
154 "parsing number of formations " +
155 "or km failed in line " + in.getLineNumber());
156 return false;
157 }
158 entry = new ImportHYKEntry(hyk, km, yearToDate(year));
159 hyk.addEntry(entry);
160
161 state = State.LINE_2;
162 break;
163
164 case LINE_2:
165 if (parts.length < 3) {
166 log.error("HYK 2: not enough elements in line " +
167 in.getLineNumber());
168 return false;
169 }
170 try {
171 numZones = Integer.parseInt(parts[0]);
172 bottom = new BigDecimal(parts[1]);
173 top = new BigDecimal(parts[2]);
174 }
175 catch (NumberFormatException nfe) {
176 log.error(
177 "HYK: parsing num zones, bottom or top height " +
178 "failed in line " + in.getLineNumber());
179 return false;
180 }
181 formation = new ImportHYKFormation();
182 formation.setBottom(bottom);
183 formation.setTop(top);
184 entry.addFormation(formation);
185
186 state = State.LINE_3;
187 break;
188
189 case LINE_3:
190 if (parts.length != numZones) {
191 log.error(
192 "HYK: number of flow zones mismatches " +
193 "in line " + in.getLineNumber());
194 return false;
195 }
196
197 fzts = new ImportHYKFlowZoneType[parts.length];
198 for (int i = 0; i < fzts.length; ++i) {
199 fzts[i] = getFlowZoneType(parts[i]);
200 }
201 coords = new BigDecimal[numZones];
202 state = State.LINE_4;
203 break;
204
205 case LINE_4:
206 try {
207 int N = Math.min(parts.length, coords.length);
208 for (coordPos = 0; coordPos < N; ++coordPos) {
209 coords[coordPos] =
210 new BigDecimal(parts[coordPos]);
211 }
212 }
213 catch (NumberFormatException nfe) {
214 log.error("HYK: cannot parse number in line " +
215 in.getLineNumber());
216 return false;
217 }
218 state = State.LINE_5;
219 break;
220
221 case LINE_5:
222 if (parts.length + coordPos < coords.length) {
223 log.error("HYK 5: not enough elements in line " +
224 in.getLineNumber());
225 return false;
226 }
227 try {
228 for (int i = 0;
229 i < parts.length && coordPos < coords.length;
230 ++i, ++coordPos
231 ) {
232 coords[coordPos] = new BigDecimal(parts[i]);
233 }
234 }
235 catch (NumberFormatException nfe) {
236 log.error("HYK: cannot parse number in line " +
237 in.getLineNumber());
238 return false;
239 }
240 for (int i = 0; i < coords.length; ++i) {
241 BigDecimal a = coords[i];
242 BigDecimal b = coords[i == coords.length-1 ? i : i+1];
243 if (a.compareTo(b) > 0) {
244 log.warn("HYK: zone coordinates swapped in line " +
245 in.getLineNumber());
246 BigDecimal c = a; a = b; b = c;
247 }
248 ImportHYKFlowZone zone = new ImportHYKFlowZone(
249 formation, fzts[i], a, b);
250 formation.addFlowZone(zone);
251 }
252 state = State.LINE_6;
253 break;
254
255 case LINE_6:
256 if (parts.length < 3) {
257 log.error("HYK 6: not enough elements in line " +
258 in.getLineNumber());
259 return false;
260 }
261 try {
262 distanceVL = new BigDecimal(parts[0]);
263 distanceHF = new BigDecimal(parts[1]);
264 distanceVR = new BigDecimal(parts[2]);
265 }
266 catch (NumberFormatException nfe) {
267 log.error("HYK: cannot parse number in line " +
268 in.getLineNumber());
269 return false;
270 }
271 formation.setDistanceVL(distanceVL);
272 formation.setDistanceHF(distanceHF);
273 formation.setDistanceVR(distanceVR);
274
275 // continue with next formation.
276 state = --numFormations > 0 // formations left?
277 ? State.LINE_2
278 : State.LINE_1;
279 break;
280 }
281 }
282 }
283 catch (IOException ioe) {
284 log.error("HYK: Error reading file.", ioe);
285 return false;
286 }
287 finally {
288 if (in != null) {
289 try {
290 in.close();
291 }
292 catch (IOException ioe) {
293 log.error("HYK: Error closing file.", ioe);
294 }
295 }
296 }
297 return true;
298 }
299
300 protected ImportHYKFlowZoneType getFlowZoneType(String name) {
301 name = name.toUpperCase();
302 ImportHYKFlowZoneType fzt = flowZoneTypes.get(name);
303 if (fzt == null) {
304 log.info("New flow zone type: " + name);
305 fzt = new ImportHYKFlowZoneType(name);
306 flowZoneTypes.put(name, fzt);
307 }
308 return fzt;
309 }
310
311 protected void reset() {
312 hyk = null;
313 }
314
315 public void parseHYKs(File root, final Callback callback) {
316
317 FileTools.walkTree(root, new FileTools.FileVisitor() {
318 @Override
319 public boolean visit(File file) {
320 if (file.isFile() && file.canRead()
321 && file.getName().toLowerCase().endsWith(".hyk")
322 && (callback == null || callback.hykAccept(file))) {
323 reset();
324 boolean success = parse(file);
325 log.info("parsing " + (success ? "succeeded" : "failed"));
326 if (success && callback != null) {
327 callback.hykParsed(HYKParser.this);
328 }
329 }
330 return true;
331 }
332 });
333 }
334
335 public static void main(String [] args) {
336
337 HYKParser parser = new HYKParser();
338
339 for (String arg: args) {
340 parser.parseHYKs(new File(arg), null);
341 }
342 }
343 }
344 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org