view gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java @ 186:8ae596be276b

Changed Domainlable for Verticalprofiles according to the Specification GT_0030.005 gnv-artifacts/trunk@230 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Fri, 16 Oct 2009 12:39:18 +0000
parents 1b2fc94766c9
children baaa1618fa27
line wrap: on
line source
/**
 *
 */
package de.intevation.gnv.transition;

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.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.transition.describedata.DefaultKeyValueDescribeData;
import de.intevation.gnv.transition.describedata.KeyValueDescibeData;
import de.intevation.gnv.transition.describedata.MinMaxDescribeData;
import de.intevation.gnv.transition.describedata.NamedArrayList;
import de.intevation.gnv.transition.describedata.NamedCollection;
import de.intevation.gnv.transition.describedata.SingleValueDescribeData;
import de.intevation.gnv.transition.exception.TransitionException;
import de.intevation.gnv.utils.ArtifactXMLUtilities;
import de.intevation.gnv.utils.InputValidator;

/**
 * @author Tim Englich <tim.englich@intevation.de>
 * 
 */
public abstract class TransitionBase implements Transition {

    /**
     * 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 String id = null;

    private String description = null;

    protected String dataName = null;

    protected boolean dataMultiSelect = false;

    protected String queryID = null;

    private Collection<String> reachableTransitions = null;

    protected Collection<String> inputValueNames = null;

    private Map<String, InputValue> inputValues = null;

    private Transition parent = null;

    protected Map<String, InputData> inputData = null;

    protected Collection<Object> descibeData = null;

    /**
     * Constructor
     */
    public TransitionBase() {
        super();
    }

