tim@64: /** tim@64: * tim@64: */ tim@64: package de.intevation.gnv.transition.timeseries; tim@64: tim@68: import java.awt.Color; tim@68: import java.awt.Dimension; tim@68: import java.io.IOException; tim@73: import java.io.OutputStream; tim@90: import java.io.OutputStreamWriter; tim@68: import java.util.Collection; tim@68: import java.util.Iterator; tim@68: tim@95: import javax.xml.transform.Transformer; tim@95: import javax.xml.transform.TransformerConfigurationException; tim@95: import javax.xml.transform.TransformerException; tim@95: import javax.xml.transform.TransformerFactory; tim@95: import javax.xml.transform.TransformerFactoryConfigurationError; tim@95: import javax.xml.transform.dom.DOMSource; tim@95: import javax.xml.transform.stream.StreamResult; tim@95: tim@68: import org.apache.log4j.Logger; tim@95: import org.w3c.dom.Document; tim@95: import org.w3c.dom.Element; tim@95: import org.w3c.dom.Node; tim@68: tim@90: import au.com.bytecode.opencsv.CSVWriter; tim@119: import de.intevation.artifactdatabase.Config; tim@95: import de.intevation.artifactdatabase.XMLUtils; tim@117: import de.intevation.artifacts.CallMeta; tim@68: import de.intevation.gnv.chart.ChartFactory; tim@68: import de.intevation.gnv.chart.ChartLabels; tim@68: import de.intevation.gnv.chart.ChartStyle; tim@68: import de.intevation.gnv.chart.exception.TechnicalChartException; tim@68: import de.intevation.gnv.geobackend.base.Result; tim@95: import de.intevation.gnv.statistics.Statistic; tim@98: import de.intevation.gnv.statistics.Statistics; tim@95: import de.intevation.gnv.statistics.TimeseriesStatistics; tim@95: import de.intevation.gnv.statistics.exception.StatisticsException; tim@91: import de.intevation.gnv.transition.InputData; tim@64: import de.intevation.gnv.transition.OutputTransitionBase; tim@68: import de.intevation.gnv.transition.describedata.KeyValueDescibeData; tim@81: import de.intevation.gnv.transition.describedata.NamedCollection; tim@68: import de.intevation.gnv.transition.exception.TransitionException; tim@95: import de.intevation.gnv.utils.ArtifactXMLUtilities; tim@64: tim@64: /** tim@64: * @author Tim Englich tim@117: * tim@64: */ tim@117: public class TimeSeriesOutputTransition extends OutputTransitionBase { tim@86: tim@86: /** tim@86: * The UID of this Class tim@86: */ tim@86: private static final long serialVersionUID = 4178407570503098858L; tim@117: tim@68: /** tim@68: * the logger, used to log exceptions and additonaly information tim@68: */ tim@117: private static Logger log = Logger tim@117: .getLogger(TimeSeriesOutputTransition.class); tim@117: tim@117: protected String domainLable = "Zeit [UTC]"; tim@119: tim@119: protected String featureValuesName = "featureid"; tim@119: protected String parameterValuesName = "parameterid"; tim@119: protected String measuremenValueName = "measurementid"; tim@117: tim@64: /** tim@64: * Constructor tim@64: */ tim@64: public TimeSeriesOutputTransition() { tim@64: super(); tim@64: } tim@64: tim@64: /** tim@64: * @see de.intevation.gnv.transition.Transition#validate() tim@64: */ tim@64: public boolean validate() { tim@64: return true; tim@64: } tim@64: tim@117: /** tim@117: * @see de.intevation.gnv.transition.OutputTransition#out(java.lang.String, tim@117: * java.util.Collection, java.io.OutputStream, java.lang.String, tim@117: * de.intevation.artifacts.CallMeta) tim@117: */ tim@117: public void out(String outputMode, Collection inputData, tim@117: OutputStream outputStream, String uuid, CallMeta callMeta) tim@117: throws TransitionException { tim@90: log.debug("TimeSeriesOutputTransition.out"); tim@68: try { tim@117: tim@117: this.advance(uuid, callMeta); tim@117: Collection chartResult = this.getChartResult(uuid); tim@117: if (outputMode.equalsIgnoreCase("chart")) { tim@90: log.debug("Chart will be generated."); tim@91: int chartWidth = 600; tim@91: int chartHeight = 400; tim@91: try { tim@117: if (inputData != null) { tim@91: Iterator it = inputData.iterator(); tim@117: while (it.hasNext()) { tim@91: InputData ip = it.next(); tim@117: if (ip.getName().equalsIgnoreCase("width")) { tim@91: chartWidth = Integer.parseInt(ip.getValue()); tim@117: } else if (ip.getName().equalsIgnoreCase("height")) { tim@91: chartHeight = Integer.parseInt(ip.getValue()); tim@91: } tim@91: } tim@91: } tim@91: } catch (NumberFormatException e) { tim@117: log.error(e, e); tim@91: throw new TransitionException(e); tim@91: } tim@117: Collection parameters = this tim@117: .getParameters(); tim@117: Collection measurements = this tim@117: .getMeasurements(); tim@117: ChartStyle chartStyle = this tim@117: .creatStyle(chartWidth, chartHeight); tim@117: ChartLabels chartLables = new ChartLabels(this tim@117: .getSelectedFeatureName(), this.domainLable); tim@90: this.createChart(outputStream, parameters, measurements, tim@117: chartStyle, chartLables, uuid); tim@117: } else if (outputMode.equalsIgnoreCase("csv")) { tim@90: log.debug("CSV-File will be generated."); tim@117: if (chartResult != null) { tim@117: CSVWriter writer = new CSVWriter(new OutputStreamWriter( tim@117: outputStream, "ISO-8859-1"), ','); // USE THIS tim@117: // ENCODING tim@117: // BECAUSE OF tim@117: // PROBLEMS WITH tim@117: // EXCEL AND tim@117: // UTF-8 tim@117: Iterator it = chartResult.iterator(); tim@117: while (it.hasNext()) { tim@90: Result result = it.next(); tim@90: int i = 0; tim@90: String[] entries = new String[5]; tim@90: entries[i++] = result.getString("XORDINATE"); tim@90: entries[i++] = result.getString("YORDINATE"); tim@90: entries[i++] = result.getString("GROUP1"); tim@90: entries[i++] = result.getString("GROUP2"); tim@90: entries[i++] = result.getString("GROUP3"); tim@90: writer.writeNext(entries); tim@90: } tim@90: writer.close(); tim@117: } else { tim@90: log.error("No Data given for generation an CSV-File."); tim@117: throw new TransitionException( tim@117: "No Data given for generation an CSV-File."); tim@90: } tim@117: } else if (outputMode.equalsIgnoreCase("statistics")) { tim@95: log.debug("Statistics will be generated."); tim@98: Statistics s = getStatisticsGenerator(); tim@117: Collection statistics = s tim@117: .calculateStatistics(chartResult); tim@95: Document doc = this.writeStatistics2XML(statistics); tim@95: this.writeDocument2OutputStream(doc, outputStream); tim@90: } tim@68: } catch (IOException e) { tim@117: log.error(e, e); tim@68: throw new TransitionException(e); tim@68: } catch (TechnicalChartException e) { tim@117: log.error(e, e); tim@68: throw new TransitionException(e); tim@117: } catch (StatisticsException e) { tim@117: log.error(e, e); tim@95: throw new TransitionException(e); tim@68: } tim@68: } tim@98: tim@98: /** tim@98: * @return tim@98: */ tim@98: protected Statistics getStatisticsGenerator() { tim@98: Statistics s = new TimeseriesStatistics(); tim@98: return s; tim@98: } tim@117: tim@117: protected void writeDocument2OutputStream(Document document, OutputStream os) { tim@117: tim@95: try { tim@117: TransformerFactory transformerFactory = TransformerFactory tim@117: .newInstance(); tim@95: Transformer transformer = transformerFactory.newTransformer(); tim@95: DOMSource source = new DOMSource(document); tim@117: StreamResult result = new StreamResult(os); tim@95: transformer.transform(source, result); tim@95: } catch (TransformerConfigurationException e) { tim@117: log.error(e, e); tim@95: } catch (TransformerFactoryConfigurationError e) { tim@117: log.error(e, e); tim@117: } catch (TransformerException e) { tim@117: log.error(e, e); tim@95: } tim@95: } tim@117: tim@117: protected Document writeStatistics2XML(Collection statistic) { tim@95: ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); tim@95: Document doc = XMLUtils.newDocument(); tim@117: if (statistic != null) { tim@117: Node statisticResults = xmlUtilities.createArtifactElement(doc, tim@117: "statistic-values"); tim@95: doc.appendChild(statisticResults); tim@95: Iterator it = statistic.iterator(); tim@117: while (it.hasNext()) { tim@95: Statistic s = it.next(); tim@117: Element result = xmlUtilities.createArtifactElement(doc, tim@117: "statistic"); tim@95: result.setAttribute("name", s.getKey()); tim@95: result.setAttribute("value", s.getStringValue()); tim@95: statisticResults.appendChild(result); tim@95: } tim@117: tim@95: } tim@95: return doc; tim@95: } tim@68: tim@117: protected String getSelectedFeatureName() { tim@117: Collection values = this tim@119: .getCollection(featureValuesName); tim@117: if (values != null) { tim@86: Iterator it = values.iterator(); tim@117: while (it.hasNext()) { tim@86: KeyValueDescibeData data = it.next(); tim@117: if (data.isSelected()) { tim@86: return data.getValue(); tim@86: } tim@86: } tim@86: } tim@86: return null; tim@86: } tim@117: tim@86: /** tim@86: * @param outputStream tim@86: * @param parameters tim@86: * @param measurements tim@86: * @param timeSeriesName tim@86: * @param chartStyle tim@86: * @param chartLables tim@86: * @throws IOException tim@86: * @throws TechnicalChartException tim@86: */ tim@86: protected void createChart(OutputStream outputStream, tim@117: Collection parameters, tim@117: Collection measurements, tim@117: ChartStyle chartStyle, ChartLabels chartLables, tim@117: String uuid) throws IOException, tim@117: TechnicalChartException { tim@86: ChartFactory chartFactory = new ChartFactory(); tim@86: chartFactory.createSimpleTimeSeriesChart(chartLables, chartStyle, tim@117: parameters, measurements, outputStream, this tim@117: .getChartResult(uuid)); tim@68: } tim@117: tim@117: protected ChartStyle creatStyle(int witdh, int height) { tim@68: // TODO Konfigurierbar machen tim@117: de.intevation.gnv.chart.Insets lInsets = new de.intevation.gnv.chart.Insets( tim@117: 5d, 5d, 5d, 5d); tim@68: Dimension lChartSize = new Dimension(witdh, height); tim@117: return new ChartStyle(Color.white, new Color(230, 230, 230), tim@117: Color.white, Color.white, true, true, lInsets, lChartSize); tim@68: } tim@117: tim@117: protected Collection getParameters() { tim@119: return this.getCollection(parameterValuesName); tim@64: } tim@117: tim@117: protected Collection getMeasurements() { tim@119: return this.getCollection(measuremenValueName); tim@119: } tim@119: tim@119: @Override tim@119: public void setup(Node configuration) { tim@119: super.setup(configuration); tim@119: String featureNameValue = Config.getStringXPath(configuration, "value-names/value-name[@name='feature']/@value"); tim@119: if (featureNameValue != null){ tim@119: this.featureValuesName = featureNameValue; tim@119: } tim@119: String parameterNameValue = Config.getStringXPath(configuration, "value-names/value-name[@name='parameter']/@value"); tim@119: if (parameterNameValue != null){ tim@119: this.parameterValuesName = parameterNameValue; tim@119: } tim@119: String measurementNameValue = Config.getStringXPath(configuration, "value-names/value-name[@name='measurement']/@value"); tim@119: if (measurementNameValue != null){ tim@119: this.measuremenValueName = measurementNameValue; tim@119: } tim@82: } tim@82: tim@82: /** tim@82: * @param collectionName tim@82: * @return tim@82: */ tim@82: protected Collection getCollection( tim@117: String collectionName) { tim@68: Iterator it = this.descibeData.iterator(); tim@117: while (it.hasNext()) { tim@117: tim@117: Object o = it.next(); tim@117: tim@117: if (o instanceof NamedCollection) { tim@117: NamedCollection nc = (NamedCollection) o; tim@117: if (nc.getName().equals(collectionName)) { tim@117: return nc; tim@117: } tim@117: } tim@68: } tim@68: return null; tim@68: } tim@64: }