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

http://dive4elements.wald.intevation.org