view gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java @ 1118:c01c220312d0

Made it compile again with an updated ArtifactDatabase. gnv-artifacts/trunk@4137 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 12 Mar 2012 08:31:46 +0000
parents dec4257ad570
children
line wrap: on
line source
/*
 * Copyright (c) 2010 by Intevation GmbH
 *
 * This program is free software under the LGPL (>=v2.1)
 * Read the file LGPL.txt coming with the software for details
 * or visit http://www.gnu.org/licenses/ if it does not exist.
 */

package de.intevation.gnv.artifacts.context;

import de.intevation.artifacts.common.utils.Config;
import de.intevation.artifacts.common.utils.XMLUtils;

import de.intevation.artifacts.ArtifactContextFactory;
import de.intevation.artifacts.GlobalContext;

import de.intevation.gnv.artifacts.cache.CacheFactory;

import de.intevation.gnv.chart.XMLChartTheme;

import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException;

import de.intevation.gnv.geobackend.config.Configuration;

import de.intevation.gnv.raster.Filter;
import de.intevation.gnv.raster.Palette;
import de.intevation.gnv.raster.PaletteManager;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Properties;

import org.apache.log4j.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * This factory class is used to create new GNVArtfactContext objects,
 * initialize required components and put them into the created context object
 * for being available in the application.
 *
 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
 * @author <a href="mailto:iweinzierl@intevation.de">Ingo Weinzierl</a>
 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
 */
public class GNVArtifactContextFactory implements ArtifactContextFactory {
    /**
     * the logger, used to log exceptions and additonaly information
     */
    private static Logger log = Logger.getLogger(GNVArtifactContext.class);

    /**
     *
     */
    public static final String XPATH_GEOBACKEND_CONFIGURATION =
        "artifact-database/geo-backend";

    /**
     *
     */
    public static final String XPATH_GEOBACKEND_QUERYCONFIGURATION =
        "artifact-database/geo-backend/query-configuration";

    private final static String CACHECONFIGNODEPATH =
        "/artifact-database/ehcache/configuration";

    private final static String CHARTCONFIGNODEPATH =
        "/artifact-database/gnv/charttemplate/configuration";

    /**
     *
     */
    public final static String PALETTES_PATH =
        "/artifact-database/gnv/palettes";

    /**
     *
     */
    public final static String PALETTE_ITEMS =
        "palette";

    /**
     *
     */
    public final static String HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES =
        "/artifact-database/gnv/horizontal-cross-section-profile/samples/@number";

    /**
     *
     */
    public final static String HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION =
        "/artifact-database/gnv/horizontal-cross-section/ground/@interpolation";

    /**
     *
     */
    public final static String HORIZONTAL_CROSS_SECTION_SAMPLES =
        "/artifact-database/gnv/horizontal-cross-section/samples/@number";

    /**
     *
     */
    public final static String HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS =
        "/artifact-database/gnv/horizontal-cross-section/extrapolation/@rounds";

    /**
     *
     */
    public final static String HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH =
        "/artifact-database/gnv/shapefile-directory/@path";

    /**
     *
     */
    public final static String VERTICAL_CROSS_SECTION_SAMPLES =
        "/artifact-database/gnv/vertical-cross-section/samples";

    /**
     *
     */
    public final static String VERTICAL_CROSS_SECTION_FILTERS =
        "/artifact-database/gnv/vertical-cross-section/filters/filter";

    /**
     *
     */
    public final static String VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION =
        "/artifact-database/gnv/vertical-cross-section/ground/@interpolation";

    /**
     *
     */
    public final static String VERTICAL_CROSS_SECTION_GROUND_FILL_COLOR =
        "/artifact-database/gnv/vertical-cross-section/ground/@fill-color";

    /**
     *
     */
    public final static String XPATH_MAPSERVER_PATH =
        "/artifact-database/mapserver/server/@path";

    /**
     *
     */
    public final static String XPATH_MAP_PATH =
        "/artifact-database/gnv/map-generator/mapfile/@path";

    /**
     * Constructor
     */
    public GNVArtifactContextFactory() {
        super();
        log.debug("GNVArtifactContextFactory.Constructor");
    }

