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