teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
teichmann@5863: * Software engineering by Intevation GmbH
teichmann@5863: *
teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5994: * documentation coming with Dive4Elements River for details.
teichmann@5863: */
teichmann@5863:
teichmann@5831: package org.dive4elements.river.artifacts.context;
ingo@106:
teichmann@7099: import java.io.File;
ingo@106: import java.util.ArrayList;
gernotbelger@9555: import java.util.Collections;
ingo@295: import java.util.HashMap;
ingo@106: import java.util.List;
ingo@295: import java.util.Map;
ingo@106:
ingo@106: import javax.xml.xpath.XPathConstants;
ingo@106:
ingo@106: import org.apache.log4j.Logger;
teichmann@7099: import org.dive4elements.artifactdatabase.state.State;
teichmann@7099: import org.dive4elements.artifactdatabase.state.StateEngine;
teichmann@7099: import org.dive4elements.artifactdatabase.transition.Transition;
teichmann@7099: import org.dive4elements.artifactdatabase.transition.TransitionEngine;
teichmann@7099: import org.dive4elements.artifacts.ArtifactContextFactory;
gernotbelger@9555: import org.dive4elements.artifacts.ContextInjector;
teichmann@7099: import org.dive4elements.artifacts.GlobalContext;
teichmann@7099: import org.dive4elements.artifacts.common.utils.Config;
teichmann@7099: import org.dive4elements.artifacts.common.utils.ElementConverter;
teichmann@7099: import org.dive4elements.artifacts.common.utils.XMLUtils;
teichmann@7099: import org.dive4elements.river.artifacts.model.Module;
rrenkert@7756: import org.dive4elements.river.artifacts.model.RiverFactory;
teichmann@7099: import org.dive4elements.river.artifacts.model.ZoomScale;
teichmann@7099: import org.dive4elements.river.artifacts.states.StateFactory;
teichmann@7099: import org.dive4elements.river.artifacts.transitions.TransitionFactory;
teichmann@7226: import org.dive4elements.river.exports.GeneratorLookup;
teichmann@7099: import org.dive4elements.river.exports.OutGenerator;
rrenkert@7756: import org.dive4elements.river.model.River;
teichmann@7099: import org.dive4elements.river.themes.Theme;
teichmann@7099: import org.dive4elements.river.themes.ThemeFactory;
teichmann@7099: import org.dive4elements.river.themes.ThemeGroup;
teichmann@7099: import org.dive4elements.river.themes.ThemeMapping;
ingo@106: import org.w3c.dom.Document;
ingo@106: import org.w3c.dom.Element;
ingo@295: import org.w3c.dom.Node;
ingo@106: import org.w3c.dom.NodeList;
ingo@106:
ingo@106: /**
ingo@106: * The ArtifactContextFactory is used to initialize basic components and put
ingo@106: * them into the global context of the application.
ingo@106: *
ingo@106: * @author Ingo Weinzierl
ingo@106: */
teichmann@5866: public class RiverContextFactory implements ArtifactContextFactory {
ingo@106:
teichmann@8202: /** The log that is used in this class. */
teichmann@8202: private static Logger log = Logger.getLogger(RiverContextFactory.class);
ingo@106:
ingo@106: /** The XPath to the artifacts configured in the configuration. */
gernotbelger@9555: private static final String XPATH_ARTIFACTS = "/artifact-database/artifacts/artifact";
ingo@106:
ingo@106: /** The XPath to the name of the artifact. */
gernotbelger@9555: private static final String XPATH_ARTIFACT_NAME = "/artifact/@name";
ingo@106:
ingo@106: /** The XPath to the xlink ref in an artifact configuration. */
gernotbelger@9555: private static final String XPATH_XLINK = "xlink:href";
ingo@106:
ingo@106: /** The XPath to the transitions configured in the artifact config. */
gernotbelger@9555: private static final String XPATH_TRANSITIONS = "/artifact/states/transition";
ingo@106:
ingo@107: /** The XPath to the states configured in the artifact config. */
gernotbelger@9555: private static final String XPATH_STATES = "/artifact/states/state";
raimund@2737:
gernotbelger@9555: private static final String XPATH_OUTPUT_GENERATORS = "/artifact-database/output-generators//output-generator";
ingo@345:
gernotbelger@9555: private static final String XPATH_THEME_CONFIG = "/artifact-database/flys/themes/configuration/text()";
ingo@958:
gernotbelger@9555: private static final String XPATH_THEMES = "theme";
bjoern@3630:
gernotbelger@9555: private static final String XPATH_LEGEND_GROUP = "/themes/legendgroup";
rrenkert@4619:
gernotbelger@9555: private static final String XPATH_THEME_GROUPS = "/themes/themegroup";
gernotbelger@9555:
gernotbelger@9555: private static final String XPATH_THEME_MAPPINGS = "/themes/mappings/mapping";
gernotbelger@9555:
gernotbelger@9555: private static final String XPATH_RIVER_WMS = "/artifact-database/floodmap/river";
gernotbelger@9555:
gernotbelger@9555: private static final String XPATH_MODULES = "/artifact-database/modules/module";
gernotbelger@9555:
gernotbelger@9555: private static final String XPATH_ZOOM_SCALES = "/artifact-database/options/zoom-scales/zoom-scale";
gernotbelger@9555:
gernotbelger@9555: private static final String XPATH_DGM_PATH = "/artifact-database/options/dgm-path/text()";
rrenkert@5152:
teichmann@6933: private static GlobalContext GLOBAL_CONTEXT_INSTANCE;
teichmann@6933:
ingo@106: /**
teichmann@5867: * Creates a new D4EArtifactContext object and initialize all
ingo@106: * components required by the application.
ingo@106: *
gernotbelger@9555: * @param config
gernotbelger@9555: * The artifact server configuration.
teichmann@5867: * @return a D4EArtifactContext.
ingo@106: */
christian@4656: @Override
gernotbelger@9555: public GlobalContext createArtifactContext(final Document config) {
gernotbelger@9555: final RiverContext context = new RiverContext(config);
ingo@106:
ingo@106: configureTransitions(config, context);
ingo@107: configureStates(config, context);
ingo@295: configureOutGenerators(config, context);
ingo@341: configureThemes(config, context);
ingo@345: configureThemesMappings(config, context);
gernotbelger@9555: configureLegend(config, context);
christian@4656: configureFloodmapWMS(config, context);
bjoern@3630: configureModules(config, context);
rrenkert@4619: configureZoomScales(config, context);
rrenkert@5152: configureDGMPath(config, context);
ingo@106:
teichmann@6933: synchronized (RiverContextFactory.class) {
teichmann@6933: GLOBAL_CONTEXT_INSTANCE = context;
teichmann@6933: }
teichmann@6933:
ingo@106: return context;
ingo@106: }
ingo@106:
teichmann@6933: public static synchronized GlobalContext getGlobalContext() {
teichmann@6933: return GLOBAL_CONTEXT_INSTANCE;
teichmann@6933: }
teichmann@6933:
gernotbelger@9555: private void configureDGMPath(final Document config, final RiverContext context) {
gernotbelger@9555: final String dgmPath = (String) XMLUtils.xpath(config, XPATH_DGM_PATH, XPathConstants.STRING);
rrenkert@5152:
rrenkert@5152: context.put("dgm-path", dgmPath);
rrenkert@5152: }
rrenkert@5152:
gernotbelger@9555: private void configureZoomScales(final Document config, final RiverContext context) {
gernotbelger@9555: final NodeList list = (NodeList) XMLUtils.xpath(config, XPATH_ZOOM_SCALES, XPathConstants.NODESET);
gernotbelger@9555: final ZoomScale scale = new ZoomScale();
rrenkert@4619: for (int i = 0; i < list.getLength(); i++) {
gernotbelger@9555: final Element element = (Element) list.item(i);
rrenkert@4619: String river = "default";
rrenkert@4619: double range = 0d;
rrenkert@4619: double radius = 10d;
rrenkert@4619: if (element.hasAttribute("river")) {
rrenkert@4619: river = element.getAttribute("river");
rrenkert@4619: }
rrenkert@4619: if (!element.hasAttribute("range")) {
rrenkert@4619: continue;
gernotbelger@9555: } else {
gernotbelger@9555: final String r = element.getAttribute("range");
rrenkert@4619: try {
rrenkert@4619: range = Double.parseDouble(r);
rrenkert@4619: }
gernotbelger@9555: catch (final NumberFormatException nfe) {
rrenkert@4619: continue;
rrenkert@4619: }
rrenkert@4619: }
rrenkert@4619: if (!element.hasAttribute("radius")) {
rrenkert@4619: continue;
gernotbelger@9555: } else {
gernotbelger@9555: final String r = element.getAttribute("radius");
rrenkert@4619: try {
rrenkert@4619: radius = Double.parseDouble(r);
rrenkert@4619: }
gernotbelger@9555: catch (final NumberFormatException nfe) {
rrenkert@4619: continue;
rrenkert@4619: }
rrenkert@4619: }
rrenkert@4619: scale.addRange(river, range, radius);
gernotbelger@9555: }
gernotbelger@9555: context.put("zoomscale", scale);
rrenkert@4619: }
rrenkert@4619:
ingo@106: /**
ingo@106: * This method initializes the transition configuration.
ingo@106: *
gernotbelger@9555: * @param config
gernotbelger@9555: * the config document.
gernotbelger@9555: * @param context
gernotbelger@9555: * the RiverContext.
ingo@106: */
gernotbelger@9555: private void configureTransitions(final Document config, final RiverContext context) {
gernotbelger@9555: final TransitionEngine engine = new TransitionEngine();
ingo@106:
gernotbelger@9555: final List artifacts = getArtifactConfigurations(config);
teichmann@8202: log.info("Found " + artifacts.size() + " artifacts in the config.");
ingo@106:
gernotbelger@9555: for (final Document doc : artifacts) {
ingo@106:
gernotbelger@9555: final String artName = (String) XMLUtils.xpath(doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING);
ingo@106:
gernotbelger@9555: final NodeList list = (NodeList) XMLUtils.xpath(doc, XPATH_TRANSITIONS, XPathConstants.NODESET);
ingo@106:
ingo@111: if (list == null) {
gernotbelger@9555: log.warn("The artifact " + artName + " has no transitions configured.");
ingo@107: continue;
ingo@106: }
ingo@106:
gernotbelger@9555: final int trans = list.getLength();
ingo@106:
gernotbelger@9555: log.info("Artifact '" + artName + "' has " + trans + " transitions.");
ingo@106:
ingo@106: for (int i = 0; i < trans; i++) {
gernotbelger@9555: final Transition t = TransitionFactory.createTransition(list.item(i));
gernotbelger@9555: final String s = t.getFrom();
ingo@111: engine.addTransition(s, t);
ingo@106: }
ingo@106: }
ingo@106:
teichmann@5866: context.put(RiverContext.TRANSITION_ENGINE_KEY, engine);
ingo@106: }
ingo@106:
ingo@106: /**
ingo@106: * This method returns all artifact documents defined in
gernotbelger@9555: * config
.
gernotbelger@9555: * NOTE: The artifact configurations need to be
ingo@106: * stored in own files referenced by an xlink.
ingo@106: *
gernotbelger@9555: * @param config
gernotbelger@9555: * The global configuration.
ingo@106: *
ingo@106: * @return an array of Artifact configurations.
ingo@106: */
gernotbelger@9555: private List getArtifactConfigurations(final Document config) {
gernotbelger@9555: final NodeList artifacts = (NodeList) XMLUtils.xpath(config, XPATH_ARTIFACTS, XPathConstants.NODESET);
ingo@106:
gernotbelger@9555: final int count = artifacts.getLength();
ingo@106:
gernotbelger@9555: final ArrayList docs = new ArrayList<>(count);
ingo@106:
ingo@106: for (int i = 0; i < count; i++) {
gernotbelger@9555: final Element tmp = (Element) artifacts.item(i);
ingo@106:
ingo@106: String xlink = tmp.getAttribute(XPATH_XLINK);
gernotbelger@9555: xlink = Config.replaceConfigDir(xlink);
ingo@106:
teichmann@8272: if (!xlink.isEmpty()) {
gernotbelger@9555: final File file = new File(xlink);
teichmann@8272: if (!file.isFile() || !file.canRead()) {
gernotbelger@9555: log.warn("Artifact configuration '" + file + "' not found.");
teichmann@8272: } else {
gernotbelger@9555: final Document doc = XMLUtils.parseDocument(file);
teichmann@8272: if (doc != null) {
teichmann@8272: docs.add(doc);
teichmann@8272: }
teichmann@8272: }
teichmann@8086: continue;
teichmann@8086: }
gernotbelger@9555: final Document doc = XMLUtils.newDocument();
gernotbelger@9555: final Node copy = doc.adoptNode(tmp.cloneNode(true));
teichmann@8272: doc.appendChild(copy);
teichmann@8272: docs.add(doc);
ingo@106: }
teichmann@8086: return docs;
ingo@106: }
ingo@107:
ingo@107: /**
ingo@107: * This method initializes the transition configuration.
ingo@107: *
gernotbelger@9555: * @param config
gernotbelger@9555: * the config document.
gernotbelger@9555: * @param context
gernotbelger@9555: * the RiverContext.
ingo@107: */
gernotbelger@9555: private void configureStates(final Document config, final RiverContext context) {
gernotbelger@9555: final StateEngine engine = new StateEngine();
ingo@107:
gernotbelger@9555: final List artifacts = getArtifactConfigurations(config);
teichmann@8202: log.info("Found " + artifacts.size() + " artifacts in the config.");
ingo@107:
gernotbelger@9555: for (final Document doc : artifacts) {
gernotbelger@9555: final List states = new ArrayList<>();
ingo@107:
gernotbelger@9555: final String artName = (String) XMLUtils.xpath(doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING);
ingo@107:
gernotbelger@9555: final NodeList stateList = (NodeList) XMLUtils.xpath(doc, XPATH_STATES, XPathConstants.NODESET);
ingo@107:
ingo@107: if (stateList == null) {
gernotbelger@9555: log.warn("The artifact " + artName + " has no states configured.");
ingo@107: continue;
ingo@107: }
ingo@107:
gernotbelger@9555: final int count = stateList.getLength();
ingo@107:
gernotbelger@9555: log.info("Artifact '" + artName + "' has " + count + " states.");
ingo@107:
ingo@107: for (int i = 0; i < count; i++) {
gernotbelger@9555: states.add(StateFactory.createState(stateList.item(i)));
ingo@107: }
ingo@107:
ingo@107: engine.addStates(artName, states);
ingo@107: }
ingo@107:
teichmann@5866: context.put(RiverContext.STATE_ENGINE_KEY, engine);
ingo@107: }
ingo@295:
ingo@295: /**
ingo@295: * This method intializes the provided output generators.
ingo@295: *
gernotbelger@9555: * @param config
gernotbelger@9555: * the config document.
gernotbelger@9555: * @param context
gernotbelger@9555: * the RiverContext.
ingo@295: */
gernotbelger@9555: private void configureOutGenerators(final Document config, final RiverContext context) {
gernotbelger@9555: final NodeList outGenerators = (NodeList) XMLUtils.xpath(config, XPATH_OUTPUT_GENERATORS, XPathConstants.NODESET);
ingo@295:
gernotbelger@9555: final int num = outGenerators == null ? 0 : outGenerators.getLength();
ingo@295:
ingo@295: if (num == 0) {
teichmann@8202: log.warn("No output generators configured in this application.");
ingo@295: return;
ingo@295: }
ingo@295:
teichmann@8202: log.info("Found " + num + " configured output generators.");
ingo@295:
gernotbelger@9555: final GeneratorLookup generators = new GeneratorLookup();
teichmann@7037:
ingo@295: int idx = 0;
ingo@295:
ingo@295: for (int i = 0; i < num; i++) {
gernotbelger@9555: final Element item = (Element) outGenerators.item(i);
ingo@295:
gernotbelger@9555: final String names = item.getAttribute("names").trim();
gernotbelger@9555: final String clazz = item.getAttribute("class").trim();
gernotbelger@9555: final String converter = item.getAttribute("converter").trim();
gernotbelger@9555: final String injectors = item.getAttribute("injectors").trim();
ingo@295:
teichmann@7074: if (names.isEmpty() || clazz.isEmpty()) {
ingo@295: continue;
ingo@295: }
ingo@295:
teichmann@7073: Class generatorClass = null;
teichmann@7073:
ingo@295: try {
gernotbelger@9555: generatorClass = (Class) Class.forName(clazz);
ingo@295: }
gernotbelger@9555: catch (final ClassNotFoundException cnfe) {
teichmann@8202: log.error(cnfe, cnfe);
teichmann@7073: continue;
teichmann@7073: }
teichmann@7073:
teichmann@7099: Object cfg = null;
teichmann@7099:
teichmann@7099: if (!converter.isEmpty()) {
teichmann@7099: try {
gernotbelger@9555: final ElementConverter ec = (ElementConverter) Class.forName(converter).newInstance();
teichmann@7099: cfg = ec.convert(item);
teichmann@7099: }
gernotbelger@9555: catch (final ClassNotFoundException cnfe) {
teichmann@8202: log.error(cnfe, cnfe);
teichmann@7099: }
gernotbelger@9555: catch (final InstantiationException ie) {
teichmann@8202: log.error(ie);
teichmann@7099: }
gernotbelger@9555: catch (final IllegalAccessException iae) {
teichmann@8202: log.error(iae);
teichmann@7099: }
teichmann@7099: }
teichmann@7099:
teichmann@8254: List cis = null;
teichmann@8219:
teichmann@8254: if (!injectors.isEmpty()) {
gernotbelger@9555: cis = new ArrayList<>();
gernotbelger@9555: for (final String injector : injectors.split("[\\s,]+")) {
teichmann@8254: try {
gernotbelger@9555: final ContextInjector ci = (ContextInjector) Class.forName(injector).newInstance();
teichmann@8254: ci.setup(item);
teichmann@8254: cis.add(ci);
teichmann@8254: }
gernotbelger@9555: catch (final ClassNotFoundException cnfe) {
teichmann@8254: log.error(cnfe, cnfe);
teichmann@8254: }
gernotbelger@9555: catch (final InstantiationException ie) {
teichmann@8254: log.error(ie);
teichmann@8254: }
gernotbelger@9555: catch (final IllegalAccessException iae) {
teichmann@8254: log.error(iae);
teichmann@8254: }
teichmann@8219: }
teichmann@8219: }
teichmann@8219:
gernotbelger@9555: for (String key : names.split("[\\s,]+")) {
teichmann@7073: if (!(key = key.trim()).isEmpty()) {
teichmann@8254: generators.putGenerator(key, generatorClass, cfg, cis);
teichmann@7073: idx++;
teichmann@7073: }
ingo@295: }
ingo@295: }
ingo@295:
teichmann@8202: log.info("Successfully loaded " + idx + " output generators.");
teichmann@5866: context.put(RiverContext.OUTGENERATORS_KEY, generators);
teichmann@7227: context.put(RiverContext.FACETFILTER_KEY, generators);
ingo@295: }
ingo@341:
ingo@341: /**
ingo@341: * This methods reads the configured themes and puts them into the
teichmann@5866: * RiverContext.
ingo@341: *
gernotbelger@9555: * @param config
gernotbelger@9555: * The global configuration.
gernotbelger@9555: * @param context
gernotbelger@9555: * The RiverContext.
ingo@341: */
gernotbelger@9555: private void configureThemes(final Document config, final RiverContext context) {
teichmann@8202: log.debug("RiverContextFactory.configureThemes");
ingo@341:
gernotbelger@9555: final Document cfg = getThemeConfig(config);
ingo@341:
gernotbelger@9555: final NodeList themeGroups = (NodeList) XMLUtils.xpath(cfg, XPATH_THEME_GROUPS, XPathConstants.NODESET);
ingo@341:
gernotbelger@9555: final int groupNum = themeGroups != null ? themeGroups.getLength() : 0;
ingo@341:
raimund@2737: if (groupNum == 0) {
teichmann@8202: log.warn("There are no theme groups configured!");
ingo@341: }
sascha@3256:
teichmann@8202: log.info("Found " + groupNum + " theme groups in configuration");
ingo@341:
gernotbelger@9555: final List groups = new ArrayList<>();
ingo@341:
raimund@2737: for (int g = 0; g < groupNum; g++) {
gernotbelger@9555: final Element themeGroup = (Element) themeGroups.item(g);
ingo@341:
gernotbelger@9555: final Map theThemes = readThemes(cfg, themeGroup);
ingo@341:
gernotbelger@9555: if (theThemes.size() == 0) {
teichmann@8202: log.warn("There are no themes configured!");
raimund@2737: return;
raimund@2737: }
raimund@2737:
gernotbelger@9555: final String gName = themeGroup.getAttribute("name");
raimund@2737: groups.add(new ThemeGroup(gName, theThemes));
sascha@3256:
gernotbelger@9555: log.info("Initialized " + theThemes.size() + "/" + theThemes.size() + " themes " + "of theme-group '" + gName + "'");
raimund@2737: }
teichmann@5866: context.put(RiverContext.THEMES, groups);
ingo@341: }
ingo@341:
ingo@341: /**
gernotbelger@9555: * This methods reads the configured themes and puts them into the
gernotbelger@9555: * RiverContext.
gernotbelger@9555: *
gernotbelger@9555: * @param config
gernotbelger@9555: * The global configuration.
gernotbelger@9555: * @param context
gernotbelger@9555: * The RiverContext.
gernotbelger@9555: */
gernotbelger@9555: private void configureLegend(final Document config, final RiverContext context) {
gernotbelger@9555: log.debug("RiverContextFactory.configureLegend");
gernotbelger@9555:
gernotbelger@9555: final Map legendGroup = readLegend(config);
gernotbelger@9555: context.put(RiverContext.LEGEND, legendGroup);
gernotbelger@9555: }
gernotbelger@9555:
gernotbelger@9555: private Map readLegend(final Document config) {
gernotbelger@9555:
gernotbelger@9555: final Document cfg = getThemeConfig(config);
gernotbelger@9555:
gernotbelger@9555: final Node legendGroup = (Node) XMLUtils.xpath(cfg, XPATH_LEGEND_GROUP, XPathConstants.NODE);
gernotbelger@9555: if (legendGroup == null) {
gernotbelger@9555: log.warn("There is no legend group configured");
gernotbelger@9555: return Collections.emptyMap();
gernotbelger@9555: }
gernotbelger@9555:
gernotbelger@9555: return readThemes(cfg, legendGroup);
gernotbelger@9555: }
gernotbelger@9555:
gernotbelger@9555: private Map readThemes(final Document cfg, final Node themeGroup) {
gernotbelger@9555: final NodeList themes = (NodeList) XMLUtils.xpath(themeGroup, XPATH_THEMES, XPathConstants.NODESET);
gernotbelger@9555: if (themes == null)
gernotbelger@9555: return Collections.emptyMap();
gernotbelger@9555:
gernotbelger@9555: final int num = themes.getLength();
gernotbelger@9555: log.info("Theme group has " + num + " themes.");
gernotbelger@9555: final Map theThemes = new HashMap<>();
gernotbelger@9555:
gernotbelger@9555: for (int i = 0; i < num; i++) {
gernotbelger@9555: final Node theme = themes.item(i);
gernotbelger@9555:
gernotbelger@9555: final Theme theTheme = ThemeFactory.createTheme(cfg, theme);
gernotbelger@9555: theThemes.put(theTheme.getName(), theTheme);
gernotbelger@9555: }
gernotbelger@9555:
gernotbelger@9555: return theThemes;
gernotbelger@9555: }
gernotbelger@9555:
gernotbelger@9555: /**
ingo@341: * This method is used to retrieve the theme configuration document.
ingo@341: *
gernotbelger@9555: * @param config
gernotbelger@9555: * The global configuration.
ingo@341: *
ingo@341: * @return the theme configuration.
ingo@341: */
gernotbelger@9555: private Document getThemeConfig(final Document config) {
gernotbelger@9555: String themeConfig = (String) XMLUtils.xpath(config, XPATH_THEME_CONFIG, XPathConstants.STRING);
ingo@341:
ingo@341: themeConfig = Config.replaceConfigDir(themeConfig);
ingo@341:
teichmann@8202: log.debug("Parse theme cfg: " + themeConfig);
ingo@341:
gernotbelger@9555: return XMLUtils.parseDocument(new File(themeConfig), true, XMLUtils.CONF_RESOLVER);
ingo@341: }
ingo@345:
gernotbelger@9555: private void configureThemesMappings(final Document cfg, final RiverContext context) {
teichmann@8202: log.debug("RiverContextFactory.configureThemesMappings");
ingo@345:
gernotbelger@9555: final Document config = getThemeConfig(cfg);
ingo@345:
gernotbelger@9555: final NodeList mappings = (NodeList) XMLUtils.xpath(config, XPATH_THEME_MAPPINGS, XPathConstants.NODESET);
ingo@345:
gernotbelger@9555: final int num = mappings != null ? mappings.getLength() : 0;
ingo@345:
ingo@345: if (num == 0) {
teichmann@8202: log.warn("No theme <--> facet mappins found!");
ingo@345: return;
ingo@345: }
ingo@345:
gernotbelger@9555: final Map> mapping = new HashMap<>();
ingo@345:
ingo@345: for (int i = 0; i < num; i++) {
gernotbelger@9555: final Element node = (Element) mappings.item(i);
ingo@345:
gernotbelger@9555: final String from = node.getAttribute("from");
gernotbelger@9555: final String to = node.getAttribute("to");
gernotbelger@9555: final String pattern = node.getAttribute("pattern");
gernotbelger@9555: final String masterAttrPattern = node.getAttribute("masterAttr");
gernotbelger@9555: final String outputPattern = node.getAttribute("output");
ingo@1747:
raimund@2742: if (from.length() > 0 && to.length() > 0) {
ingo@1747: List tm = mapping.get(from);
ingo@1747:
ingo@1747: if (tm == null) {
gernotbelger@9555: tm = new ArrayList<>();
ingo@1747: mapping.put(from, tm);
ingo@1747: }
ingo@1747:
gernotbelger@9555: tm.add(new ThemeMapping(from, to, pattern, masterAttrPattern, outputPattern));
ingo@345: }
ingo@345: }
ingo@345:
teichmann@8202: log.debug("Found " + mapping.size() + " theme mappings.");
ingo@345:
teichmann@5866: context.put(RiverContext.THEME_MAPPING, mapping);
ingo@345: }
ingo@958:
christian@4656: /**
christian@4656: * Reads configured floodmap river WMSs from floodmap.xml and
teichmann@5866: * loads them into the given RiverContext.
gernotbelger@9555: *
christian@4656: * @param cfg
christian@4656: * @param context
christian@4656: */
gernotbelger@9555: private void configureFloodmapWMS(final Document cfg, final RiverContext context) {
gernotbelger@9555: final Map riverWMS = new HashMap<>();
ingo@958:
gernotbelger@9555: final NodeList rivers = (NodeList) XMLUtils.xpath(cfg, XPATH_RIVER_WMS, XPathConstants.NODESET);
ingo@958:
gernotbelger@9555: final int num = rivers != null ? rivers.getLength() : 0;
ingo@958:
ingo@958: for (int i = 0; i < num; i++) {
gernotbelger@9555: final Element e = (Element) rivers.item(i);
ingo@958:
gernotbelger@9555: final String river = e.getAttribute("name");
gernotbelger@9555: final String url = XMLUtils.xpathString(e, "river-wms/@url", null);
ingo@958:
ingo@958: if (river != null && url != null) {
ingo@958: riverWMS.put(river, url);
ingo@958: }
ingo@958: }
ingo@958:
teichmann@8202: log.debug("Found " + riverWMS.size() + " river WMS.");
ingo@958:
teichmann@5866: context.put(RiverContext.RIVER_WMS, riverWMS);
ingo@958: }
bjoern@3630:
bjoern@3630: /**
bjoern@3630: * This method initializes the modules configuration.
bjoern@3630: *
gernotbelger@9555: * @param config
gernotbelger@9555: * the config document.
gernotbelger@9555: * @param context
gernotbelger@9555: * the RiverContext.
bjoern@3630: */
gernotbelger@9555: private void configureModules(final Document cfg, final RiverContext context) {
gernotbelger@9555: final NodeList modulenodes = (NodeList) XMLUtils.xpath(cfg, XPATH_MODULES, XPathConstants.NODESET);
bjoern@3630:
gernotbelger@8870: final int num = modulenodes != null ? modulenodes.getLength() : 0;
gernotbelger@8870:
gernotbelger@8870: final List modules = new ArrayList<>(num);
bjoern@3630:
bjoern@3630: for (int i = 0; i < num; i++) {
gernotbelger@8870: final Element e = (Element) modulenodes.item(i);
gernotbelger@8870: final String modulename = e.getAttribute("name");
gernotbelger@8870: final String attrselected = e.getAttribute("selected");
gernotbelger@8870: final boolean selected = Boolean.parseBoolean(attrselected);
gernotbelger@8870: final String group = e.getAttribute("group");
gernotbelger@9555:
teichmann@8202: log.debug("Loaded module " + modulename);
gernotbelger@9555:
gernotbelger@8870: final NodeList children = e.getChildNodes();
gernotbelger@8870: final List rivers = new ArrayList<>(children.getLength());
rrenkert@7756: for (int j = 0; j < children.getLength(); j++) {
rrenkert@7756: if (children.item(j).getNodeType() != Node.ELEMENT_NODE) {
rrenkert@7756: continue;
rrenkert@7756: }
gernotbelger@9555:
gernotbelger@9555: final Element ce = (Element) children.item(j);
rrenkert@7756: if (ce.hasAttribute("uuid")) {
rrenkert@7756: rivers.add(ce.getAttribute("uuid"));
gernotbelger@9555: } else if (ce.hasAttribute("name")) {
gernotbelger@8870: final List allRivers = RiverFactory.getRivers();
gernotbelger@8870: final String name = ce.getAttribute("name");
gernotbelger@9555: for (final River r : allRivers) {
rrenkert@7756: if (name.equals(r.getName())) {
rrenkert@7756: rivers.add(r.getModelUuid());
rrenkert@7756: break;
rrenkert@7756: }
rrenkert@7756: }
rrenkert@7756: }
rrenkert@7756: }
gernotbelger@8870: modules.add(new Module(modulename, selected, group, rivers));
bjoern@3630: }
teichmann@5866: context.put(RiverContext.MODULES, modules);
bjoern@3630: }
gernotbelger@9555: }