view flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java @ 4573:b87073a05f9d

flys-client: Patch to render combobox options as clickable links. The way of passing data arguments to the links and further to the Artifact feeding service is somewhat hacked and should be refactored (later...).
author Christian Lins <christian.lins@intevation.de>
date Tue, 27 Nov 2012 12:50:10 +0100
parents ecd237428af6
children 1c6c2ddac3d6
line wrap: on
line source
package de.intevation.flys.utils;

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.Label;
import de.intevation.flys.artifacts.model.MapserverStyle.Style;

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

import javax.xml.xpath.XPathConstants;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


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

    /** Private logger. */
    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 static final String XPATH_POINT_COLOR =
            "/theme/field[@name='pointcolor']/@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_VERTICAL_LINE =
            "/theme/field[@name='showverticalline']/@default";

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    public final static String XPATH_BACKGROUND_COLOR =
            "/theme/field[@name='backgroundcolor']/@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";

    /** XPATH to bandwidth field. */
    public final static String XPATH_BANDWIDTH =
            "/theme/field[@name='bandwidth']/@default";

    /** XPATH to find showextramark field. */
    public final static String XPATH_SHOWEXTRAMARK =
            "/theme/field[@name='showextramark']/@default";

    /** 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;
        }
    }


    /**
     * Attempt converting \param value to an integer, in failing cases,
     * return \param defaultsTo.
     * @param value String to be converted to integer.
     * @param defaultsTo Default to return if conversion failed.
     * @return \param value as integer or defaultsto if conversion failed.
     */
    public static int parseInteger(String value, int defaultsTo) {
        if (value == null || value.length() == 0) {
            return defaultsTo;
        }

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

        return defaultsTo;
    }


    /**
     * Attempt converting \param value to a double, in failing cases,
     * return \param defaultsTo.
     * @param value String to be converted to double.
     * @param defaultsTo Default to return if conversion failed.
     * @return \param value as integer or defaultsto if conversion failed.
     */
    public static double parseDouble(String value, double defaultsTo) {
        if (value == null || value.length() == 0) {
            return defaultsTo;
        }

        try {
            return Double.parseDouble(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.parseInt(size);
        }
        catch (NumberFormatException nfe) {
            logger.warn("Unable to set line size from string: '" + size + "'");
        }
        return 0;
    }


    /**
     * Parse band width, defaulting to 0.
     * @param theme the theme.
     */
    public static double parseBandWidth(Document theme) {
        String bandWidth = XMLUtils.xpathString(theme, XPATH_BANDWIDTH, null);

        return parseDouble(bandWidth, 0);
    }


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

        return parseInteger(width, 3);
    }


    public static Color parsePointColor(Document theme) {
        String color = XMLUtils.xpathString(theme, XPATH_POINT_COLOR, null);
        logger.debug("parsePointColor(): color = " + color);
        return parseColor(color);
    }


    /**
     * 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.parseInt(size);
        }
        catch (NumberFormatException nfe) {
        }
        return 10;
    }


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


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

    /**
     * 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 'showmiddleheight', defaults to false.
     * @param theme The theme.
     */
    public static boolean parseShowMiddleHeight(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_MIDDLE_HEIGHT, null);
        return parseBoolean(show, false);
    }

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

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

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

    /**
     * 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, false);
    }

    public static boolean parseShowPointLabel(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_POINT_LABEL, null);
        return parseBoolean(show, false);
    }

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


    /**
     * Parses the font.
     * @param theme The theme.
     */
    public static Font parseTextFont(Document theme) {
        String font = XMLUtils.xpathString(theme, XPATH_LABEL_FONT_FACE, 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;
    }


    /**
     * 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_LABEL_FONT_STYLE);
    }


    public static boolean parseShowWidth(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_WIDTH, null);
        return parseBoolean(show, false);
    }


    public static boolean parseShowLevel(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_SHOW_LEVEL, null);
        return parseBoolean(show, false);
    }

    /**
     * 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 ("true".equals(o)) {
            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 = getLabelBackgroundColorString(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 parseLabelShowBackground(Document theme) {
        String show = XMLUtils.xpathString(theme, XPATH_LABEL_SHOW_BACKGROUND, null);
        return parseBoolean(show, false);
    }


    public static Color parseColor(String colorString) {
        if (colorString == null || colorString.length() == 0) {
            return null;
        }
        else if (colorString.indexOf("#") == 0) {
            return parseHexColor(colorString);
        }
        else if (colorString.indexOf(",") >= 0) {
            return parseRGB(colorString);
        }

        return null;
    }


    /**
     * Parse a string like "#00CC22" and return the corresponding color.
     *
     * @param hex The hex color value.
     *
     * @return a Color or null, if <i>hex</i> is empty.
     */
    public static Color parseHexColor(String hex) {
        if (hex == null) {
            return null;
        }

        return Color.decode(hex);
    }

    /**
     * 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.parseInt(rgb[0].trim()),
                    Integer.parseInt(rgb[1].trim()),
                    Integer.parseInt(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 getLabelBackgroundColorString(Document theme) {
        return XMLUtils.xpathString(theme, XPATH_LABEL_BGCOLOR, null);
    }


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


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


    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 int parseTransparency(Document theme) {
        return parseInteger(getTransparencyString(theme), 50);
    }


    /**
     * Gets color from color field.
     * @param theme    the theme document.
     * @return color.
     */
    public static Color parseLineColorField(Document theme) {
        String lineColorStr = getLineColorString(theme);
        logger.debug("parseLineColorField: lineColorStr = " +
                (lineColorStr == null ? "null" : lineColorStr));
        return parseColor(lineColorStr);
    }


    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();
    }

    /**
     * Creates a style for the Mapfile template used by MapfileGenerator
     * to generate floodmaps.
     * @param categories
     * @return
     */
    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.parseInt(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 = getLabelBackgroundColorString(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