Mercurial > dive4elements > river
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 : |