Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | 078ba6799bd2 |
children | dde7f51dbe1e |
comparison
equal
deleted
inserted
replaced
590:5f5f273c8566 | 657:af3f56758f59 |
---|---|
1 package de.intevation.gnv.state; | |
2 | |
3 import de.intevation.artifactdatabase.Config; | |
4 import de.intevation.artifactdatabase.XMLUtils; | |
5 | |
6 import de.intevation.artifacts.ArtifactNamespaceContext; | |
7 import de.intevation.artifacts.CallContext; | |
8 import de.intevation.artifacts.CallMeta; | |
9 | |
10 import de.intevation.gnv.artifacts.cache.CacheFactory; | |
11 | |
12 import de.intevation.gnv.artifacts.ressource.RessourceFactory; | |
13 | |
14 import de.intevation.gnv.geobackend.base.Result; | |
15 | |
16 import de.intevation.gnv.geobackend.base.query.QueryExecutor; | |
17 import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; | |
18 | |
19 import de.intevation.gnv.geobackend.base.query.exception.QueryException; | |
20 | |
21 import de.intevation.gnv.geobackend.util.DateUtils; | |
22 | |
23 import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; | |
24 import de.intevation.gnv.state.describedata.KeyValueDescibeData; | |
25 import de.intevation.gnv.state.describedata.MinMaxDescribeData; | |
26 import de.intevation.gnv.state.describedata.NamedArrayList; | |
27 import de.intevation.gnv.state.describedata.NamedCollection; | |
28 import de.intevation.gnv.state.describedata.SingleValueDescribeData; | |
29 | |
30 import de.intevation.gnv.state.exception.StateException; | |
31 | |
32 import de.intevation.gnv.utils.InputValidator; | |
33 | |
34 import java.util.ArrayList; | |
35 import java.util.Arrays; | |
36 import java.util.Collection; | |
37 import java.util.Date; | |
38 import java.util.GregorianCalendar; | |
39 import java.util.HashMap; | |
40 import java.util.Iterator; | |
41 import java.util.List; | |
42 import java.util.Map; | |
43 | |
44 import javax.xml.xpath.XPathConstants; | |
45 | |
46 import net.sf.ehcache.Cache; | |
47 | |
48 import org.apache.log4j.Logger; | |
49 | |
50 import org.w3c.dom.Document; | |
51 import org.w3c.dom.Element; | |
52 import org.w3c.dom.Node; | |
53 import org.w3c.dom.NodeList; | |
54 | |
55 /** | |
56 * @author Tim Englich (tim.englich@intevation.de) | |
57 * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) | |
58 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) | |
59 */ | |
60 public abstract class StateBase implements State { | |
61 | |
62 /** | |
63 * The UID of this Class | |
64 */ | |
65 private static final long serialVersionUID = 2411169179001645426L; | |
66 | |
67 /** | |
68 * the logger, used to log exceptions and additonaly information | |
69 */ | |
70 private static Logger log = Logger.getLogger(StateBase.class); | |
71 | |
72 protected final static String MINVALUEFIELDNAME = "minvalue"; | |
73 protected final static String MAXVALUEFIELDNAME = "maxvalue"; | |
74 | |
75 private final static String NODATASELECTIONKEY = "n/n"; | |
76 | |
77 public final static String DESCRIBEDATAKEY = "_DESCRIBEDATA"; | |
78 | |
79 public final static String XPATH_STATIC_UI = "art:static"; | |
80 public final static String XPATH_DYNAMIC_UI = "art:dynamic"; | |
81 | |
82 /** input value names which should not be rendered from State itself */ | |
83 public final static String[] BLACKLIST = {"sourceid", "fisname"}; | |
84 | |
85 private String id = null; | |
86 | |
87 protected String hash; | |
88 | |
89 private String description = null; | |
90 | |
91 protected String dataName = null; | |
92 | |
93 protected String preSettingsName = null; | |
94 | |
95 protected boolean dataMultiSelect = false; | |
96 | |
97 protected boolean dataNoSelect = false; | |
98 | |
99 protected String queryID = null; | |
100 | |
101 protected Collection<String> inputValueNames = null; | |
102 | |
103 protected Map<String, InputValue> inputValues = null; | |
104 | |
105 protected State parent = null; | |
106 | |
107 protected Map<String, InputData> inputData = null; | |
108 | |
109 protected Map<String, InputData> preSettings = null; | |
110 | |
111 /** | |
112 * Constructor | |
113 */ | |
114 public StateBase() { | |
115 super(); | |
116 } | |
117 | |
118 /** | |
119 * @see de.intevation.gnv.state.State#getID() | |
120 */ | |
121 public String getID() { | |
122 return this.id; | |
123 } | |
124 | |
125 /** | |
126 * @see de.intevation.gnv.state.State#getDescription() | |
127 */ | |
128 public String getDescription() { | |
129 return this.description; | |
130 } | |
131 | |
132 | |
133 | |
134 /** | |
135 * @see de.intevation.gnv.state.State#getRequiredInputValues() | |
136 */ | |
137 public Collection<InputValue> getRequiredInputValues() { | |
138 return this.inputValues.values(); | |
139 } | |
140 | |
141 | |
142 public void reset(String uuid) { | |
143 inputData.remove(dataName); | |
144 } | |
145 | |
146 | |
147 /** | |
148 * @see de.intevation.gnv.state.State#setup(org.w3c.dom.Node) | |
149 */ | |
150 public void setup(Node configuration) { | |
151 this.id = ((Element)configuration).getAttribute("id"); | |
152 this.description = ((Element)configuration).getAttribute("description"); | |
153 | |
154 log.info("State-ID = " + this.id); | |
155 | |
156 NodeList inputValuesNodes = Config.getNodeSetXPath(configuration, | |
157 "inputvalues/inputvalue"); | |
158 this.inputValues = new HashMap<String, InputValue>(inputValuesNodes | |
159 .getLength()); | |
160 this.inputValueNames = new ArrayList<String>(inputValuesNodes | |
161 .getLength()); | |
162 for (int i = 0; i < inputValuesNodes.getLength(); i++) { | |
163 Element inputValueNode = (Element)inputValuesNodes.item(i); | |
164 String usedinQueryValue = inputValueNode.getAttribute("usedinquery"); | |
165 int usedinQuery = 1; | |
166 if (usedinQueryValue != null) { | |
167 try { | |
168 usedinQuery = Integer.parseInt(usedinQueryValue); | |
169 } catch (NumberFormatException e) { | |
170 log | |
171 .warn("Used in Query Value cannot be transformed into a Number"); | |
172 } | |
173 } | |
174 InputValue inputValue = new DefaultInputValue(inputValueNode.getAttribute("name"), | |
175 inputValueNode.getAttribute("type"), | |
176 Boolean.parseBoolean(inputValueNode. | |
177 getAttribute("multiselect")), usedinQuery); | |
178 this.inputValues.put(inputValue.getName(), inputValue); | |
179 this.inputValueNames.add(inputValue.getName()); | |
180 } | |
181 | |
182 this.queryID = Config.getStringXPath(configuration, "queryID"); | |
183 log.info("QueryID ==> " + this.queryID); | |
184 | |
185 this.dataName = Config.getStringXPath(configuration, "dataname"); | |
186 | |
187 String dataMultiSelectValue = Config.getStringXPath(configuration, | |
188 "data-multiselect"); | |
189 if (dataMultiSelectValue != null) { | |
190 this.dataMultiSelect = Boolean.parseBoolean(dataMultiSelectValue); | |
191 } | |
192 | |
193 String dataNoSelectValue =Config.getStringXPath(configuration, | |
194 "data-noselect"); | |
195 if (dataNoSelectValue != null) { | |
196 this. dataNoSelect = Boolean.parseBoolean(dataNoSelectValue); | |
197 } | |
198 | |
199 this.preSettingsName = Config.getStringXPath(configuration, "presettings-name"); | |
200 | |
201 } | |
202 | |
203 /** | |
204 * @see de.intevation.gnv.state.State#getParent() | |
205 */ | |
206 public State getParent() { | |
207 return this.parent; | |
208 } | |
209 | |
210 /** | |
211 * @see de.intevation.gnv.state.State#setParent(de.intevation.gnv.state.State) | |
212 */ | |
213 public void setParent(State state) { | |
214 this.parent = state; | |
215 } | |
216 | |
217 | |
218 public void feed(Collection<InputData> inputData, String uuid) | |
219 throws StateException | |
220 { | |
221 if (inputData != null) { | |
222 Iterator<InputData> it = inputData.iterator(); | |
223 InputValidator iv = new InputValidator(); | |
224 while (it.hasNext()) { | |
225 InputData tmpItem = it.next(); | |
226 InputValue inputValue = this.inputValues.get(tmpItem.getName()); | |
227 if (inputValue != null) { | |
228 if (this.inputData == null) { | |
229 this.inputData = new HashMap<String, InputData>( | |
230 inputData.size()); | |
231 } | |
232 | |
233 boolean valid = iv.isInputValid(tmpItem.getValue(), | |
234 inputValue.getType()); | |
235 if (valid) { | |
236 String[] desc = getDescriptionForInputData(tmpItem, uuid); | |
237 tmpItem.setDescription(desc); | |
238 this.inputData.put(tmpItem.getName(), tmpItem); | |
239 } else { | |
240 String errMsg = "Wrong input for " + tmpItem.getValue() | |
241 + " is not an " + inputValue.getType() | |
242 + " Value."; | |
243 log.warn(errMsg); | |
244 throw new StateException(errMsg); | |
245 } | |
246 | |
247 } else { | |
248 String errMsg = "No Inputvalue given for Inputdata " | |
249 + tmpItem.getName(); | |
250 log.warn(errMsg + "Value will be ignored"); | |
251 | |
252 } | |
253 } | |
254 } else { | |
255 log.warn("No Inputdata given"); | |
256 } | |
257 } | |
258 | |
259 | |
260 private String[] getDescriptionForInputData(InputData data, String uuid) { | |
261 // there is only one element in the list, so take the first | |
262 Object obj = getDescibeData(uuid).get(0); | |
263 List descs = new ArrayList(); | |
264 | |
265 if (obj instanceof NamedArrayList) { | |
266 NamedArrayList list = (NamedArrayList) obj; | |
267 List selected = Arrays.asList(data.splitValue()); | |
268 int size = list.size(); | |
269 | |
270 for (int i = 0; i < size; i++) { | |
271 KeyValueDescibeData kv = (KeyValueDescibeData) list.get(i); | |
272 | |
273 // values are concatinated in InputData, so one InputData object can | |
274 // contain many input | |
275 String key = kv.getKey(); | |
276 int idx = selected.indexOf(key); | |
277 if (idx >= 0) { | |
278 descs.add(kv.getValue()); | |
279 | |
280 // XXX Workarround: I just wanted to remove the element at | |
281 // 'idx' from selected, but for any reason this is not | |
282 // possible (throws an exception) (iw) | |
283 List tmp = new ArrayList(); | |
284 for (int j = 0; j < selected.size(); j++) { | |
285 if (j != idx) | |
286 tmp.add(selected.get(j)); | |
287 } | |
288 | |
289 selected = tmp; | |
290 } | |
291 } | |
292 } | |
293 | |
294 return (String[]) descs.toArray(new String[descs.size()]); | |
295 } | |
296 | |
297 | |
298 /** | |
299 * @see de.intevation.gnv.state.State#putInputData(java.util.Collection) | |
300 */ | |
301 public void putInputData(Collection<InputData> inputData, String uuid) | |
302 throws StateException { | |
303 if (inputData != null) { | |
304 Iterator<InputData> it = inputData.iterator(); | |
305 InputValidator iv = new InputValidator(); | |
306 while (it.hasNext()) { | |
307 InputData tmpItem = it.next(); | |
308 InputValue inputValue = this.inputValues.get(tmpItem.getName()); | |
309 if (inputValue != null) { | |
310 if (this.inputData == null) { | |
311 this.inputData = new HashMap<String, InputData>( | |
312 inputData.size()); | |
313 } | |
314 | |
315 boolean valid = iv.isInputValid(tmpItem.getValue(), | |
316 inputValue.getType()); | |
317 if (valid) { | |
318 if (tmpItem.getName().equals(MINVALUEFIELDNAME)){ | |
319 String minValue = tmpItem.getValue(); | |
320 String maxValue = this.getInputValue4ID(inputData, MAXVALUEFIELDNAME); | |
321 valid = iv.isInputValid(maxValue,inputValue.getType()); | |
322 if (!valid){ | |
323 String errMsg = "Wrong input for " + tmpItem.getValue() | |
324 + " is not an " + inputValue.getType() | |
325 + " Value."; | |
326 log.warn(errMsg); | |
327 throw new StateException(errMsg); | |
328 } | |
329 | |
330 valid = iv.isInputValid(minValue, | |
331 maxValue, | |
332 inputValue.getType()); | |
333 if (!valid){ | |
334 String errMsg = "MaxValue-Input is less than MinValue-Input "; | |
335 log.warn(errMsg); | |
336 throw new StateException(errMsg); | |
337 } | |
338 }else if (tmpItem.getName().equals(MAXVALUEFIELDNAME)){ | |
339 String minValue = this.getInputValue4ID(inputData, MINVALUEFIELDNAME); | |
340 String maxValue = tmpItem.getValue(); | |
341 valid = iv.isInputValid(minValue,inputValue.getType()); | |
342 if (!valid){ | |
343 String errMsg = "Wrong input for " + tmpItem.getValue() | |
344 + " is not an " + inputValue.getType() | |
345 + " Value."; | |
346 log.warn(errMsg); | |
347 throw new StateException(errMsg); | |
348 } | |
349 | |
350 valid = iv.isInputValid(minValue, | |
351 maxValue, | |
352 inputValue.getType()); | |
353 if (!valid){ | |
354 String errMsg = "MaxValue-Input is less than MinValue-Input "; | |
355 log.warn(errMsg); | |
356 throw new StateException(errMsg); | |
357 } | |
358 } | |
359 this.inputData.put(tmpItem.getName(), tmpItem); | |
360 } else { | |
361 String errMsg = "Wrong input for " + tmpItem.getValue() | |
362 + " is not an " + inputValue.getType() | |
363 + " Value."; | |
364 log.warn(errMsg); | |
365 throw new StateException(errMsg); | |
366 } | |
367 | |
368 } else { | |
369 String errMsg = "No Inputvalue given for Inputdata " | |
370 + tmpItem.getName(); | |
371 log.warn(errMsg + "Value will be ignored"); | |
372 | |
373 } | |
374 } | |
375 } else { | |
376 log.warn("No Inputdata given"); | |
377 } | |
378 | |
379 setHash(uuid); | |
380 } | |
381 | |
382 | |
383 /** | |
384 * | |
385 * @see de.intevation.gnv.state.State#setPreSettings(java.util.Map) | |
386 */ | |
387 public void setPreSettings(Map<String, InputData> preSettings) { | |
388 this.preSettings = preSettings; | |
389 } | |
390 | |
391 | |
392 | |
393 public Map<String, InputData> getPreSettings() { | |
394 return this.preSettings; | |
395 } | |
396 | |
397 protected String getInputValue4ID(Collection<InputData> inputData, String inputName){ | |
398 Iterator<InputData> it = inputData.iterator(); | |
399 while (it.hasNext()) { | |
400 InputData tmpItem = it.next(); | |
401 if (tmpItem.getName().equals(inputName)){ | |
402 return tmpItem.getValue(); | |
403 } | |
404 } | |
405 return null; | |
406 } | |
407 | |
408 | |
409 /** | |
410 * @see de.intevation.gnv.state.State#advance(java.lang.String, | |
411 * de.intevation.artifacts.CallMeta) | |
412 */ | |
413 public void advance(String uuid, CallContext context) | |
414 throws StateException | |
415 { | |
416 } | |
417 | |
418 public void initialize(String uuid, CallContext context) | |
419 throws StateException | |
420 { | |
421 } | |
422 | |
423 /** | |
424 * @return | |
425 */ | |
426 protected String[] generateFilterValuesFromInputData() { | |
427 List<String> list = new ArrayList<String>(); | |
428 Iterator<String> it = this.inputValueNames.iterator(); | |
429 while (it.hasNext()) { | |
430 String value = it.next(); | |
431 InputData data = this.inputData.get(value); | |
432 if (data != null | |
433 && this.inputValues.containsKey(data.getName())) { | |
434 int size = this.inputValues.get(data.getName()) | |
435 .usedInQueries(); | |
436 String type = this.inputValues.get(data.getName()) | |
437 .getType(); | |
438 String requestValue = data.getValue(); | |
439 if (type.equalsIgnoreCase("string")) { | |
440 requestValue = this | |
441 .prepareInputData4DBQuery(requestValue); | |
442 } else if (type.equalsIgnoreCase("date")) { | |
443 requestValue = this | |
444 .prepareInputData4DateDBQuery(requestValue); | |
445 } else if (type.equalsIgnoreCase("coordinate")){ | |
446 requestValue = this | |
447 .prepareInputData4RegionDBQuery(requestValue); | |
448 } | |
449 for (int j = 0; j < size; j++) { | |
450 list.add(requestValue); | |
451 } | |
452 } | |
453 } | |
454 String[] filterValues = list.toArray(new String[list.size()]); | |
455 return filterValues; | |
456 } | |
457 | |
458 protected String prepareInputData4RegionDBQuery(String value){ | |
459 return value; | |
460 } | |
461 | |
462 private String prepareInputData4DateDBQuery(String value) { | |
463 if (value != null) { | |
464 String[] values = value.split(","); | |
465 String newValue = ""; | |
466 for (int i = 0; i < values.length; i++) { | |
467 if (newValue.length() > 0) { | |
468 newValue = newValue + " , "; | |
469 } | |
470 // TODO JUST HACK FIND A BETTER RESOLUTION | |
471 newValue = newValue + "to_date('" + values[i].trim() | |
472 + "', 'YYYY.MM.DD HH24:MI:SS')"; | |
473 } | |
474 return newValue; | |
475 } | |
476 | |
477 return value; | |
478 } | |
479 | |
480 private String prepareInputData4DBQuery(String value) { | |
481 if (value != null) { | |
482 String[] values = value.split(","); | |
483 String newValue = ""; | |
484 for (int i = 0; i < values.length; i++) { | |
485 if (newValue.length() > 0) { | |
486 newValue = newValue + " , "; | |
487 } | |
488 newValue = newValue + "'" + values[i].trim() + "'"; | |
489 } | |
490 return newValue; | |
491 } | |
492 | |
493 return value; | |
494 | |
495 } | |
496 | |
497 /** | |
498 * @param result | |
499 */ | |
500 protected List<Object> purifyResult(Collection<Result> result, String uuid) { | |
501 List<Object> describeData = new ArrayList<Object>(); | |
502 | |
503 NamedCollection<KeyValueDescibeData> keyValueDescibeData = | |
504 extractKVP(result, "KEY", "VALUE"); | |
505 | |
506 describeData.add(keyValueDescibeData); | |
507 | |
508 return describeData; | |
509 } | |
510 | |
511 /** | |
512 * @param result | |
513 * @return | |
514 */ | |
515 protected NamedCollection<KeyValueDescibeData> extractKVP(Collection<Result> result, | |
516 String keyid, | |
517 String valueid) { | |
518 Iterator<Result> rit = result.iterator(); | |
519 int dataSize = (this.dataNoSelect ? result.size()+1 : result.size()); | |
520 | |
521 NamedCollection<KeyValueDescibeData> keyValueDescibeData = new NamedArrayList<KeyValueDescibeData>( | |
522 this.dataName, dataSize); | |
523 keyValueDescibeData.setMultiSelect(this.dataMultiSelect); | |
524 | |
525 if (this.dataNoSelect){ | |
526 keyValueDescibeData.add(new DefaultKeyValueDescribeData( | |
527 NODATASELECTIONKEY, | |
528 "No Selection", | |
529 getID() | |
530 )); | |
531 } | |
532 | |
533 boolean initialized = false; | |
534 int keyPos = 0; | |
535 int valuePos = 1; | |
536 String previousKey = null; | |
537 InputData preSettingsData = | |
538 (this.preSettings != null && this.preSettingsName != null) | |
539 ? this.preSettings.get(this.preSettingsName) | |
540 : null; | |
541 boolean filterWithPresettings = preSettingsData != null; | |
542 | |
543 List<String> preSettingValues = null; | |
544 if(filterWithPresettings){ | |
545 preSettingValues = Arrays.asList(preSettingsData.splitValue()); | |
546 } | |
547 while (rit.hasNext()) { | |
548 Result resultValue = rit.next(); | |
549 if (!initialized){ | |
550 keyPos = resultValue.getResultDescriptor().getColumnIndex(keyid); | |
551 valuePos = resultValue.getResultDescriptor().getColumnIndex(valueid); | |
552 if (valuePos < 0){ | |
553 valuePos = 1; | |
554 } | |
555 initialized = true; | |
556 } | |
557 String tmpKey = resultValue.getString(keyPos); | |
558 | |
559 // TODO: FIXME: We have to do that because the arcsde does not | |
560 // support a distinct Query on Layers. | |
561 if (previousKey == null || !tmpKey.equals(previousKey)){ | |
562 previousKey = tmpKey; | |
563 if (!filterWithPresettings || preSettingValues.contains(tmpKey)){ | |
564 keyValueDescibeData.add( | |
565 new DefaultKeyValueDescribeData( | |
566 tmpKey, | |
567 resultValue.getString(valuePos), | |
568 getID()) | |
569 ); | |
570 } | |
571 } | |
572 } | |
573 return keyValueDescibeData; | |
574 } | |
575 | |
576 | |
577 public static boolean inBlackList(String key) { | |
578 int length = BLACKLIST.length; | |
579 for (int i = 0; i < length; i++) { | |
580 if (BLACKLIST[i].equals(key)) { | |
581 return true; | |
582 } | |
583 } | |
584 | |
585 return false; | |
586 } | |
587 | |
588 /** | |
589 * @see de.intevation.gnv.state.State#describe(org.w3c.dom.Document, | |
590 * org.w3c.dom.Node, de.intevation.artifacts.CallMeta, | |
591 * java.lang.String) | |
592 */ | |
593 public void describe( | |
594 Document document, | |
595 Node rootNode, | |
596 CallContext context, | |
597 String uuid) | |
598 { | |
599 XMLUtils.ElementCreator xCreator = new XMLUtils.ElementCreator( | |
600 document, | |
601 XMLUtils.XFORM_URL, | |
602 XMLUtils.XFORM_PREFIX | |
603 ); | |
604 | |
605 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( | |
606 document, | |
607 ArtifactNamespaceContext.NAMESPACE_URI, | |
608 ArtifactNamespaceContext.NAMESPACE_PREFIX | |
609 ); | |
610 | |
611 // append dynamic node | |
612 Node dynamic = (Node) XMLUtils.xpath( | |
613 rootNode, | |
614 XPATH_DYNAMIC_UI, | |
615 XPathConstants.NODE, | |
616 ArtifactNamespaceContext.INSTANCE | |
617 ); | |
618 | |
619 describeDynamic( | |
620 creator, xCreator, document, dynamic, context, uuid); | |
621 | |
622 // append static nodes | |
623 Node staticNode = (Node) XMLUtils.xpath( | |
624 rootNode, | |
625 XPATH_STATIC_UI, | |
626 XPathConstants.NODE, | |
627 ArtifactNamespaceContext.INSTANCE | |
628 ); | |
629 | |
630 State parent = getParent(); | |
631 if (parent != null && parent instanceof StateBase) { | |
632 ((StateBase) parent).describeStatic( | |
633 creator,xCreator, document, staticNode, context,uuid); | |
634 } | |
635 } | |
636 | |
637 | |
638 protected void describeDynamic( | |
639 XMLUtils.ElementCreator artCreator, | |
640 XMLUtils.ElementCreator creator, | |
641 Document document, | |
642 Node dynamic, | |
643 CallContext context, | |
644 String uuid) | |
645 { | |
646 CallMeta callMeta = context.getMeta(); | |
647 | |
648 if (dataName == null) | |
649 return; | |
650 | |
651 List<Object> descibeData = getDescibeData(uuid); | |
652 if (descibeData != null) { | |
653 Iterator<Object> it = descibeData.iterator(); | |
654 | |
655 while (it.hasNext()) { | |
656 Object o = it.next(); | |
657 if ((!it.hasNext() && dataName != null)) { | |
658 appendToDynamicNode( | |
659 artCreator, creator, document, dynamic, callMeta, o); | |
660 } | |
661 } | |
662 } | |
663 } | |
664 | |
665 | |
666 protected void describeStatic( | |
667 XMLUtils.ElementCreator artCreator, | |
668 XMLUtils.ElementCreator creator, | |
669 Document document, | |
670 Node staticNode, | |
671 CallContext context, | |
672 String uuid) | |
673 { | |
674 State parent = getParent(); | |
675 if (parent != null && parent instanceof StateBase) { | |
676 ((StateBase) parent).describeStatic( | |
677 artCreator, creator, document, staticNode, context, uuid); | |
678 } | |
679 | |
680 CallMeta callMeta = context.getMeta(); | |
681 appendToStaticNode(artCreator, creator, document, staticNode, callMeta); | |
682 } | |
683 | |
684 | |
685 protected void appendToStaticNode( | |
686 XMLUtils.ElementCreator artCreator, | |
687 XMLUtils.ElementCreator creator, | |
688 Document document, | |
689 Node staticNode, | |
690 CallMeta callMeta | |
691 ) { | |
692 InputData data = inputData.get(dataName); | |
693 | |
694 if (data == null) { | |
695 return; | |
696 } | |
697 | |
698 Element selectNode = creator.create("select1"); | |
699 creator.addAttr(selectNode, "ref", dataName); | |
700 | |
701 Element lableNode = creator.create("label"); | |
702 lableNode.setTextContent(RessourceFactory.getInstance() | |
703 .getRessource(callMeta.getLanguages(), dataName, dataName)); | |
704 Element choiceNode = creator.create("choices"); | |
705 | |
706 artCreator.addAttr( | |
707 selectNode, "state", getID(), true | |
708 ); | |
709 | |
710 String[] descriptions = data.getDescription(); | |
711 int size = descriptions.length; | |
712 | |
713 for (int i = 0; i < size; i++) { | |
714 Element itemNode = creator.create("item"); | |
715 String value = data.getValue(); | |
716 String desc = descriptions[i]; | |
717 desc = desc == null ? value : desc; | |
718 | |
719 creator.addAttr(itemNode, "selected", "true"); | |
720 | |
721 Element choiceLableNode = creator.create("label"); | |
722 choiceLableNode.setTextContent(desc); | |
723 itemNode.appendChild(choiceLableNode); | |
724 | |
725 Element choiceValueNode = creator.create("value"); | |
726 choiceValueNode.setTextContent(value); | |
727 itemNode.appendChild(choiceValueNode); | |
728 choiceNode.appendChild(itemNode); | |
729 } | |
730 | |
731 selectNode.appendChild(lableNode); | |
732 selectNode.appendChild(choiceNode); | |
733 | |
734 staticNode.appendChild(selectNode); | |
735 } | |
736 | |
737 | |
738 protected void appendToDynamicNode( | |
739 XMLUtils.ElementCreator artCreator, | |
740 XMLUtils.ElementCreator creator, | |
741 Document document, | |
742 Node dynamicNode, | |
743 CallMeta callMeta, | |
744 Object o | |
745 ) { | |
746 if (o instanceof Collection<?>) { | |
747 String name = null; | |
748 boolean multiselect = false; | |
749 if (o instanceof NamedCollection<?>) { | |
750 NamedCollection<?> nc = ((NamedCollection<?>) o); | |
751 name = nc.getName(); | |
752 multiselect = nc.isMultiSelect(); | |
753 } else { | |
754 Object[] names = this.inputValueNames.toArray(); | |
755 name = names[names.length - 1].toString(); | |
756 } | |
757 | |
758 Element selectNode = creator.create(multiselect?"select":"select1"); | |
759 creator.addAttr(selectNode, "ref", name); | |
760 | |
761 Element lableNode = creator.create("label"); | |
762 lableNode.setTextContent(RessourceFactory.getInstance() | |
763 .getRessource(callMeta.getLanguages(), name, name)); | |
764 Element choiceNode = creator.create("choices"); | |
765 | |
766 Collection<KeyValueDescibeData> values = (Collection<KeyValueDescibeData>) o; | |
767 Iterator<KeyValueDescibeData> resultIt = values.iterator(); | |
768 while (resultIt.hasNext()) { | |
769 KeyValueDescibeData result = resultIt.next(); | |
770 Element itemNode = creator.create("item"); | |
771 | |
772 if (result.isSelected()) { | |
773 itemNode.setAttribute("selected", "true"); | |
774 } | |
775 | |
776 Element choiceLableNode = creator.create("label"); | |
777 choiceLableNode.setTextContent(result.getValue()); | |
778 itemNode.appendChild(choiceLableNode); | |
779 | |
780 Element choicValueNode = creator.create("value"); | |
781 choicValueNode.setTextContent("" + result.getKey()); | |
782 itemNode.appendChild(choicValueNode); | |
783 choiceNode.appendChild(itemNode); | |
784 } | |
785 selectNode.appendChild(lableNode); | |
786 selectNode.appendChild(choiceNode); | |
787 | |
788 dynamicNode.appendChild(selectNode); | |
789 } | |
790 else if (o instanceof MinMaxDescribeData) { | |
791 appendMinMaxDescribeData( | |
792 artCreator, | |
793 creator, | |
794 document, | |
795 dynamicNode, | |
796 callMeta, | |
797 o); | |
798 } | |
799 else if (o instanceof SingleValueDescribeData) { | |
800 appendSingleValueDescribeData( | |
801 artCreator, | |
802 creator, | |
803 document, | |
804 dynamicNode, | |
805 callMeta, | |
806 o); | |
807 } | |
808 } | |
809 | |
810 | |
811 protected void appendMinMaxDescribeData( | |
812 XMLUtils.ElementCreator artCreator, | |
813 XMLUtils.ElementCreator creator, | |
814 Document document, | |
815 Node node, | |
816 CallMeta callMeta, | |
817 Object o | |
818 ) { | |
819 MinMaxDescribeData minMaxDescibeData = (MinMaxDescribeData) o; | |
820 Object min = minMaxDescibeData.getMinValue(); | |
821 Object max = minMaxDescibeData.getMaxValue(); | |
822 if (min instanceof GregorianCalendar) { | |
823 Date d = ((GregorianCalendar) min).getTime(); | |
824 min = DateUtils.getPatternedDateAmer(d); | |
825 } | |
826 | |
827 if (max instanceof GregorianCalendar) { | |
828 Date d = ((GregorianCalendar) max).getTime(); | |
829 max = DateUtils.getPatternedDateAmer(d); | |
830 } | |
831 | |
832 Element groupNode = creator.create("group"); | |
833 artCreator.addAttr(groupNode, "state", minMaxDescibeData.getState(), true); | |
834 | |
835 creator.addAttr(groupNode, "ref", minMaxDescibeData.getName()); | |
836 Element groupNodeLableNode = creator.create("label"); | |
837 groupNodeLableNode.setTextContent(RessourceFactory | |
838 .getInstance().getRessource( | |
839 callMeta.getLanguages(), | |
840 minMaxDescibeData.getName(), | |
841 minMaxDescibeData.getName())); | |
842 groupNode.appendChild(groupNodeLableNode); | |
843 | |
844 Element inputMinNode = creator.create("input"); | |
845 creator.addAttr(inputMinNode, "ref", MINVALUEFIELDNAME); | |
846 Element inputMinLableNode = creator.create("label"); | |
847 inputMinLableNode.setTextContent(RessourceFactory | |
848 .getInstance().getRessource( | |
849 callMeta.getLanguages(), MINVALUEFIELDNAME, | |
850 MINVALUEFIELDNAME)); | |
851 inputMinNode.appendChild(inputMinLableNode); | |
852 | |
853 Element inputMinValueNode = creator.create("value"); | |
854 inputMinValueNode.setTextContent(min.toString()); | |
855 inputMinNode.appendChild(inputMinValueNode); | |
856 | |
857 Element inputMaxNode = creator.create("input"); | |
858 creator.addAttr(inputMaxNode, "ref", MAXVALUEFIELDNAME); | |
859 Element inputMaxLableNode = creator.create("label"); | |
860 inputMaxLableNode.setTextContent(RessourceFactory | |
861 .getInstance().getRessource( | |
862 callMeta.getLanguages(), MAXVALUEFIELDNAME, | |
863 MAXVALUEFIELDNAME)); | |
864 inputMaxNode.appendChild(inputMaxLableNode); | |
865 | |
866 Element inputMaxValueNode = creator.create("value"); | |
867 inputMaxValueNode.setTextContent(max.toString()); | |
868 inputMaxNode.appendChild(inputMaxValueNode); | |
869 | |
870 groupNode.appendChild(inputMinNode); | |
871 groupNode.appendChild(inputMaxNode); | |
872 | |
873 node.appendChild(groupNode); | |
874 } | |
875 | |
876 | |
877 protected void appendSingleValueDescribeData( | |
878 XMLUtils.ElementCreator artCreator, | |
879 XMLUtils.ElementCreator creator, | |
880 Document document, | |
881 Node node, | |
882 CallMeta callMeta, | |
883 Object o | |
884 ) { | |
885 SingleValueDescribeData svdb = (SingleValueDescribeData) o; | |
886 | |
887 Element groupNode = creator.create("group"); | |
888 artCreator.addAttr(groupNode, "state", svdb.getState(), true); | |
889 creator.addAttr(groupNode, "ref", svdb.getName()); | |
890 | |
891 Element groupNodeLableNode = creator.create("label"); | |
892 groupNodeLableNode.setTextContent(RessourceFactory | |
893 .getInstance().getRessource( | |
894 callMeta.getLanguages(), | |
895 svdb.getName(), | |
896 svdb.getName())); | |
897 groupNode.appendChild(groupNodeLableNode); | |
898 | |
899 Element inputNode = creator.create("input"); | |
900 creator.addAttr(inputNode, "ref", svdb.getName()); | |
901 | |
902 Element inputLableNode = creator.create("label"); | |
903 inputLableNode.setTextContent(""); | |
904 inputNode.appendChild(inputLableNode); | |
905 | |
906 Element inputValueNode = creator.create("value"); | |
907 inputValueNode.setTextContent(svdb.getValue()); | |
908 inputNode.appendChild(inputValueNode); | |
909 | |
910 groupNode.appendChild(inputNode); | |
911 | |
912 node.appendChild(groupNode); | |
913 } | |
914 | |
915 | |
916 protected void setHash(String uuid) { | |
917 this.hash = uuid + id + inputData.hashCode(); | |
918 } | |
919 | |
920 | |
921 protected String getHash() { | |
922 return this.hash; | |
923 } | |
924 | |
925 | |
926 /** | |
927 * @see de.intevation.gnv.state.State#getDescibeData() | |
928 */ | |
929 public List<Object> getDescibeData(String uuid) { | |
930 CacheFactory factory = CacheFactory.getInstance(); | |
931 if (factory.isInitialized()) { | |
932 // we use a cache | |
933 log.debug("Using cache."); | |
934 Cache cache = factory.getCache(); | |
935 String key = getHash(); | |
936 | |
937 net.sf.ehcache.Element value = cache.get(key); | |
938 if (value != null) { | |
939 // element already in cache, so return it. | |
940 log.debug("Found element in cache."); | |
941 return (List<Object>) (value.getObjectValue()); | |
942 } | |
943 else { | |
944 // element is not in cache yet, so we need to fetch data from | |
945 // database and put it into cache right now | |
946 log.debug("Element not in cache, we need to ask the database"); | |
947 try { | |
948 String[] filterValues = generateFilterValuesFromInputData(); | |
949 List<Object> data = queryDatabase(filterValues, uuid); | |
950 | |
951 cache.put(new net.sf.ehcache.Element(key, data)); | |
952 return data; | |
953 } | |
954 catch (QueryException qe) { | |
955 log.error(qe, qe); | |
956 } | |
957 } | |
958 } | |
959 else { | |
960 // we don't use a cache, so we have to query the database every | |
961 // single time | |
962 log.debug("Not using cache."); | |
963 String[] filterValues = generateFilterValuesFromInputData(); | |
964 Collection<Result> result = null; | |
965 try { | |
966 return queryDatabase(filterValues, uuid); | |
967 } | |
968 catch (RuntimeException e) { | |
969 log.error(e, e); | |
970 } | |
971 catch (QueryException e) { | |
972 log.error(e, e); | |
973 } | |
974 } | |
975 | |
976 return null; | |
977 } | |
978 | |
979 protected List<Object> queryDatabase(String[] filterValues, String uuid) | |
980 throws QueryException { | |
981 Collection<Result> result = null; | |
982 | |
983 if (queryID != null) { | |
984 QueryExecutor queryExecutor = | |
985 QueryExecutorFactory.getInstance().getQueryExecutor(); | |
986 | |
987 result = queryExecutor.executeQuery(queryID, filterValues); | |
988 } | |
989 return purifyResult(result, uuid); | |
990 } | |
991 | |
992 | |
993 public Map<String, InputData> inputData() { | |
994 return inputData; | |
995 } | |
996 | |
997 /** | |
998 * @see de.intevation.gnv.state.State#getInputData() | |
999 */ | |
1000 public Collection<InputData> getInputData() throws StateException { | |
1001 return this.inputData != null ? this.inputData.values() : null; | |
1002 } | |
1003 | |
1004 public void endOfLife(Object globalContext) { | |
1005 } | |
1006 } | |
1007 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: |