Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/org/dive4elements/river/artifacts/context/FLYSContextFactory.java @ 5831:bd047b71ab37
Repaired internal references
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 12:06:39 +0200 |
parents | flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java@b26465581abf |
children |
comparison
equal
deleted
inserted
replaced
5830:160f53ee0870 | 5831:bd047b71ab37 |
---|---|
1 package org.dive4elements.river.artifacts.context; | |
2 | |
3 import org.dive4elements.artifactdatabase.state.State; | |
4 import org.dive4elements.artifactdatabase.state.StateEngine; | |
5 import org.dive4elements.artifactdatabase.transition.Transition; | |
6 import org.dive4elements.artifactdatabase.transition.TransitionEngine; | |
7 import org.dive4elements.artifacts.ArtifactContextFactory; | |
8 import org.dive4elements.artifacts.GlobalContext; | |
9 import org.dive4elements.artifacts.common.utils.Config; | |
10 import org.dive4elements.artifacts.common.utils.XMLUtils; | |
11 import org.dive4elements.river.artifacts.model.Module; | |
12 import org.dive4elements.river.artifacts.model.ZoomScale; | |
13 import org.dive4elements.river.artifacts.states.StateFactory; | |
14 import org.dive4elements.river.artifacts.transitions.TransitionFactory; | |
15 import org.dive4elements.river.themes.Theme; | |
16 import org.dive4elements.river.themes.ThemeFactory; | |
17 import org.dive4elements.river.themes.ThemeGroup; | |
18 import org.dive4elements.river.themes.ThemeMapping; | |
19 | |
20 import java.io.File; | |
21 import java.util.ArrayList; | |
22 import java.util.HashMap; | |
23 import java.util.List; | |
24 import java.util.Map; | |
25 | |
26 import javax.xml.xpath.XPathConstants; | |
27 | |
28 import org.apache.log4j.Logger; | |
29 import org.w3c.dom.Document; | |
30 import org.w3c.dom.Element; | |
31 import org.w3c.dom.Node; | |
32 import org.w3c.dom.NodeList; | |
33 | |
34 | |
35 /** | |
36 * The ArtifactContextFactory is used to initialize basic components and put | |
37 * them into the global context of the application. | |
38 * | |
39 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | |
40 */ | |
41 public class FLYSContextFactory implements ArtifactContextFactory { | |
42 | |
43 /** The logger that is used in this class. */ | |
44 private static Logger logger = Logger.getLogger(FLYSContextFactory.class); | |
45 | |
46 /** The XPath to the artifacts configured in the configuration. */ | |
47 public static final String XPATH_ARTIFACTS = | |
48 "/artifact-database/artifacts/artifact"; | |
49 | |
50 /** The XPath to the name of the artifact. */ | |
51 public static final String XPATH_ARTIFACT_NAME = "/artifact/@name"; | |
52 | |
53 /** The XPath to the xlink ref in an artifact configuration. */ | |
54 public static final String XPATH_XLINK = "xlink:href"; | |
55 | |
56 /** The XPath to the transitions configured in the artifact config. */ | |
57 public static final String XPATH_TRANSITIONS = | |
58 "/artifact/states/transition"; | |
59 | |
60 /** The XPath to the states configured in the artifact config. */ | |
61 public static final String XPATH_STATES = | |
62 "/artifact/states/state"; | |
63 | |
64 public static final String XPATH_OUTPUT_GENERATORS = | |
65 "/artifact-database/output-generators/output-generator"; | |
66 | |
67 public static final String XPATH_THEME_CONFIG = | |
68 "/artifact-database/flys/themes/configuration/text()"; | |
69 | |
70 public static final String XPATH_THEMES = | |
71 "theme"; | |
72 | |
73 public static final String XPATH_THEME_GROUPS = | |
74 "/themes/themegroup"; | |
75 | |
76 public static final String XPATH_THEME_MAPPINGS = | |
77 "/themes/mappings/mapping"; | |
78 | |
79 public static final String XPATH_RIVER_WMS = | |
80 "/artifact-database/floodmap/river"; | |
81 | |
82 public static final String XPATH_MODULES = "/artifact-database/modules/module"; | |
83 | |
84 private static final String XPATH_ZOOM_SCALES = "/artifact-database/options/zoom-scales/zoom-scale"; | |
85 | |
86 private static final String XPATH_DGM_PATH = "/artifact-database/options/dgm-path/text()"; | |
87 | |
88 | |
89 /** | |
90 * Creates a new FLYSArtifactContext object and initialize all | |
91 * components required by the application. | |
92 * | |
93 * @param config The artifact server configuration. | |
94 * @return a FLYSArtifactContext. | |
95 */ | |
96 @Override | |
97 public GlobalContext createArtifactContext(Document config) { | |
98 FLYSContext context = new FLYSContext(config); | |
99 | |
100 configureTransitions(config, context); | |
101 configureStates(config, context); | |
102 configureOutGenerators(config, context); | |
103 configureThemes(config, context); | |
104 configureThemesMappings(config, context); | |
105 configureFloodmapWMS(config, context); | |
106 configureModules(config, context); | |
107 configureZoomScales(config, context); | |
108 configureDGMPath(config, context); | |
109 | |
110 return context; | |
111 } | |
112 | |
113 | |
114 private void configureDGMPath(Document config, FLYSContext context) { | |
115 String dgmPath = (String) XMLUtils.xpath( | |
116 config, | |
117 XPATH_DGM_PATH, | |
118 XPathConstants.STRING); | |
119 | |
120 context.put("dgm-path", dgmPath); | |
121 } | |
122 | |
123 | |
124 protected void configureZoomScales(Document config, FLYSContext context) { | |
125 NodeList list = (NodeList)XMLUtils.xpath( | |
126 config, | |
127 XPATH_ZOOM_SCALES, | |
128 XPathConstants.NODESET); | |
129 ZoomScale scale = new ZoomScale(); | |
130 for (int i = 0; i < list.getLength(); i++) { | |
131 Element element = (Element)list.item(i); | |
132 String river = "default"; | |
133 double range = 0d; | |
134 double radius = 10d; | |
135 if (element.hasAttribute("river")) { | |
136 river = element.getAttribute("river"); | |
137 } | |
138 if (!element.hasAttribute("range")) { | |
139 continue; | |
140 } | |
141 else { | |
142 String r = element.getAttribute("range"); | |
143 try { | |
144 range = Double.parseDouble(r); | |
145 } | |
146 catch (NumberFormatException nfe) { | |
147 continue; | |
148 } | |
149 } | |
150 if (!element.hasAttribute("radius")) { | |
151 continue; | |
152 } | |
153 else { | |
154 String r = element.getAttribute("radius"); | |
155 try { | |
156 radius = Double.parseDouble(r); | |
157 } | |
158 catch (NumberFormatException nfe) { | |
159 continue; | |
160 } | |
161 } | |
162 scale.addRange(river, range, radius); | |
163 } | |
164 context.put("zoomscale", scale); | |
165 } | |
166 | |
167 | |
168 /** | |
169 * This method initializes the transition configuration. | |
170 * | |
171 * @param config the config document. | |
172 * @param context the FLYSContext. | |
173 */ | |
174 protected void configureTransitions(Document config, FLYSContext context) { | |
175 TransitionEngine engine = new TransitionEngine(); | |
176 | |
177 Document[] artifacts = getArtifactConfigurations(config); | |
178 logger.info("Found " + artifacts.length + " artifacts in the config."); | |
179 | |
180 for (Document doc: artifacts) { | |
181 | |
182 String artName = (String) XMLUtils.xpath( | |
183 doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING); | |
184 | |
185 NodeList list = (NodeList) XMLUtils.xpath( | |
186 doc, XPATH_TRANSITIONS, XPathConstants.NODESET); | |
187 | |
188 if (list == null) { | |
189 logger.warn("The artifact " + artName + | |
190 " has no transitions configured."); | |
191 continue; | |
192 } | |
193 | |
194 int trans = list.getLength(); | |
195 | |
196 logger.info( | |
197 "Artifact '" + artName + "' has " + trans + " transitions."); | |
198 | |
199 for (int i = 0; i < trans; i++) { | |
200 Transition t = TransitionFactory.createTransition(list.item(i)); | |
201 String s = t.getFrom(); | |
202 engine.addTransition(s, t); | |
203 } | |
204 } | |
205 | |
206 context.put(FLYSContext.TRANSITION_ENGINE_KEY, engine); | |
207 } | |
208 | |
209 | |
210 /** | |
211 * This method returns all artifact documents defined in | |
212 * <code>config</code>. <br>NOTE: The artifact configurations need to be | |
213 * stored in own files referenced by an xlink. | |
214 * | |
215 * @param config The global configuration. | |
216 * | |
217 * @return an array of Artifact configurations. | |
218 */ | |
219 protected Document[] getArtifactConfigurations(Document config) { | |
220 NodeList artifacts = (NodeList) XMLUtils.xpath( | |
221 config, XPATH_ARTIFACTS, XPathConstants.NODESET); | |
222 | |
223 int count = artifacts.getLength(); | |
224 | |
225 Document[] artifactDocs = new Document[count]; | |
226 | |
227 for (int i = 0; i < count; i++) { | |
228 Element tmp = (Element) artifacts.item(i); | |
229 | |
230 String xlink = tmp.getAttribute(XPATH_XLINK); | |
231 xlink = Config.replaceConfigDir(xlink); | |
232 | |
233 File artifactFile = new File(xlink); | |
234 artifactDocs[i] = XMLUtils.parseDocument(artifactFile); | |
235 } | |
236 | |
237 return artifactDocs; | |
238 } | |
239 | |
240 | |
241 /** | |
242 * This method initializes the transition configuration. | |
243 * | |
244 * @param config the config document. | |
245 * @param context the FLYSContext. | |
246 */ | |
247 protected void configureStates(Document config, FLYSContext context) { | |
248 StateEngine engine = new StateEngine(); | |
249 | |
250 Document[] artifacts = getArtifactConfigurations(config); | |
251 logger.info("Found " + artifacts.length + " artifacts in the config."); | |
252 | |
253 for (Document doc: artifacts) { | |
254 List<State> states = new ArrayList<State>(); | |
255 | |
256 String artName = (String) XMLUtils.xpath( | |
257 doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING); | |
258 | |
259 NodeList stateList = (NodeList) XMLUtils.xpath( | |
260 doc, XPATH_STATES, XPathConstants.NODESET); | |
261 | |
262 if (stateList == null) { | |
263 logger.warn("The artifact " + artName + | |
264 " has no states configured."); | |
265 continue; | |
266 } | |
267 | |
268 int count = stateList.getLength(); | |
269 | |
270 logger.info( | |
271 "Artifact '" + artName + "' has " + count + " states."); | |
272 | |
273 for (int i = 0; i < count; i++) { | |
274 states.add(StateFactory.createState( | |
275 stateList.item(i))); | |
276 } | |
277 | |
278 engine.addStates(artName, states); | |
279 } | |
280 | |
281 context.put(FLYSContext.STATE_ENGINE_KEY, engine); | |
282 } | |
283 | |
284 | |
285 /** | |
286 * This method intializes the provided output generators. | |
287 * | |
288 * @param config the config document. | |
289 * @param context the FLYSContext. | |
290 */ | |
291 protected void configureOutGenerators(Document config, FLYSContext context){ | |
292 Map<String, Class<?>> generators = new HashMap<String, Class<?>>(); | |
293 | |
294 NodeList outGenerators = (NodeList) XMLUtils.xpath( | |
295 config, | |
296 XPATH_OUTPUT_GENERATORS, | |
297 XPathConstants.NODESET); | |
298 | |
299 int num = outGenerators == null ? 0 : outGenerators.getLength(); | |
300 | |
301 if (num == 0) { | |
302 logger.warn("No output generators configured in this application."); | |
303 return; | |
304 } | |
305 | |
306 logger.info("Found " + num + " configured output generators."); | |
307 | |
308 int idx = 0; | |
309 | |
310 for (int i = 0; i < num; i++) { | |
311 Node item = outGenerators.item(i); | |
312 | |
313 String name = (String) XMLUtils.xpath( | |
314 item, "@name", XPathConstants.STRING); | |
315 | |
316 String clazz = (String) XMLUtils.xpath( | |
317 item, "text()", XPathConstants.STRING); | |
318 | |
319 if (name == null || clazz == null) { | |
320 continue; | |
321 } | |
322 | |
323 try { | |
324 generators.put(name, Class.forName(clazz)); | |
325 | |
326 idx++; | |
327 } | |
328 catch (ClassNotFoundException cnfe) { | |
329 logger.warn(cnfe, cnfe); | |
330 } | |
331 } | |
332 | |
333 logger.info("Successfully loaded " + idx + " output generators."); | |
334 context.put(FLYSContext.OUTGENERATORS_KEY, generators); | |
335 } | |
336 | |
337 | |
338 /** | |
339 * This methods reads the configured themes and puts them into the | |
340 * FLYSContext. | |
341 * | |
342 * @param config The global configuration. | |
343 * @param context The FLYSContext. | |
344 */ | |
345 protected void configureThemes(Document config, FLYSContext context) { | |
346 logger.debug("FLYSContextFactory.configureThemes"); | |
347 | |
348 Document cfg = getThemeConfig(config); | |
349 | |
350 NodeList themeGroups = (NodeList) XMLUtils.xpath( | |
351 cfg, XPATH_THEME_GROUPS, XPathConstants.NODESET); | |
352 | |
353 int groupNum = themeGroups != null ? themeGroups.getLength() : 0; | |
354 | |
355 if (groupNum == 0) { | |
356 logger.warn("There are no theme groups configured!"); | |
357 } | |
358 | |
359 logger.info("Found " + groupNum + " theme groups in configuration"); | |
360 | |
361 List<ThemeGroup> groups = new ArrayList<ThemeGroup>(); | |
362 | |
363 for (int g = 0; g < groupNum; g++) { | |
364 Element themeGroup = (Element) themeGroups.item(g); | |
365 NodeList themes = (NodeList) XMLUtils.xpath( | |
366 themeGroup, XPATH_THEMES, XPathConstants.NODESET); | |
367 | |
368 int num = themes != null ? themes.getLength() : 0; | |
369 | |
370 if (num == 0) { | |
371 logger.warn("There are no themes configured!"); | |
372 return; | |
373 } | |
374 | |
375 logger.info("Theme group has " + num + " themes."); | |
376 | |
377 Map<String, Theme> theThemes = new HashMap<String, Theme>(); | |
378 | |
379 for (int i = 0; i < num; i++) { | |
380 Node theme = themes.item(i); | |
381 | |
382 Theme theTheme = ThemeFactory.createTheme(cfg, theme); | |
383 | |
384 if (theme != null) { | |
385 theThemes.put(theTheme.getName(), theTheme); | |
386 } | |
387 } | |
388 String gName = themeGroup.getAttribute("name"); | |
389 groups.add(new ThemeGroup(gName, theThemes)); | |
390 | |
391 logger.info( | |
392 "Initialized " + theThemes.size() + "/" + num + " themes " + | |
393 "of theme-group '" + gName + "'"); | |
394 } | |
395 context.put(FLYSContext.THEMES, groups); | |
396 } | |
397 | |
398 /** | |
399 * This method is used to retrieve the theme configuration document. | |
400 * | |
401 * @param config The global configuration. | |
402 * | |
403 * @return the theme configuration. | |
404 */ | |
405 protected Document getThemeConfig(Document config) { | |
406 String themeConfig = (String) XMLUtils.xpath( | |
407 config, | |
408 XPATH_THEME_CONFIG, | |
409 XPathConstants.STRING); | |
410 | |
411 themeConfig = Config.replaceConfigDir(themeConfig); | |
412 | |
413 logger.debug("Parse theme cfg: " + themeConfig); | |
414 | |
415 return XMLUtils.parseDocument(new File(themeConfig)); | |
416 } | |
417 | |
418 | |
419 protected void configureThemesMappings(Document cfg, FLYSContext context) { | |
420 logger.debug("FLYSContextFactory.configureThemesMappings"); | |
421 | |
422 Document config = getThemeConfig(cfg); | |
423 | |
424 NodeList mappings = (NodeList) XMLUtils.xpath( | |
425 config, XPATH_THEME_MAPPINGS, XPathConstants.NODESET); | |
426 | |
427 int num = mappings != null ? mappings.getLength() : 0; | |
428 | |
429 if (num == 0) { | |
430 logger.warn("No theme <--> facet mappins found!"); | |
431 return; | |
432 } | |
433 | |
434 Map<String, List<ThemeMapping>> mapping = | |
435 new HashMap<String, List<ThemeMapping>>(); | |
436 | |
437 for (int i = 0; i < num; i++) { | |
438 Element node = (Element)mappings.item(i); | |
439 | |
440 String from = node.getAttribute("from"); | |
441 String to = node.getAttribute("to"); | |
442 String pattern = node.getAttribute("pattern"); | |
443 String masterAttrPattern = node.getAttribute("masterAttr"); | |
444 String outputPattern = node.getAttribute("output"); | |
445 | |
446 if (from.length() > 0 && to.length() > 0) { | |
447 List<ThemeMapping> tm = mapping.get(from); | |
448 | |
449 if (tm == null) { | |
450 tm = new ArrayList<ThemeMapping>(); | |
451 mapping.put(from, tm); | |
452 } | |
453 | |
454 tm.add(new ThemeMapping( | |
455 from, to, pattern, masterAttrPattern, outputPattern)); | |
456 } | |
457 } | |
458 | |
459 logger.debug("Found " + mapping.size() + " theme mappings."); | |
460 | |
461 context.put(FLYSContext.THEME_MAPPING, mapping); | |
462 } | |
463 | |
464 | |
465 /** | |
466 * Reads configured floodmap river WMSs from floodmap.xml and | |
467 * loads them into the given FLYSContext. | |
468 * @param cfg | |
469 * @param context | |
470 */ | |
471 protected void configureFloodmapWMS(Document cfg, FLYSContext context) { | |
472 Map<String, String> riverWMS = new HashMap<String, String>(); | |
473 | |
474 NodeList rivers = (NodeList) XMLUtils.xpath( | |
475 cfg, XPATH_RIVER_WMS, XPathConstants.NODESET); | |
476 | |
477 int num = rivers != null ? rivers.getLength() : 0; | |
478 | |
479 for (int i = 0; i < num; i++) { | |
480 Element e = (Element) rivers.item(i); | |
481 | |
482 String river = e.getAttribute("name"); | |
483 String url = XMLUtils.xpathString(e, "river-wms/@url", null); | |
484 | |
485 if (river != null && url != null) { | |
486 riverWMS.put(river, url); | |
487 } | |
488 } | |
489 | |
490 logger.debug("Found " + riverWMS.size() + " river WMS."); | |
491 | |
492 context.put(FLYSContext.RIVER_WMS, riverWMS); | |
493 } | |
494 | |
495 | |
496 /** | |
497 * This method initializes the modules configuration. | |
498 * | |
499 * @param config the config document. | |
500 * @param context the FLYSContext. | |
501 */ | |
502 protected void configureModules(Document cfg, FLYSContext context) { | |
503 NodeList modulenodes = (NodeList) XMLUtils.xpath( | |
504 cfg, XPATH_MODULES, XPathConstants.NODESET); | |
505 | |
506 int num = modulenodes != null ? modulenodes.getLength() : 0; | |
507 ArrayList<Module> modules = new ArrayList<Module>(num); | |
508 | |
509 for (int i = 0; i < num; i++) { | |
510 Element e = (Element) modulenodes.item(i); | |
511 String modulename = e.getAttribute("name"); | |
512 String attrselected = e.getAttribute("selected"); | |
513 boolean selected = attrselected == null ? false : | |
514 attrselected.equalsIgnoreCase("true"); | |
515 logger.debug("Loaded module " + modulename); | |
516 modules.add(new Module(modulename, selected)); | |
517 } | |
518 context.put(FLYSContext.MODULES, modules); | |
519 } | |
520 } | |
521 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |