view gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/FISSelectArtifact.java @ 469:62fc63d0f71d

Added a new State in Product Verticalprofile in Timeseriespoints. Now it will be displayed the Years where measurements happened and than only the dates of the chosen Year will be fetched and displayed. gnv-artifacts/trunk@532 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 12 Jan 2010 12:42:53 +0000
parents 70df44021a9f
children
line wrap: on
line source
package de.intevation.gnv.artifacts.fis;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
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.DefaultArtifact;
import de.intevation.artifactdatabase.ProxyArtifact;
import de.intevation.artifactdatabase.XMLUtils;
import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.ArtifactFactory;
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.context.GNVArtifactContext;
import de.intevation.gnv.artifacts.fis.product.DefaultProduct;
import de.intevation.gnv.artifacts.fis.product.Product;
import de.intevation.gnv.artifacts.ressource.RessourceFactory;
import de.intevation.gnv.state.DefaultInputData;
import de.intevation.gnv.state.InputData;
import de.intevation.gnv.utils.ArtifactFactoryUtilities;


/**
 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
 */
public class FISSelectArtifact extends DefaultArtifact {

    public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER";

    public static final String XPATH_ARTIFACT_CONFIGURATION =
        "/artifact-database/artifacts/artifact[@name='"
        + XPATH_IDENTIFIER_REPLACE + "']";

    public static final String XPATH_UUID = "art:action/art:uuid/@value";

    public static final String XPATH_HASH = "art:action/art:hash/@value";

    public static final String XPATH_INPUT_DATA_VALUE =
        "art:action/art:data/art:input[@name='product']/@value";

    /**
     * this xpath is related to the config.xml document which doesn't have any
     * prefixes yet
     */
    public static final String XPATH_PRODUCTS = "products/product";

    /**
     * this xpath is related to the config.xml document which doesn't have any
     * prefixes yet
     */
    public static final String XPATH_PRODUCT_PARAMETER = "parameters/parameter";

    public static final String XFORM_URL    = "http://www.w3.org/2002/xforms";
    public static final String XFORM_PREFIX = "xform";

    private static Logger log = Logger.getLogger(FISSelectArtifact.class);

    private HashMap  products;
    private Product  current;
    private Artifact artifact;
    private String   name;

    public FISSelectArtifact() {
        super();
    }


    @Override
    public void setup(
        String          identifier,
        ArtifactFactory factory,
        Object          context
    ) {
        log.debug("setup()");
        super.setup(identifier, factory, context);
        this.name = factory.getName();

        if (context instanceof GNVArtifactContext) {
            GNVArtifactContext gnvContext   = (GNVArtifactContext) context;
            Document           doc          = gnvContext.getConfig();
            Node               artifactNode = getConfigurationFragment(doc);

            NodeList products = (NodeList) XMLUtils.xpath(
                artifactNode, XPATH_PRODUCTS, XPathConstants.NODESET);

            if (products != null) {
                this.products = new HashMap(products.getLength());

                for (int i = 0; i < products.getLength(); i++) {
                    Element  productNode    = (Element)products.item(i);
                    String   productName    = productNode.getAttribute("name");
                    NodeList parameterNodes = (NodeList) XMLUtils.xpath(
                        productNode,
                        XPATH_PRODUCT_PARAMETER,
                        XPathConstants.NODESET
                    );

                    Collection<InputData> parameter = null;
                    if (parameterNodes != null) {
                        parameter = new ArrayList(parameterNodes.getLength());

                        for (int j = 0; j < parameterNodes.getLength(); j++) {
                            Element parameterNode = (Element)parameterNodes.item(j);
                            String name  = parameterNode.getAttribute("name");
                            String value = parameterNode.getAttribute("value");
                            parameter.add(new DefaultInputData(name, value));
                        }
                    }
                    Node artifactFactoryNode = (Node) XMLUtils.xpath(
                        productNode, "artifact-factory", XPathConstants.NODE
                    );

                    ArtifactFactory artifactFactory =
                        new ArtifactFactoryUtilities().createArtitfactFactor(
                            doc, artifactFactoryNode
                        );

                    this.products.put(productName, new DefaultProduct(
                        productName, parameter, artifactFactory)
                    );
                }
            }
        }
    }


