view flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java @ 2660:1a044c51abe4

Respect colors of theme for linelabels. flys-artifacts/trunk@4334 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Wed, 02 May 2012 22:30:27 +0000
parents 4d8959a4b49d
children bdc86e61428c
line wrap: on
line source
package de.intevation.flys.utils;

import org.apache.log4j.Logger;

import java.awt.Color;
import java.awt.Font;

import javax.xml.xpath.XPathConstants;

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

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

import de.intevation.flys.artifacts.model.MapserverStyle;
import de.intevation.flys.artifacts.model.MapserverStyle.Clazz;
import de.intevation.flys.artifacts.model.MapserverStyle.Expression;
import de.intevation.flys.artifacts.model.MapserverStyle.Style;
import de.intevation.flys.artifacts.model.MapserverStyle.Label;


/**
 * Utility to deal with themes and their representations.
 */
public class ThemeUtil {

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

    public final static String XPATH_FILL_COLOR =
        "/theme/field[@name='fillcolor']/@default";

    public final static String XPATH_LINE_COLOR =
        "/theme/field[@name='linecolor']/@default";

    public static final String XPATH_LINE_SIZE =
        "/theme/field[@name='linesize']/@default";

    public static final String XPATH_LINE_STYLE =
        "/theme/field[@name='linetype']/@default";

    public static final String XPATH_POINT_SIZE =
        "/theme/field[@name='pointsize']/@default";

    public final static String XPATH_SHOW_BORDER =
        "/theme/field[@name='showborder']/@default";

    public final static String XPATH_SHOW_POINTS =
        "/theme/field[@name='showpoints']/@default";

    public final static String XPATH_SHOW_LINE =
        "/theme/field[@name='showlines']/@default";

    public final static String XPATH_SHOW_LINE_LABEL =
        "/theme/field[@name='showlinelabel']/@default";

    public final static String XPATH_LINE_LABEL_FONT =
        "/theme/field[@name='linelabelfont']/@default";

    public final static String XPATH_LINE_LABEL_COLOR =
        "/theme/field[@name='linelabelcolor']/@default";

    public final static String XPATH_LINE_LABEL_SIZE =
        "/theme/field[@name='linelabelsize']/@default";

    public final static String XPATH_LINE_LABEL_STYLE =
        "/theme/field[@name='linelabelstyle']/@default";

    public final static String XPATH_LINE_LABEL_BGCOLOR =
        "/theme/field[@name='linelabelbgcolor']/@default";

    public final static String XPATH_LINE_LABEL_SHOWBG =
        "/theme/field[@name='linelabelshowbg']/@default";

    public final static String XPATH_TRANSPARENCY =
        "/theme/field[@name='transparent']/@default";

    public final static String XPATH_TEXT_COLOR =
        "/theme/field[@name='textcolor']/@default";

    public final static String XPATH_TEXT_SIZE =
        "/theme/field[@name='textsize']/@default";

    public final static String XPATH_TEXT_FONT =
        "/theme/field[@name='font']/@default";

    public final static String XPATH_TEXT_STYLE =
        "/theme/field[@name='textstyle']/@default";

    public final static String XPATH_TEXT_ORIENTATION =
        "/theme/field[@name='textorientation']/@default";

    public final static String XPATH_TEXT_BACKGROUND =
        "/theme/field[@name='backgroundcolor']/@default";

    public final static String XPATH_SHOW_BACKGROUND =
        "/theme/field[@name='showbackground']/@default";

    public final static String XPATH_SYMBOL =
        "/theme/field[@name='symbol']/@default";

    public final static String XPATH_SHOW_MINIMUM =
        "/theme/field[@name='showminimum']/@default";

    public final static String XPATH_SHOW_MAXIMUM =
        "/theme/field[@name='showmaximum']/@default";

    public final static String XPATH_WSPLGEN_FIELDS =
        "/theme[@name='WSPLGEN']/field";


    /** Parse string to be boolean with default if empty or unrecognized. */
    public static boolean parseBoolean(String value, boolean defaultsTo) {
        if (value == null || value.length() == 0) {
            return defaultsTo;
        }
        if (value.equals("false")) {
            return false;
        }
        else if (value.equals("true")) {
            return true;
        }
        else {
            return defaultsTo;
        }
    }


    public static int parseInteger(String value, int defaultsTo) {
        if (value == null || value.length() == 0) {
            return defaultsTo;
        }

        try {
            return Integer.valueOf(value);
        }
        catch (NumberFormatException nfe) {
            // do nothing
        }

        return defaultsTo;
    }


    /**
     * Parses line width, defaulting to 0.
     * @param theme the theme
     */
    public static int parseLineWidth(Document theme) {
        String size = XMLUtils.xpathString(theme, XPATH_LINE_SIZE, null);
        if (size == null || size.length() == 0) {
            return 0;
        }

        try {
            return Integer.valueOf(size);
        }
        catch (NumberFormatException nfe) {
            logger.warn("Unable to set line size from string: '" + size + "'");
        }
        return 0;
    }


    public static int parsePointWidth(Document theme) {
        String width = XMLUtils.xpathString(theme, XPATH_POINT_SIZE, null);

        return parseInteger(width, 3);
    }


    /**
     * Parses the line style, defaulting to '10'.
     * @param theme The theme.
     */
    public static float[] parseLineStyle(Document theme) {
        String dash = XMLUtils.xpathString(theme, XPATH_LINE_STYLE, null);

        float[] def = {10};
        if (dash == null || dash.length() == 0) {
            return def;
        }

        String[] pattern = dash.split(",");
        if(pattern.length == 1) {
            return def;
        }

        try {
            float[] dashes = new float[pattern.length];
            for (int i = 0; i < pattern.length; i++) {
                dashes[i] = Float.parseFloat(pattern[i]);
            }
            return dashes;
        }
        catch(NumberFormatException nfe) {
            logger.warn("Unable to set dash from string: '" + dash + "'");
            return def;
        }
    }


    /**
     * Parses text size, defaulting to 10.
     * @param theme The theme.
     */
    public static int parseTextSize(Document theme, String path) {
        String size = XMLUtils.xpathString(theme, path, null);
        if (size == null || size.length() == 0) {
            return 10;
        }

        try {
            return Integer.valueOf(size);
        }
        catch (NumberFormatException nfe) {
        }
        return 10;
    }


    public static int parseTextSize(Document theme) {
        return parseTextSize(theme, XPATH_TEXT_SIZE);
    }


    public static int parseLineLabelSize(Document theme) {
        return parseTextSize(theme, XPATH_LINE_LABEL_SIZE);
    }


