view flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java @ 1944:21a4d2c677a1

Changed doOut signature, side effect from blackboard feature (to come). flys-artifacts/trunk@3334 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Wed, 30 Nov 2011 10:10:42 +0000
parents 41ba2276d785
children 65f9d707caff
line wrap: on
line source
package de.intevation.flys.exports;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Locale;

import javax.xml.xpath.XPathConstants;

import org.apache.log4j.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.jfree.data.Range;

import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.CallContext;
import de.intevation.artifacts.CallMeta;
import de.intevation.artifacts.PreferredLocale;

import de.intevation.artifacts.ArtifactNamespaceContext;
import de.intevation.artifacts.common.utils.XMLUtils;

import de.intevation.artifactdatabase.state.Facet;

import de.intevation.flys.model.River;

import de.intevation.flys.artifacts.WINFOArtifact;
import de.intevation.artifactdatabase.state.ArtifactAndFacet;

import de.intevation.flys.artifacts.resources.Resources;
import de.intevation.flys.utils.FLYSUtils;


/**
 * The base class for chart creation. It should provide some basic things that
 * equal in all chart types.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public abstract class ChartGenerator implements OutGenerator {

    private static Logger logger = Logger.getLogger(ChartGenerator.class);

    /** The default chart width, if no other width is set. */
    public static final int DEFAULT_CHART_WIDTH  = 600;

    /** The default chart height, if no other height is set.*/
    public static final int DEFAULT_CHART_HEIGHT = 400;

    /** The default chart format, if no other height is set.*/
    public static final String DEFAULT_CHART_FORMAT = "png";

    /** The XPath that points to the chart size of the incoming request
     * document.*/
    public static final String XPATH_CHART_SIZE =
        "/art:action/art:attributes/art:size";

    public static final String XPATH_CHART_FORMAT =
        "/art:action/art:attributes/art:format/@art:value";

    public static final String XPATH_CHART_X_RANGE =
        "/art:action/art:attributes/art:xrange";

    public static final String XPATH_CHART_Y_RANGE =
        "/art:action/art:attributes/art:yrange";


    /** The document of the incoming out() request.*/
    protected Document request;

    /** The output stream where the data should be written to.*/
    protected OutputStream out;

    /** The CallContext object.*/
    protected CallContext context;

    /** The artifact that is used to decorate the chart with meta information.*/
    protected Artifact master;


    public void init(Document request, OutputStream out, CallContext context) {
        logger.debug("ChartGenerator.init");

        this.request = request;
        this.out     = out;
        this.context = context;
    }


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


    protected Locale getLocale() {
        CallMeta           meta = context.getMeta();
        PreferredLocale[] prefs = meta.getLanguages();

        int len = prefs != null ? prefs.length : 0;

        Locale[] locales = new Locale[len];

        for (int i = 0; i < len; i++) {
            locales[i] = prefs[i].getLocale();
        }

        return meta.getPreferredLocale(locales);
    }


    protected String msg(String key, String def) {
        return Resources.getMsg(context.getMeta(), key, def);
    }


    protected String msg(String key, String def, Object[] args) {
        return Resources.getMsg(context.getMeta(), key, def, args);
    }


    protected String getRiverName() {
        WINFOArtifact flys = (WINFOArtifact) master;

        River river = FLYSUtils.getRiver(flys);
        return (river != null) ? river.getName() : "";
    }


    protected double[] getRange() {
        WINFOArtifact flys = (WINFOArtifact) master;

        return FLYSUtils.getKmRange(flys);
    }


    /**
     * 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 the result of
     * getDefaultSize() 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 : getDefaultSize();
    }


    protected String getFormat() {
        String format = (String) XMLUtils.xpath(
            request,
            XPATH_CHART_FORMAT,
            XPathConstants.STRING,
            ArtifactNamespaceContext.INSTANCE);

        return format == null || format.length() == 0
            ? DEFAULT_CHART_FORMAT
            : format;
    }


    /**
     * Get Range of Domain ("X"-) Axis from request.
     */
    protected Range getDomainAxisRange() {
        Element xrange = (Element)XMLUtils.xpath(
            request,
            XPATH_CHART_X_RANGE,
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE);

        if (xrange == null) {
            return null;
        }

        String uri = ArtifactNamespaceContext.NAMESPACE_URI;

        String lower = xrange.getAttributeNS(uri, "from");
        String upper = xrange.getAttributeNS(uri, "to");

        if (lower.length() > 0 && upper.length() > 0) {
            try {
                double from = Double.parseDouble(lower);
                double to   = Double.parseDouble(upper);

                if (from == 0 && to == 0) {
                    logger.debug("No range specified. Lower and upper X == 0");
                    return null;
                }

                if (from > to) {
                    double tmp = to;
                    to         = from;
                    from       = tmp;
                }

                return new Range(from, to);
            }
            catch (NumberFormatException nfe) {
                logger.warn("Wrong values for domain axis range.");
            }
        }

        return null;
    }


    protected Range getValueAxisRange() {
        Element yrange = (Element)XMLUtils.xpath(
            request,
            XPATH_CHART_Y_RANGE,
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE);

        if (yrange == null) {
            return null;
        }


        String uri = ArtifactNamespaceContext.NAMESPACE_URI;


        String lower = yrange.getAttributeNS(uri, "from");
        String upper = yrange.getAttributeNS(uri, "to");

        if (lower.length() > 0 && upper.length() > 0) {
            try {
                double from = Double.parseDouble(lower);
                double to   = Double.parseDouble(upper);

                if (from == 0 && to == 0) {
                    logger.debug("No range specified. Lower and upper Y == 0");
                    return null;
                }

                return from > to
                       ? new Range(to, from)
                       : new Range(from, to);
            }
            catch (NumberFormatException nfe) {
                logger.warn("Wrong values for value axis range.");
            }
        }

        return null;
    }


    /**
     * Returns the default size of a chart export as array.
     *
     * @return the default size of a chart as [width, height].
     */
    protected int[] getDefaultSize() {
        return new int[] { DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT };
    }


    public abstract void doOut(
        ArtifactAndFacet bundle,
        Document attr,
        boolean  visible);

    public abstract void generate() throws IOException;
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org