diff artifacts/src/main/java/org/dive4elements/river/themes/ThemeFactory.java @ 5838:5aa05a7a34b7

Rename modules to more fitting names.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 15:23:37 +0200
parents flys-artifacts/src/main/java/org/dive4elements/river/themes/ThemeFactory.java@bd047b71ab37
children 4897a58c8746
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/themes/ThemeFactory.java	Thu Apr 25 15:23:37 2013 +0200
@@ -0,0 +1,312 @@
+package org.dive4elements.river.themes;
+
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+import org.dive4elements.river.artifacts.FLYSArtifact;
+import org.dive4elements.river.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)
+    {
+        if (logger.isDebugEnabled()) {
+            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;
+                break;
+            }
+        }
+
+        if (group == null) {
+            logger.warn("No theme group found: '" + groupName + "'");
+            return null;
+        }
+
+        Map<String, Theme> t = group.getThemes();
+
+        FLYSArtifact artifact = (FLYSArtifact) c.get(FLYSContext.ARTIFACT_KEY);
+
+        if (map == null || map.isEmpty() || t == null || t.isEmpty()) {
+            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))
+            {
+                String target = tm.getTo();
+
+                logger.debug("Found theme '" + target + "'");
+                return t.get(target);
+            }
+        }
+
+        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