view gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java @ 605:e8ebdbc7f1e3

First step of removing the cache blob. The static part of the describe document will be created by using the input data stored at each state. Some TODOs left (see ChangeLog). gnv-artifacts/trunk@671 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 09 Feb 2010 14:27:55 +0000
parents 9681ac6b6527
children 292fbcd5e9ac
line wrap: on
line source
package de.intevation.gnv.state;

import java.util.ArrayList;
import java.util.Arrays;
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 javax.xml.xpath.XPathConstants;

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.artifactdatabase.XMLUtils;
import de.intevation.artifacts.ArtifactNamespaceContext;
import de.intevation.artifacts.CallContext;
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.InputValidator;

/**
 * @author Tim Englich         (tim.englich@intevation.de)
 * @author Ingo Weinzierl      (ingo.weinzierl@intevation.de)
 * @author Sascha L. Teichmann (sascha.teichmann@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";

    public final static String DESCRIBEDATAKEY = "_DESCRIBEDATA";

    public final static String XPATH_STATIC_UI  = "art:static";
    public final static String XPATH_DYNAMIC_UI = "art:dynamic";

    /** input value names which should not be rendered from State itself */
    public final static String[] BLACKLIST = {"sourceid", "fisname"};

    private String id = null;

    private String description = null;

    protected String dataName = null;

    protected String preSettingsName = null;

    protected boolean dataMultiSelect = false;

    protected boolean dataNoSelect = false;

    protected String queryID = null;

    protected Collection<String> inputValueNames = null;

    private Map<String, InputValue> inputValues = null;

    private State parent = null;

    protected Map<String, InputData> inputData = null;

    private Map<String, InputData> preSettings = 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#getRequiredInputValues()
     */
    public Collection<InputValue> getRequiredInputValues() {
        return this.inputValues.values();
    }


    public void reset(String uuid) {
        
        if (parent != null) {
            inputData = parent.inputData();
        }
    }


    /**
     * @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 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);
        }
        
        this.preSettingsName = Config.getStringXPath(configuration, "presettings-name"); 
        
    }

    /**
     * @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");
        }
    }

    /**
     * 
     * @see de.intevation.gnv.state.State#setPreSettings(java.util.Map)
     */
    public void setPreSettings(Map<String, InputData> preSettings) {
        this.preSettings = preSettings;
    }

    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#advance(java.lang.String,
     *      de.intevation.artifacts.CallMeta)
     */
    public void advance(String uuid, CallContext context)
    throws StateException
    {
    }
    
    public void initialize(String uuid, CallContext context)
    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[list.size()]);
        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");
        List<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",
                getID()
            ));
        }

        boolean initialized = false;
        int     keyPos      = 0;
        int     valuePos    = 1;
        String  previousKey = null;
        InputData preSettingsData = (this.preSettings != null && 
                                    this.preSettingsName != null) ? 
                                    this.preSettings.get(this.preSettingsName) :
                                    null;
        boolean filterWithPresettings = preSettingsData != null;
        
        List<String> preSettingValues = null;
        if(filterWithPresettings){
            preSettingValues = Arrays.asList(preSettingsData.splitValue());
        }
        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: FIXME: We have to do that because the arcsde does not 
            //       support a distinct Query on Layers.
            if (previousKey == null || !tmpKey.equals(previousKey)){
                previousKey = tmpKey;
                if (!filterWithPresettings || preSettingValues.contains(tmpKey)){
                    keyValueDescibeData.add(
                            new DefaultKeyValueDescribeData(
                                                tmpKey, 
                                                resultValue.getString(valuePos),
                                                getID())
                                );
                }
            }
        }
        return keyValueDescibeData;
    }


    public String findNewValue() {
        Iterator iter = inputValueNames.iterator();

        while (iter.hasNext()) {
            String  key = (String) iter.next();
            boolean old = false;

            StateBase parent = (StateBase) getParent();
            if (parent == null) {
                // first state should always render a dynamic part
                old = true;
            }

            while (parent != null) {
                if (parent.inputValueNames.contains(key) || inBlackList(key)) {
                    old = true;
                    break;
                }

                parent = (StateBase) parent.getParent();
            }

            if (!old) {
                return key;
            }
        }

        return null;
    }


    public static boolean inBlackList(String key) {
        int length = BLACKLIST.length;
        for (int i = 0; i < length; i++) {
            if (BLACKLIST[i].equals(key)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @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,
        CallContext context,
        String      uuid
    ) {
        log.debug("StateBase.describe");
        CallMeta callMeta = context.getMeta();

        List<Object> descibeData = this.getDescibeData(uuid);
        if (descibeData != null) {
            Iterator<Object> it = descibeData.iterator();

            XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
                document,
                ArtifactNamespaceContext.NAMESPACE_URI,
                ArtifactNamespaceContext.NAMESPACE_PREFIX
            );

            Node staticNode = (Node) XMLUtils.xpath(
                rootNode,
                XPATH_STATIC_UI,
                XPathConstants.NODE,
                ArtifactNamespaceContext.INSTANCE
            );

            Node dynamic = (Node) XMLUtils.xpath(
                rootNode,
                XPATH_DYNAMIC_UI,
                XPathConstants.NODE,
                ArtifactNamespaceContext.INSTANCE
            );

            XMLUtils.ElementCreator xCreator = new XMLUtils.ElementCreator(
                document,
                XMLUtils.XFORM_URL,
                XMLUtils.XFORM_PREFIX
            );

            while (it.hasNext()) {
                Object o = it.next();
                if ((!it.hasNext() && dataName != null)) {
                    appendToDynamicNode(
                        creator, xCreator, document, dynamic, callMeta, o);
                }
                else {
                    appendToStaticNode(
                        creator, xCreator, document, staticNode, callMeta, o);
                }
            }
        }
    }
    */


    public void describe(
        Document    document,
        Node        rootNode,
        CallContext context,
        String      uuid)
    {
        log.debug("StateBase.describe");

        XMLUtils.ElementCreator xCreator = new XMLUtils.ElementCreator(
            document,
            XMLUtils.XFORM_URL,
            XMLUtils.XFORM_PREFIX
        );

        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX
        );

        // append dynamic node
        Node dynamic = (Node) XMLUtils.xpath(
            rootNode,
            XPATH_DYNAMIC_UI,
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE
        );

        describeDynamic(
            creator, xCreator, document, dynamic, context, uuid);

        // append static nodes
        Node staticNode = (Node) XMLUtils.xpath(
            rootNode,
            XPATH_STATIC_UI,
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE
        );

        describeStatic(
            creator,xCreator, document, staticNode, context,uuid);
    }


    protected void describeDynamic(
        XMLUtils.ElementCreator artCreator,
        XMLUtils.ElementCreator creator,
        Document                document,
        Node                    dynamic,
        CallContext             context,
        String                  uuid)
    {
        log.debug("StateBase.describeDynamic");
        CallMeta callMeta = context.getMeta();

        List<Object> descibeData = getDescibeData(uuid);
        if (descibeData != null) {
            Iterator<Object> it = descibeData.iterator();

            while (it.hasNext()) {
                Object o = it.next();
                if ((!it.hasNext() && dataName != null)) {
                    appendToDynamicNode(
                        artCreator, creator, document, dynamic, callMeta, o);
                }
            }
        }
    }


    protected void describeStatic(
        XMLUtils.ElementCreator artCreator,
        XMLUtils.ElementCreator creator,
        Document                document,
        Node                    staticNode,
        CallContext             context,
        String                  uuid)
    {
        State parent = getParent();
        if (parent != null && parent instanceof StateBase) {
            ((StateBase) parent).describeStatic(
                artCreator, creator, document, staticNode, context, uuid);
        }

        CallMeta callMeta = context.getMeta();
        String inputKey   = findNewValue();
        appendToStaticNode(
            artCreator, creator, document, staticNode, callMeta, inputKey);
    }


    protected void appendToStaticNode(
        XMLUtils.ElementCreator artCreator,
        XMLUtils.ElementCreator creator,
        Document                document,
        Node                    staticNode,
        CallMeta                callMeta,
        String                  inputKey
    ) {
        InputValue meta = inputValues.get(inputKey);
        InputData  data = inputData.get(inputKey);

        if (meta == null || data == null) {
            return;
        }

        boolean multiselect = meta.isMultiselect();

        Element selectNode = creator.create(multiselect?"select":"select1");
        creator.addAttr(selectNode, "ref", inputKey);

        Element lableNode = creator.create("label");
        lableNode.setTextContent(RessourceFactory.getInstance()
                .getRessource(callMeta.getLanguages(), inputKey, inputKey));
        Element choiceNode = creator.create("choices");

        /* TODO InputData can have more than 1 value if multiselect, implement a
         * loop over these values

        while (resultIt.hasNext()) {
            KeyValueDescibeData result = resultIt.next();
        */

        artCreator.addAttr(
            selectNode, "state", getID(), true
        );

        Element itemNode = creator.create("item");

        creator.addAttr(itemNode, "selected", "true");

        Element choiceLableNode = creator.create("label");
        choiceLableNode.setTextContent(data.getValue());
        itemNode.appendChild(choiceLableNode);

        Element choiceValueNode = creator.create("value");
        choiceValueNode.setTextContent(inputKey);
        itemNode.appendChild(choiceValueNode);
        choiceNode.appendChild(itemNode);
        /*
        }
        */
        selectNode.appendChild(lableNode);
        selectNode.appendChild(choiceNode);

        staticNode.appendChild(selectNode);
    }


    protected void appendToDynamicNode(
        XMLUtils.ElementCreator artCreator,
        XMLUtils.ElementCreator creator,
        Document                document,
        Node                    dynamicNode,
        CallMeta                callMeta,
        Object                  o
    ) {
        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 = creator.create(multiselect?"select":"select1");
            creator.addAttr(selectNode, "ref", name);

            Element lableNode = creator.create("label");
            lableNode.setTextContent(RessourceFactory.getInstance()
                    .getRessource(callMeta.getLanguages(), name, name));
            Element choiceNode = creator.create("choices");

            Collection<KeyValueDescibeData> values = (Collection<KeyValueDescibeData>) o;
            Iterator<KeyValueDescibeData> resultIt = values.iterator();
            while (resultIt.hasNext()) {
                KeyValueDescibeData result = resultIt.next();
                Element itemNode = creator.create("item");

                if (result.isSelected()) {
                    itemNode.setAttribute("selected", "true");
                }

                Element choiceLableNode = creator.create("label");
                choiceLableNode.setTextContent(result.getValue());
                itemNode.appendChild(choiceLableNode);

                Element choicValueNode = creator.create("value");
                choicValueNode.setTextContent("" + result.getKey());
                itemNode.appendChild(choicValueNode);
                choiceNode.appendChild(itemNode);
            }
            selectNode.appendChild(lableNode);
            selectNode.appendChild(choiceNode);

            dynamicNode.appendChild(selectNode);
        }
        else if (o instanceof MinMaxDescribeData) {
            appendMinMaxDescribeData(
                artCreator,
                creator,
                document,
                dynamicNode,
                callMeta,
                o);
        }
        else if (o instanceof SingleValueDescribeData) {
            appendSingleValueDescribeData(
                artCreator,
                creator,
                document,
                dynamicNode,
                callMeta,
                o);
        }
    }


    protected void appendMinMaxDescribeData(
        XMLUtils.ElementCreator artCreator,
        XMLUtils.ElementCreator creator,
        Document                document,
        Node                    node,
        CallMeta                callMeta,
        Object                  o
    ) {
        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 = creator.create("group");
        artCreator.addAttr(groupNode, "state", minMaxDescibeData.getState(), true);

        creator.addAttr(groupNode, "ref", minMaxDescibeData.getName());
        Element groupNodeLableNode = creator.create("label");
        groupNodeLableNode.setTextContent(RessourceFactory
                .getInstance().getRessource(
                        callMeta.getLanguages(),
                        minMaxDescibeData.getName(),
                        minMaxDescibeData.getName()));
        groupNode.appendChild(groupNodeLableNode);

        Element inputMinNode = creator.create("input");
        creator.addAttr(inputMinNode, "ref", MINVALUEFIELDNAME);
        Element inputMinLableNode = creator.create("label");
        inputMinLableNode.setTextContent(RessourceFactory
                .getInstance().getRessource(
                        callMeta.getLanguages(), MINVALUEFIELDNAME,
                        MINVALUEFIELDNAME));
        inputMinNode.appendChild(inputMinLableNode);

        Element inputMinValueNode = creator.create("value");
        inputMinValueNode.setTextContent(min.toString());
        inputMinNode.appendChild(inputMinValueNode);

        Element inputMaxNode = creator.create("input");
        creator.addAttr(inputMaxNode, "ref", MAXVALUEFIELDNAME);
        Element inputMaxLableNode = creator.create("label");
        inputMaxLableNode.setTextContent(RessourceFactory
                .getInstance().getRessource(
                        callMeta.getLanguages(), MAXVALUEFIELDNAME,
                        MAXVALUEFIELDNAME));
        inputMaxNode.appendChild(inputMaxLableNode);

        Element inputMaxValueNode = creator.create("value");
        inputMaxValueNode.setTextContent(max.toString());
        inputMaxNode.appendChild(inputMaxValueNode);

        groupNode.appendChild(inputMinNode);
        groupNode.appendChild(inputMaxNode);

        node.appendChild(groupNode);
    }


    protected void appendSingleValueDescribeData(
        XMLUtils.ElementCreator artCreator,
        XMLUtils.ElementCreator creator,
        Document                document,
        Node                    node,
        CallMeta                callMeta,
        Object                  o
    ) {
        SingleValueDescribeData svdb = (SingleValueDescribeData) o;

        Element groupNode = creator.create("group");
        artCreator.addAttr(groupNode, "state", svdb.getState(), true);
        creator.addAttr(groupNode, "ref",  svdb.getName());

        Element groupNodeLableNode = creator.create("label");
        groupNodeLableNode.setTextContent(RessourceFactory
                .getInstance().getRessource(
                        callMeta.getLanguages(),
                        svdb.getName(),
                        svdb.getName()));
        groupNode.appendChild(groupNodeLableNode);

        Element inputNode = creator.create("input");
        creator.addAttr(inputNode, "ref", svdb.getName());

        Element inputLableNode = creator.create("label");
        inputLableNode.setTextContent("");
        inputNode.appendChild(inputLableNode);

        Element inputValueNode = creator.create("value");
        inputValueNode.setTextContent(svdb.getValue());
        inputNode.appendChild(inputValueNode);

        groupNode.appendChild(inputNode);

        node.appendChild(groupNode);
    }

    /**
     * @see de.intevation.gnv.state.State#getDescibeData()
     */
    protected List<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 (List<Object>) (value.getObjectValue());
            }
        }
        return null;
    }

    /**
     * @see de.intevation.gnv.state.State#getDescibeData()
     */
    protected void setDescibeData(String uuid, List<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));
        }
    }

    public Map<String, InputData> inputData() {
        return inputData;
    }

    /**
     * @see de.intevation.gnv.state.State#getInputData()
     */
    public Collection<InputData> getInputData() throws StateException {
        return this.inputData != null ? this.inputData.values() : null;
    }

    public void endOfLife(Object globalContext) {
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org