comparison flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeFactory.java @ 2793:6310b1582f2d

merged flys-artifacts/2.7
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:30 +0200
parents faf73245ec73
children 74c974b10c75
comparison
equal deleted inserted replaced
2548:ada02bbd3b7f 2793:6310b1582f2d
1 package de.intevation.flys.themes;
2
3 import java.util.List;
4 import java.util.Map;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7
8 import javax.xml.xpath.XPathConstants;
9
10 import org.apache.log4j.Logger;
11
12 import org.w3c.dom.Document;
13 import org.w3c.dom.NamedNodeMap;
14 import org.w3c.dom.Node;
15 import org.w3c.dom.NodeList;
16 import org.w3c.dom.Element;
17
18 import de.intevation.artifacts.common.utils.XMLUtils;
19
20 import de.intevation.flys.artifacts.context.FLYSContext;
21 import de.intevation.flys.artifacts.FLYSArtifact;
22
23 /**
24 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
25 *
26 * Mapping-matching rules:
27 *
28 */
29 public class ThemeFactory {
30
31 private static Logger logger = Logger.getLogger(ThemeFactory.class);
32
33 /** Trivial, hidden constructor. */
34 private ThemeFactory() {
35 }
36
37
38 /**
39 * Creates a new theme from <i>config</i>.
40 *
41 * @param themeCfg The theme config document that is used to fetch parent
42 * themes.
43 * @param config The theme config node.
44 *
45 * @return a new theme.
46 */
47 public static Theme createTheme(Document themeCfg, Node config) {
48 String name = getName(config);
49 String desc = getDescription(config);
50
51 logger.debug("Create new theme: " + name);
52
53 Theme theme = new DefaultTheme(name, desc);
54
55 parseInherits(themeCfg, config, theme);
56 parseFields(config, theme);
57 parseAttrs(config, theme);
58
59 return theme;
60 }
61
62
63 /**
64 * Get first matching theme for facet.
65 *
66 * @param name Name to match "from" of theme mapping.
67 * @param pattern String to 'compare' to pattern in mapping.
68 * @param output Name of the current output
69 *
70 * @return First matching theme.
71 */
72 public static Theme getTheme(
73 FLYSContext c,
74 String name,
75 String pattern,
76 String output,
77 String groupName)
78 {
79 logger.debug("Search theme for: " + name + " - pattern: " + pattern);
80
81 if (c == null || name == null) {
82 logger.warn("Cannot search for theme.");
83 return null;
84 }
85
86 // Fetch mapping and themes.
87 Map<String, List<ThemeMapping>> map = (Map<String, List<ThemeMapping>>)
88 c.get(FLYSContext.THEME_MAPPING);
89
90 List<ThemeGroup> tgs = (List<ThemeGroup>)
91 c.get(FLYSContext.THEMES);
92
93 ThemeGroup group = null;
94 for (ThemeGroup tg: tgs) {
95 if(tg.getName().equals(groupName)) {
96 group = tg;
97 }
98 }
99
100 if (group == null) {
101 return null;
102 }
103
104 Map<String, Theme> t = group.getThemes();
105
106 FLYSArtifact artifact = (FLYSArtifact) c.get(FLYSContext.ARTIFACT_KEY);
107
108 if (map == null || map.size() == 0 || t == null || t.size() == 0) {
109 logger.warn("No mappings or themes found. Cannot retrieve theme!");
110 return null;
111 }
112
113 List<ThemeMapping> mapping = map.get(name);
114
115 if (mapping == null) {
116 logger.warn("No theme found for mapping: " + name);
117 return null;
118 }
119
120 // Take first mapping of which all conditions are satisfied.
121 for (ThemeMapping tm: mapping) {
122 if (name.equals(tm.getFrom())
123 && tm.applyPattern(pattern)
124 && tm.masterAttrMatches(artifact)
125 && tm.outputMatches(output))
126 {
127 return t.get(tm.getTo());
128 }
129 }
130
131 String msg =
132 "No theme found for '" + name +
133 "' with pattern '" + pattern + "' and output " + output + ".";
134
135 logger.warn(msg);
136
137 return null;
138 }
139
140
141 public static List<ThemeGroup> getThemeGroups(FLYSContext c) {
142 List<ThemeGroup> tgs = (List<ThemeGroup>)
143 c.get(FLYSContext.THEMES);
144 return tgs;
145 }
146
147
148 public static List<Theme> getThemes (FLYSContext c, String name) {
149 List<ThemeGroup> tgs = (List<ThemeGroup>)
150 c.get(FLYSContext.THEMES);
151 if (tgs == null) {
152 return null;
153 }
154
155 List<Theme> themes = new ArrayList<Theme>();
156 for (ThemeGroup tg: tgs) {
157 themes.add(tg.getThemeByName(name));
158 }
159 return themes;
160 }
161
162 protected static String getName(Node config) {
163 return ((Element)config).getAttribute("name");
164 }
165
166
167 protected static String getDescription(Node config) {
168 return ((Element)config).getAttribute("desc");
169 }
170
171
172 protected static void parseInherits(Document themeCfg, Node cfg, Theme t) {
173 parseInherits(themeCfg, cfg, t, null);
174 }
175
176 protected static void parseInherits(
177 Document themeCfg,
178 Node cfg,
179 Theme t,
180 Map<String, Node> themes
181 ) {
182 logger.debug("ThemeFactory.parseInherits");
183
184 NodeList inherits = ((Element)cfg).getElementsByTagName("inherit");
185
186 int num = inherits.getLength();
187
188 if (num == 0) {
189 logger.debug("Theme does not inherit from other themes.");
190 return;
191 }
192
193 logger.debug("Theme inherits from " + num + " other themes.");
194
195 if (themes == null) {
196 themes = buildThemeMap(themeCfg);
197 }
198
199 for (int i = 0; i < num; i++) {
200 Node inherit = inherits.item(i);
201 String from = ((Element)inherit).getAttribute("from");
202
203 Node tmp = themes.get(from);
204
205 parseInherits(themeCfg, tmp, t, themes);
206 parseFields(tmp, t);
207 }
208 }
209
210 protected static Map<String, Node> buildThemeMap(Document themeCfg) {
211 Map<String, Node> map = new HashMap<String, Node>();
212 String xpath = "/themes/themegroup/theme";
213
214 NodeList nodes = (NodeList)XMLUtils.xpath(
215 themeCfg, xpath, XPathConstants.NODESET);
216
217 if (nodes != null) {
218 for (int i = 0, N = nodes.getLength(); i < N; ++i) {
219 Node node = nodes.item(i);
220 String name = ((Element)node).getAttribute("name");
221 map.put(name, node);
222 }
223 }
224 return map;
225 }
226
227
228 protected static void parseFields(Node config, Theme theme) {
229 if (config == null || theme == null) {
230 logger.warn("Parsing fields without node or theme is senseless!");
231 return;
232 }
233
234 NodeList fields = ((Element)config).getElementsByTagName("field");
235
236 int num = fields.getLength();
237
238 logger.debug("Found " + num + " own fields in this theme.");
239
240 if (num == 0) {
241 logger.debug("Theme has no own fields.");
242 return;
243 }
244
245 for (int i = 0; i < num; i++) {
246 Node field = fields.item(i);
247
248 addField(theme, field);
249 }
250 }
251
252
253 protected static void addField(Theme theme, Node field) {
254 String name = ((Element)field).getAttribute("name");
255
256 logger.debug("Add field: " + name);
257
258 NamedNodeMap attrs = field.getAttributes();
259
260 int num = attrs != null ? attrs.getLength() : 0;
261
262 if (num == 0) {
263 logger.warn("This field has no attributes.");
264 return;
265 }
266
267 ThemeField theField = new DefaultThemeField(name);
268
269 for (int i = 0; i < num; i++) {
270 Node attr = attrs.item(i);
271
272 String key = attr.getNodeName();
273 String value = attr.getNodeValue();
274
275 theField.setAttribute(key, value);
276 }
277
278 theme.addField(name, theField);
279 }
280
281
282 protected static void parseAttrs(Node config, Theme theme) {
283 NamedNodeMap attrs = config.getAttributes();
284
285 int num = attrs != null ? attrs.getLength() : 0;
286
287 if (num == 0) {
288 logger.debug("Theme has no attributes set.");
289 return;
290 }
291
292 for (int i = 0; i < num; i++) {
293 Node attr = attrs.item(i);
294
295 String name = attr.getNodeName();
296 String value = attr.getNodeValue();
297
298 theme.addAttribute(name, value);
299 }
300 }
301 }
302 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org