    /**
     * Parses the attribute 'showpoints', defaults to false.
     * @param theme The theme.
     */
    public static boolean parseShowPoints(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_POINTS, null);
        return parseBoolean(show, false);
    }


    /**
     * Parses the attribute 'showlines', defaults to true.
     * @param theme The theme.
     */
    public static boolean parseShowLine(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_LINE, null);
        return parseBoolean(show, true);
    }

    /**
     * Parses the attribute 'showlinelabel', defaults to true.
     * @param theme The theme.
     */
    public static boolean parseShowLineLabel(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_LINE_LABEL, null);
        return parseBoolean(show, true);
    }

    /**
     * Parses text color.
     * @param theme The theme.
     */
    public static Color parseTextColor(Document theme) {
        return parseRGB(getTextColorString(theme));
    }

    
    /** Parse color for line label(s text). */
    public static Color parseLineLabelTextColor(Document theme) {
        return parseRGB(getLineLabelTextColorString(theme));
    }

    /** Parse bg color for line label(s text). */
    public static Color parseLineLabelBGColor(Document theme) {
        return parseRGB(getLineLabelBGColorString(theme));
    }

    // TODO showbg and bg color for linelabels


    /**
     * Parses the font.
     * @param theme The theme.
     */
    public static Font parseTextFont(Document theme) {
        String font = XMLUtils.xpathString(theme, XPATH_TEXT_FONT, null);
        if (font == null || font.length() == 0) {
            return null;
        }

        int size = parseTextSize(theme);
        int style = parseTextStyle(theme);
        Font f = new Font (font, style, size);
        return f;
    }

    /** Parse font (name, size and style) for linelabels. */
    public static Font parseLineLabelFont(Document theme) {
        String font = XMLUtils.xpathString(theme, XPATH_LINE_LABEL_FONT, null);
        if (font == null || font.length() == 0) {
            return null;
        }

        int size = parseLineLabelSize(theme);
        int style = parseLineLabelStyle(theme);

        Font f = new Font (font, style, size);
        return f;
    }


    /**
     * Parses the text style, defaults to 'Font.PLAIN'.
     * @param theme The theme.
     */
    public static int parseTextStyle(Document theme, String path) {
        String style = XMLUtils.xpathString(theme, path, null);
        if (style == null || style.length() == 0) {
            return Font.PLAIN;
        }

        if (style.equals("italic")) {
            return Font.ITALIC;
        }
        else if (style.equals("bold")) {
            return Font.BOLD;
        }
        else {
            return Font.PLAIN;
        }
    }


    public static int parseTextStyle(Document theme) {
        return parseTextStyle(theme, XPATH_TEXT_STYLE);
    }


    public static int parseLineLabelStyle(Document theme) {
        return parseTextStyle(theme, XPATH_LINE_LABEL_STYLE);
    }


    /**
     * Parses the textorientation, defaults to 'vertical'.
     * @param theme The theme.
     */
    public static String parseTextOrientation(Document theme) {
        String o = XMLUtils.xpathString(theme, XPATH_TEXT_ORIENTATION, null);
        if (o == null || o.length() == 0) {
            return "vertical";
        }
        if(o.equals("true")) {
            return "horizontal";
        }
        else {
            return "vertical";
        }
    }


    /**
     * Parses the text background color, defaults to white.
     * @param theme The theme.
     */
    public static Color parseTextBackground(Document theme) {
        String color = getBackgroundColorString(theme);
        if (color == null || color.length() == 0) {
            return Color.WHITE;
        }
        return parseRGB(color);
    }


    /**
     * Parses the attribute whether to show background or not, defaults to
     * false.
     * @param theme The theme.
     */
    public static boolean parseShowTextBackground(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_BACKGROUND, null);
        return parseBoolean(show, false);
    }


    /**
     * Parse a string like "103, 100, 0" and return a corresping color.
     * @param rgbtext Color as string representation, e.g. "255,0,20".
     * @return Color, null in case of issues.
     */
    public static Color parseRGB(String rgbtext) {
        if (rgbtext == null) {
            return null;
        }
        String rgb[] = rgbtext.split(",");
        Color c = null;
        try {
            c = new Color(
                    Integer.valueOf(rgb[0].trim()),
                    Integer.valueOf(rgb[1].trim()),
                    Integer.valueOf(rgb[2].trim()));
        }
        catch (NumberFormatException nfe) {
            c = null;
        }
        return c;
    }


    public static String getLineColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_LINE_COLOR, null);
    }

    /** Get show border as string. */
    public static String getShowBorderString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_SHOW_BORDER, null);
    }

    /** Get fill color as string. */
    public static String getFillColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_FILL_COLOR, null);
    }

    public static String getBackgroundColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_TEXT_BACKGROUND, null);
    }


    public static String getTextColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_TEXT_COLOR, null);
    }

    public static String getLineLabelTextColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_LINE_LABEL_COLOR, null);
    }

    public static String getLineLabelBGColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_LINE_LABEL_BGCOLOR, null);
    }

    public static String getSymbol(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_SYMBOL, null);
    }

    public static String getTransparencyString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_TRANSPARENCY, null);
    }


    public static String getShowMinimum(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_SHOW_MINIMUM, null);
    }


    public static String getShowMaximum(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_SHOW_MAXIMUM, null);
    }


    /**
     * Gets color from color field.
     * @param theme    the theme document.
     * @return color.
     */
    public static Color parseFillColorField(Document theme) {
        return parseRGB(getFillColorString(theme));
    }

    public static boolean parseShowBorder(Document theme) {
        return parseBoolean(getShowBorderString(theme), false);
    }

    public static boolean parseTransparency(Document theme) {
        return parseBoolean(getTransparencyString(theme), false);
    }

    /**
     * Gets color from color field.
     * @param theme    the theme document.
     * @return color.
     */
    public static Color parseLineColorField(Document theme) {
        return parseRGB(getLineColorString(theme));
    }


    public static boolean parseShowMinimum(Document theme) {
        return parseBoolean(getShowMinimum(theme), false);
    }

    public static boolean parseShowMaximum(Document theme) {
        return parseBoolean(getShowMaximum(theme), false);
    }


    public static String createWSPLGENStyle(Document theme) {
        NodeList categories = (NodeList) XMLUtils.xpath(
            theme,
            XPATH_WSPLGEN_FIELDS,
            XPathConstants.NODESET);

        return createWSPLGENStyle(categories).toString();
    }

    protected static MapserverStyle createWSPLGENStyle(NodeList categories) {
        MapserverStyle ms = new MapserverStyle();

        for (int i = 0, n = categories.getLength(); i < n; i++) {
            Element  cat = (Element) categories.item(i);
            String color = cat.getAttribute("default");
            String name  = cat.getAttribute("name");

            String expr;

            try {
                int length = name.length();
                int idx    = Integer.valueOf(name.substring(length-1, length));

                expr = createWSPLGENExpression(idx);
            }
            catch (NumberFormatException nfe) {
                logger.warn("Error while parsing WSPLGEN category.", nfe);
                continue;
            }

            Clazz      c = new Clazz(expr);
            Style      s = new Style();
            s.setColor(color.replace(",", ""));
            s.setSize(5);

            c.addItem(new Expression("(" + expr + ")"));
            c.addItem(s);

            ms.addClazz(c);
        }

        return ms;
    }


    protected static String createWSPLGENExpression(int idx) {
        if (idx < 5) {
            int lower = idx - 1;
            return "[DIFF] >= " + lower + " AND  [DIFF] < " + idx;
        }
        else {
            return "[DIFF] >= 4";
        }
    }


    public static String createMapserverStyle(Document theme) {
        String symbol    = getSymbol(theme);
        String backcolor = getBackgroundColorString(theme);
        String linecolor = getLineColorString(theme);

        int linewidth = parseLineWidth(theme);

        MapserverStyle ms = new MapserverStyle();

        Clazz c = new Clazz(" ");

        Style s = new Style();
        s.setOutlineColor(linecolor.replace(",", ""));

        if (backcolor != null && backcolor.length() > 0) {
            s.setColor(backcolor.replace(",", ""));
        }

        s.setSize(linewidth);
        s.setSymbol(symbol);
        c.addItem(s);

        String textcolor = getTextColorString(theme);
        int    textsize  = parseTextSize(theme);

        if (textcolor != null && textcolor.length() > 0 && textsize > 0) {
            Label l = new Label();
            l.setColor(textcolor.replace(",", ""));
            l.setSize(textsize);
            c.addItem(l);
        }

        ms.addClazz(c);

        return ms.toString();
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org