diff gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java @ 335:e964a3d8f7bc

Some Refactoring work done. Moved Transition to State gnv-artifacts/trunk@401 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 08 Dec 2009 08:39:03 +0000
parents
children a887074460b6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java	Tue Dec 08 08:39:03 2009 +0000
@@ -0,0 +1,788 @@
+/**
+ *
+ */
+package de.intevation.gnv.state;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifactdatabase.Config;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.gnv.artifacts.GNVArtifactBase;
+import de.intevation.gnv.artifacts.cache.CacheFactory;
+import de.intevation.gnv.artifacts.ressource.RessourceFactory;
+import de.intevation.gnv.geobackend.base.Result;
+import de.intevation.gnv.geobackend.base.query.QueryExecutor;
+import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;
+import de.intevation.gnv.geobackend.base.query.exception.QueryException;
+import de.intevation.gnv.geobackend.util.DateUtils;
+import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData;
+import de.intevation.gnv.state.describedata.KeyValueDescibeData;
+import de.intevation.gnv.state.describedata.MinMaxDescribeData;
+import de.intevation.gnv.state.describedata.NamedArrayList;
+import de.intevation.gnv.state.describedata.NamedCollection;
+import de.intevation.gnv.state.describedata.SingleValueDescribeData;
+import de.intevation.gnv.state.exception.StateException;
+import de.intevation.gnv.utils.ArtifactXMLUtilities;
+import de.intevation.gnv.utils.InputValidator;
+
+/**
+ * @author Tim Englich <tim.englich@intevation.de>
+ * 
+ */
+public abstract class StateBase implements State {
+
+    
+
+    /**
+     * The UID of this Class
+     */
+    private static final long serialVersionUID = 2411169179001645426L;
+
+    /**
+     * the logger, used to log exceptions and additonaly information
+     */
+    private static Logger log = Logger.getLogger(GNVArtifactBase.class);
+    
+    private final static String MINVALUEFIELDNAME = "minvalue";
+    private final static String MAXVALUEFIELDNAME = "maxvalue";
+    
+    private final static String NODATASELECTIONKEY = "n/n";
+    
+    private final static String DESCRIBEDATAKEY = "_DESCRIBEDATA";
+
+    private String id = null;
+
+    private String description = null;
+
+    protected String dataName = null;
+
+    protected boolean dataMultiSelect = false;
+    
+    protected boolean dataNoSelect = false;
+
+    protected String queryID = null;
+
+    private Collection<String> reachableStates = null;
+
+    protected Collection<String> inputValueNames = null;
+
+    private Map<String, InputValue> inputValues = null;
+
+    private State parent = null;
+
+    protected Map<String, InputData> inputData = null;
+    
+
+    /**
+     * Constructor
+     */
+    public StateBase() {
+        super();
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#getID()
+     */
+    public String getID() {
+        return this.id;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#getDescription()
+     */
+    public String getDescription() {
+        return this.description;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#reachableStates()
+     */
+    public Collection<String> reachableStates() {
+        
+        if (this.couldAlternativeStateUsed()){
+            Iterator<String> it = this.reachableStates.iterator();
+            String transValue = null;
+            while (it.hasNext()){
+                transValue = it.next();
+            }
+            Collection<String> returnValue = new ArrayList<String>(1);
+            returnValue.add(transValue);
+            return returnValue;
+        }else{
+            return this.reachableStates;
+        }
+        
+    }
+
+    /**
+     * @return
+     */
+    private boolean couldAlternativeStateUsed() {
+     // TODO das muss hier noch etwas freier gestaltet werden.
+        String key = this.dataName;
+        boolean returnValue=this.inputData != null &&
+                            this.inputData.containsKey(key) && 
+                            this.inputData.get(key).getValue().
+                                                    equals(NODATASELECTIONKEY);
+        return returnValue;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#getRequiredInputValues()
+     */
+    public Collection<InputValue> getRequiredInputValues() {
+        return this.inputValues.values();
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#setup(org.w3c.dom.Node)
+     */
+    public void setup(Node configuration) {
+        log.debug("StateBase.setup");
+        this.id = ((Element)configuration).getAttribute("id");
+        this.description = ((Element)configuration).getAttribute("description");
+
+        log.info("State-ID = " + this.id);
+        NodeList nodes = Config.getNodeSetXPath(configuration,
+                "reachablestates/state");
+        this.reachableStates = new ArrayList<String>(nodes.getLength());
+        for (int i = 0; i < nodes.getLength(); i++) {
+            String reachableState = nodes.item(i).getTextContent();
+            log.info("ReachableState ==> " + reachableState);
+            this.reachableStates.add(reachableState);
+
+        }
+        
+        NodeList inputValuesNodes = Config.getNodeSetXPath(configuration,
+                "inputvalues/inputvalue");
+        this.inputValues = new HashMap<String, InputValue>(inputValuesNodes
+                .getLength());
+        this.inputValueNames = new ArrayList<String>(inputValuesNodes
+                .getLength());
+        for (int i = 0; i < inputValuesNodes.getLength(); i++) {
+            Element inputValueNode = (Element)inputValuesNodes.item(i);
+            String usedinQueryValue = inputValueNode.getAttribute("usedinquery");
+            int usedinQuery = 1;
+            if (usedinQueryValue != null) {
+                try {
+                    usedinQuery = Integer.parseInt(usedinQueryValue);
+                } catch (NumberFormatException e) {
+                    log
+                            .warn("Used in Query Value cannot be transformed into a Number");
+                }
+            }
+            InputValue inputValue = new DefaultInputValue(inputValueNode.getAttribute("name"), 
+                                                          inputValueNode.getAttribute("type"), 
+                                                          Boolean.parseBoolean(inputValueNode.
+                                                          getAttribute("multiselect")), usedinQuery);
+            log.debug(inputValue.toString());
+            this.inputValues.put(inputValue.getName(), inputValue);
+            this.inputValueNames.add(inputValue.getName());
+        }
+
+        this.queryID = Config.getStringXPath(configuration, "queryID");
+        log.info("QueryID ==> " + this.queryID);
+
+        this.dataName = Config.getStringXPath(configuration, "dataname");
+
+        String dataMultiSelectValue = Config.getStringXPath(configuration,
+                                                           "data-multiselect");
+        if (dataMultiSelectValue != null) {
+            this.dataMultiSelect = Boolean.parseBoolean(dataMultiSelectValue);
+        }
+        
+        String dataNoSelectValue =Config.getStringXPath(configuration,
+                                                        "data-noselect");
+        if (dataNoSelectValue != null) {
+            this. dataNoSelect = Boolean.parseBoolean(dataNoSelectValue);
+        }
+        
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#getParent()
+     */
+    public State getParent() {
+        return this.parent;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#setParent(de.intevation.gnv.state.State)
+     */
+    public void setParent(State state) {
+        this.parent = state;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#putInputData(java.util.Collection)
+     */
+    public void putInputData(Collection<InputData> inputData, String uuid)
+                                                                          throws StateException {
+        log.debug("StateBase.putInputData");
+        if (inputData != null) {
+            Iterator<InputData> it = inputData.iterator();
+            InputValidator iv = new InputValidator();
+            while (it.hasNext()) {
+                InputData tmpItem = it.next();
+                InputValue inputValue = this.inputValues.get(tmpItem.getName());
+                if (inputValue != null) {
+                    if (this.inputData == null) {
+                        this.inputData = new HashMap<String, InputData>(
+                                inputData.size());
+                    }
+                    
+                    boolean valid = iv.isInputValid(tmpItem.getValue(),
+                            inputValue.getType());
+                    if (valid) {
+                        if (tmpItem.getName().equals(MINVALUEFIELDNAME)){
+                            String minValue = tmpItem.getValue();
+                            String maxValue = this.getInputValue4ID(inputData, MAXVALUEFIELDNAME);
+                            valid = iv.isInputValid(maxValue,inputValue.getType());
+                            if (!valid){
+                                String errMsg = "Wrong input for " + tmpItem.getValue()
+                                                + " is not an " + inputValue.getType()
+                                                + " Value.";
+                                log.warn(errMsg);
+                                throw new StateException(errMsg);
+                            }
+                            
+                            valid = iv.isInputValid(minValue, 
+                                    maxValue,
+                                    inputValue.getType());
+                            if (!valid){
+                                String errMsg = "MaxValue-Input is less than MinValue-Input ";
+                                log.warn(errMsg);
+                                throw new StateException(errMsg);
+                            }
+                        }else if (tmpItem.getName().equals(MAXVALUEFIELDNAME)){
+                            String minValue = this.getInputValue4ID(inputData, MINVALUEFIELDNAME);
+                            String maxValue = tmpItem.getValue();
+                            valid = iv.isInputValid(minValue,inputValue.getType());
+                            if (!valid){
+                                String errMsg = "Wrong input for " + tmpItem.getValue()
+                                                + " is not an " + inputValue.getType()
+                                                + " Value.";
+                                log.warn(errMsg);
+                                throw new StateException(errMsg);
+                            }
+                            
+                            valid = iv.isInputValid(minValue, 
+                                                    maxValue,
+                                                    inputValue.getType());
+                            if (!valid){
+                                String errMsg = "MaxValue-Input is less than MinValue-Input ";
+                                log.warn(errMsg);
+                                throw new StateException(errMsg);
+                            }
+                        }
+                        this.setSelection(tmpItem, uuid);
+                        this.inputData.put(tmpItem.getName(), tmpItem);
+                    } else {
+                        String errMsg = "Wrong input for " + tmpItem.getValue()
+                                        + " is not an " + inputValue.getType()
+                                        + " Value.";
+                        log.warn(errMsg);
+                        throw new StateException(errMsg);
+                    }
+
+                } else {
+                    String errMsg = "No Inputvalue given for Inputdata "
+                                    + tmpItem.getName();
+                    log.warn(errMsg + "Value will be ignored");
+
+                }
+            }
+        } else {
+            log.warn("No Inputdata given");
+        }
+    }
+    
+    private String getInputValue4ID(Collection<InputData> inputData, String inputName){
+        Iterator<InputData> it = inputData.iterator();
+        while (it.hasNext()) {
+            InputData tmpItem = it.next();
+            if (tmpItem.getName().equals(inputName)){
+                return tmpItem.getValue();
+            }
+        }
+        return null;
+    }
+
+    private void setSelection(InputData inputData, String uuid) {
+        log.debug("StateBase.setSelection");
+
+        Object o = this.getDescribeData(inputData.getName(),uuid);
+        if (o != null) {
+            if (o instanceof Collection<?>) {
+                Collection<KeyValueDescibeData> values = (Collection<KeyValueDescibeData>) o;
+
+                String value = inputData.getValue();
+                String[] selectedValues = value.split(",");
+                Set<String> selectedItems = new HashSet<String>(
+                        selectedValues.length);
+                for (int i = 0; i < selectedValues.length; i++) {
+                    selectedItems.add(selectedValues[i].trim());
+                }
+                // Selektion umsetzen
+                Iterator<KeyValueDescibeData> it = values.iterator();
+                while (it.hasNext()) {
+                    KeyValueDescibeData data = it.next();
+                    String key = "" + data.getKey();
+                    boolean selected = selectedItems.contains(key);
+                    data.setSelected(selected);
+                }
+            } else if (o instanceof MinMaxDescribeData) {
+                MinMaxDescribeData data = (MinMaxDescribeData) o;
+                if (inputData.getName().equals(MINVALUEFIELDNAME)) {
+                    data.setMinValue(inputData.getValue());
+                }
+                if (inputData.getName().equals(MAXVALUEFIELDNAME)) {
+                    data.setMaxValue(inputData.getValue());
+                }
+            } else if (o instanceof SingleValueDescribeData) {
+                ((SingleValueDescribeData)o).setValue(inputData.getValue());
+            }
+        }
+    }
+
+    private Object getDescribeData(String name, String uuid) {
+        log.debug("StateBase.getDescribeData");
+        Collection<Object> descibeData = this.getDescibeData(uuid);
+        if (descibeData != null) {
+            Iterator<Object> it = descibeData.iterator();
+            while (it.hasNext()) {
+                Object o = it.next();
+                if (o instanceof NamedCollection<?>) {
+                    if (name.equals(((NamedCollection<?>) o).getName())) {
+                        return o;
+                    }
+                } else if (o instanceof MinMaxDescribeData) {
+                    if (name.equals(((MinMaxDescribeData) o).getMinName())) {
+                        return o;
+                    }
+                    if (name.equals(((MinMaxDescribeData) o).getMaxName())) {
+                        return o;
+                    }
+                }else if (o instanceof SingleValueDescribeData) {
+                    if (name.equals(((SingleValueDescribeData)o).getName())){
+                        return o;
+                    }
+                }
+            }
+        }
+        return null;
+
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#isStateReachable(java.lang.String)
+     */
+    public boolean isStateReachable(String stateID) {
+        log.debug("StateBase.isStateReachable");
+        boolean returnValue = false;
+        Iterator<String> states = reachableStates.iterator();
+        while (states.hasNext()) {
+            if (states.next().equals(stateID)) {
+                log.debug("State " + stateID + " wird unterstützt.");
+                returnValue = true;
+                break;
+            }
+        }
+        return returnValue;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#advance(java.lang.String,
+     *      de.intevation.artifacts.CallMeta)
+     */
+    public void advance(String uuid, CallMeta callMeta)
+                                                   throws StateException {
+    }
+    
+    public void initialize(String uuid, CallMeta callMeta)
+                                                   throws StateException {
+        log.debug("StateBase.initialize");
+        try {
+            String[] filterValues = this
+                    .generateFilterValuesFromInputData();
+            Collection<Result> result = null;
+            try {
+                if (this.queryID != null) {
+                    QueryExecutor queryExecutor = QueryExecutorFactory
+                            .getInstance().getQueryExecutor();
+                    result = queryExecutor.executeQuery(this.queryID,
+                            filterValues);
+                }
+                this.purifyResult(result, uuid);
+            } catch (RuntimeException e) {
+                log.error(e, e);
+            }
+        } catch (QueryException e) {
+            log.error(e, e);
+            throw new StateException(e);
+        }
+    }
+
+    /**
+     * @return
+     */
+    protected String[] generateFilterValuesFromInputData() {
+        List<String> list = new ArrayList<String>();
+        Iterator<String> it = this.inputValueNames.iterator();
+        while (it.hasNext()) {
+            String value = it.next();
+            InputData data = this.inputData.get(value);
+            if (data != null
+                && this.inputValues.containsKey(data.getName())) {
+                int size = this.inputValues.get(data.getName())
+                        .usedInQueries();
+                String type = this.inputValues.get(data.getName())
+                        .getType();
+                String requestValue = data.getValue();
+                if (type.equalsIgnoreCase("string")) {
+                    requestValue = this
+                            .prepareInputData4DBQuery(requestValue);
+                } else if (type.equalsIgnoreCase("date")) {
+                    requestValue = this
+                            .prepareInputData4DateDBQuery(requestValue);
+                } else if (type.equalsIgnoreCase("coordinate")){
+                    requestValue = this
+                    .prepareInputData4RegionDBQuery(requestValue);
+                }
+                for (int j = 0; j < size; j++) {
+                    list.add(requestValue);
+                }
+            }
+        }
+        String[] filterValues = list.toArray(new String[0]);
+        return filterValues;
+    }
+    
+    protected String prepareInputData4RegionDBQuery(String value){
+        return value;
+    }
+
+    private String prepareInputData4DateDBQuery(String value) {
+        log.debug("StateBase.prepareInputData4DateDBQuery");
+        if (value != null) {
+            String[] values = value.split(",");
+            String newValue = "";
+            for (int i = 0; i < values.length; i++) {
+                if (newValue.length() > 0) {
+                    newValue = newValue + " , ";
+                }
+                // TODO JUST HACK FIND A BETTER RESOLUTION
+                newValue = newValue + "to_date('" + values[i].trim()
+                           + "', 'YYYY.MM.DD HH24:MI:SS')";
+            }
+            return newValue;
+        }
+
+        return value;
+    }
+
+    private String prepareInputData4DBQuery(String value) {
+        log.debug("StateBase.prepareInputData4DBQuery");
+        if (value != null) {
+            String[] values = value.split(",");
+            String newValue = "";
+            for (int i = 0; i < values.length; i++) {
+                if (newValue.length() > 0) {
+                    newValue = newValue + " , ";
+                }
+                newValue = newValue + "'" + values[i].trim() + "'";
+            }
+            return newValue;
+        }
+
+        return value;
+
+    }
+
+    /**
+     * @param result
+     */
+    protected void purifyResult(Collection<Result> result, String uuid) {
+        log.debug("StateBase.purifyResult");
+        Collection<Object> describeData = this.getDescibeData(uuid);
+        if (describeData == null) {
+            describeData = new ArrayList<Object>();
+        }
+        NamedCollection<KeyValueDescibeData> keyValueDescibeData = extractKVP(result, "KEY", "VALUE");
+        describeData.add(keyValueDescibeData); 
+        this.setDescibeData(uuid, describeData);
+    }
+
+    /**
+     * @param result
+     * @return
+     */
+    protected NamedCollection<KeyValueDescibeData> extractKVP(Collection<Result> result,
+                                                              String keyid,
+                                                              String valueid) {
+        Iterator<Result> rit = result.iterator();
+        int dataSize = (this.dataNoSelect ? result.size()+1 : result.size());
+        
+        NamedCollection<KeyValueDescibeData> keyValueDescibeData = new NamedArrayList<KeyValueDescibeData>(
+                this.dataName, dataSize);
+        keyValueDescibeData.setMultiSelect(this.dataMultiSelect);
+        
+        if (this.dataNoSelect){
+            keyValueDescibeData.add(new DefaultKeyValueDescribeData(NODATASELECTIONKEY, 
+                                                                    "No Selection"));
+        }
+        boolean initialized = false;
+        int keyPos= 0;
+        int valuePos = 1;
+        String previousKey = null;
+        while (rit.hasNext()) {
+            Result resultValue = rit.next();
+            if (!initialized){
+                keyPos = resultValue.getResultDescriptor().getColumnIndex(keyid);
+                valuePos = resultValue.getResultDescriptor().getColumnIndex(valueid);
+                if (valuePos < 0){
+                    valuePos = 1;
+                }
+                initialized = true;
+            }
+            String tmpKey = resultValue.getString(keyPos);
+            // TODO: HACK da die ARCSDE kein DISTINCT auf räumlichen Anfragen unterstützt.
+            if (previousKey == null || !tmpKey.equals(previousKey)){
+                previousKey = tmpKey;
+                keyValueDescibeData.add(new DefaultKeyValueDescribeData(tmpKey, resultValue.getString(valuePos)));
+            }
+        }
+        return keyValueDescibeData;
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#describe(org.w3c.dom.Document,
+     *      org.w3c.dom.Node, de.intevation.artifacts.CallMeta,
+     *      java.lang.String)
+     */
+    public void describe(Document document, Node rootNode, CallMeta callMeta,String uuid) {
+        log.debug("StateBase.describe");
+        Collection<Object> descibeData = this.getDescibeData(uuid);
+        if (descibeData != null) {
+            ArtifactXMLUtilities xmlutilities = new ArtifactXMLUtilities();
+            Iterator<Object> it = descibeData.iterator();
+            Node staticNode = xmlutilities.createArtifactElement(document,
+                    "static");
+            Node dynamic = xmlutilities.createArtifactElement(document,
+                    "dynamic");
+            rootNode.appendChild(staticNode);
+            rootNode.appendChild(dynamic);
+            while (it.hasNext()) {
+
+                Object o = it.next();
+                if (o instanceof Collection<?>) {
+                    String name = null;
+                    boolean multiselect = false;
+                    if (o instanceof NamedCollection<?>) {
+                        NamedCollection<?> nc = ((NamedCollection<?>) o);
+                        name = nc.getName();
+                        multiselect = nc.isMultiSelect();
+                    } else {
+                        Object[] names = this.inputValueNames.toArray();
+                        name = names[names.length - 1].toString();
+                    }
+
+                    Element selectNode = xmlutilities.createXFormElement(
+                            document, multiselect ? "select" : "select1");
+                    selectNode.setAttribute("ref", name);
+
+                    Element lableNode = xmlutilities.createXFormElement(
+                            document, "label");
+                    lableNode.setTextContent(RessourceFactory.getInstance()
+                            .getRessource(callMeta.getLanguages(), name, name));
+                    Element choiceNode = xmlutilities.createXFormElement(
+                            document, "choices");
+
+                    Collection<KeyValueDescibeData> values = (Collection<KeyValueDescibeData>) o;
+                    Iterator<KeyValueDescibeData> resultIt = values.iterator();
+                    while (resultIt.hasNext()) {
+                        KeyValueDescibeData result = resultIt.next();
+                        Element itemNode = xmlutilities.createXFormElement(
+                                document, "item");
+
+                        if (result.isSelected()) {
+                            itemNode.setAttribute("selected", "true");
+                        }
+
+                        Element choiceLableNode = xmlutilities
+                                .createXFormElement(document, "label");
+                        choiceLableNode.setTextContent(result.getValue());
+                        itemNode.appendChild(choiceLableNode);
+
+                        Element choicValueNode = xmlutilities
+                                .createXFormElement(document, "value");
+                        choicValueNode.setTextContent("" + result.getKey());
+                        itemNode.appendChild(choicValueNode);
+                        choiceNode.appendChild(itemNode);
+                    }
+                    selectNode.appendChild(lableNode);
+                    selectNode.appendChild(choiceNode);
+
+                    if (!it.hasNext() && this.dataName != null) {
+                        dynamic.appendChild(selectNode);
+                    } else {
+                        staticNode.appendChild(selectNode);
+                    }
+
+                } else if (o instanceof MinMaxDescribeData) {
+                    MinMaxDescribeData minMaxDescibeData = (MinMaxDescribeData) o;
+                    Object min = minMaxDescibeData.getMinValue();
+                    Object max = minMaxDescibeData.getMaxValue();
+                    if (min instanceof GregorianCalendar) {
+                        Date d = ((GregorianCalendar) min).getTime();
+                        min = DateUtils.getPatternedDateAmer(d);
+                    }
+
+                    if (max instanceof GregorianCalendar) {
+                        Date d = ((GregorianCalendar) max).getTime();
+                        max = DateUtils.getPatternedDateAmer(d);
+                    }
+                    
+                    Element groupNode = xmlutilities.createXFormElement(
+                            document, "group");
+                    groupNode.setAttribute("ref", minMaxDescibeData.getName());
+                    Element groupNodeLableNode = xmlutilities
+                            .createXFormElement(document, "label");
+                    groupNodeLableNode.setTextContent(RessourceFactory
+                            .getInstance().getRessource(
+                                    callMeta.getLanguages(),
+                                    minMaxDescibeData.getName(),
+                                    minMaxDescibeData.getName()));
+                    groupNode.appendChild(groupNodeLableNode);
+
+                    Element inputMinNode = xmlutilities.createXFormElement(
+                            document, "input");
+                    inputMinNode.setAttribute("ref", MINVALUEFIELDNAME);
+                    Element inputMinLableNode = xmlutilities
+                            .createXFormElement(document, "label");
+                    inputMinLableNode.setTextContent(RessourceFactory
+                            .getInstance().getRessource(
+                                    callMeta.getLanguages(), MINVALUEFIELDNAME,
+                                    MINVALUEFIELDNAME));
+                    inputMinNode.appendChild(inputMinLableNode);
+
+                    Element inputMinValueNode = xmlutilities
+                            .createXFormElement(document, "value");
+                    inputMinValueNode.setTextContent(min.toString());
+                    inputMinNode.appendChild(inputMinValueNode);
+
+                    Element inputMaxNode = xmlutilities.createXFormElement(
+                            document, "input");
+                    inputMaxNode.setAttribute("ref", MAXVALUEFIELDNAME);
+                    Element inputMaxLableNode = xmlutilities
+                            .createXFormElement(document, "label");
+                    inputMaxLableNode.setTextContent(RessourceFactory
+                            .getInstance().getRessource(
+                                    callMeta.getLanguages(), MAXVALUEFIELDNAME,
+                                    MAXVALUEFIELDNAME));
+                    inputMaxNode.appendChild(inputMaxLableNode);
+
+                    Element inputMaxValueNode = xmlutilities
+                            .createXFormElement(document, "value");
+                    inputMaxValueNode.setTextContent(max.toString());
+                    inputMaxNode.appendChild(inputMaxValueNode);
+
+                    groupNode.appendChild(inputMinNode);
+                    groupNode.appendChild(inputMaxNode);
+                    
+                    if (!it.hasNext() && this.dataName != null) {
+                        dynamic.appendChild(groupNode);
+                    } else {
+                        staticNode.appendChild(groupNode);
+                    }
+                } else if (o instanceof SingleValueDescribeData) {
+
+                    SingleValueDescribeData svdb = (SingleValueDescribeData) o;
+                    
+                    Element groupNode = xmlutilities.createXFormElement(
+                            document, "group");
+                    groupNode.setAttribute("ref",  svdb.getName());
+                    Element groupNodeLableNode = xmlutilities
+                            .createXFormElement(document, "label");
+                    groupNodeLableNode.setTextContent(RessourceFactory
+                            .getInstance().getRessource(
+                                    callMeta.getLanguages(),
+                                    svdb.getName(),
+                                    svdb.getName()));
+                    groupNode.appendChild(groupNodeLableNode);
+
+                    Element inputNode = xmlutilities.createXFormElement(
+                            document, "input");
+                    inputNode.setAttribute("ref", svdb.getName());
+
+                    Element inputLableNode = xmlutilities.createXFormElement(
+                            document, "label");
+                    inputLableNode.setTextContent("");
+                    inputNode.appendChild(inputLableNode);
+
+                    Element inputValueNode = xmlutilities.createXFormElement(
+                            document, "value");
+                    inputValueNode.setTextContent(svdb.getValue());
+                    inputNode.appendChild(inputValueNode);
+
+                    groupNode.appendChild(inputNode);
+                    if (!it.hasNext() && this.dataName != null) {
+                        dynamic.appendChild(groupNode);
+                    } else {
+                        staticNode.appendChild(groupNode);
+                    }
+                }
+
+            }
+        }
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#getDescibeData()
+     */
+    protected Collection<Object> getDescibeData(String uuid) {
+        if (CacheFactory.getInstance().isInitialized()) {
+            String key = uuid + DESCRIBEDATAKEY;
+            log.debug("Hash for Queryelements: " + key);
+            net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key);
+            if (value != null) {
+                return (Collection<Object>) (value.getObjectValue());
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * @see de.intevation.gnv.state.State#getDescibeData()
+     */
+    protected void setDescibeData(String uuid, Collection<Object> describeData) {
+        
+        if (CacheFactory.getInstance().isInitialized()) {
+            String key = uuid + DESCRIBEDATAKEY;
+            log.debug("Hash for Queryelements: " + key);
+            CacheFactory.getInstance().getCache().put(new net.sf.ehcache.Element(key, describeData));
+        }
+    }
+
+    /**
+     * @see de.intevation.gnv.state.State#getInputData()
+     */
+    public Collection<InputData> getInputData() throws StateException {
+        return this.inputData != null ? this.inputData.values() : null;
+    }
+}

http://dive4elements.wald.intevation.org