view artifacts/src/main/java/org/dive4elements/river/exports/sq/SQOverviewGenerator.java @ 7242:69709f490d92

Polish labels and remove unused classes. SQOverview is currently broken.
author Andre Heinecke <aheinecke@intevation.de>
date Fri, 04 Oct 2013 17:56:02 +0200
parents ada424214b02
children 01deeed9d169
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.exports.sq;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.xml.xpath.XPathConstants;

import org.apache.log4j.Logger;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifactdatabase.state.Settings;
import org.dive4elements.artifacts.Artifact;
import org.dive4elements.artifacts.ArtifactDatabaseException;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
import org.dive4elements.artifacts.common.utils.XMLUtils;
import org.dive4elements.river.artifacts.context.RiverContext;
import org.dive4elements.river.collections.D4EArtifactCollection;
import org.dive4elements.river.exports.ChartGenerator2;
import org.dive4elements.river.exports.OutGenerator;
import org.dive4elements.river.exports.OutputHelper;
import org.dive4elements.river.themes.ThemeDocument;

public class SQOverviewGenerator
implements OutGenerator
{
    private static Logger logger = Logger.getLogger(SQOverviewGenerator.class);

    public static final String XPATH_CHART_SIZE =
        "/art:action/art:attributes/art:size";

    protected D4EArtifactCollection collection;

    protected Artifact master;

    protected Settings settings;

    protected Document request;

    protected OutputStream out;

    protected CallContext context;

    protected List<JFreeChart> charts;

    protected String outName;

    @Override
    public void setup(Object config) {
        logger.debug("SQOverviewGenerator.setup");
    }

    /**
     * Produce output.
     * @param artifactAndFacet current facet and artifact.
     * @param attr  theme for facet
     */
    @Override
    public void doOut(
        ArtifactAndFacet artifactAndFacet,
        ThemeDocument    attr,
        boolean          visible
    ) {
        logger.debug("doOut()");

        // TODO: Why not using outName for this.

        String name = artifactAndFacet.getData(context).toString();
        if(name != null) {
            logger.debug("name: " + name);
            ChartGenerator2 g =
                (ChartGenerator2)RiverContext.getOutGenerator(
                    context,
                    name,
                    null);

            if (g == null) {
                logger.debug("generator is null.");
                return;
            }

            OutputHelper helper = new OutputHelper(master.identifier());
            Document collectionAttribute = collection.getAttribute();

            try {
                Document cAttr = getAttribute(context, collectionAttribute, name);
                g.init(name, request, out, context);

                helper.doOut(g, name, name, cAttr, context);
                JFreeChart chart = g.generateChart();
                chart.removeLegend();
                charts.add(chart);
            }
            catch (IOException e) {
                logger.warn(e);
            }
            catch (ArtifactDatabaseException e) {
                logger.warn(e);
            }
        }
    }

    @Override
    public void init(String outName, Document request, OutputStream out, CallContext context) {
        this.outName = outName;
        this.request = request;
        this.out = out;
        this.context = context;
        charts = new ArrayList<JFreeChart>();
    }

    @Override
    public void setMasterArtifact(Artifact master) {
        this.master = master;
    }

    @Override
    public void setCollection(D4EArtifactCollection collection) {
        this.collection = collection;
    }

    @Override
    public void generate() throws IOException {
        logger.debug("SQOverviewGenerator.generate");

        int[] size = getSize();

        if (size == null) {
            size = new int[] {400, 600};
        }
        BufferedImage result =
            new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB);
        for (int i = 0; i < charts.size(); i++) {
            logger.debug("index: " + i);
            JFreeChart chart = charts.get(i);
            ChartRenderingInfo info = new ChartRenderingInfo();
            BufferedImage img =
                chart.createBufferedImage(size[0]/2, size[1]/3, info);
            int horPos = 0;
            int vertPos = 0;
            if (i % 2 == 1) {
                horPos = size[0]/2;
            }
            if (i > 1) {
                vertPos = (size[1] / 3) * (i / 2);
            }
            // TODO: Dispose Graphics object!
            result.createGraphics().drawImage(img, horPos, vertPos, null);
        }
        ImageIO.write(result, "png", out);
    }

    @Override
    public void setSettings(Settings settings) {
        this.settings = settings;
    }

    @Override
    public Settings getSettings() {
        return this.settings;
    }


    /**
     * Returns the "attribute" (part of description document) for a specific
     * output type.
     *
     * @param context The CallContext object.
     * @param attr The xml attribute saved at the collection.
     * @param output The name of the desired output type.
     *
     * @return the attribute for the desired output type.
     */
    protected Document getAttribute(
        CallContext context,
        Document    attr,
        String      output)
    throws    ArtifactDatabaseException
    {
        logger.debug("find specific XML node for Output: " + output);

        Map<String, String> vars = new HashMap<String, String>();
        vars.put("output", output);

        Node out = (Node) XMLUtils.xpath(
            attr,
            "art:attribute/art:outputs/art:output[@name=$output]",
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE,
            vars);

        if (out != null) {
            Document o = XMLUtils.newDocument();
            o.appendChild(o.importNode(out, true));

            return o;
        }

        return null;
    }


    /**
     * Returns the size of a chart export as array which has been specified by
     * the incoming request document.
     *
     * @return the size of a chart as [width, height] or null if no width or
     * height are given in the request document.
     */
    protected int[] getSize() {
        int[] size = new int[2];

        Element sizeEl = (Element)XMLUtils.xpath(
            request,
            XPATH_CHART_SIZE,
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE);

        if (sizeEl != null) {
            String uri = ArtifactNamespaceContext.NAMESPACE_URI;

            String w = sizeEl.getAttributeNS(uri, "width");
            String h = sizeEl.getAttributeNS(uri, "height");

            if (w.length() > 0 && h.length() > 0) {
                try {
                    size[0] = Integer.parseInt(w);
                    size[1] = Integer.parseInt(h);
                }
                catch (NumberFormatException nfe) {
                    logger.warn("Wrong values for chart width/height.");
                }
            }
        }

        return size[0] > 0 && size[1] > 0 ? size : null;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org