    /**
     * @see de.intevation.gnv.transition.Transition#getID()
     */
    public String getID() {
        return this.id;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#getDescription()
     */
    public String getDescription() {
        return this.description;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#reachableTransitions()
     */
    public Collection<String> reachableTransitions() {
        return this.reachableTransitions;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#getRequiredInputValues()
     */
    public Collection<InputValue> getRequiredInputValues() {
        return this.inputValues.values();
    }

    /**
     * @see de.intevation.gnv.transition.Transition#setup(org.w3c.dom.Node)
     */
    public void setup(Node configuration) {
        log.debug("TransitionBase.setup");
        this.id = Config.getStringXPath(configuration, "@id");
        this.description = Config.getStringXPath(configuration, "@description");

        log.info("Transition-ID = " + this.id);
        NodeList nodes = Config.getNodeSetXPath(configuration,
                "reachableTransitions/transition");
        this.reachableTransitions = new ArrayList<String>(nodes.getLength());
        for (int i = 0; i < nodes.getLength(); i++) {
            String reachableTransition = nodes.item(i).getTextContent();
            log.info("ReachableTransition ==> " + reachableTransition);
            this.reachableTransitions.add(reachableTransition);

        }

        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++) {
            Node inputValueNode = inputValuesNodes.item(i);
            String usedinQueryValue = Config.getStringXPath(inputValueNode,
                    "@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(Config
                    .getStringXPath(inputValueNode, "@name"), Config
                    .getStringXPath(inputValueNode, "@type"), Boolean
                    .parseBoolean(Config.getStringXPath(inputValueNode,
                            "@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);
        }

    }

    /**
     * @see de.intevation.gnv.transition.Transition#getParent()
     */
    public Transition getParent() {
        return this.parent;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#setParent(de.intevation.gnv.transition.Transition)
     */
    public void setParent(Transition transition) {
        this.parent = transition;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#putInputData(java.util.Collection)
     */
    public void putInputData(Collection<InputData> inputData, String uuid)
                                                                          throws TransitionException {
        log.debug("TransitionBase.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) {
                        this.setSelection(tmpItem);
                        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 TransitionException(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 void setSelection(InputData inputData) {
        log.debug("TransitionBase.setSelection");

        Object o = this.getDescribeData(inputData.getName());
        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(data.getMinName())) {
                    // TODO: m�ssen die werte geparst werden?
                    data.setMinValue(inputData.getValue());
                }
                if (inputData.getName().equals(data.getMaxName())) {
                    // TODO: m�ssen die werte geparst werden?
                    data.setMaxValue(inputData.getValue());
                }
            }
        }
    }

    private Object getDescribeData(String name) {
        log.debug("TransitionBase.getDescribeData");
        if (this.descibeData != null) {
            Iterator<Object> it = this.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;
                    }
                }
            }
        }
        return null;

    }

    /**
     * @see de.intevation.gnv.transition.Transition#isTransitionReachable(java.lang.String)
     */
    public boolean isTransitionReachable(String transitionID) {
        log.debug("TransitionBase.isTransitionReachable");
        boolean returnValue = false;
        Iterator<String> transitions = reachableTransitions.iterator();
        while (transitions.hasNext()) {
            if (transitions.next().equals(transitionID)) {
                log.debug("Transition " + transitionID + " wird unterst�tzt.");
                returnValue = true;
                break;
            }
        }
        return returnValue;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#advance(java.lang.String,
     *      de.intevation.artifacts.CallMeta)
     */
    public void advance(String uuid, CallMeta callMeta)
                                                       throws TransitionException {
        log.debug("TransitionBase.advance");
        try {
            List<String> list = new ArrayList<String>();

            Iterator<String> it = this.inputValueNames.iterator();
            int i = 0;
            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]);
            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 TransitionException(e);
        }
    }
    
    protected String prepareInputData4RegionDBQuery(String value){
        return value;
    }

    private String prepareInputData4DateDBQuery(String value) {
        log.debug("TransitionBase.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("TransitionBase.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("TransitionBase.purifyResult");
        if (this.descibeData == null) {
            this.descibeData = new ArrayList<Object>();
        }
        NamedCollection<KeyValueDescibeData> keyValueDescibeData = extractKVP(result, "KEY", "VALUE");
        this.descibeData.add(keyValueDescibeData);
    }

    /**
     * @param result
     * @return
     */
    protected NamedCollection<KeyValueDescibeData> extractKVP(
                                                              Collection<Result> result,
                                                              String keyid,
                                                              String valueid) {
        Iterator<Result> rit = result.iterator();
        NamedCollection<KeyValueDescibeData> keyValueDescibeData = new NamedArrayList<KeyValueDescibeData>(
                this.dataName, result.size());
        keyValueDescibeData.setMultiSelect(this.dataMultiSelect);
        while (rit.hasNext()) {
            Result resultValue = rit.next();
            keyValueDescibeData.add(new DefaultKeyValueDescribeData(resultValue
                    .getString(keyid), resultValue.getString(valueid)));
        }
        return keyValueDescibeData;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#describe(org.w3c.dom.Document,
     *      org.w3c.dom.Node, de.intevation.artifacts.CallMeta)
     */
    public void describe(Document document, Node rootNode, CallMeta callMeta) {
        log.debug("TransitionBase.describe");
        if (this.descibeData != null) {
            ArtifactXMLUtilities xmlutilities = new ArtifactXMLUtilities();
            Iterator<Object> it = this.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()) {
                        dynamic.appendChild(selectNode);
                    } else {
                        staticNode.appendChild(selectNode);
                    }

                } else if (o instanceof MinMaxDescribeData) {
                    MinMaxDescribeData descibeData = (MinMaxDescribeData) o;
                    Object min = descibeData.getMinValue();
                    Object max = descibeData.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 inputMinNode = xmlutilities.createXFormElement(
                            document, "input");
                    inputMinNode.setAttribute("ref", "minvalue");
                    Element inputMinLableNode = xmlutilities
                            .createXFormElement(document, "label");
                    inputMinLableNode.setTextContent(RessourceFactory
                            .getInstance().getRessource(
                                    callMeta.getLanguages(), "minvalue",
                                    "minvalue"));
                    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", "maxvalue");
                    Element inputMaxLableNode = xmlutilities
                            .createXFormElement(document, "label");
                    inputMaxLableNode.setTextContent(RessourceFactory
                            .getInstance().getRessource(
                                    callMeta.getLanguages(), "maxvalue",
                                    "maxvalue"));
                    inputMaxNode.appendChild(inputMaxLableNode);

                    Element inputMaxValueNode = xmlutilities
                            .createXFormElement(document, "value");
                    inputMaxValueNode.setTextContent(max.toString());
                    inputMaxNode.appendChild(inputMaxValueNode);

                    if (!it.hasNext()) {
                        dynamic.appendChild(inputMinNode);
                        dynamic.appendChild(inputMaxNode);
                    } else {
                        staticNode.appendChild(inputMinNode);
                        staticNode.appendChild(inputMaxNode);
                    }
                } else if (o instanceof SingleValueDescribeData) {

                    SingleValueDescribeData svdb = (SingleValueDescribeData) o;

                    Element inputNode = xmlutilities.createXFormElement(
                            document, "input");
                    inputNode.setAttribute("ref", svdb.getName());

                    Element inputLableNode = xmlutilities.createXFormElement(
                            document, "label");
                    inputLableNode.setTextContent(RessourceFactory
                            .getInstance().getRessource(
                                    callMeta.getLanguages(), svdb.getName(),
                                    svdb.getName()));
                    inputNode.appendChild(inputLableNode);

                    Element inputValueNode = xmlutilities.createXFormElement(
                            document, "value");
                    inputValueNode.setTextContent(svdb.getValue());
                    inputNode.appendChild(inputValueNode);

                    if (!it.hasNext()) {
                        dynamic.appendChild(inputNode);
                    } else {
                        staticNode.appendChild(inputNode);
                    }
                }

            }
        }
    }

    /**
     * @see de.intevation.gnv.transition.Transition#getDescibeData()
     */
    public Collection<Object> getDescibeData() {
        return this.descibeData;
    }

    /**
     * @see de.intevation.gnv.transition.Transition#setDescibeData(java.util.Collection)
     */
    public void setDescibeData(Collection<Object> descibeData) {
        this.descibeData = descibeData;

    }

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

http://dive4elements.wald.intevation.org