comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQSelect.java @ 3812:f788d2d901d6

merged flys-artifacts/pre2.6-2011-12-05
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:53 +0200
parents 8a2cbf947395
children 6762f54b23b1
comparison
equal deleted inserted replaced
3808:5fab0fe3c445 3812:f788d2d901d6
1 package de.intevation.flys.artifacts.states;
2
3 import java.text.NumberFormat;
4
5 import gnu.trove.TDoubleArrayList;
6
7 import org.apache.log4j.Logger;
8
9 import org.w3c.dom.Element;
10
11 import de.intevation.artifacts.Artifact;
12 import de.intevation.artifacts.CallContext;
13
14 import de.intevation.artifacts.common.utils.XMLUtils;
15 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
16
17 import de.intevation.artifactdatabase.ProtocolUtils;
18 import de.intevation.artifactdatabase.data.StateData;
19
20 import de.intevation.flys.model.Gauge;
21 import de.intevation.flys.model.River;
22 import de.intevation.flys.model.Wst;
23
24 import de.intevation.flys.artifacts.FLYSArtifact;
25 import de.intevation.flys.artifacts.WINFOArtifact;
26
27 import de.intevation.flys.artifacts.model.WstFactory;
28 import de.intevation.flys.artifacts.resources.Resources;
29
30 import de.intevation.flys.utils.FLYSUtils;
31
32
33 /**
34 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
35 */
36 public class WQSelect extends DefaultState {
37
38 /** The logger used in this class. */
39 private static Logger logger = Logger.getLogger(WQSelect.class);
40
41
42 /** The default step width for Qs. */
43 public static final String DEFAULT_STEP_Q = "50";
44
45 /** The default step width for Qs. */
46 public static final String DEFAULT_STEP_W = "30";
47
48 /** The name of the 'mode' field. */
49 public static final String WQ_MODE = "wq_mode";
50
51 /** Them name fo the 'free' field. */
52 public static final String WQ_FREE = "wq_free";
53
54 /** The name of the 'selection' field. */
55 public static final String WQ_SELECTION = "wq_selection";
56
57 /** The name of the 'from' field. */
58 public static final String WQ_FROM = "wq_from";
59
60 /** The name of the 'to' field. */
61 public static final String WQ_TO = "wq_to";
62
63 /** The name of the 'step' field. */
64 public static final String WQ_STEP = "wq_step";
65
66 /** The name of the 'single' field. */
67 public static final String WQ_SINGLE = "wq_single";
68
69
70 /**
71 * The default constructor that initializes an empty State object.
72 */
73 public WQSelect() {
74 }
75
76
77 @Override
78 protected Element createStaticData(
79 FLYSArtifact flys,
80 ElementCreator creator,
81 CallContext cc,
82 String name,
83 String value,
84 String type
85 ) {
86 if (!name.equals(WQ_SINGLE)) {
87 return super.createStaticData(flys, creator, cc, name, value, type);
88 }
89
90 String mode = flys.getDataAsString(WQ_MODE);
91 String free = flys.getDataAsString(WQ_FREE);
92 if (mode == null || mode.equals("W") || Boolean.valueOf(free)) {
93 return super.createStaticData(flys, creator, cc, name, value, type);
94 }
95
96 WINFOArtifact winfo = (WINFOArtifact) flys;
97
98 Element dataElement = creator.create("data");
99 creator.addAttr(dataElement, "name", name, true);
100 creator.addAttr(dataElement, "type", type, true);
101
102 Element itemElement = creator.create("item");
103 creator.addAttr(itemElement, "value", value, true);
104 creator.addAttr(itemElement, "label", getLabel(winfo, cc, value), true);
105
106 dataElement.appendChild(itemElement);
107
108 return dataElement;
109 }
110
111
112 protected static String getLabel(
113 WINFOArtifact winfo,
114 CallContext cc,
115 String raw
116 ) {
117 String[] values = raw.split(" ");
118 String label = null;
119
120 NumberFormat nf = NumberFormat.getInstance(
121 Resources.getLocale(cc.getMeta()));
122
123 for (String value: values) {
124 try {
125 double v = Double.valueOf(value.trim());
126
127 String tmp = nf.format(v);
128 String mv = FLYSUtils.getNamedMainValue(winfo.getGauge(),v);
129
130 if (mv != null && mv.length() > 0) {
131 String add = mv + ": " + tmp;
132 label = label != null ? label + ", " + add : add;
133 }
134 else {
135 label = label != null ? label + ", " + tmp : tmp;
136 }
137 }
138 catch (NumberFormatException nfe) {
139 // do nothing here
140 }
141 }
142
143 return label;
144 }
145
146
147 @Override
148 protected Element createData(
149 XMLUtils.ElementCreator cr,
150 Artifact artifact,
151 StateData data,
152 CallContext context)
153 {
154 Element select = ProtocolUtils.createArtNode(
155 cr, "select", null, null);
156
157 cr.addAttr(select, "name", data.getName(), true);
158
159 Element label = ProtocolUtils.createArtNode(
160 cr, "label", null, null);
161
162 Element choices = ProtocolUtils.createArtNode(
163 cr, "choices", null, null);
164
165 label.setTextContent(Resources.getMsg(
166 context.getMeta(),
167 data.getName(),
168 data.getName()));
169
170 select.appendChild(label);
171
172 return select;
173 }
174
175
176 @Override
177 protected Element[] createItems(
178 XMLUtils.ElementCreator cr,
179 Artifact artifact,
180 String name,
181 CallContext context)
182 {
183 // TODO Insert correct min/max values!
184 double[] minmaxW = determineMinMaxW(artifact);
185 double[] minmaxQ = determineMinMaxQ(artifact);
186
187 if (name.equals("wq_from")) {
188 Element minW = createItem(
189 cr, new String[] {"minW", new Double(minmaxW[0]).toString()});
190 Element minQ = createItem(
191 cr, new String[] {"minQ", new Double(minmaxQ[0]).toString()});
192 return new Element[] { minW, minQ };
193 }
194 else if (name.equals("wq_to")) {
195 Element maxW = createItem(
196 cr, new String[] {"maxW", new Double(minmaxW[1]).toString()});
197 Element maxQ = createItem(
198 cr, new String[] {"maxQ", new Double(minmaxQ[1]).toString()});
199 return new Element[] { maxW, maxQ };
200 }
201 else {
202 Element stepW = createItem(
203 cr, new String[] {"stepW", DEFAULT_STEP_W});
204 Element stepQ = createItem(
205 cr, new String[] {"stepQ", DEFAULT_STEP_Q});
206 return new Element[] { stepW, stepQ };
207 }
208 }
209
210
211 protected Element createItem(XMLUtils.ElementCreator cr, Object obj) {
212 Element item = ProtocolUtils.createArtNode(cr, "item", null, null);
213 Element label = ProtocolUtils.createArtNode(cr, "label", null, null);
214 Element value = ProtocolUtils.createArtNode(cr, "value", null, null);
215
216 String[] arr = (String[]) obj;
217
218 label.setTextContent(arr[0]);
219 value.setTextContent(arr[1]);
220
221 item.appendChild(label);
222 item.appendChild(value);
223
224 return item;
225 }
226
227
228 @Override
229 protected String getUIProvider() {
230 return "wq_panel";
231 }
232
233
234 /**
235 * Determines the min and max W value for the current gauge. If no min and
236 * max values could be determined, this method will return
237 * [Double.MIN_VALUE, Double.MAX_VALUE].
238 *
239 * @param artifact The FLYSArtifact.
240 *
241 * @return the min and max W values for the current gauge.
242 */
243 protected double[] determineMinMaxW(Artifact artifact) {
244 logger.debug("WQSelect.determineCurrentGauge");
245
246 Gauge gauge = ((WINFOArtifact) artifact).getGauge();
247 double[] minmaxW = gauge != null ? gauge.determineMinMaxW() : null;
248
249 double minW = minmaxW != null ? minmaxW[0] : Double.MIN_VALUE;
250 double maxW = minmaxW != null ? minmaxW[1] : Double.MAX_VALUE;
251
252 return new double[] { minW, maxW };
253 }
254
255
256 /**
257 * Determines the min and max Q value for the current gauge. If no min and
258 * max values could be determined, this method will return
259 * [Double.MIN_VALUE, Double.MAX_VALUE].
260 *
261 * @param artifact The FLYSArtifact.
262 *
263 * @return the min and max Q values for the current gauge.
264 */
265 protected double[] determineMinMaxQ(Artifact artifact) {
266 logger.debug("WQSelect.determineMinMaxQ");
267
268 WINFOArtifact flysArtifact = (WINFOArtifact) artifact;
269
270 River river = FLYSUtils.getRiver(flysArtifact);
271 Gauge gauge = flysArtifact.getGauge();
272 Wst wst = WstFactory.getWst(river);
273
274 double[] minmaxQ = gauge != null
275 ? wst.determineMinMaxQ(gauge.getRange())
276 : null;
277
278 double minQ = minmaxQ != null ? minmaxQ[0] : Double.MIN_VALUE;
279 double maxQ = minmaxQ != null ? minmaxQ[1] : Double.MAX_VALUE;
280
281 return new double[] { minQ, maxQ };
282 }
283
284
285 @Override
286 public boolean validate(Artifact artifact)
287 throws IllegalArgumentException
288 {
289 logger.debug("WQSelect.validate");
290
291 WINFOArtifact flys = (WINFOArtifact) artifact;
292
293 StateData data = getData(flys, WQ_SELECTION);
294 String selectionMode = data != null ? (String) data.getValue() : null;
295
296 if (selectionMode == null || selectionMode.equals("single")) {
297 return validateSingle(artifact);
298 }
299 else {
300 return validateRange(artifact);
301 }
302 }
303
304
305 protected boolean validateBounds(
306 double fromValid, double toValid,
307 double from, double to, double step)
308 throws IllegalArgumentException
309 {
310 logger.debug("RangeState.validateRange");
311
312 if (from < fromValid) {
313 logger.error(
314 "Invalid 'from'. " + from + " is smaller than " + fromValid);
315 throw new IllegalArgumentException("error_feed_from_out_of_range");
316 }
317 else if (to > toValid) {
318 logger.error(
319 "Invalid 'to'. " + to + " is bigger than " + toValid);
320 throw new IllegalArgumentException("error_feed_to_out_of_range");
321 }
322
323 return true;
324 }
325
326
327 protected boolean validateSingle(Artifact artifact)
328 throws IllegalArgumentException
329 {
330 logger.debug("WQSelect.validateSingle");
331
332 WINFOArtifact flys = (WINFOArtifact) artifact;
333 StateData data = getData(flys, WQ_SINGLE);
334
335 String tmp = data != null ? (String) data.getValue() : null;
336
337 if (tmp == null || tmp.length() == 0) {
338 throw new IllegalArgumentException("error_empty_state");
339 }
340
341 String[] strValues = tmp.split(" ");
342 TDoubleArrayList all = new TDoubleArrayList();
343
344 for (String strValue: strValues) {
345 try {
346 all.add(Double.parseDouble(strValue));
347 }
348 catch (NumberFormatException nfe) {
349 logger.warn(nfe, nfe);
350 }
351 }
352
353 all.sort();
354
355 StateData dMode = getData(flys, WQ_MODE);
356 String mode = dMode != null ? (String) data.getValue() : null;
357
358 logger.debug("WQ Mode: " + mode);
359
360 double[] minmax = null;
361
362 if (mode != null && mode.trim().toLowerCase().equals("w")) {
363 minmax = determineMinMaxW(artifact);
364 }
365 else {
366 minmax = determineMinMaxQ(artifact);
367 }
368
369 double min = all.get(0);
370 double max = all.get(all.size()-1);
371
372 logger.debug("Inserted min value = " + min);
373 logger.debug("Inserted max value = " + max);
374
375 return validateBounds(minmax[0], minmax[1], min, max, 0d);
376 }
377
378
379 protected boolean validateRange(Artifact artifact)
380 throws IllegalArgumentException
381 {
382 logger.debug("WQSelect.validateRange");
383 WINFOArtifact flys = (WINFOArtifact) artifact;
384
385 StateData data = flys.getData(WQ_MODE);
386 String mode = data != null ? (String) data.getValue() : null;
387 logger.debug("WQ Mode: " + mode);
388
389 if (mode == null || mode.length() == 0) {
390 throw new IllegalArgumentException("error_feed_invalid_wq_mode");
391 }
392
393 StateData dFrom = flys.getData(WQ_FROM);
394 StateData dTo = flys.getData(WQ_TO);
395 StateData dStep = flys.getData(WQ_STEP);
396
397 String fromStr = dFrom != null ? (String) dFrom.getValue() : null;
398 String toStr = dTo != null ? (String) dTo.getValue() : null;
399 String stepStr = dStep != null ? (String) dStep.getValue() : null;
400
401 if (fromStr == null || toStr == null || stepStr == null) {
402 throw new IllegalArgumentException("error_empty_state");
403 }
404
405 try {
406 double from = Double.parseDouble(fromStr);
407 double to = Double.parseDouble(toStr);
408 double step = Double.parseDouble(stepStr);
409
410 if (mode != null && mode.trim().toLowerCase().equals("w")) {
411 return validateW(artifact, from, to, step);
412 }
413 else if (mode != null && mode.trim().toLowerCase().equals("q")) {
414 return validateQ(artifact, from, to, step);
415 }
416 else {
417 throw new IllegalArgumentException(
418 "error_feed_invalid_wq_mode");
419 }
420 }
421 catch (NumberFormatException nfe) {
422 throw new IllegalArgumentException("error_feed_number_format");
423 }
424 }
425
426
427 /**
428 * Validates the inserted W values.
429 *
430 * @param artifact The owner artifact.
431 * @param from The lower value of the W range.
432 * @param to The upper value of the W range.
433 * @param step The step width.
434 *
435 * @return true, if everything was fine, otherwise an exception is thrown.
436 */
437 protected boolean validateW(
438 Artifact artifact,
439 double from,
440 double to,
441 double step)
442 throws IllegalArgumentException
443 {
444 logger.debug("WQSelect.validateW");
445
446 double[] minmaxW = determineMinMaxW(artifact);
447
448 return validateBounds(minmaxW[0], minmaxW[1], from, to, step);
449 }
450
451
452 /**
453 * Validates the inserted Q values.
454 *
455 * @param artifact The owner artifact.
456 * @param from The lower value of the Q range.
457 * @param to The upper value of the Q range.
458 * @param step The step width.
459 *
460 * @return true, if everything was fine, otherwise an exception is thrown.
461 */
462 protected boolean validateQ(
463 Artifact artifact,
464 double from,
465 double to,
466 double step)
467 throws IllegalArgumentException
468 {
469 logger.debug("WQSelect.validateQ");
470
471 double[] minmaxQ = determineMinMaxQ(artifact);
472
473 return validateBounds(minmaxQ[0], minmaxQ[1], from, to, step);
474 }
475 }
476 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org