diff gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java @ 335:e964a3d8f7bc

Some Refactoring work done. Moved Transition to State gnv-artifacts/trunk@401 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 08 Dec 2009 08:39:03 +0000
parents
children bb1afbbd93e4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java	Tue Dec 08 08:39:03 2009 +0000
@@ -0,0 +1,835 @@
+/**
+ *
+ */
+package de.intevation.gnv.state.timeseries;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.jfree.chart.ChartTheme;
+
+import au.com.bytecode.opencsv.CSVWriter;
+import de.intevation.artifactdatabase.Config;
+import de.intevation.artifactdatabase.XMLUtils;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.PreferredLocale;
+import de.intevation.gnv.artifacts.ressource.RessourceFactory;
+import de.intevation.gnv.chart.Chart;
+import de.intevation.gnv.chart.ChartLabels;
+import de.intevation.gnv.chart.TimeSeriesChart;
+import de.intevation.gnv.chart.XMLChartTheme;
+import de.intevation.gnv.chart.exception.TechnicalChartException;
+import de.intevation.gnv.exports.ChartExportHelper;
+import de.intevation.gnv.exports.DefaultExport;
+import de.intevation.gnv.exports.DefaultDataCollector;
+import de.intevation.gnv.exports.SimpleOdvDataCollector;
+import de.intevation.gnv.exports.DefaultProfile;
+import de.intevation.gnv.exports.Export.Profile;
+import de.intevation.gnv.geobackend.base.Result;
+import de.intevation.gnv.state.InputData;
+import de.intevation.gnv.state.OutputStateBase;
+import de.intevation.gnv.state.describedata.KeyValueDescibeData;
+import de.intevation.gnv.state.describedata.NamedCollection;
+import de.intevation.gnv.state.exception.StateException;
+import de.intevation.gnv.statistics.Statistic;
+import de.intevation.gnv.statistics.StatisticSet;
+import de.intevation.gnv.statistics.Statistics;
+import de.intevation.gnv.statistics.TimeseriesStatistics;
+import de.intevation.gnv.statistics.exception.StatisticsException;
+import de.intevation.gnv.timeseries.gap.DefaultTimeGap;
+import de.intevation.gnv.timeseries.gap.TimeGap;
+import de.intevation.gnv.utils.ArtifactXMLUtilities;
+
+
+/**
+ * @author Tim Englich <tim.englich@intevation.de>
+ * 
+ */
+public class TimeSeriesOutputState extends OutputStateBase {
+
+    protected static final boolean CACHE_CHART =
+        Boolean.parseBoolean(System.getProperty("cache.chart", "false"));
+
+    protected static final boolean PDF_FORMAT_LANDSCAPE =
+        Boolean.parseBoolean(System.getProperty("export.pdf.landscape","true"));
+
+    protected static final String[] IMG_EXPORT_FORMAT = {
+        "PNG", "JPEG", "GIF"
+    };
+
+    /**
+     * The UID of this Class
+     */
+    private static final long serialVersionUID = 4178407570503098858L;
+
+    /**
+     * the logger, used to log exceptions and additonaly information
+     */
+    private static Logger log = Logger
+            .getLogger(TimeSeriesOutputState.class);
+
+    private static List<TimeGap> timeGapDefinitions = null;
+
+    protected String domainLable = "Zeit [UTC]";
+
+    protected String featureValuesName = "featureid";
+    protected String parameterValuesName = "parameterid";
+    protected String measuremenValueName = "measurementid";
+    protected String dateValueName = "dateid";
+    
+    public static final String [] TIMESERIES_CSV_PROFILE_NAMES = {
+        "XORDINATE",
+        "YORDINATE",
+        "GROUP1",
+        "GROUP2",
+        "GROUP3"
+    };
+    
+    public static final String [] TIMESERIES_ODV_PROFILE_NAMES = {
+          "CRUISE",
+          "STATION",
+          "TYPE",
+          "SHAPE",
+          "BOTDEPTH",
+          "DEPTH",
+          "TIMEVALUE",
+          "DATAVALUE",
+          "PARAMETER"
+    };
+
+
+    public static final String [] ODV_COLUMN_HEADER = {
+        "Cruise",
+        "Station",
+        "Type",
+        "Longitude [deegrees_east]",
+        "Latitude [deegrees_north]",
+        "Bot. Depth [m]",
+        "Depth [m]",
+        "Date/Time",
+        "Value",
+        "Parameterid"
+    };
+
+    /**
+     * Profile for exporting data to cvs
+     */
+    public static final Profile TIMESERIES_CSV_PROFILE =
+        new DefaultProfile(
+            null,
+            ',',
+            '"',
+            '"',
+            "CSV",
+            "ISO-8859-1");
+
+    /**
+     * Profile for exporting data to odv
+     * TODO Change TIMESERIES_PROFILE_NAMES, which belong to CSV exports
+     */
+    public static final Profile TIMESERIES_ODV_PROFILE =
+        new DefaultProfile(
+            ODV_COLUMN_HEADER,
+            '\t',
+            CSVWriter.NO_QUOTE_CHARACTER,
+            CSVWriter.NO_ESCAPE_CHARACTER,
+            "ODV",
+            "ISO-8859-1");
+
+    /**
+     * Constructor
+     */
+    public TimeSeriesOutputState() {
+        super();
+    }
+
+    /**
+     * @see de.intevation.gnv.transition.OutputTransition#out(java.lang.String,
+     *      java.util.Collection, java.io.OutputStream, java.lang.String,
+     *      de.intevation.artifacts.CallMeta)
+     */
+    public void out(
+        Document format,
+        Collection<InputData> inputData,
+        OutputStream outputStream,
+        String uuid,
+        CallMeta callMeta
+    ) throws StateException
+    {
+        log.debug("TimeSeriesOutputTransition.out");
+
+        String outputMode = Config.getStringXPath(
+            format,
+            "action/out/@name"
+        );
+        String mimeType   = Config.getStringXPath(
+            format,
+            "action/out/mime-type/@value"
+        );
+
+        try {
+            if (outputMode.equalsIgnoreCase("chart")) {
+                log.debug("Chart will be generated.");
+                int chartWidth = 600;
+                int chartHeight = 400;
+                try {
+                    if (inputData != null) {
+                        Iterator<InputData> it = inputData.iterator();
+                        while (it.hasNext()) {
+                            InputData ip = it.next();
+                            if (ip.getName().equalsIgnoreCase("width")) {
+                                chartWidth = Integer.parseInt(ip.getValue());
+                            } else if (ip.getName().equalsIgnoreCase("height")) {
+                                chartHeight = Integer.parseInt(ip.getValue());
+                            }
+                        }
+                    }
+                } catch (NumberFormatException e) {
+                    log.error(e, e);
+                    throw new StateException(e);
+                }
+
+                PreferredLocale[] locales = callMeta.getLanguages();
+                Locale[] serverLocales    =
+                    RessourceFactory.getInstance().getLocales();
+                Locale locale             =
+                    callMeta.getPreferredLocale(serverLocales);
+
+                log.debug(
+                    "Best locale - regarding intersection of server and " +
+                    "browser locales -  is " + locale.toString()
+                );
+
+                Collection parameters   = this.getCleanedParameters(uuid);
+                Collection measurements = this.getMeasurements(uuid);
+                Collection dates        = this.getDates(uuid);
+
+                ChartLabels chartLables = new ChartLabels(
+                    createChartTitle(locale, uuid),
+                    createChartSubtitle(locale, uuid),
+                    domainLable
+                );
+
+                String exportFormat = getExportFormat(mimeType);
+
+                // TODO Remove this and parse input data
+                boolean linesVisible = true;
+                boolean shapesVisible = true;
+
+                this.createChart(
+                    outputStream,
+                    parameters,
+                    measurements,
+                    dates,
+                    chartLables,
+                    uuid,
+                    exportFormat,
+                    locale,
+                    chartWidth,
+                    chartHeight,
+                    linesVisible,
+                    shapesVisible
+                );
+            }
+            else if (outputMode.equalsIgnoreCase("pdf")) {
+                log.debug("Output mode == pdf");
+
+                Locale[] serverLocales    =
+                    RessourceFactory.getInstance().getLocales();
+                Locale locale             =
+                    callMeta.getPreferredLocale(serverLocales);
+
+                // TODO Remove this and parse input data
+                boolean linesVisible = true;
+                boolean shapesVisible = true;
+
+                log.debug(
+                    "Best locale - regarding intersection of server and " +
+                    "browser locales -  is " + locale.toString()
+                );
+
+                createPDF(
+                    outputStream,
+                    getCleanedParameters(uuid),
+                    getMeasurements(uuid),
+                    getDates(uuid),
+                    new ChartLabels(
+                        createChartTitle(locale, uuid),
+                        createChartSubtitle(locale, uuid),
+                        domainLable),
+                    uuid,
+                    "A4",
+                    true,
+                    locale,
+                    linesVisible,
+                    shapesVisible
+                );
+            }
+            else if (outputMode.equalsIgnoreCase("svg")) {
+                log.debug("Output mode == svg");
+                int width  = 600;
+                int height = 400;
+
+                // TODO Remove this and parse input data
+                boolean linesVisible = true;
+                boolean shapesVisible = true;
+
+                Locale[] serverLocales    =
+                    RessourceFactory.getInstance().getLocales();
+                Locale locale             =
+                    callMeta.getPreferredLocale(serverLocales);
+
+                log.debug(
+                    "Best locale - regarding intersection of server and " +
+                    "browser locales -  is " + locale.toString()
+                );
+
+                createSVG(
+                    outputStream,
+                    getCleanedParameters(uuid),
+                    getMeasurements(uuid),
+                    getDates(uuid),
+                    new ChartLabels(
+                        createChartTitle(locale, uuid),
+                        createChartSubtitle(locale, uuid),
+                        domainLable
+                    ),
+                    uuid,
+                    locale,
+                    width,
+                    height,
+                    linesVisible,
+                    shapesVisible
+                );
+            }
+            else if (outputMode.equalsIgnoreCase("csv")) {
+                log.debug("CSV-File will be generated.");
+                Collection<Result> chartResult = this.getChartResult(uuid);
+                this.createCSV(outputStream, chartResult);
+            } else if (outputMode.equalsIgnoreCase("statistics")) {
+                log.debug("Statistics will be generated.");
+                Statistics s = getStatisticsGenerator();
+                Collection<Result> chartResult = this.getChartResult(uuid);
+                Collection<KeyValueDescibeData> parameters = 
+                                                this.getParameters(uuid);
+                Collection<KeyValueDescibeData> measurements = 
+                                                this.getMeasurements(uuid);
+                Collection<KeyValueDescibeData> dates = 
+                                                this.getDates(uuid);
+                Collection<StatisticSet> statistics = 
+                                      s.calculateStatistics(chartResult,
+                                                            parameters,
+                                                            measurements,
+                                                            dates);
+                Document doc = this.writeStatistics2XML(statistics);
+                this.writeDocument2OutputStream(doc, outputStream);
+            } else if (outputMode.equalsIgnoreCase("odv")) {
+                
+                Collection<Result> odvResult = this.getODVResult(uuid);
+                this.createODV(outputStream, odvResult);
+            }
+        } catch (IOException e) {
+            log.error(e, e);
+            throw new StateException(e);
+        } catch (TechnicalChartException e) {
+            log.error(e, e);
+            throw new StateException(e);
+        } catch (StatisticsException e) {
+            log.error(e, e);
+            throw new StateException(e);
+        }
+    }
+
+
+    protected String getExportFormat(String mime) {
+        for(int i = 0; i < IMG_EXPORT_FORMAT.length; i++) {
+            if (mime.trim().toUpperCase().indexOf(IMG_EXPORT_FORMAT[i]) > 0)
+                return IMG_EXPORT_FORMAT[i];
+        }
+
+        // no format found relating to mimeType, default export as PNG
+        return IMG_EXPORT_FORMAT[0];
+    }
+
+
+    protected Collection getCleanedParameters(Collection parameters) {
+        Iterator iter        = parameters.iterator();
+        Collection parameter = new Vector(parameters);
+        while (iter.hasNext()) {
+            KeyValueDescibeData data = (KeyValueDescibeData)iter.next();
+            if (!data.isSelected())
+                parameter.remove(data);
+        }
+
+        return parameter;
+    }
+
+
+    protected Collection getCleanedParameters(String uuid) {
+        return getCleanedParameters(getParameters(uuid));
+    }
+
+
+    /**
+     * @param outputStream
+     * @param chartResult
+     * @throws UnsupportedEncodingException
+     * @throws IOException
+     * @throws StateException
+     */
+    protected void createCSV(OutputStream outputStream,
+                            Collection<Result> chartResult)
+                                                          throws UnsupportedEncodingException,
+                                                          IOException,
+                                                          StateException {
+        DefaultExport export = new DefaultExport(new DefaultDataCollector(
+            TIMESERIES_CSV_PROFILE_NAMES));
+
+        export.create(TIMESERIES_CSV_PROFILE, outputStream, chartResult);
+    }
+
+    /**
+     * TODO Result is not used at the moment. Change result with correct data.
+     */
+    protected void createODV(OutputStream outputStream, Collection result)
+    throws IOException, StateException {
+
+        DefaultExport export = new DefaultExport(new SimpleOdvDataCollector(
+            TIMESERIES_ODV_PROFILE_NAMES));
+
+        if (result == null)
+            log.error("#################### RESULT == NULL #################");
+        export.create(TIMESERIES_ODV_PROFILE, outputStream, result);
+    }
+
+    /**
+     * @return
+     */
+    protected Statistics getStatisticsGenerator() {
+        Statistics s = new TimeseriesStatistics();
+        return s;
+    }
+
+    protected void writeDocument2OutputStream(Document document, OutputStream os) {
+
+        try {
+            TransformerFactory transformerFactory = TransformerFactory
+                    .newInstance();
+            Transformer transformer = transformerFactory.newTransformer();
+            DOMSource source = new DOMSource(document);
+            StreamResult result = new StreamResult(os);
+            transformer.transform(source, result);
+        } catch (TransformerConfigurationException e) {
+            log.error(e, e);
+        } catch (TransformerFactoryConfigurationError e) {
+            log.error(e, e);
+        } catch (TransformerException e) {
+            log.error(e, e);
+        }
+    }
+
+    protected Document writeStatistics2XML( Collection<StatisticSet> statistic) {
+        ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities();
+        Document doc = XMLUtils.newDocument();
+        if (statistic != null) {
+            Node statisticResults = xmlUtilities.createArtifactElement(doc,
+                    "statistics");
+            doc.appendChild(statisticResults);
+            Iterator<StatisticSet> it = statistic.iterator();
+            while (it.hasNext()) {
+                StatisticSet set = it.next();
+                Element setElement = xmlUtilities.createArtifactElement(doc,
+                                                                       "statistic");
+                setElement.setAttribute("name", set.getName());
+                
+                Iterator<Statistic> sit = set.getStatistics().iterator();
+                while (sit.hasNext()){
+                    Statistic s = sit.next();
+                    Element result = xmlUtilities.createArtifactElement(doc,
+                    "statistic-value");
+                    result.setAttribute("name", s.getKey());
+                    result.setAttribute("value", s.getStringValue());
+                    setElement.appendChild(result);
+                }
+                statisticResults.appendChild(setElement);
+            }
+
+        }
+        return doc;
+    }
+
+
+    protected String getSelectedFeatureName(String uuid) {
+        Collection values = getCollection(featureValuesName, uuid);
+
+        if (values != null) {
+            Iterator it = values.iterator();
+
+            while (it.hasNext()) {
+                KeyValueDescibeData data = (KeyValueDescibeData) it.next();
+
+                if (data.isSelected()) {
+                    return data.getValue();
+                }
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * @param outputStream
+     * @param parameters
+     * @param measurements
+     * @param timeSeriesName
+     * @param chartStyle
+     * @param chartLables
+     * @throws IOException
+     * @throws TechnicalChartException
+     */
+    protected void createChart(
+        OutputStream outputStream,
+        Collection   parameters,
+        Collection   measurements,
+        Collection   dates,
+        ChartLabels  chartLables,
+        String       uuid,
+        String       exportFormat,
+        Locale       locale,
+        int          width,
+        int          height,
+        boolean      linesVisible,
+        boolean      shapesVisible
+    )
+    throws IOException, TechnicalChartException
+    {
+        log.debug("Create chart.");
+        Chart chart = getChart(
+            chartLables,
+            parameters,
+            measurements,
+            dates,
+            getChartResult(uuid),
+            locale, // Locale
+            uuid,
+            linesVisible,
+            shapesVisible
+        );
+
+        if (chart == null) {
+            log.error("Could not initialize chart.");
+            return;
+        }
+
+        log.debug(
+            "export chart as " + exportFormat +
+            " in " + width + "x" + height
+        );
+
+        ChartExportHelper.exportImage(
+            outputStream,
+            chart.generateChart(),
+            exportFormat,
+            width,
+            height
+        );
+    }
+
+
+    protected void createPDF(
+        OutputStream outputStream,
+        Collection   parameters,
+        Collection   measurements,
+        Collection   dates,
+        ChartLabels  chartLables,
+        String       uuid,
+        String       exportFormat,
+        boolean      landscape,
+        Locale       locale,
+        boolean      linesVisible,
+        boolean      shapesVisible
+    ) {
+        Chart chart = getChart(
+            chartLables,
+            parameters,
+            measurements,
+            dates,
+            getChartResult(uuid),
+            locale,
+            uuid,
+            linesVisible,
+            shapesVisible
+        );
+
+        if (chart == null) {
+            log.error("Could not initialize chart.");
+            return;
+        }
+
+        ChartExportHelper.exportPDF(
+            outputStream,
+            chart.generateChart(),
+            "A4",
+            PDF_FORMAT_LANDSCAPE,
+            50F, 50F, 50F, 50F
+        );
+
+        try {
+            OutputStream toFile = new FileOutputStream("/vol1/home/iweinzierl/tmp/test.svg");
+            ChartExportHelper.exportSVG(
+                toFile,
+                chart.generateChart(),
+                null,
+                600, 400
+            );
+            toFile.flush();
+            toFile.close();
+        }
+        catch(Exception e) { log.debug("ERROR WHLILE TEST."); }
+    }
+
+
+    protected void createSVG(
+        OutputStream outputStream,
+        Collection   parameters,
+        Collection   measurements,
+        Collection   dates,
+        ChartLabels  chartLables,
+        String       uuid,
+        Locale       locale,
+        int          width,
+        int          height,
+        boolean      linesVisible,
+        boolean      shapesVisible
+    ) {
+        Chart chart = getChart(
+            chartLables,
+            parameters,
+            measurements,
+            dates,
+            getChartResult(uuid),
+            locale,
+            uuid,
+            linesVisible,
+            shapesVisible
+        );
+
+        if (chart == null) {
+            log.error("Could not initialize chart.");
+            return;
+        }
+
+        ChartExportHelper.exportSVG(
+            outputStream,
+            chart.generateChart(),
+            null,
+            600, 400
+        );
+
+        log.debug("svg export finished.");
+    }
+
+
+    protected Chart getChart(
+        ChartLabels  chartLables,
+        Collection   parameters,
+        Collection   measurements,
+        Collection   dates,
+        Collection   result,
+        Locale       locale,
+        String       uuid,
+        boolean      linesVisible,
+        boolean      shapesVisible
+    ) {
+        Chart chart = null;
+
+        if (CACHE_CHART) {
+            log.info("Try to get timeseries chart from cache.");
+            chart = (Chart) getChartFromCache(uuid);
+        }
+
+        if (chart != null)
+            return chart;
+
+        log.info("Chart not in cache yet.");
+        chart = new TimeSeriesChart(
+            chartLables,
+            createStyle(),
+            parameters,
+            measurements,
+            dates,
+            result,
+            timeGapDefinitions,
+            locale,
+            linesVisible,
+            shapesVisible
+        );
+        chart.generateChart();
+
+        if (CACHE_CHART) {
+            log.info("Put chart into cache.");
+            purifyChart(chart, uuid);
+        }
+
+        return chart;
+    }
+
+    protected ChartTheme createStyle() {
+        XMLChartTheme theme = null;
+
+        Document template = Config.getChartTemplate();
+        String   name     = Config.getStringXPath(
+            template,
+            "theme/name/@value"
+        );
+
+        theme  = new XMLChartTheme(name);
+        theme.applyXMLConfiguration(template);
+
+        return theme;
+    }
+
+
+    protected String createChartTitle(Locale locale, String uuid) {
+        return getFisName(locale);
+
+    }
+
+
+    protected String createChartSubtitle(Locale locale, String uuid) {
+        return getSelectedFeatureName(uuid);
+    }
+
+
+    protected String getFisName(Locale locale) {
+        String    returnValue = "";
+        InputData input       = inputData.get("fisname");
+
+        if (input != null) {
+            String value = input.getValue();
+
+            returnValue = RessourceFactory.getInstance().getRessource(
+                locale,
+                value,
+                value
+            );
+        }
+        return returnValue;
+    }
+
+
+    protected Collection<KeyValueDescibeData> getParameters(String uuid) {
+        return this.getCollection(parameterValuesName, uuid);
+    }
+
+    protected Collection<KeyValueDescibeData> getMeasurements(String uuid) {
+        return this.getCollection(measuremenValueName, uuid);
+    }
+    protected Collection<KeyValueDescibeData> getDates(String uuid) {
+        return this.getCollection(dateValueName,uuid);
+    }
+
+    @Override
+    public void setup(Node configuration) {
+        super.setup(configuration);
+        String featureNameValue = Config.getStringXPath(configuration,
+                "value-names/value-name[@name='feature']/@value");
+        if (featureNameValue != null) {
+            this.featureValuesName = featureNameValue;
+        }
+        String parameterNameValue = Config.getStringXPath(configuration,
+                "value-names/value-name[@name='parameter']/@value");
+        if (parameterNameValue != null) {
+            this.parameterValuesName = parameterNameValue;
+        }
+        String measurementNameValue = Config.getStringXPath(configuration,
+                "value-names/value-name[@name='measurement']/@value");
+        if (measurementNameValue != null) {
+            this.measuremenValueName = measurementNameValue;
+        }
+        
+        String dateNameValue = Config.getStringXPath(configuration,
+        "value-names/value-name[@name='date']/@value");
+        if (dateNameValue != null) {
+            this.dateValueName = dateNameValue;
+        }
+        if (timeGapDefinitions == null){
+            Element gapDefinition =  (Element)Config.getNodeXPath(configuration,
+                                                                 "time-gap-definition");
+            synchronized (this.getClass()) {
+                if (gapDefinition != null){
+                    String link = gapDefinition.getAttribute("xlink:href");
+                    if (link != null ){
+                        String absolutFileName = Config.replaceConfigDir(link);
+                        gapDefinition = (Element)new ArtifactXMLUtilities().
+                                                     readConfiguration(absolutFileName);
+                    }
+                    
+                    NodeList gapDefinitions = Config.getNodeSetXPath(gapDefinition, 
+                                                                    "/time-gaps/time-gap");
+                    if (gapDefinition != null){
+                        timeGapDefinitions = new ArrayList<TimeGap>(gapDefinitions.
+                                                                    getLength());
+                        for (int i = 0; i < gapDefinitions.getLength(); i++){
+                            Element gapNode = (Element)gapDefinitions.item(i);
+                            String unit = gapNode.getAttribute("unit");
+                            int key = Integer.parseInt(gapNode.getAttribute("key"));
+                            int value = Integer.parseInt(gapNode.getAttribute("gap"));
+                            log.info("Add new Timegap: "+key+" "+value+" "+ unit);
+                            timeGapDefinitions.add(new DefaultTimeGap(unit, 
+                                                                      key, 
+                                                                      value));
+                        }
+                    }
+                    
+                }
+            }
+        }
+    }
+    
+    /**
+     * @param collectionName
+     * @return
+     */
+    protected Collection<KeyValueDescibeData> getCollection(
+                                                            String collectionName, 
+                                                            String uuid) {
+        Iterator<Object> it = this.getDescibeData(uuid).iterator();
+        while (it.hasNext()) {
+
+            Object o = it.next();
+
+            if (o instanceof NamedCollection<?>) {
+                NamedCollection<KeyValueDescibeData> nc = (NamedCollection<KeyValueDescibeData>) o;
+                if (nc.getName().equals(collectionName)) {
+                    return nc;
+                }
+            }
+        }
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org