diff flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeFactory.java @ 3468:f37e7e8907cb

merged flys-artifacts/2.8.1
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:39 +0200
parents 0b9b2a0c4e64
children b1912514e0f5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeFactory.java	Fri Sep 28 12:14:39 2012 +0200
@@ -0,0 +1,304 @@
+package de.intevation.flys.themes;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.context.FLYSContext;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ *
+ * Mapping-matching rules:
+ *
+ */
+public class ThemeFactory {
+
+    private static Logger logger = Logger.getLogger(ThemeFactory.class);
+
+    /** Trivial, hidden constructor. */
+    private ThemeFactory() {
+    }
+
+
+    /**
+     * Creates a new theme from <i>config</i>.
+     *
+     * @param themeCfg The theme config document that is used to fetch parent
+     * themes.
+     * @param config The theme config node.
+     *
+     * @return a new theme.
+     */
+    public static Theme createTheme(Document themeCfg, Node config) {
+        String name = getName(config);
+        String desc = getDescription(config);
+
+        logger.debug("Create new theme: " + name);
+
+        Theme theme = new DefaultTheme(name, desc);
+
+        parseInherits(themeCfg, config, theme);
+        parseFields(config, theme);
+        parseAttrs(config, theme);
+
+        return theme;
+    }
+
+
+    /**
+     * Get first matching theme for facet.
+     *
+     * @param name    Name to match "from" of theme mapping.
+     * @param pattern String to 'compare' to pattern in mapping.
+     * @param output  Name of the current output
+     *
+     * @return First matching theme.
+     */
+    public static Theme getTheme(
+        FLYSContext c,
+        String name,
+        String pattern,
+        String output,
+        String groupName)
+    {
+        logger.debug("Search theme for: " + name + " - pattern: " + pattern);
+
+        if (c == null || name == null) {
+            logger.warn("Cannot search for theme.");
+            return null;
+        }
+
+        // Fetch mapping and themes.
+        @SuppressWarnings("unchecked")
+        Map<String, List<ThemeMapping>> map = (Map<String, List<ThemeMapping>>)
+            c.get(FLYSContext.THEME_MAPPING);
+
+        @SuppressWarnings("unchecked")
+        List<ThemeGroup> tgs = (List<ThemeGroup>)
+            c.get(FLYSContext.THEMES);
+
+        ThemeGroup group = null;
+        for (ThemeGroup tg: tgs) {
+            if(tg.getName().equals(groupName)) {
+                group = tg;
+            }
+        }
+
+        if (group == null) {
+            return null;
+        }
+
+        Map<String, Theme> t = group.getThemes();
+
+        FLYSArtifact artifact = (FLYSArtifact) c.get(FLYSContext.ARTIFACT_KEY);
+
+        if (map == null || map.size() == 0 || t == null || t.size() == 0) {
+            logger.warn("No mappings or themes found. Cannot retrieve theme!");
+            return null;
+        }
+
+        List<ThemeMapping> mapping = map.get(name);
+
+        if (mapping == null) {
+            logger.warn("No theme found for mapping: " + name);
+            return null;
+        }
+
+        // Take first mapping of which all conditions are satisfied.
+        for (ThemeMapping tm: mapping) {
+            if (name.equals(tm.getFrom())
+                && tm.applyPattern(pattern)
+                && tm.masterAttrMatches(artifact)
+                && tm.outputMatches(output))
+            {
+                return t.get(tm.getTo());
+            }
+        }
+
+        String msg =
+            "No theme found for '" + name +
+            "' with pattern '" + pattern + "' and output " + output + ".";
+
+        logger.warn(msg);
+
+        return null;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static List<ThemeGroup> getThemeGroups(FLYSContext c) {
+        List<ThemeGroup> tgs = (List<ThemeGroup>)
+            c.get(FLYSContext.THEMES);
+        return tgs;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static List<Theme> getThemes (FLYSContext c, String name) {
+        List<ThemeGroup> tgs = (List<ThemeGroup>)
+            c.get(FLYSContext.THEMES);
+        if (tgs == null) {
+            return null;
+        }
+
+        List<Theme> themes = new ArrayList<Theme>();
+        for (ThemeGroup tg: tgs) {
+            themes.add(tg.getThemeByName(name));
+        }
+        return themes;
+    }
+
+    protected static String getName(Node config) {
+        return ((Element)config).getAttribute("name");
+    }
+
+
+    protected static String getDescription(Node config) {
+        return ((Element)config).getAttribute("desc");
+    }
+
+
+    protected static void parseInherits(Document themeCfg, Node cfg, Theme t) {
+        parseInherits(themeCfg, cfg, t, null);
+    }
+
+    protected static void parseInherits(
+        Document themeCfg,
+        Node     cfg,
+        Theme    t,
+        Map<String, Node> themes
+    ) {
+        logger.debug("ThemeFactory.parseInherits");
+
+        NodeList inherits = ((Element)cfg).getElementsByTagName("inherit");
+
+        int num = inherits.getLength();
+
+        if (num == 0) {
+            logger.debug("Theme does not inherit from other themes.");
+            return;
+        }
+
+        logger.debug("Theme inherits from " + num + " other themes.");
+
+        if (themes == null) {
+            themes = buildThemeMap(themeCfg);
+        }
+
+        for (int i = 0; i < num; i++) {
+            Node inherit = inherits.item(i);
+            String from = ((Element)inherit).getAttribute("from");
+
+            Node tmp = themes.get(from);
+
+            parseInherits(themeCfg, tmp, t, themes);
+            parseFields(tmp, t);
+        }
+    }
+
+    protected static Map<String, Node> buildThemeMap(Document themeCfg) {
+        Map<String, Node> map = new HashMap<String, Node>();
+        String xpath = "/themes/themegroup/theme";
+
+        NodeList nodes = (NodeList)XMLUtils.xpath(
+            themeCfg, xpath, XPathConstants.NODESET);
+
+        if (nodes != null) {
+            for (int i = 0, N = nodes.getLength(); i < N; ++i) {
+                Node node = nodes.item(i);
+                String name = ((Element)node).getAttribute("name");
+                map.put(name, node);
+            }
+        }
+        return map;
+    }
+
+
+    protected static void parseFields(Node config, Theme theme) {
+        if (config == null || theme == null) {
+            logger.warn("Parsing fields without node or theme is senseless!");
+            return;
+        }
+
+        NodeList fields = ((Element)config).getElementsByTagName("field");
+
+        int num = fields.getLength();
+
+        logger.debug("Found " + num + " own fields in this theme.");
+
+        if (num == 0) {
+            logger.debug("Theme has no own fields.");
+            return;
+        }
+
+        for (int i = 0; i < num; i++) {
+            Node field = fields.item(i);
+
+            addField(theme, field);
+        }
+    }
+
+
+    protected static void addField(Theme theme, Node field) {
+        String name = ((Element)field).getAttribute("name");
+
+        logger.debug("Add field " + name + " to theme " + theme.getName());
+
+        NamedNodeMap attrs = field.getAttributes();
+
+        int num = attrs != null ? attrs.getLength() : 0;
+
+        if (num == 0) {
+            logger.warn("This field has no attributes.");
+            return;
+        }
+
+        ThemeField theField = new DefaultThemeField(name);
+
+        for (int i = 0; i < num; i++) {
+            Node attr    = attrs.item(i);
+
+            String key   = attr.getNodeName();
+            String value = attr.getNodeValue();
+
+            theField.setAttribute(key, value);
+        }
+
+        theme.addField(name, theField);
+    }
+
+
+    protected static void parseAttrs(Node config, Theme theme) {
+        NamedNodeMap attrs = config.getAttributes();
+
+        int num = attrs != null ? attrs.getLength() : 0;
+
+        if (num == 0) {
+            logger.debug("Theme has no attributes set.");
+            return;
+        }
+
+        for (int i = 0; i < num; i++) {
+            Node attr = attrs.item(i);
+
+            String name  = attr.getNodeName();
+            String value = attr.getNodeValue();
+
+            theme.addAttribute(name, value);
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org