    /**
     * Create a new {@link GNVArtifactContext} object and initialize all
     * components required by the application.
     *
     * @param config
     * @return GNVArtifactContext
     * @see de.intevation.artifacts.ArtifactContextFactory#createArtifactContext(org.w3c.dom.Document)
     */
    public GlobalContext createArtifactContext(Document config) {
        GNVArtifactContext returnValue = null;
        try {
            log.debug("GNVArtifactContextFactory.createArtifactContext");

            configureGeoBackend(config);

            configureCache(config);

            returnValue = new GNVArtifactContext(config);

            configurePalettes(config, returnValue);

            configureChartTemplate(config, returnValue);

            configureHorizontalCrossSectionProfile(config, returnValue);

            configureHorizontalCrossSection(config,returnValue);

            configureVerticalCrossSection(config, returnValue);

            configureMapserver(config, returnValue);

        } catch (FileNotFoundException e) {
            log.error(e, e);
        } catch (IOException e) {
            log.error(e, e);
        } catch (QueryContainerException e) {
            log.error(e, e);
        }
        return returnValue;
    }

    protected void configureGeoBackend(Document config)
    throws FileNotFoundException, IOException, QueryContainerException
    {
        Configuration geoConf = Configuration.getInstance();
        String configDir      = Config.getConfigDirectory().getAbsolutePath();
        geoConf.init(config, configDir, Config.CONFIG_DIR_PLACEHOLDER);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureVerticalCrossSection(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configuration of vertical cross section");
        configureVerticalCrossSectionSamples(config, context);
        configureVerticalCrossSectionFilters(config, context);
        configureVerticalCrossSectionGroundInterpolation(config, context);
        configureVerticalCrossSectionGroundFillColor(config, context);
    }


    /**
     *
     * @param config
     */
    protected void configureCache(Document config) {
        String cacheConfigurationFile = Config.getStringXPath(
            config, CACHECONFIGNODEPATH);

        if (cacheConfigurationFile != null
        && !cacheConfigurationFile.equals(""))
        {
            log.info("Initialisation of the Cache");
            cacheConfigurationFile = Config.replaceConfigDir(
                cacheConfigurationFile);

            CacheFactory cf = CacheFactory.getInstance();
            cf.initializeCache(cacheConfigurationFile);
        }
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureVerticalCrossSectionGroundFillColor(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configuration of vertical cross section ground fill color");

        String fillColor = Config.getStringXPath(
            config,
            VERTICAL_CROSS_SECTION_GROUND_FILL_COLOR);

        Paint fill =
            GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_GROUND_FILL;

        if (fillColor != null
        && (fillColor = fillColor.trim()).length() != 0) {
            try {
                Color color = Color.decode(fillColor);
                log.info("ground fill color: #" +
                    Integer.toHexString(color.getRGB()));
                fill = color;
            }
            catch (NumberFormatException nfe) {
                log.error("'" + fillColor + "' is not a valid color");
            }
        }

        context.put(
            GNVArtifactContext
                .VERTICAL_CROSS_SECTION_GROUND_FILL_KEY,
            fill);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureVerticalCrossSectionGroundInterpolation(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configuration of vertical cross section ground interpolation");
        String interpolation = Config.getStringXPath(
            config,
            VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION);

        if (interpolation == null
        || (interpolation = interpolation.trim()).length() == 0) {
            interpolation = GNVArtifactContext
                .DEFAULT_VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION;
        }

        log.info("ground interpolation: " + interpolation);

        context.put(
            GNVArtifactContext
                .VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY,
            interpolation);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureVerticalCrossSectionFilters(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configuration of vertical cross section filters");

        NodeList filters = Config.getNodeSetXPath(
            VERTICAL_CROSS_SECTION_FILTERS);

        ArrayList<Filter.Factory> filterFactories =
            new ArrayList<Filter.Factory>();

        if (filters == null) {
            log.warn("no filters found");
        }
        else {
            for (int i = 0, N = filters.getLength(); i < N; ++i) {
                Element filterElement = (Element)filters.item(i);
                String factoryName = filterElement.getAttribute("factory");
                if ((factoryName = factoryName.trim()).length() > 0) {
                    try {
                        Class clazz = Class.forName(factoryName);
                        Filter.Factory filterFactory =
                            (Filter.Factory)clazz.newInstance();
                        filterFactories.add(filterFactory);
                    }
                    catch (ClassNotFoundException cnfe) {
                        log.error("filter class not found", cnfe);
                    }
                    catch (InstantiationException ie) {
                        log.error("cannot instantiate filter factory", ie);
                    }
                    catch (IllegalAccessException iae) {
                        log.error("cannot access filter factory", iae);
                    }
                    catch (ClassCastException cce) {
                        log.error("not a filter factory class", cce);
                    }
                }
                else {
                    log.error("No factory name given");
                }
            }
        }

        log.info("number of filters: " + filterFactories.size());

        context.put(
            GNVArtifactContext.VERTICAL_CROSS_SECTION_FILTER_FACTORIES_KEY,
            Collections.unmodifiableList(filterFactories));
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureVerticalCrossSectionSamples(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configuration of vertical cross section samples");

        Element samples = (Element)Config.getNodeXPath(
            VERTICAL_CROSS_SECTION_SAMPLES);

        Dimension sampleSize = new Dimension(
            GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_SAMPLES);

        if (samples == null) {
            log.warn("no samples found");
        }
        else {
            String widthString = samples.getAttribute("width");
            if ((widthString = widthString.trim()).length() > 0) {
                try {
                    sampleSize.width = Math.max(1, Integer.parseInt(widthString));
                }
                catch (NumberFormatException nfe) {
                    log.error("invalid value for width: '" + widthString + "'");
                }
            }
            String heightString = samples.getAttribute("height");
            if ((heightString = heightString.trim()).length() > 0) {
                try {
                    sampleSize.height = Math.max(1, Integer.parseInt(heightString));
                }
                catch (NumberFormatException nfe) {
                    log.error("invalid value for height: '" + heightString + "'");
                }
            }
        }
        log.info("samples (width x height): " +
            sampleSize.width + " x " + sampleSize.height);

        context.put(
            GNVArtifactContext.VERTICAL_CROSS_SECTION_SAMPLES_KEY,
            sampleSize);

    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureHorizontalCrossSectionProfile(
        Document           config,
        GNVArtifactContext context
    )
    {
        log.info("configuration of horizontal cross section profile");

        String numSamples = Config.getStringXPath(
            config,
            HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES);

        Integer samples =
            GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES;

        if (numSamples == null) {
            log.warn("No number of samples found.");
        }
        else {
            try {
                samples = Integer.valueOf(numSamples);
            }
            catch (NumberFormatException nfe) {
                log.warn("Invalid integer for number of samples");
            }
        }

        log.info("# horizontal cross section profile samples: " + samples);

        context.put(
            GNVArtifactContext.HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES_KEY,
            samples);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureHorizontalCrossSection(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configuration of horizontal cross section");

        configureHorizontalCrossSectionSamples(config, context);
        configureHorizontalCrossSectionExtrapolation(config, context);
        configureHorizontalCrossSectionResultShapeFilePath(config, context);
        configureHorizontalCrossSectionGroundInterpolation(config, context);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureHorizontalCrossSectionExtrapolation(
        Document           config,
        GNVArtifactContext context
    )
    {
        log.info(
            "configuration of horizontal cross section extrapolation");

        String extrapolationRoundsValue = Config.getStringXPath(
            config,
            HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS);

        Integer extrapolationRounds =
            GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS;

        if (extrapolationRoundsValue != null
        && (extrapolationRoundsValue = extrapolationRoundsValue.trim()).length() > 0
        ) {
            try {
                extrapolationRounds =
                    Integer.valueOf(extrapolationRoundsValue);
            }
            catch (NumberFormatException nfe) {
                log.error(
                    "'" + extrapolationRoundsValue + "' is not a valid integer");
            }
        }

        log.info("extrapolation rounds: " + extrapolationRounds);

        context.put(
            GNVArtifactContext
                .HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS_KEY,
            extrapolationRounds);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureHorizontalCrossSectionGroundInterpolation(
        Document           config,
        GNVArtifactContext context
    )
    {
        log.info(
            "configuration of horizontal cross section ground interpolation");

        String interpolation = Config.getStringXPath(
            config,
            HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION);

        if (interpolation == null
        || (interpolation = interpolation.trim()).length() == 0) {
            interpolation = GNVArtifactContext
                .DEFAULT_HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION;
        }

        log.info("ground interpolation: " + interpolation);

        context.put(
            GNVArtifactContext
                .HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY,
            interpolation);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureHorizontalCrossSectionResultShapeFilePath(
        Document           config,
        GNVArtifactContext context
    )
    {
        log.info(
            "configuration of horizontal cross section result shape file path");

        File dir =
            GNVArtifactContext.
            DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH;

        String path = Config.getStringXPath(
            config,
            HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH);

        if (path != null && (path = path.trim()).length() > 0) {
            dir = new File(Config.replaceConfigDir(path));
        }
        else {
            log.warn("No 'result-shapefile-directory' given");
        }

        log.info("writing shape files to '"
            + dir.getAbsolutePath() + "'");

        context.put(
            GNVArtifactContext
                .HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY,
            dir);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configureHorizontalCrossSectionSamples(
        Document           config,
        GNVArtifactContext context
    )
    {
        log.info("configuration of horizontal cross section samples");
        String numSamples = Config.getStringXPath(
            config,
            HORIZONTAL_CROSS_SECTION_SAMPLES);

        Integer samples =
            GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_SAMPLES;

        if (numSamples == null) {
            log.warn("No number of samples found.");
        }
        else {
            try {
                samples = Integer.valueOf(numSamples);
            }
            catch (NumberFormatException nfe) {
                log.warn("Invalid integer for number of samples");
            }
        }

        log.info("# horizontal cross section profile samples: " + samples);

        context.put(
            GNVArtifactContext.HORIZONTAL_CROSS_SECTION_SAMPLES_KEY,
            samples);
    }


    /**
     *
     * @param config
     * @param context
     */
    protected void configureChartTemplate(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("Initialisation of chart template");
        String chartConfigFile = Config.getStringXPath(
            config, CHARTCONFIGNODEPATH
        );

        XMLChartTheme theme = new XMLChartTheme("XMLChartTheme");

        if (chartConfigFile == null) {
            log.warn("no configuration file for chart template found");
        }
        else {
            chartConfigFile = Config.replaceConfigDir(chartConfigFile);
            log.debug("Parse xml configuration of " + chartConfigFile);

            Document tmpl = XMLUtils.parseDocument(new File(chartConfigFile));
            if (tmpl != null) {
                theme.applyXMLConfiguration(tmpl);
            }
            else {
                log.error(
                    "Cannot load chart template from '" +
                    chartConfigFile + "'");
            }
        }

        context.put(GNVArtifactContext.CHART_TEMPLATE_KEY, theme);
    }

    /**
     *
     * @param config
     * @param context
     */
    protected void configurePalettes(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("configure palettes");

        HashMap<Integer, PaletteManager> palettes = new HashMap();

        Element node = (Element)Config.getNodeXPath(config, PALETTES_PATH);

        if (node == null) {
            log.error("No palettes found");
        }
        else {
            NodeList pals = node.getElementsByTagName(PALETTE_ITEMS);
            for (int i = 0, N = pals==null?0:pals.getLength(); i < N; ++i) {
                Element pal = (Element)pals.item(i);
                String name         = pal.getAttribute("name");
                String description  = pal.getAttribute("description");
                String filename     = pal.getAttribute("file");
                String parameterIds = pal.getAttribute("parameter-ids");

                if (name == null || (name = name.trim()).length() == 0) {
                    log.error("Palette has no 'name' attribute.");
                }
                else if (filename == null
                || (filename = filename.trim()).length() == 0) {
                    log.error("Palette '" + name + "' has no 'file' attribute.");
                }
                else if (parameterIds == null
                || (parameterIds = parameterIds.trim()).length() == 0) {
                    log.error("no parameter ids given for '" + name + "'");
                }
                else {
                    ArrayList<Integer> ids = new ArrayList<Integer>();
                    for (String idString: parameterIds.split("[\t ,]+")) {
                        try {
                            ids.add(Integer.valueOf(idString));
                        }
                        catch (NumberFormatException nfe) {
                            log.error(
                                "parameter id '" + idString + "' is integer");
                        }
                    }
                    filename = Config.replaceConfigDir(filename);
                    Document document = XMLUtils.parseDocument(
                        new File(filename));
                    if (document == null) {
                        log.error("Cannot load palette file '" +
                            filename + "'");
                    }
                    else {
                        PaletteManager manager = new PaletteManager(
                            name,
                            description,
                            new Palette(document));
                        for (Integer id: ids) {
                            palettes.put(id, manager);
                        }
                    }
                }
            } // for all palettes
        }

        context.put(GNVArtifactContext.PALETTES_KEY, palettes);
    }


    /**
     *
     * @param config
     * @param context
     */
    protected void configureMapserver(
        Document           config,
        GNVArtifactContext context
    ) {
        log.info("read configuration of mapserver.");

        String serverPath = (String) Config.getStringXPath(
            config, XPATH_MAPSERVER_PATH);

        String mapPath = (String) Config.getStringXPath(
            config, XPATH_MAP_PATH);
        mapPath        = Config.replaceConfigDir(mapPath);

        if (serverPath != null && mapPath != null) {
            context.put(GNVArtifactContext.MAPSERVER_SERVER_PATH_KEY,serverPath);
            context.put(GNVArtifactContext.MAPSERVER_MAP_PATH_KEY, mapPath);
        }
    }

    /**
     * Read some properties from config file specified by <code>filePath</code>.
     *
     * @param filePath Path to a cofig file.
     * @return Properties contained in <code>filePath</code>.
     * @throws FileNotFoundException if file specified by filePath is not
     * existing.
     * @throws IOException if an error occured while reading from file.
     */
    private Properties getProperties(String filePath)
    throws FileNotFoundException, IOException
    {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(filePath);
            Properties properties = new Properties();
            properties.load(inputStream);
            return properties;
        }
        finally {
            if (inputStream != null) {
                try { inputStream.close(); }
                catch (IOException ioe) {}
            }
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org