tim@335: package de.intevation.gnv.state.timeseries; tim@335: sascha@480: import au.com.bytecode.opencsv.CSVWriter; sascha@480: sascha@480: import de.intevation.artifactdatabase.Config; sascha@480: import de.intevation.artifactdatabase.XMLUtils; sascha@480: sascha@480: import de.intevation.artifacts.ArtifactNamespaceContext; sascha@480: import de.intevation.artifacts.CallContext; sascha@480: import de.intevation.artifacts.CallMeta; sascha@480: sascha@480: import de.intevation.gnv.artifacts.context.GNVArtifactContext; sascha@480: sascha@480: import de.intevation.gnv.artifacts.ressource.RessourceFactory; sascha@480: sascha@480: import de.intevation.gnv.chart.Chart; sascha@480: import de.intevation.gnv.chart.ChartLabels; ingo@617: import de.intevation.gnv.chart.DefaultHistogram; sascha@480: import de.intevation.gnv.chart.TimeSeriesChart; sascha@480: import de.intevation.gnv.chart.XMLChartTheme; sascha@480: sascha@480: import de.intevation.gnv.chart.exception.TechnicalChartException; sascha@480: sascha@480: import de.intevation.gnv.exports.ChartExportHelper; sascha@480: import de.intevation.gnv.exports.DefaultDataCollector; sascha@480: import de.intevation.gnv.exports.DefaultExport; sascha@480: import de.intevation.gnv.exports.DefaultProfile; sascha@480: sascha@480: import de.intevation.gnv.exports.Export.Profile; sascha@480: sascha@480: import de.intevation.gnv.exports.SimpleOdvDataCollector; sascha@480: sascha@480: import de.intevation.gnv.geobackend.base.Result; sascha@480: ingo@617: import de.intevation.gnv.histogram.HistogramHelper; ingo@617: sascha@480: import de.intevation.gnv.state.InputData; sascha@480: import de.intevation.gnv.state.OutputStateBase; sascha@480: ingo@610: import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; sascha@480: import de.intevation.gnv.state.describedata.KeyValueDescibeData; ingo@610: import de.intevation.gnv.state.describedata.NamedArrayList; sascha@480: import de.intevation.gnv.state.describedata.NamedCollection; sascha@480: sascha@480: import de.intevation.gnv.state.exception.StateException; sascha@480: sascha@480: import de.intevation.gnv.statistics.Statistic; sascha@480: import de.intevation.gnv.statistics.StatisticSet; sascha@480: import de.intevation.gnv.statistics.Statistics; sascha@480: import de.intevation.gnv.statistics.TimeseriesStatistics; sascha@480: sascha@480: import de.intevation.gnv.statistics.exception.StatisticsException; sascha@480: sascha@480: import de.intevation.gnv.timeseries.gap.DefaultTimeGap; sascha@480: import de.intevation.gnv.timeseries.gap.TimeGap; sascha@480: sascha@480: import de.intevation.gnv.utils.ArtifactXMLUtilities; sascha@480: tim@335: import java.io.File; sascha@480: import java.io.IOException; tim@335: import java.io.OutputStream; tim@335: import java.io.UnsupportedEncodingException; sascha@480: tim@335: import java.util.ArrayList; tim@335: import java.util.Collection; ingo@629: import java.util.HashMap; tim@335: import java.util.Iterator; tim@335: import java.util.List; tim@335: import java.util.Locale; ingo@629: import java.util.Map; tim@335: import java.util.Vector; tim@335: tim@335: import org.apache.log4j.Logger; sascha@480: sascha@480: import org.jfree.chart.ChartTheme; sascha@480: tim@335: import org.w3c.dom.Document; tim@335: import org.w3c.dom.Element; tim@335: import org.w3c.dom.Node; tim@335: import org.w3c.dom.NodeList; tim@335: tim@335: /** sascha@481: * @author Tim Englich (tim.englich@intevation.de) sascha@481: * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) tim@335: */ tim@335: public class TimeSeriesOutputState extends OutputStateBase { tim@335: tim@335: protected static final boolean CACHE_CHART = tim@335: Boolean.parseBoolean(System.getProperty("cache.chart", "false")); tim@335: tim@335: protected static final boolean PDF_FORMAT_LANDSCAPE = tim@335: Boolean.parseBoolean(System.getProperty("export.pdf.landscape","true")); tim@335: tim@335: protected static final String[] IMG_EXPORT_FORMAT = { tim@335: "PNG", "JPEG", "GIF" tim@335: }; tim@335: tim@335: /** tim@335: * The UID of this Class tim@335: */ tim@335: private static final long serialVersionUID = 4178407570503098858L; tim@335: tim@335: /** tim@335: * the logger, used to log exceptions and additonaly information tim@335: */ tim@335: private static Logger log = Logger tim@335: .getLogger(TimeSeriesOutputState.class); tim@335: tim@335: private static List timeGapDefinitions = null; tim@335: ingo@342: protected String domainLable = "chart.timeseries.title.xaxis"; tim@335: tim@335: protected String featureValuesName = "featureid"; tim@335: protected String parameterValuesName = "parameterid"; tim@335: protected String measuremenValueName = "measurementid"; tim@335: protected String dateValueName = "dateid"; ingo@368: ingo@368: public static final String [] TIMESERIES_CSV_PROFILE_COLUMNS = { tim@335: "XORDINATE", tim@335: "YORDINATE", tim@335: "GROUP1", tim@335: "GROUP2", tim@335: "GROUP3" tim@335: }; ingo@368: ingo@368: ingo@368: public static final String [] TIMESERIES_TIMESERIES_CSV_COLUMN_LABEL = { ingo@368: "Date/Time", ingo@368: "Value", ingo@368: "ParameterID", ingo@368: "MeasurementID", ingo@368: "TimeseriesID" ingo@368: }; ingo@368: ingo@368: public static final String [] TIMESERIES_MESH_CSV_COLUMN_LABEL = { ingo@368: "Date/Time", ingo@368: "Value", ingo@368: "ParameterID", ingo@368: "FeatureID", ingo@368: "MeshID" ingo@368: }; ingo@368: tim@335: public static final String [] TIMESERIES_ODV_PROFILE_NAMES = { tim@335: "CRUISE", tim@335: "STATION", tim@335: "TYPE", tim@335: "SHAPE", tim@335: "BOTDEPTH", tim@335: "DEPTH", tim@335: "TIMEVALUE", tim@335: "DATAVALUE", tim@335: "PARAMETER" tim@335: }; tim@335: tim@335: tim@335: public static final String [] ODV_COLUMN_HEADER = { tim@335: "Cruise", tim@335: "Station", tim@335: "Type", tim@335: "Longitude [deegrees_east]", tim@335: "Latitude [deegrees_north]", tim@335: "Bot. Depth [m]", tim@335: "Depth [m]", tim@335: "Date/Time", tim@335: "Value", tim@335: "Parameterid" tim@335: }; tim@335: tim@335: /** tim@335: * Profile for exporting data to odv tim@335: * TODO Change TIMESERIES_PROFILE_NAMES, which belong to CSV exports tim@335: */ tim@335: public static final Profile TIMESERIES_ODV_PROFILE = tim@335: new DefaultProfile( tim@335: ODV_COLUMN_HEADER, tim@335: '\t', tim@335: CSVWriter.NO_QUOTE_CHARACTER, tim@335: CSVWriter.NO_ESCAPE_CHARACTER, tim@335: "ODV", tim@335: "ISO-8859-1"); tim@335: tim@335: /** tim@335: * Constructor tim@335: */ tim@335: public TimeSeriesOutputState() { tim@335: super(); tim@335: } tim@335: ingo@536: ingo@536: @Override ingo@536: public void initialize(String uuid, CallContext context) ingo@536: throws StateException ingo@536: { ingo@536: getChartResult(uuid, context); ingo@536: } ingo@536: ingo@536: tim@335: /** tim@335: * @see de.intevation.gnv.transition.OutputTransition#out(java.lang.String, tim@335: * java.util.Collection, java.io.OutputStream, java.lang.String, tim@335: * de.intevation.artifacts.CallMeta) tim@335: */ tim@335: public void out( sascha@480: Document format, tim@335: Collection inputData, sascha@480: OutputStream outputStream, sascha@480: String uuid, sascha@480: CallContext callContext tim@335: ) throws StateException tim@335: { tim@335: log.debug("TimeSeriesOutputTransition.out"); tim@335: ingo@467: String outputMode = XMLUtils.xpathString( ingo@467: format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); ingo@467: ingo@639: String mode = XMLUtils.xpathString( ingo@639: format, XPATH_EXPORT_MODE, ArtifactNamespaceContext.INSTANCE); ingo@639: ingo@639: if (mode == null || mode.equals("")) { ingo@639: mode = "img"; ingo@639: } ingo@639: ingo@467: String mimeType = XMLUtils.xpathString( ingo@467: format, XPATH_MIME_TYPE, ArtifactNamespaceContext.INSTANCE); tim@335: ingo@358: CallMeta callMeta = callContext.getMeta(); ingo@358: ingo@502: int chartWidth = 600; ingo@502: int chartHeight = 400; ingo@502: boolean sVisible = false; ingo@629: int binCount = 0; ingo@629: int binWidth = 0; ingo@629: ingo@629: Map requestParameter = new HashMap(); ingo@502: ingo@502: // lines are always visible. if lines should be configurable we need a ingo@502: // parameter in the user interface ingo@502: boolean lVisible = true; ingo@502: ingo@502: try { ingo@502: if (inputData != null) { ingo@502: Iterator it = inputData.iterator(); ingo@502: while (it.hasNext()) { ingo@502: InputData ip = it.next(); ingo@502: String optionName = ip.getName().trim(); ingo@629: requestParameter.put(optionName, ip.getValue()); ingo@502: ingo@502: if (optionName.equals("width")) { ingo@502: chartWidth = Integer.parseInt(ip.getValue()); ingo@502: } ingo@502: else if (optionName.equals("height")) { ingo@502: chartHeight = Integer.parseInt(ip.getValue()); ingo@502: } ingo@502: else if (optionName.equals("points")) { ingo@502: sVisible = Boolean.parseBoolean(ip.getValue()); ingo@502: } ingo@502: } ingo@502: } ingo@502: } catch (NumberFormatException e) { ingo@502: log.error(e, e); ingo@502: throw new StateException(e); ingo@502: } ingo@502: tim@335: try { ingo@639: Collection parameters = ingo@639: getParameters(uuid); ingo@639: Collection measurements = ingo@639: getMeasurements(uuid); ingo@639: Collection dates = ingo@639: getDates(uuid); ingo@639: ingo@639: Locale[] serverLocales = ingo@639: RessourceFactory.getInstance().getLocales(); ingo@639: Locale locale = ingo@639: callMeta.getPreferredLocale(serverLocales); ingo@639: ingo@639: ChartLabels chartLables = createChartLabels(locale, uuid); ingo@639: ingo@639: log.debug( ingo@639: "Best locale - regarding intersection of server and " + ingo@639: "browser locales - is " + locale.toString() ingo@639: ); ingo@639: ingo@639: String exportFormat = getExportFormat(mimeType); ingo@639: ingo@639: // CHART tim@335: if (outputMode.equalsIgnoreCase("chart")) { tim@335: log.debug("Chart will be generated."); tim@335: ingo@639: if (mode.equalsIgnoreCase("img")) { ingo@639: createChart( ingo@639: outputStream, ingo@639: parameters, ingo@639: measurements, ingo@639: dates, ingo@639: chartLables, ingo@639: callContext, ingo@639: uuid, ingo@639: exportFormat, ingo@639: locale, ingo@639: chartWidth, ingo@639: chartHeight, ingo@639: lVisible, ingo@639: sVisible, ingo@639: callContext ingo@639: ); ingo@639: } ingo@639: else if (mode.equalsIgnoreCase("pdf")) { ingo@639: createPDF( ingo@639: outputStream, ingo@639: parameters, ingo@639: measurements, ingo@639: dates, ingo@639: chartLables, ingo@639: uuid, ingo@639: "A4", ingo@639: true, ingo@639: lVisible, ingo@639: sVisible, ingo@639: locale, ingo@639: callContext ingo@639: ); ingo@639: } ingo@639: else if (mode.equalsIgnoreCase("svg")) { ingo@639: createSVG( ingo@639: outputStream, ingo@639: getParameters(uuid), ingo@639: getMeasurements(uuid), ingo@639: getDates(uuid), ingo@639: createChartLabels(locale, uuid), ingo@639: uuid, ingo@639: locale, ingo@639: chartWidth, ingo@639: chartHeight, ingo@639: lVisible, ingo@639: sVisible, ingo@639: callContext ingo@639: ); ingo@639: } ingo@639: } ingo@639: // HISTOGRAM ingo@639: else if (outputMode.equalsIgnoreCase("histogram")) { ingo@639: Collection results = (Collection) getChartResult(uuid, callContext); ingo@639: requestParameter.put("locale", locale); tim@335: ingo@617: Object[][] data = HistogramHelper.prepareHistogramData( ingo@617: results, parameters, measurements, dates); ingo@617: ingo@617: int size = data.length; ingo@617: Chart[] histograms = new Chart[size]; ingo@617: ingo@617: for (int i = 0; i < size; i++) { ingo@617: ChartLabels labels = createHistogramLabels( ingo@617: uuid, callContext, data[i]); ingo@617: ingo@617: ChartTheme theme = createStyle(callContext); ingo@617: ingo@617: histograms[i] = new DefaultHistogram( ingo@629: labels, data[i], theme, requestParameter); ingo@617: } ingo@617: ingo@639: if (mode.equalsIgnoreCase("img")) { ingo@639: ChartExportHelper.exportHistograms( ingo@639: outputStream, ingo@639: histograms, ingo@639: exportFormat, ingo@639: chartWidth, ingo@639: chartHeight ingo@639: ); ingo@639: } ingo@639: else if (mode.equalsIgnoreCase("pdf")) { ingo@640: ChartExportHelper.exportHistogramsAsPDF( ingo@640: outputStream, ingo@640: histograms, ingo@640: "A4", ingo@640: PDF_FORMAT_LANDSCAPE, ingo@640: 50F, 50F, 50F, 50F ingo@640: ); ingo@639: } ingo@639: else if (mode.equalsIgnoreCase("svg")) { ingo@639: ChartExportHelper.exportHistogramsAsSVG( ingo@639: outputStream, ingo@639: histograms, ingo@639: null, ingo@639: chartWidth, ingo@639: chartHeight ingo@639: ); ingo@639: } tim@335: } tim@335: else if (outputMode.equalsIgnoreCase("csv")) { tim@335: log.debug("CSV-File will be generated."); sascha@452: Object result = getChartResult(uuid, callContext); sascha@452: if (result instanceof Collection) { sascha@452: this.createCSV( sascha@452: outputStream, sascha@452: (Collection)result); sascha@452: } tim@335: } else if (outputMode.equalsIgnoreCase("statistics")) { tim@335: log.debug("Statistics will be generated."); sascha@446: sascha@446: Collection statistics; sascha@446: sascha@454: Statistics s = getStatisticsGenerator(); sascha@454: Object result = getChartResult(uuid, callContext); sascha@446: sascha@454: if (result != null && s != null) { sascha@446: statistics = s.calculateStatistics( sascha@454: result, sascha@446: parameters, sascha@446: measurements, sascha@446: dates); sascha@446: } sascha@446: else { sascha@446: statistics = new ArrayList(); sascha@446: } sascha@446: sascha@454: Document doc = writeStatistics2XML(statistics); sascha@454: sascha@481: XMLUtils.toStream(doc, outputStream); sascha@454: ingo@617: } ingo@617: else if (outputMode.equalsIgnoreCase("odv")) { tim@335: Collection odvResult = this.getODVResult(uuid); tim@335: this.createODV(outputStream, odvResult); tim@335: } tim@335: } catch (IOException e) { tim@335: log.error(e, e); tim@335: throw new StateException(e); tim@335: } catch (TechnicalChartException e) { tim@335: log.error(e, e); tim@335: throw new StateException(e); tim@335: } catch (StatisticsException e) { tim@335: log.error(e, e); tim@335: throw new StateException(e); tim@335: } tim@335: } tim@335: tim@335: tim@335: protected String getExportFormat(String mime) { tim@335: for(int i = 0; i < IMG_EXPORT_FORMAT.length; i++) { tim@335: if (mime.trim().toUpperCase().indexOf(IMG_EXPORT_FORMAT[i]) > 0) tim@335: return IMG_EXPORT_FORMAT[i]; tim@335: } tim@335: tim@335: // no format found relating to mimeType, default export as PNG tim@335: return IMG_EXPORT_FORMAT[0]; tim@335: } tim@335: tim@335: tim@335: protected Collection getCleanedParameters(Collection parameters) { tim@335: Iterator iter = parameters.iterator(); tim@335: Collection parameter = new Vector(parameters); tim@335: while (iter.hasNext()) { tim@335: KeyValueDescibeData data = (KeyValueDescibeData)iter.next(); tim@335: if (!data.isSelected()) tim@335: parameter.remove(data); tim@335: } tim@335: tim@335: return parameter; tim@335: } tim@335: tim@335: tim@335: protected Collection getCleanedParameters(String uuid) { tim@335: return getCleanedParameters(getParameters(uuid)); tim@335: } tim@335: tim@335: ingo@368: protected void createCSV(OutputStream out, Collection results) ingo@368: throws UnsupportedEncodingException, IOException, StateException ingo@368: { ingo@368: Iterator iter = results.iterator(); ingo@368: Result res = iter.hasNext() ? (Result) iter.next() : null; tim@335: ingo@368: if (res == null) ingo@368: return; ingo@368: ingo@368: Profile profile = null; ingo@368: int dataid = res.getInteger("DATAID").intValue(); ingo@368: ingo@368: // on meshes ingo@368: if (dataid == 2) { ingo@368: profile = new DefaultProfile( ingo@368: TIMESERIES_MESH_CSV_COLUMN_LABEL, ingo@368: ',', ingo@368: '"', ingo@368: '"', ingo@368: "CSV", ingo@368: "ISO-8859-1"); ingo@368: } ingo@368: ingo@368: // on timeseries ingo@368: else { ingo@368: profile = new DefaultProfile( ingo@368: TIMESERIES_TIMESERIES_CSV_COLUMN_LABEL, ingo@368: ',', ingo@368: '"', ingo@368: '"', ingo@368: "CSV", ingo@368: "ISO-8859-1"); ingo@368: } ingo@368: ingo@368: DefaultExport export = new DefaultExport( ingo@368: new DefaultDataCollector(TIMESERIES_CSV_PROFILE_COLUMNS)); ingo@368: export.create(profile, out, results); tim@335: } tim@335: ingo@368: tim@335: /** tim@335: * TODO Result is not used at the moment. Change result with correct data. tim@335: */ tim@335: protected void createODV(OutputStream outputStream, Collection result) tim@335: throws IOException, StateException { tim@335: tim@335: DefaultExport export = new DefaultExport(new SimpleOdvDataCollector( tim@335: TIMESERIES_ODV_PROFILE_NAMES)); tim@335: tim@335: if (result == null) tim@335: log.error("#################### RESULT == NULL #################"); tim@335: export.create(TIMESERIES_ODV_PROFILE, outputStream, result); tim@335: } tim@335: tim@335: /** tim@335: * @return tim@335: */ tim@335: protected Statistics getStatisticsGenerator() { tim@335: Statistics s = new TimeseriesStatistics(); tim@335: return s; tim@335: } tim@335: tim@335: protected Document writeStatistics2XML( Collection statistic) { tim@335: ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); tim@335: Document doc = XMLUtils.newDocument(); tim@335: if (statistic != null) { tim@335: Node statisticResults = xmlUtilities.createArtifactElement(doc, tim@335: "statistics"); tim@335: doc.appendChild(statisticResults); tim@335: Iterator it = statistic.iterator(); tim@335: while (it.hasNext()) { tim@335: StatisticSet set = it.next(); tim@335: Element setElement = xmlUtilities.createArtifactElement(doc, tim@335: "statistic"); tim@335: setElement.setAttribute("name", set.getName()); tim@335: tim@335: Iterator sit = set.getStatistics().iterator(); tim@335: while (sit.hasNext()){ tim@335: Statistic s = sit.next(); tim@335: Element result = xmlUtilities.createArtifactElement(doc, tim@335: "statistic-value"); tim@335: result.setAttribute("name", s.getKey()); tim@335: result.setAttribute("value", s.getStringValue()); tim@335: setElement.appendChild(result); tim@335: } tim@335: statisticResults.appendChild(setElement); tim@335: } tim@335: tim@335: } tim@335: return doc; tim@335: } tim@335: tim@335: tim@335: protected String getSelectedFeatureName(String uuid) { tim@335: Collection values = getCollection(featureValuesName, uuid); tim@335: tim@335: if (values != null) { tim@335: Iterator it = values.iterator(); tim@335: tim@335: while (it.hasNext()) { tim@335: KeyValueDescibeData data = (KeyValueDescibeData) it.next(); ingo@610: return data.getValue(); ingo@610: } tim@335: ingo@610: return ""; tim@335: } ingo@610: return ""; tim@335: } tim@335: tim@335: tim@335: /** tim@335: * @param outputStream tim@335: * @param parameters tim@335: * @param measurements tim@335: * @param timeSeriesName tim@335: * @param chartStyle tim@335: * @param chartLables tim@335: * @throws IOException tim@335: * @throws TechnicalChartException tim@335: */ tim@335: protected void createChart( tim@335: OutputStream outputStream, tim@335: Collection parameters, tim@335: Collection measurements, tim@335: Collection dates, tim@335: ChartLabels chartLables, ingo@358: CallContext context, tim@335: String uuid, tim@335: String exportFormat, tim@335: Locale locale, tim@335: int width, tim@335: int height, tim@335: boolean linesVisible, sascha@439: boolean shapesVisible, sascha@439: CallContext callContext tim@335: ) tim@335: throws IOException, TechnicalChartException tim@335: { tim@335: log.debug("Create chart."); tim@335: Chart chart = getChart( tim@335: chartLables, ingo@358: createStyle(context), tim@335: parameters, tim@335: measurements, tim@335: dates, sascha@439: getChartResult(uuid, callContext), tim@335: locale, // Locale tim@335: uuid, tim@335: linesVisible, sascha@439: shapesVisible, sascha@439: callContext tim@335: ); tim@335: tim@335: if (chart == null) { tim@335: log.error("Could not initialize chart."); tim@335: return; tim@335: } tim@335: tim@335: log.debug( tim@335: "export chart as " + exportFormat + tim@335: " in " + width + "x" + height tim@335: ); tim@335: tim@335: ChartExportHelper.exportImage( tim@335: outputStream, tim@335: chart.generateChart(), tim@335: exportFormat, tim@335: width, tim@335: height tim@335: ); tim@335: } tim@335: tim@335: tim@335: protected void createPDF( tim@335: OutputStream outputStream, tim@335: Collection parameters, tim@335: Collection measurements, tim@335: Collection dates, tim@335: ChartLabels chartLables, tim@335: String uuid, tim@335: String exportFormat, tim@335: boolean landscape, ingo@358: boolean linesVisible, ingo@358: boolean shapesVisible, tim@335: Locale locale, ingo@358: CallContext context tim@335: ) { tim@335: Chart chart = getChart( tim@335: chartLables, ingo@358: createStyle(context), tim@335: parameters, tim@335: measurements, tim@335: dates, sascha@452: getChartResult(uuid, context), tim@335: locale, tim@335: uuid, tim@335: linesVisible, sascha@439: shapesVisible, sascha@439: context tim@335: ); tim@335: tim@335: if (chart == null) { tim@335: log.error("Could not initialize chart."); tim@335: return; tim@335: } tim@335: tim@335: ChartExportHelper.exportPDF( tim@335: outputStream, tim@335: chart.generateChart(), tim@335: "A4", tim@335: PDF_FORMAT_LANDSCAPE, tim@335: 50F, 50F, 50F, 50F tim@335: ); tim@335: } tim@335: tim@335: tim@335: protected void createSVG( tim@335: OutputStream outputStream, tim@335: Collection parameters, tim@335: Collection measurements, tim@335: Collection dates, tim@335: ChartLabels chartLables, tim@335: String uuid, tim@335: Locale locale, tim@335: int width, tim@335: int height, tim@335: boolean linesVisible, ingo@358: boolean shapesVisible, ingo@358: CallContext callContext tim@335: ) { tim@335: Chart chart = getChart( tim@335: chartLables, ingo@358: createStyle(callContext), tim@335: parameters, tim@335: measurements, tim@335: dates, sascha@446: getChartResult(uuid, callContext), tim@335: locale, tim@335: uuid, tim@335: linesVisible, sascha@439: shapesVisible, sascha@439: callContext tim@335: ); tim@335: tim@335: if (chart == null) { tim@335: log.error("Could not initialize chart."); tim@335: return; tim@335: } tim@335: tim@335: ChartExportHelper.exportSVG( tim@335: outputStream, tim@335: chart.generateChart(), tim@335: null, tim@335: 600, 400 tim@335: ); tim@335: tim@335: log.debug("svg export finished."); tim@335: } tim@335: tim@335: tim@335: protected Chart getChart( tim@335: ChartLabels chartLables, ingo@358: ChartTheme theme, tim@335: Collection parameters, tim@335: Collection measurements, tim@335: Collection dates, ingo@429: Object result, tim@335: Locale locale, tim@335: String uuid, tim@335: boolean linesVisible, sascha@439: boolean shapesVisible, sascha@439: CallContext callContext tim@335: ) { tim@335: Chart chart = null; tim@335: tim@335: if (CACHE_CHART) { tim@335: log.info("Try to get timeseries chart from cache."); sascha@439: chart = (Chart) getChartFromCache(uuid, callContext); tim@335: } tim@335: tim@335: if (chart != null) tim@335: return chart; tim@335: tim@335: log.info("Chart not in cache yet."); tim@335: chart = new TimeSeriesChart( tim@335: chartLables, ingo@358: theme, tim@335: parameters, tim@335: measurements, tim@335: dates, ingo@429: (Collection)result, tim@335: timeGapDefinitions, tim@335: locale, tim@335: linesVisible, tim@335: shapesVisible tim@335: ); tim@335: chart.generateChart(); tim@335: tim@335: if (CACHE_CHART) { tim@335: log.info("Put chart into cache."); tim@335: purifyChart(chart, uuid); tim@335: } tim@335: tim@335: return chart; tim@335: } tim@335: ingo@358: protected ChartTheme createStyle(CallContext callContext) { ingo@358: log.debug("Fetch chart theme from global context"); tim@335: ingo@358: GNVArtifactContext context = ingo@358: (GNVArtifactContext) callContext.globalContext(); ingo@358: ingo@358: XMLChartTheme theme = (XMLChartTheme) context.get( sascha@443: GNVArtifactContext.CHART_TEMPLATE_KEY); tim@335: tim@335: return theme; tim@335: } tim@335: ingo@492: protected ChartLabels createChartLabels(Locale locale, String uuid) { ingo@492: return new ChartLabels( ingo@492: createChartTitle(locale, uuid), ingo@492: createChartSubtitle(locale, uuid), ingo@492: RessourceFactory.getInstance().getRessource( ingo@492: locale, ingo@492: domainLable, ingo@492: domainLable ingo@492: ) ingo@492: ); ingo@492: } ingo@492: tim@335: tim@335: protected String createChartTitle(Locale locale, String uuid) { tim@335: return getFisName(locale); tim@335: tim@335: } tim@335: tim@335: tim@335: protected String createChartSubtitle(Locale locale, String uuid) { tim@335: return getSelectedFeatureName(uuid); tim@335: } tim@335: tim@335: ingo@617: protected ChartLabels createHistogramLabels( ingo@617: String uuid, CallContext context, Object[] data) ingo@617: { ingo@617: return new ChartLabels((String) data[0], "", ""); ingo@617: } ingo@617: ingo@617: tim@335: protected String getFisName(Locale locale) { tim@335: String returnValue = ""; tim@335: InputData input = inputData.get("fisname"); tim@335: tim@335: if (input != null) { tim@335: String value = input.getValue(); tim@335: tim@335: returnValue = RessourceFactory.getInstance().getRessource( tim@335: locale, tim@335: value, tim@335: value tim@335: ); tim@335: } tim@335: return returnValue; tim@335: } tim@335: tim@335: ingo@492: protected String getSelectedInputDataName(String uuid, String key) { ingo@492: Collection values = getCollection(key, uuid); ingo@492: ingo@492: if (values != null) { ingo@492: Iterator it = values.iterator(); ingo@492: ingo@492: while (it.hasNext()) { ingo@492: KeyValueDescibeData data = (KeyValueDescibeData) it.next(); ingo@492: ingo@492: if (data.isSelected()) { ingo@492: return data.getValue(); ingo@492: } ingo@492: } ingo@492: } ingo@492: return null; ingo@492: } ingo@492: ingo@492: tim@335: protected Collection getParameters(String uuid) { tim@335: return this.getCollection(parameterValuesName, uuid); tim@335: } tim@335: tim@335: protected Collection getMeasurements(String uuid) { tim@335: return this.getCollection(measuremenValueName, uuid); tim@335: } tim@335: protected Collection getDates(String uuid) { tim@335: return this.getCollection(dateValueName,uuid); tim@335: } tim@335: tim@335: @Override tim@335: public void setup(Node configuration) { tim@335: super.setup(configuration); tim@335: String featureNameValue = Config.getStringXPath(configuration, tim@335: "value-names/value-name[@name='feature']/@value"); tim@335: if (featureNameValue != null) { tim@335: this.featureValuesName = featureNameValue; tim@335: } tim@335: String parameterNameValue = Config.getStringXPath(configuration, tim@335: "value-names/value-name[@name='parameter']/@value"); tim@335: if (parameterNameValue != null) { tim@335: this.parameterValuesName = parameterNameValue; tim@335: } tim@335: String measurementNameValue = Config.getStringXPath(configuration, tim@335: "value-names/value-name[@name='measurement']/@value"); tim@335: if (measurementNameValue != null) { tim@335: this.measuremenValueName = measurementNameValue; tim@335: } tim@335: tim@335: String dateNameValue = Config.getStringXPath(configuration, tim@335: "value-names/value-name[@name='date']/@value"); tim@335: if (dateNameValue != null) { tim@335: this.dateValueName = dateNameValue; tim@335: } tim@335: if (timeGapDefinitions == null){ tim@335: Element gapDefinition = (Element)Config.getNodeXPath(configuration, tim@335: "time-gap-definition"); tim@335: synchronized (this.getClass()) { tim@335: if (gapDefinition != null){ tim@335: String link = gapDefinition.getAttribute("xlink:href"); tim@335: if (link != null ){ tim@335: String absolutFileName = Config.replaceConfigDir(link); tim@335: gapDefinition = (Element)new ArtifactXMLUtilities(). tim@335: readConfiguration(absolutFileName); tim@335: } tim@335: tim@335: NodeList gapDefinitions = Config.getNodeSetXPath(gapDefinition, tim@335: "/time-gaps/time-gap"); tim@335: if (gapDefinition != null){ tim@335: timeGapDefinitions = new ArrayList(gapDefinitions. tim@335: getLength()); tim@335: for (int i = 0; i < gapDefinitions.getLength(); i++){ tim@335: Element gapNode = (Element)gapDefinitions.item(i); tim@335: String unit = gapNode.getAttribute("unit"); tim@335: int key = Integer.parseInt(gapNode.getAttribute("key")); tim@335: int value = Integer.parseInt(gapNode.getAttribute("gap")); tim@335: log.info("Add new Timegap: "+key+" "+value+" "+ unit); tim@335: timeGapDefinitions.add(new DefaultTimeGap(unit, tim@335: key, tim@335: value)); tim@335: } tim@335: } tim@335: } tim@335: } tim@335: } tim@335: } ingo@610: tim@335: /** tim@335: * @param collectionName tim@335: * @return tim@335: */ tim@335: protected Collection getCollection( ingo@610: String collectionName, ingo@610: String uuid) ingo@610: { ingo@610: NamedCollection c = new NamedArrayList(collectionName); tim@335: ingo@610: InputData data = inputData.get(collectionName); ingo@610: if (data == null) { ingo@610: log.warn("No collection found with name: " + collectionName); ingo@610: return c; tim@335: } ingo@610: ingo@615: String[] descs = data.getDescription(); ingo@615: String[] values = data.splitValue(); ingo@615: int size = values.length; ingo@615: ingo@615: for (int i = 0; i < size; i++){ ingo@615: c.add(new DefaultKeyValueDescribeData( ingo@615: values[i], descs[i], getID())); ingo@615: } ingo@610: ingo@610: return c; tim@335: } tim@335: } tim@335: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :