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 :

http://dive4elements.wald.intevation.org