    @Override
    public Document feed(Document target, CallContext context) {
        log.debug("FISSelectArtifact.feed()");

        if (artifact == null) {
            Document document    = XMLUtils.newDocument();
            String   productName = XMLUtils.xpathString(
                target,
                XPATH_INPUT_DATA_VALUE,
                ArtifactNamespaceContext.INSTANCE
            );

            current = (Product) products.get(productName);

            String reportNode = null;
            String resultNode = null;
            String msg        = null;

            if (current != null) {
                reportNode = "result";
                resultNode = "success";
                msg        = "Feed was successfully. New Artifact created.";
            }
            else {
                reportNode = "exceptionreport";
                resultNode = "exception";
                msg        = "Product does not exist.";
            }

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

            Element report  = creator.create(reportNode);
            Element success = creator.create(resultNode);
            success.setTextContent(msg);
            report.appendChild(success);
            document.appendChild(report);

            return document;
        }
        else {
            return artifact.feed(target, context);
        }
    }


    @Override
    public Document advance(Document target, CallContext context) {
        log.debug("FISSelectArtifact.advance()");

        if (artifact != null) {
            Document result = artifact.advance(target, context);
            context.putContextValue(ProxyArtifact.REPLACE_PROXY, artifact);
            return result;
        }

        Document result = XMLUtils.newDocument();
        if (current == null) {
            // artifact needs to be feeded first
            String msg = "Artifact is not configured properly. Call 'feed' fist.";
            log.error(msg);

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

            Element report = creator.create("exceptionreport");
            Element exception = creator.create("exception");
            exception.setTextContent(msg);
            report.appendChild(exception);
            result.appendChild(report);

            return result;
        }

        String uuid = XMLUtils.xpathString(
            target, XPATH_UUID, ArtifactNamespaceContext.INSTANCE
        );

        String hash = XMLUtils.xpathString(
            target, XPATH_HASH, ArtifactNamespaceContext.INSTANCE
        );

        artifact = current.getArtifactFactory().createArtifact(
            uuid, context
        );

        Document feedDocument = feedDocument(uuid, hash);
        artifact.feed(feedDocument(uuid, hash), context);

        result = ((GNVArtifactBase) artifact).initialize(context);
        if (artifact instanceof GNVArtifactBase) {
            ((GNVArtifactBase) artifact).setProduct(current);
        }
        context.putContextValue(ProxyArtifact.REPLACE_PROXY, artifact);
        return result;
    }


    @Override
    public Document describe(Document data, CallContext context) {
        log.debug("FISSelectArtifact.describe()");

        // create root node
        Document document               = XMLUtils.newDocument();
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX
        );

        Element rootNode = creator.create("result");
        Element typeNode = creator.create("type");
        creator.addAttr(typeNode, "name", "describe");
        rootNode.appendChild(typeNode);

        Element uuidNode = creator.create("uuid");
        creator.addAttr(uuidNode, "value", super.identifier);
        rootNode.appendChild(uuidNode);

        Element hashNode = creator.create("hash");
        creator.addAttr(hashNode, "value", hash());
        rootNode.appendChild(hashNode);

        // create output node
        Element out = creator.create("outputs");
        rootNode.appendChild(out);

        // create current state
        Element state = creator.create("state");
        creator.addAttr(state, "name", "choose-product");
        creator.addAttr(state, "description", "Auswahl des Produktes.");
        rootNode.appendChild(state);

        // create reachable states
        Element rStates = creator.create("reachable-states");
        appendProducts(document, rStates, context);
        rootNode.appendChild(rStates);

