Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/utils/FLYSUtils.java @ 3818:dc18457b1cef
merged flys-artifacts/pre2.7-2012-03-16
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:59 +0200 |
parents | efb2038783f9 |
children | 3f1cc396d253 |
comparison
equal
deleted
inserted
replaced
2456:60ab1054069d | 3818:dc18457b1cef |
---|---|
1 package de.intevation.flys.utils; | |
2 | |
3 import org.apache.log4j.Logger; | |
4 | |
5 import java.text.NumberFormat; | |
6 import java.util.HashMap; | |
7 import java.util.List; | |
8 import java.util.Map; | |
9 import java.util.regex.Matcher; | |
10 import java.util.regex.Pattern; | |
11 | |
12 import javax.xml.xpath.XPathConstants; | |
13 | |
14 import org.w3c.dom.Document; | |
15 | |
16 import org.hibernate.SessionFactory; | |
17 import org.hibernate.impl.SessionFactoryImpl; | |
18 | |
19 import gnu.trove.TDoubleArrayList; | |
20 import gnu.trove.TIntArrayList; | |
21 | |
22 import de.intevation.artifacts.Artifact; | |
23 import de.intevation.artifacts.CallContext; | |
24 | |
25 import de.intevation.artifacts.common.utils.Config; | |
26 import de.intevation.artifacts.common.utils.XMLUtils; | |
27 | |
28 import de.intevation.flys.backend.SessionFactoryProvider; | |
29 | |
30 import de.intevation.flys.artifacts.context.FLYSContext; | |
31 import de.intevation.flys.artifacts.FLYSArtifact; | |
32 import de.intevation.flys.artifacts.WINFOArtifact; | |
33 import de.intevation.flys.artifacts.StaticWKmsArtifact; | |
34 import de.intevation.flys.artifacts.model.RiverFactory; | |
35 import de.intevation.flys.artifacts.model.LocationProvider; | |
36 import de.intevation.flys.artifacts.model.WQ; | |
37 import de.intevation.flys.artifacts.model.WKms; | |
38 import de.intevation.flys.artifacts.model.WQKms; | |
39 | |
40 import de.intevation.artifactdatabase.state.State; | |
41 import de.intevation.flys.artifacts.states.WaterlevelSelectState; | |
42 import de.intevation.flys.artifacts.states.WDifferencesState; | |
43 import de.intevation.flys.model.Gauge; | |
44 import de.intevation.flys.model.MainValue; | |
45 import de.intevation.flys.model.River; | |
46 | |
47 public class FLYSUtils { | |
48 | |
49 /** The logger that is used in this utility. */ | |
50 private static Logger logger = Logger.getLogger(FLYSUtils.class); | |
51 | |
52 public static enum KM_MODE { RANGE, LOCATIONS, NONE }; | |
53 | |
54 /** | |
55 * An enum that represents the 5 possible WQ modes in FLYS. The 5 values are | |
56 * <i>QFREE</i> <i>QGAUGE</i> <i>WGAUGE</i> <i>WFREE</i> and <i>NONE</i>. | |
57 */ | |
58 public static enum WQ_MODE { QFREE, QGAUGE, WFREE, WGAUGE, NONE }; | |
59 | |
60 /** | |
61 * An enum that represents the 4 possible WQ input modes in FLYS. The 4 | |
62 * values are | |
63 * <i>ADAPTED</i> <i>SINGLE</i> <i>RANGE</i> and <i>NONE</i>. | |
64 */ | |
65 public static enum WQ_INPUT { ADAPTED, SINGLE, RANGE, NONE }; | |
66 | |
67 public static final Pattern NUMBERS_PATTERN = | |
68 Pattern.compile("\\D*(\\d++.\\d*)\\D*"); | |
69 | |
70 public static final String XPATH_RIVER_PROJECTION = | |
71 "/artifact-database/floodmap/river[@name=$name]/srid/@value"; | |
72 | |
73 public static final String XPATH_SHAPEFILE_DIR = | |
74 "/artifact-database/floodmap/shapefile-path/@value"; | |
75 | |
76 public static final String XPATH_VELOCITY_LOGFILE = | |
77 "/artifact-database/floodmap/velocity/logfile/@path"; | |
78 | |
79 public static final String XPATH_MAPSERVER_URL = | |
80 "/artifact-database/floodmap/mapserver/server/@path"; | |
81 | |
82 public static final String XPATH_MAPFILE_PATH = | |
83 "/artifact-database/floodmap/mapserver/mapfile/@path"; | |
84 | |
85 public static final String XPATH_MAPFILE_TEMPLATE = | |
86 "/artifact-database/floodmap/mapserver/map-template/@path"; | |
87 | |
88 public static final String XPATH_MAPSERVER_TEMPLATE_PATH = | |
89 "/artifact-database/floodmap/mapserver/templates/@path"; | |
90 | |
91 | |
92 private FLYSUtils() { | |
93 } | |
94 | |
95 | |
96 /** | |
97 * Pulls Artifact with given UUID fromm database. | |
98 * @return FLYSArtifact with given UUID or null (in case of errors). | |
99 */ | |
100 public static FLYSArtifact getArtifact(String uuid, CallContext context) { | |
101 try { | |
102 Artifact artifact = context.getDatabase().getRawArtifact(uuid); | |
103 | |
104 if (artifact == null) { | |
105 logger.error("Artifact '" + uuid + "' does not exist."); | |
106 return null; | |
107 } | |
108 | |
109 if (!(artifact instanceof FLYSArtifact)) { | |
110 logger.error("Artifact '" +uuid+ "' is no valid FLYSArtifact."); | |
111 return null; | |
112 } | |
113 | |
114 return (FLYSArtifact) artifact; | |
115 } | |
116 // TODO: catch more selective | |
117 catch (Exception e) { | |
118 logger.error("Cannot get FLYSArtifact " + uuid | |
119 + " from database (" + e.getMessage() + ")."); | |
120 return null; | |
121 } | |
122 } | |
123 | |
124 | |
125 /** | |
126 * Returns the FLYSContext from context object. | |
127 * | |
128 * @param context The CallContext or the FLYSContext. | |
129 * | |
130 * @return the FLYSContext. | |
131 */ | |
132 public static FLYSContext getFlysContext(Object context) { | |
133 return context instanceof FLYSContext | |
134 ? (FLYSContext) context | |
135 : (FLYSContext) ((CallContext) context).globalContext(); | |
136 } | |
137 | |
138 | |
139 /** | |
140 * Convinience function to retrieve an XPath as string with replaced config | |
141 * directory. | |
142 * | |
143 * @param xpath The XPath expression. | |
144 * | |
145 * @return a string with replaced config directory. | |
146 */ | |
147 public static String getXPathString(String xpath) { | |
148 String tmp = Config.getStringXPath(xpath); | |
149 tmp = Config.replaceConfigDir(tmp); | |
150 | |
151 return tmp; | |
152 } | |
153 | |
154 | |
155 public static boolean isUsingOracle() { | |
156 SessionFactory sf = SessionFactoryProvider.getSessionFactory(); | |
157 | |
158 String d = SessionFactoryProvider.getDriver((SessionFactoryImpl) sf); | |
159 | |
160 return d != null ? d.indexOf("Oracle") >= 0 : false; | |
161 } | |
162 | |
163 | |
164 /** | |
165 * This method returns an WQ_MODE enum which is based on the parameters | |
166 * stored in <i>flys</i> Artifact. If there is no <i>wq_isq</i> parameter | |
167 * existing, WQ_MODE.NONE is returned. | |
168 * | |
169 * @param flys The FLYSArtifact that stores wq mode relevant parameters. | |
170 * | |
171 * @return an enum WQ_MODE. | |
172 */ | |
173 public static WQ_MODE getWQMode(FLYSArtifact flys) { | |
174 if (flys == null) { | |
175 return WQ_MODE.NONE; | |
176 } | |
177 | |
178 String values = flys.getDataAsString("wq_values"); | |
179 Boolean isQ = flys.getDataAsBoolean("wq_isq"); | |
180 | |
181 if (values != null) { | |
182 return isQ ? WQ_MODE.QGAUGE : WQ_MODE.WGAUGE; | |
183 } | |
184 | |
185 Boolean isFree = flys.getDataAsBoolean("wq_isfree"); | |
186 | |
187 if (isQ) { | |
188 return isFree ? WQ_MODE.QFREE : WQ_MODE.QGAUGE; | |
189 } | |
190 else if (!isQ) { | |
191 return isFree ? WQ_MODE.WFREE : WQ_MODE.WGAUGE; | |
192 } | |
193 else { | |
194 return WQ_MODE.NONE; | |
195 } | |
196 } | |
197 | |
198 | |
199 public static WQ_INPUT getWQInputMode(FLYSArtifact flys) { | |
200 if (flys == null) { | |
201 return WQ_INPUT.NONE; | |
202 } | |
203 | |
204 Boolean selection = flys.getDataAsBoolean("wq_isrange"); | |
205 String adapted = flys.getDataAsString("wq_values"); | |
206 | |
207 if(adapted != null && adapted.length() > 0) { | |
208 return WQ_INPUT.ADAPTED; | |
209 } | |
210 | |
211 if (selection != null && selection) { | |
212 return WQ_INPUT.RANGE; | |
213 } | |
214 else { | |
215 return WQ_INPUT.SINGLE; | |
216 } | |
217 } | |
218 | |
219 public static KM_MODE getKmRangeMode(FLYSArtifact flys) { | |
220 String mode = flys.getDataAsString("ld_mode"); | |
221 | |
222 if (mode == null || mode.length() == 0) { | |
223 return KM_MODE.NONE; | |
224 } | |
225 else if (mode.equals("distance")) { | |
226 return KM_MODE.RANGE; | |
227 } | |
228 else if (mode.equals("locations")) { | |
229 return KM_MODE.LOCATIONS; | |
230 } | |
231 else { | |
232 return KM_MODE.NONE; | |
233 } | |
234 } | |
235 | |
236 /** | |
237 * Get min and max kilometer, independent of parametization | |
238 * (ld_from/to vs ld_locations). | |
239 */ | |
240 public static double[] getKmRange(FLYSArtifact flys) { | |
241 switch (getKmRangeMode(flys)) { | |
242 case RANGE: { | |
243 return getKmFromTo(flys); | |
244 } | |
245 | |
246 case LOCATIONS: { | |
247 double[] locs = getLocations(flys); | |
248 return new double[] { locs[0], locs[locs.length-1] }; | |
249 } | |
250 | |
251 case NONE: { | |
252 double[] locs = getLocations(flys); | |
253 if (locs != null) { | |
254 return new double[] { locs[0], locs[locs.length-1] }; | |
255 } | |
256 else { | |
257 return getKmFromTo(flys); | |
258 } | |
259 } | |
260 } | |
261 | |
262 return new double[] { Double.NaN, Double.NaN }; | |
263 } | |
264 | |
265 | |
266 /** | |
267 * Get bounds for river of artifact. | |
268 * @param flysArtifact artifact which has a "river" data. | |
269 * @return double array. min is at[0], max at[1]. null if given artifact is null | |
270 */ | |
271 public static double[] getRiverMinMax(FLYSArtifact flysArtifact) { | |
272 if (flysArtifact == null) { | |
273 return null; | |
274 } | |
275 | |
276 String riverName = flysArtifact.getDataAsString("river"); | |
277 | |
278 if (riverName == null) { | |
279 riverName = ""; | |
280 } | |
281 | |
282 logger.debug("Search for the min/max distances of '" + riverName + "'"); | |
283 | |
284 River river = RiverFactory.getRiver(riverName); | |
285 | |
286 return river != null | |
287 ? river.determineMinMaxDistance() | |
288 : null; | |
289 } | |
290 | |
291 | |
292 public static double[] getKmFromTo(FLYSArtifact flys) { | |
293 String strFrom = flys.getDataAsString("ld_from"); | |
294 String strTo = flys.getDataAsString("ld_to"); | |
295 | |
296 if (strFrom == null || strTo == null) { | |
297 return null; | |
298 } | |
299 | |
300 try { | |
301 return new double[] { | |
302 Double.parseDouble(strFrom), | |
303 Double.parseDouble(strTo) }; | |
304 } | |
305 catch (NumberFormatException nfe) { | |
306 return null; | |
307 } | |
308 } | |
309 | |
310 | |
311 /** | |
312 * Return sorted array of locations at which stuff was calculated | |
313 * (from ld_locations data), null if not parameterized this way. | |
314 */ | |
315 public static double[] getLocations(FLYSArtifact flys) { | |
316 String locationStr = flys.getDataAsString("ld_locations"); | |
317 | |
318 if (locationStr == null || locationStr.length() == 0) { | |
319 return null; | |
320 } | |
321 | |
322 String[] tmp = locationStr.split(" "); | |
323 TDoubleArrayList locations = new TDoubleArrayList(); | |
324 | |
325 for (String l: tmp) { | |
326 try { | |
327 locations.add(Double.parseDouble(l)); | |
328 } | |
329 catch (NumberFormatException nfe) { | |
330 } | |
331 } | |
332 | |
333 locations.sort(); | |
334 | |
335 return locations.toNativeArray(); | |
336 } | |
337 | |
338 | |
339 /** | |
340 * Returns the Qs for a given FLYSArtifact. This method currently accepts | |
341 * only instances of WINFOArtifact. | |
342 * | |
343 * @param flys A FLYSArtifact. | |
344 * | |
345 * @return the Qs. | |
346 */ | |
347 public static double[] getQs(FLYSArtifact flys) { | |
348 // XXX this is not nice! | |
349 if (flys instanceof WINFOArtifact) { | |
350 return ((WINFOArtifact) flys).getQs(); | |
351 } | |
352 | |
353 logger.warn("This method currently supports WINFOArtifact only!"); | |
354 | |
355 return null; | |
356 } | |
357 | |
358 | |
359 /** | |
360 * Returns the Ws for a given FLYSArtifact. This method currently accepts | |
361 * only instances of WINFOArtifact. | |
362 * | |
363 * @param flys A FLYSArtifact. | |
364 * | |
365 * @return the Ws. | |
366 */ | |
367 public static double[] getWs(FLYSArtifact flys) { | |
368 // XXX this is not nice! | |
369 if (flys instanceof WINFOArtifact) { | |
370 return ((WINFOArtifact) flys).getWs(); | |
371 } | |
372 | |
373 logger.warn("This method currently supports WINFOArtifact only!"); | |
374 | |
375 return null; | |
376 } | |
377 | |
378 | |
379 /** | |
380 * Returns the selected River object based on the 'river' data that might | |
381 * have been inserted by the user. | |
382 * | |
383 * @return the selected River or null if no river has been chosen yet. | |
384 */ | |
385 public static River getRiver(FLYSArtifact flys) { | |
386 String sRiver = getRivername(flys); | |
387 | |
388 return (sRiver != null) | |
389 ? RiverFactory.getRiver(sRiver) | |
390 : null; | |
391 } | |
392 | |
393 | |
394 /** | |
395 * Returns the name of the river specified in the given <i>flys</i> | |
396 * Artifact. | |
397 * | |
398 * @param flys The FLYSArtifact that stores a river relevant information. | |
399 * | |
400 * @return the name of the specified river or null. | |
401 */ | |
402 public static String getRivername(FLYSArtifact flys) { | |
403 return flys != null ? flys.getDataAsString("river") : null; | |
404 } | |
405 | |
406 | |
407 /** | |
408 * Extracts the SRID defined in the global configuration for the river | |
409 * specified in <i>artifact</i>. | |
410 * | |
411 * @param artifact The FLYSArtifact that stores the name of the river. | |
412 * | |
413 * @return the SRID as string (e.g. "31466"). | |
414 */ | |
415 public static String getRiverSrid(FLYSArtifact artifact) { | |
416 String river = artifact.getDataAsString("river"); | |
417 | |
418 if (river == null || river.length() == 0) { | |
419 return null; | |
420 } | |
421 | |
422 return getRiverSrid(river); | |
423 } | |
424 | |
425 | |
426 public static String getRiverSrid(String rivername) { | |
427 Map<String, String> variables = new HashMap<String, String>(1); | |
428 variables.put("name", rivername); | |
429 | |
430 Document cfg = Config.getConfig(); | |
431 | |
432 return (String) XMLUtils.xpath( | |
433 cfg, | |
434 XPATH_RIVER_PROJECTION, | |
435 XPathConstants.STRING, | |
436 null, | |
437 variables); | |
438 } | |
439 | |
440 | |
441 public static Gauge getGauge(FLYSArtifact flys) { | |
442 River river = getRiver(flys); | |
443 | |
444 if (river == null) { | |
445 logger.debug("no river found"); | |
446 return null; | |
447 } | |
448 | |
449 double[] dist = getKmRange(flys); | |
450 | |
451 if (dist == null) { | |
452 logger.debug("no range found"); | |
453 return null; | |
454 } | |
455 | |
456 if (logger.isDebugEnabled()) { | |
457 logger.debug("Determine gauge for:"); | |
458 logger.debug("... river: " + river.getName()); | |
459 logger.debug("... distance: " + dist[0] + " - " + dist[1]); | |
460 } | |
461 | |
462 Gauge gauge = river.determineGauge(dist[0], dist[1]); | |
463 | |
464 String name = gauge != null ? gauge.getName() : "'n/a"; | |
465 logger.debug("Found gauge: " + name); | |
466 | |
467 return gauge; | |
468 } | |
469 | |
470 | |
471 public static String getGaugename(FLYSArtifact flys) { | |
472 Gauge gauge = getGauge(flys); | |
473 | |
474 return gauge != null ? gauge.getName() : null; | |
475 } | |
476 | |
477 | |
478 public static Gauge getReferenceGauge(FLYSArtifact flys) { | |
479 Long officialNumber = flys.getDataAsLong("reference_gauge"); | |
480 | |
481 return officialNumber != null | |
482 ? Gauge.getGaugeByOfficialNumber(officialNumber) | |
483 : null; | |
484 } | |
485 | |
486 | |
487 public static String getReferenceGaugeName(FLYSArtifact flys) { | |
488 Gauge refGauge = getReferenceGauge(flys); | |
489 | |
490 return refGauge != null | |
491 ? refGauge.getName() | |
492 : "-- not found --"; | |
493 } | |
494 | |
495 | |
496 public static Double getValueFromWQ(WQ wq) { | |
497 if (wq == null) { | |
498 return null; | |
499 } | |
500 | |
501 Matcher m = NUMBERS_PATTERN.matcher(wq.getName()); | |
502 | |
503 if (m.matches()) { | |
504 logger.debug("Found a number."); | |
505 | |
506 String raw = m.group(1); | |
507 | |
508 try { | |
509 return Double.valueOf(raw); | |
510 } | |
511 catch (NumberFormatException nfe) { | |
512 } | |
513 } | |
514 | |
515 return null; | |
516 } | |
517 | |
518 | |
519 public static String createWspWTitle( | |
520 WINFOArtifact winfo, | |
521 CallContext cc, | |
522 String name | |
523 ) { | |
524 String[] parts = name.split("="); | |
525 | |
526 NumberFormat nf = Formatter.getWaterlevelW(cc); | |
527 | |
528 String namedMainValue = null; | |
529 | |
530 boolean isQ = winfo.isQ(); | |
531 boolean isFree = winfo.isFreeQ(); | |
532 | |
533 double v; | |
534 | |
535 try { | |
536 v = Double.valueOf(parts[1]); | |
537 | |
538 namedMainValue = getNamedMainValue(winfo.getGauge(), v); | |
539 } | |
540 catch (NumberFormatException nfe) { | |
541 logger.warn("Cannot parse Double of: '" + parts[1] + "'"); | |
542 return name; | |
543 } | |
544 | |
545 String prefix = null; | |
546 | |
547 if (isQ && !isFree && namedMainValue != null) { | |
548 return "W (" + namedMainValue + ")"; | |
549 } | |
550 | |
551 if (isQ) { | |
552 prefix = "Q="; | |
553 } | |
554 | |
555 return prefix == null | |
556 ? "W(" + nf.format(v) + ")" | |
557 : "W(" + prefix + nf.format(v) + ")"; | |
558 } | |
559 | |
560 | |
561 public static String createWspQTitle( | |
562 WINFOArtifact winfo, | |
563 CallContext cc, | |
564 String name | |
565 ) { | |
566 String[] parts = name.split("="); | |
567 | |
568 NumberFormat nf = Formatter.getWaterlevelQ(cc); | |
569 | |
570 String namedMainValue = null; | |
571 | |
572 boolean isQ = winfo.isQ(); | |
573 boolean isFree = winfo.isFreeQ(); | |
574 | |
575 double v; | |
576 | |
577 try { | |
578 v = Double.valueOf(parts[1]); | |
579 | |
580 namedMainValue = getNamedMainValue(winfo.getGauge(), v); | |
581 } | |
582 catch (NumberFormatException nfe) { | |
583 logger.warn("Cannot parse Double of: '" + parts[1] + "'"); | |
584 return name; | |
585 } | |
586 | |
587 String prefix = null; | |
588 | |
589 if (isQ && !isFree && namedMainValue != null) { | |
590 return namedMainValue; | |
591 } | |
592 | |
593 if (!isQ) { | |
594 prefix = "W="; | |
595 } | |
596 | |
597 return prefix == null | |
598 ? "Q(" + nf.format(v) + ")" | |
599 : "Q(" + prefix + nf.format(v) + ")"; | |
600 } | |
601 | |
602 | |
603 /** | |
604 * Returns the named main value if a Q was selected and if this Q fits to a | |
605 * named main value. Otherwise, this function returns null. | |
606 * | |
607 * @param winfo The WINFO Artifact. | |
608 * @param value The Q (or W) value. | |
609 * | |
610 * @return a named main value or null. | |
611 */ | |
612 public static String getNamedMainValue(WINFOArtifact winfo, double value) { | |
613 WQ_MODE wqmode = getWQMode(winfo); | |
614 | |
615 if (wqmode != WQ_MODE.QGAUGE) { | |
616 return null; | |
617 } | |
618 else { | |
619 return getNamedMainValue(winfo.getGauge(), value); | |
620 } | |
621 } | |
622 | |
623 | |
624 public static String getNamedMainValue(Gauge gauge, double value) { | |
625 List<MainValue> mainValues = gauge.getMainValues(); | |
626 logger.debug("Search named main value for: " + value); | |
627 | |
628 for (MainValue mv: mainValues) { | |
629 if (mv.getValue().doubleValue() == value) { | |
630 logger.debug("Found named main value: " + mv.getMainValue().getName()); | |
631 return mv.getMainValue().getName(); | |
632 } | |
633 } | |
634 | |
635 logger.debug("Did not find a named main value for: " + value); | |
636 return null; | |
637 } | |
638 | |
639 | |
640 /** | |
641 * | |
642 * @param nmv A string that represents a named main value. | |
643 * | |
644 * @throws NullPointerException if nmv is null. | |
645 */ | |
646 public static String stripNamedMainValue(String nmv) { | |
647 int startIndex = nmv.indexOf("("); | |
648 int endIndex = nmv.indexOf(")"); | |
649 | |
650 if (startIndex > 0 && endIndex > 0 && startIndex < endIndex) { | |
651 return nmv.substring(0, startIndex); | |
652 } | |
653 | |
654 return nmv; | |
655 } | |
656 | |
657 | |
658 /** | |
659 * Returns the URL of user mapfile for the owner of Artifact | |
660 * <i>artifactId</i>. | |
661 * | |
662 * @param artifactId The UUID of an artifact. | |
663 * | |
664 * @return the URL of the user wms. | |
665 */ | |
666 public static String getUserWMSUrl(String artifactId) { | |
667 String url = getXPathString(XPATH_MAPSERVER_URL); | |
668 url = url.endsWith("/") ? url + "user-wms" : url + "/" + "user-wms"; | |
669 | |
670 return url; | |
671 } | |
672 | |
673 | |
674 /** | |
675 * This method returns the description for a given <i>km</i> for a specific | |
676 * river. The river is provided by the FLYSArtifact <i>flys</i>. | |
677 * | |
678 * @param flys The FLYSArtifact that provides a river. | |
679 * @param km The kilometer. | |
680 * | |
681 * @return the description for <i>km</i> or an empty string if no | |
682 * description was found. | |
683 */ | |
684 public static String getLocationDescription(FLYSArtifact flys, double km) { | |
685 String river = getRivername(flys); | |
686 | |
687 if (river == null) { | |
688 return ""; | |
689 } | |
690 | |
691 return LocationProvider.getLocation(river, km); | |
692 } | |
693 | |
694 | |
695 /** | |
696 * This method returns the differences for a w-differences calculation. | |
697 * | |
698 * @param winfo The WINFOArtifact. | |
699 * @param context The context. | |
700 * | |
701 * @return The differences as string separated by semicolon and linebreak. | |
702 */ | |
703 public static String getWDifferences( | |
704 WINFOArtifact winfo, | |
705 CallContext context) | |
706 { | |
707 State state = winfo.getCurrentState(context); | |
708 if(state instanceof WDifferencesState) { | |
709 String diffids = winfo.getDataAsString("diffids"); | |
710 String datas[] = diffids.split("#"); | |
711 | |
712 // Validate the Data-Strings. | |
713 for (String s: datas) { | |
714 if (!WaterlevelSelectState.isValueValid(winfo.getDataAsString("diffids"))) { | |
715 return ""; | |
716 } | |
717 } | |
718 | |
719 if (datas.length < 2) { | |
720 return ""; | |
721 } | |
722 | |
723 String diffs = ""; | |
724 for(int i = 0; i < datas.length; i+=2) { | |
725 // e.g.: | |
726 // 42537f1e-3522-42ef-8968-635b03d8e9c6;longitudinal_section.w;1 | |
727 WKms minuendWKms = getWKms(StringUtil.unbracket(datas[i+0]), | |
728 context); | |
729 WKms subtrahendWKms = getWKms(StringUtil.unbracket(datas[i+1]), | |
730 context); | |
731 if (minuendWKms != null && subtrahendWKms != null) { | |
732 diffs += StringUtil.wWrap(minuendWKms.getName()) | |
733 + " - " + StringUtil.wWrap(subtrahendWKms.getName()); | |
734 } | |
735 diffs += ";\n"; | |
736 } | |
737 return diffs; | |
738 } | |
739 else { | |
740 logger.warn("Not a valid state for differences."); | |
741 return ""; | |
742 } | |
743 } | |
744 | |
745 | |
746 protected static WKms getWKms(String mingle, CallContext context) { | |
747 String[] def = mingle.split(";"); | |
748 String uuid = def[0]; | |
749 String name = def[1]; | |
750 int idx = Integer.parseInt(def[2]); | |
751 | |
752 if (name.startsWith("staticwkms")) { | |
753 StaticWKmsArtifact staticWKms = | |
754 (StaticWKmsArtifact) FLYSUtils.getArtifact( | |
755 uuid, | |
756 context); | |
757 WKms wkms = staticWKms.getWKms(idx); | |
758 if (wkms == null) | |
759 logger.error("No WKms from artifact."); | |
760 return wkms; | |
761 } | |
762 | |
763 WINFOArtifact flys = (WINFOArtifact) FLYSUtils.getArtifact( | |
764 uuid, | |
765 context); | |
766 | |
767 if (flys == null) { | |
768 logger.warn("One of the artifacts (1) for diff calculation could not be loaded"); | |
769 return null; | |
770 } | |
771 else{ | |
772 WQKms[] wqkms = (WQKms[]) flys.getWaterlevelData(). | |
773 getData(); | |
774 if (wqkms == null) | |
775 logger.warn("not waterlevels in artifact"); | |
776 else if (wqkms.length < idx) | |
777 logger.warn("not enough waterlevels in artifact"); | |
778 return wqkms[idx]; | |
779 } | |
780 } | |
781 | |
782 | |
783 /** | |
784 * This method transform a string into an int array. Therefore, the string | |
785 * <i>raw</i> must consist of int values separated by a <i>';'</i>. | |
786 * | |
787 * @param raw The raw integer array as string separated by a ';'. | |
788 * | |
789 * @return an array of int values. | |
790 */ | |
791 public static int[] intArrayFromString(String raw) { | |
792 String[] splitted = raw != null ? raw.split(";") : null; | |
793 | |
794 if (splitted == null || splitted.length == 0) { | |
795 logger.warn("No integer values found in '" + raw + "'"); | |
796 return new int[0]; | |
797 } | |
798 | |
799 TIntArrayList integers = new TIntArrayList(splitted.length); | |
800 | |
801 for (String value: splitted) { | |
802 try { | |
803 integers.add(Integer.valueOf(value)); | |
804 } | |
805 catch (NumberFormatException nfe) { | |
806 logger.warn("Parsing integer failed: " + nfe); | |
807 } | |
808 } | |
809 | |
810 return integers.toNativeArray(); | |
811 } | |
812 | |
813 | |
814 /** | |
815 * This method transform a string into an double array. Therefore, the | |
816 * string <i>raw</i> must consist of double values separated by a | |
817 * <i>';'</i>. | |
818 * | |
819 * @param raw The raw double array as string separated by a ';'. | |
820 * | |
821 * @return an array of double values. | |
822 */ | |
823 public static double[] doubleArrayFromString(String raw) { | |
824 String[] splitted = raw != null ? raw.split(";") : null; | |
825 | |
826 if (splitted == null || splitted.length == 0) { | |
827 logger.warn("No double values found in '" + raw + "'"); | |
828 return new double[0]; | |
829 } | |
830 | |
831 TDoubleArrayList doubles = new TDoubleArrayList(splitted.length); | |
832 | |
833 for (String value: splitted) { | |
834 try { | |
835 doubles.add(Double.valueOf(value)); | |
836 } | |
837 catch (NumberFormatException nfe) { | |
838 logger.warn("Parsing double failed: " + nfe); | |
839 } | |
840 } | |
841 | |
842 return doubles.toNativeArray(); | |
843 } | |
844 } | |
845 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |