comparison 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
comparison
equal deleted inserted replaced
3387:5ffad8bde8ad 3468:f37e7e8907cb
1 package de.intevation.flys.themes;
2
3 import de.intevation.artifacts.common.utils.XMLUtils;
4 import de.intevation.flys.artifacts.FLYSArtifact;
5 import de.intevation.flys.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 logger.debug("Search theme for: " + name + " - pattern: " + pattern);
78
79 if (c == null || name == null) {
80 logger.warn("Cannot search for theme.");
81 return null;
82 }
83
84 // Fetch mapping and themes.
85 @SuppressWarnings("unchecked")
86 Map<String, List<ThemeMapping>> map = (Map<String, List<ThemeMapping>>)
87 c.get(FLYSContext.THEME_MAPPING);
88
89 @SuppressWarnings("unchecked")
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 @SuppressWarnings("unchecked")
142 public static List<ThemeGroup> getThemeGroups(FLYSContext c) {
143 List<ThemeGroup> tgs = (List<ThemeGroup>)
144 c.get(FLYSContext.THEMES);
145 return tgs;
146 }
147
148
149 @SuppressWarnings("unchecked")
150 public static List<Theme> getThemes (FLYSContext c, String name) {
151 List<ThemeGroup> tgs = (List<ThemeGroup>)
152 c.get(FLYSContext.THEMES);
153 if (tgs == null) {
154 return null;
155 }
156
157 List<Theme> themes = new ArrayList<Theme>();
158 for (ThemeGroup tg: tgs) {
159 themes.add(tg.getThemeByName(name));
160 }
161 return themes;
162 }
163
164 protected static String getName(Node config) {
165 return ((Element)config).getAttribute("name");
166 }
167
168
169 protected static String getDescription(Node config) {
170 return ((Element)config).getAttribute("desc");
171 }
172
173
174 protected static void parseInherits(Document themeCfg, Node cfg, Theme t) {
175 parseInherits(themeCfg, cfg, t, null);
176 }
177
178 protected static void parseInherits(
179 Document themeCfg,
180 Node cfg,
181 Theme t,
182 Map<String, Node> themes
183 ) {
184 logger.debug("ThemeFactory.parseInherits");
185
186 NodeList inherits = ((Element)cfg).getElementsByTagName("inherit");
187
188 int num = inherits.getLength();
189
190 if (num == 0) {
191 logger.debug("Theme does not inherit from other themes.");
192 return;
193 }
194
195 logger.debug("Theme inherits from " + num + " other themes.");
196
197 if (themes == null) {
198 themes = buildThemeMap(themeCfg);
199 }
200
201 for (int i = 0; i < num; i++) {
202 Node inherit = inherits.item(i);
203 String from = ((Element)inherit).getAttribute("from");
204
205 Node tmp = themes.get(from);
206
207 parseInherits(themeCfg, tmp, t, themes);
208 parseFields(tmp, t);
209 }
210 }
211
212 protected static Map<String, Node> buildThemeMap(Document themeCfg) {
213 Map<String, Node> map = new HashMap<String, Node>();
214 String xpath = "/themes/themegroup/theme";
215
216 NodeList nodes = (NodeList)XMLUtils.xpath(
217 themeCfg, xpath, XPathConstants.NODESET);
218
219 if (nodes != null) {
220 for (int i = 0, N = nodes.getLength(); i < N; ++i) {
221 Node node = nodes.item(i);
222 String name = ((Element)node).getAttribute("name");
223 map.put(name, node);
224 }
225 }
226 return map;
227 }
228
229
230 protected static void parseFields(Node config, Theme theme) {
231 if (config == null || theme == null) {
232 logger.warn("Parsing fields without node or theme is senseless!");
233 return;
234 }
235
236 NodeList fields = ((Element)config).getElementsByTagName("field");
237
238 int num = fields.getLength();
239
240 logger.debug("Found " + num + " own fields in this theme.");
241
242 if (num == 0) {
243 logger.debug("Theme has no own fields.");
244 return;
245 }
246
247 for (int i = 0; i < num; i++) {
248 Node field = fields.item(i);
249
250 addField(theme, field);
251 }
252 }
253
254
255 protected static void addField(Theme theme, Node field) {
256 String name = ((Element)field).getAttribute("name");
257
258 logger.debug("Add field " + name + " to theme " + theme.getName());
259
260 NamedNodeMap attrs = field.getAttributes();
261
262 int num = attrs != null ? attrs.getLength() : 0;
263
264 if (num == 0) {
265 logger.warn("This field has no attributes.");
266 return;
267 }
268
269 ThemeField theField = new DefaultThemeField(name);
270
271 for (int i = 0; i < num; i++) {
272 Node attr = attrs.item(i);
273
274 String key = attr.getNodeName();
275 String value = attr.getNodeValue();
276
277 theField.setAttribute(key, value);
278 }
279
280 theme.addField(name, theField);
281 }
282
283
284 protected static void parseAttrs(Node config, Theme theme) {
285 NamedNodeMap attrs = config.getAttributes();
286
287 int num = attrs != null ? attrs.getLength() : 0;
288
289 if (num == 0) {
290 logger.debug("Theme has no attributes set.");
291 return;
292 }
293
294 for (int i = 0; i < num; i++) {
295 Node attr = attrs.item(i);
296
297 String name = attr.getNodeName();
298 String value = attr.getNodeValue();
299
300 theme.addAttribute(name, value);
301 }
302 }
303 }
304 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org