        // create model
        Element model = creator.create("model");
        Element input = creator.create("input");
        creator.addAttr(input, "name", "product");
        creator.addAttr(input, "type", "String");
        model.appendChild(input);
        rootNode.appendChild(model);

        // create ui
        Element ui      = creator.create("ui");
        Element dynamic = creator.create("dynamic");
        appendSelectProducts(document, dynamic, context.getMeta());
        ui.appendChild(dynamic);
        rootNode.appendChild(ui);

        document.appendChild(rootNode);
        return document;
    }


    @Override
    public void out(Document document, OutputStream out, CallContext context)
    throws IOException
    {
        log.debug("FISSelectArtifact.out()");
        if (artifact != null) {
            artifact.out(document, out, context);
        }
    }


    protected void appendProducts(
        Document document,
        Node     parent,
        Object   context
    ) {
        Iterator iter = products.values().iterator();

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

        while(iter.hasNext()) {
            Product prod = (Product) iter.next();
            String  name = prod.getName();

            Element current = creator.create("state");
            creator.addAttr(current, "name", name);
            creator.addAttr(current, "description", name);
            parent.appendChild(current);
        }
    }


    protected void appendSelectProducts(
        Document document,
        Node     node,
        CallMeta callMeta
    ) {
        RessourceFactory ressource = RessourceFactory.getInstance();

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

        String  selectboxName = "product";
        Element selectNode    = creator.create("select1");
        creator.addAttr(selectNode, "ref", selectboxName);

        Element lableNode = creator.create("label");
        lableNode.setTextContent(ressource.getRessource(callMeta.getLanguages(),
                selectboxName,
                selectboxName
            )
        );

        Element choiceNode = creator.create("choices");
        selectNode.appendChild(lableNode);
        selectNode.appendChild(choiceNode);

        Iterator it = products.values().iterator();
        while (it.hasNext()) {
            Product p               = (Product) it.next();
            Element itemNode        = creator.create("item");
            Element choiceLableNode = creator.create("label");
            choiceLableNode.setTextContent(ressource.getRessource(
                callMeta.getLanguages(),
                p.getName(),
                p.getName()
            ));
            itemNode.appendChild(choiceLableNode);

            Element choiceValueNode = creator.create("value");
            choiceValueNode.setTextContent(p.getName());
            itemNode.appendChild(choiceValueNode);
            choiceNode.appendChild(itemNode);
        }

        node.appendChild(selectNode);
    }


    protected Node getConfigurationFragment(Document document) {
        String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll(
            XPATH_IDENTIFIER_REPLACE, name
        );

        return (Node) XMLUtils.xpath(document, xpathQuery, XPathConstants.NODE);
    }


    protected Document feedDocument(String uuid, String hash) {
        Document document = XMLUtils.newDocument();

        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX
        );
        Element  rootNode = creator.create("action");

        Element typeNode = creator.create("type");
        creator.addAttr(typeNode, "name", "feed");
        rootNode.appendChild(typeNode);

        Element uuidNode = creator.create("uuid");
        creator.addAttr(uuidNode, "value", uuid);
        rootNode.appendChild(uuidNode);

        Element hashNode = creator.create("hash");
        creator.addAttr(hashNode, "value", hash);
        rootNode.appendChild(hashNode);

        Element dataNode = creator.create("data");
        rootNode.appendChild(dataNode);

        Collection<InputData> parameter = this.current.getParameter();
        if (parameter != null) {
            Iterator<InputData> parameterIt = parameter.iterator();

            while (parameterIt.hasNext()) {
                InputData inputData = parameterIt.next();

                Element inputNode = creator.create("input");
                creator.addAttr(inputNode, "name", inputData.getName());
                creator.addAttr(inputNode, "value", inputData.getValue());
                dataNode.appendChild(inputNode);
            }
        }
        document.appendChild(rootNode);
        return document;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org