comparison gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java @ 875:5e9efdda6894

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

http://dive4elements.wald.intevation.org