tim@335: /** tim@335: * tim@335: */ tim@335: package de.intevation.gnv.state.timeseries; tim@335: tim@335: import java.io.IOException; tim@335: import java.io.File; tim@335: import java.io.OutputStream; tim@335: import java.io.FileOutputStream; tim@335: import java.io.UnsupportedEncodingException; tim@335: import java.util.ArrayList; tim@335: import java.util.Collection; tim@335: import java.util.Iterator; tim@335: import java.util.List; tim@335: import java.util.Locale; tim@335: import java.util.Vector; tim@335: tim@335: import javax.xml.transform.Transformer; tim@335: import javax.xml.transform.TransformerConfigurationException; tim@335: import javax.xml.transform.TransformerException; tim@335: import javax.xml.transform.TransformerFactory; tim@335: import javax.xml.transform.TransformerFactoryConfigurationError; tim@335: import javax.xml.transform.dom.DOMSource; tim@335: import javax.xml.transform.stream.StreamResult; tim@335: tim@335: import org.apache.log4j.Logger; 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: import org.jfree.chart.ChartTheme; tim@335: tim@335: import au.com.bytecode.opencsv.CSVWriter; tim@335: import de.intevation.artifactdatabase.Config; tim@335: import de.intevation.artifactdatabase.XMLUtils; tim@335: import de.intevation.artifacts.CallMeta; ingo@358: import de.intevation.artifacts.CallContext; tim@335: import de.intevation.artifacts.PreferredLocale; ingo@358: import de.intevation.gnv.artifacts.context.GNVArtifactContext; tim@335: import de.intevation.gnv.artifacts.ressource.RessourceFactory; tim@335: import de.intevation.gnv.chart.Chart; tim@335: import de.intevation.gnv.chart.ChartLabels; tim@335: import de.intevation.gnv.chart.TimeSeriesChart; tim@335: import de.intevation.gnv.chart.XMLChartTheme; tim@335: import de.intevation.gnv.chart.exception.TechnicalChartException; tim@335: import de.intevation.gnv.exports.ChartExportHelper; tim@335: import de.intevation.gnv.exports.DefaultExport; tim@335: import de.intevation.gnv.exports.DefaultDataCollector; tim@335: import de.intevation.gnv.exports.SimpleOdvDataCollector; tim@335: import de.intevation.gnv.exports.DefaultProfile; tim@335: import de.intevation.gnv.exports.Export.Profile; tim@335: import de.intevation.gnv.geobackend.base.Result; tim@335: import de.intevation.gnv.state.InputData; tim@335: import de.intevation.gnv.state.OutputStateBase; tim@335: import de.intevation.gnv.state.describedata.KeyValueDescibeData; tim@335: import de.intevation.gnv.state.describedata.NamedCollection; tim@335: import de.intevation.gnv.state.exception.StateException; tim@335: import de.intevation.gnv.statistics.Statistic; tim@335: import de.intevation.gnv.statistics.StatisticSet; tim@335: import de.intevation.gnv.statistics.Statistics; tim@335: import de.intevation.gnv.statistics.TimeseriesStatistics; tim@335: import de.intevation.gnv.statistics.exception.StatisticsException; tim@335: import de.intevation.gnv.timeseries.gap.DefaultTimeGap; tim@335: import de.intevation.gnv.timeseries.gap.TimeGap; tim@335: import de.intevation.gnv.utils.ArtifactXMLUtilities; tim@335: tim@335: tim@335: /** tim@335: * @author Tim Englich tim@335: * 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: 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( tim@335: Document format, tim@335: Collection inputData, tim@335: OutputStream outputStream, tim@335: String uuid, ingo@358: CallContext callContext tim@335: ) throws StateException tim@335: { tim@335: log.debug("TimeSeriesOutputTransition.out"); tim@335: tim@335: String outputMode = Config.getStringXPath( tim@335: format, tim@335: "action/out/@name" tim@335: ); tim@335: String mimeType = Config.getStringXPath( tim@335: format, tim@335: "action/out/mime-type/@value" tim@335: ); tim@335: ingo@358: CallMeta callMeta = callContext.getMeta(); ingo@358: tim@335: try { tim@335: if (outputMode.equalsIgnoreCase("chart")) { tim@335: log.debug("Chart will be generated."); tim@335: int chartWidth = 600; tim@335: int chartHeight = 400; tim@335: try { tim@335: if (inputData != null) { tim@335: Iterator it = inputData.iterator(); tim@335: while (it.hasNext()) { tim@335: InputData ip = it.next(); tim@335: if (ip.getName().equalsIgnoreCase("width")) { tim@335: chartWidth = Integer.parseInt(ip.getValue()); tim@335: } else if (ip.getName().equalsIgnoreCase("height")) { tim@335: chartHeight = Integer.parseInt(ip.getValue()); tim@335: } tim@335: } tim@335: } tim@335: } catch (NumberFormatException e) { tim@335: log.error(e, e); tim@335: throw new StateException(e); tim@335: } tim@335: tim@335: PreferredLocale[] locales = callMeta.getLanguages(); tim@335: Locale[] serverLocales = tim@335: RessourceFactory.getInstance().getLocales(); tim@335: Locale locale = tim@335: callMeta.getPreferredLocale(serverLocales); tim@335: tim@335: log.debug( tim@335: "Best locale - regarding intersection of server and " + tim@335: "browser locales - is " + locale.toString() tim@335: ); tim@335: tim@335: Collection parameters = this.getCleanedParameters(uuid); tim@335: Collection measurements = this.getMeasurements(uuid); tim@335: Collection dates = this.getDates(uuid); tim@335: tim@335: ChartLabels chartLables = new ChartLabels( tim@335: createChartTitle(locale, uuid), tim@335: createChartSubtitle(locale, uuid), ingo@342: RessourceFactory.getInstance().getRessource( ingo@342: locale, ingo@342: domainLable, ingo@342: domainLable ingo@342: ) tim@335: ); tim@335: tim@335: String exportFormat = getExportFormat(mimeType); tim@335: tim@335: // TODO Remove this and parse input data tim@335: boolean linesVisible = true; tim@335: boolean shapesVisible = true; tim@335: tim@335: this.createChart( tim@335: outputStream, tim@335: parameters, tim@335: measurements, tim@335: dates, tim@335: chartLables, ingo@358: callContext, tim@335: uuid, tim@335: exportFormat, tim@335: locale, tim@335: chartWidth, tim@335: chartHeight, tim@335: linesVisible, sascha@439: shapesVisible, sascha@439: callContext tim@335: ); tim@335: } tim@335: else if (outputMode.equalsIgnoreCase("pdf")) { tim@335: log.debug("Output mode == pdf"); tim@335: tim@335: Locale[] serverLocales = tim@335: RessourceFactory.getInstance().getLocales(); tim@335: Locale locale = tim@335: callMeta.getPreferredLocale(serverLocales); tim@335: tim@335: // TODO Remove this and parse input data tim@335: boolean linesVisible = true; tim@335: boolean shapesVisible = true; tim@335: tim@335: log.debug( tim@335: "Best locale - regarding intersection of server and " + tim@335: "browser locales - is " + locale.toString() tim@335: ); tim@335: tim@335: createPDF( tim@335: outputStream, tim@335: getCleanedParameters(uuid), tim@335: getMeasurements(uuid), tim@335: getDates(uuid), tim@335: new ChartLabels( tim@335: createChartTitle(locale, uuid), tim@335: createChartSubtitle(locale, uuid), ingo@342: RessourceFactory.getInstance().getRessource( ingo@342: locale, ingo@342: domainLable, ingo@342: domainLable ingo@342: ) ingo@342: ), tim@335: uuid, tim@335: "A4", tim@335: true, ingo@358: linesVisible, ingo@358: shapesVisible, tim@335: locale, ingo@358: callContext tim@335: ); tim@335: } tim@335: else if (outputMode.equalsIgnoreCase("svg")) { tim@335: log.debug("Output mode == svg"); tim@335: int width = 600; tim@335: int height = 400; tim@335: tim@335: // TODO Remove this and parse input data tim@335: boolean linesVisible = true; tim@335: boolean shapesVisible = true; tim@335: tim@335: Locale[] serverLocales = tim@335: RessourceFactory.getInstance().getLocales(); tim@335: Locale locale = tim@335: callMeta.getPreferredLocale(serverLocales); tim@335: tim@335: log.debug( tim@335: "Best locale - regarding intersection of server and " + tim@335: "browser locales - is " + locale.toString() tim@335: ); tim@335: tim@335: createSVG( tim@335: outputStream, tim@335: getCleanedParameters(uuid), tim@335: getMeasurements(uuid), tim@335: getDates(uuid), tim@335: new ChartLabels( tim@335: createChartTitle(locale, uuid), tim@335: createChartSubtitle(locale, uuid), ingo@342: RessourceFactory.getInstance().getRessource( ingo@342: locale, ingo@342: domainLable, ingo@342: domainLable ingo@342: ) tim@335: ), tim@335: uuid, tim@335: locale, tim@335: width, tim@335: height, tim@335: linesVisible, ingo@358: shapesVisible, ingo@358: callContext tim@335: ); tim@335: } tim@335: else if (outputMode.equalsIgnoreCase("csv")) { tim@335: log.debug("CSV-File will be generated."); ingo@429: Collection chartResult = sascha@439: (Collection) getChartResult(uuid, callContext); tim@335: this.createCSV(outputStream, chartResult); tim@335: } else if (outputMode.equalsIgnoreCase("statistics")) { tim@335: log.debug("Statistics will be generated."); sascha@446: tim@335: Statistics s = getStatisticsGenerator(); sascha@446: sascha@446: Collection statistics; sascha@446: sascha@446: Object result = getChartResult(uuid, callContext); sascha@446: sascha@446: if (result instanceof Collection) { sascha@446: Collection chartResult = sascha@446: (Collection) result; sascha@446: Collection parameters = sascha@446: this.getParameters(uuid); sascha@446: Collection measurements = sascha@446: this.getMeasurements(uuid); sascha@446: Collection dates = sascha@446: this.getDates(uuid); sascha@446: statistics = s.calculateStatistics( sascha@446: chartResult, sascha@446: parameters, sascha@446: measurements, sascha@446: dates); sascha@446: } sascha@446: else { sascha@446: statistics = new ArrayList(); sascha@446: } sascha@446: tim@335: Document doc = this.writeStatistics2XML(statistics); tim@335: this.writeDocument2OutputStream(doc, outputStream); tim@335: } else if (outputMode.equalsIgnoreCase("odv")) { tim@335: 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 void writeDocument2OutputStream(Document document, OutputStream os) { tim@335: tim@335: try { tim@335: TransformerFactory transformerFactory = TransformerFactory tim@335: .newInstance(); tim@335: Transformer transformer = transformerFactory.newTransformer(); tim@335: DOMSource source = new DOMSource(document); tim@335: StreamResult result = new StreamResult(os); tim@335: transformer.transform(source, result); tim@335: } catch (TransformerConfigurationException e) { tim@335: log.error(e, e); tim@335: } catch (TransformerFactoryConfigurationError e) { tim@335: log.error(e, e); tim@335: } catch (TransformerException e) { tim@335: log.error(e, e); tim@335: } 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(); tim@335: tim@335: if (data.isSelected()) { tim@335: return data.getValue(); tim@335: } tim@335: } tim@335: } tim@335: return null; 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@439: (Collection) 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: sascha@439: /* XXX: @Ingo: What's this? Looks like dev test remains. tim@335: try { tim@335: OutputStream toFile = new FileOutputStream("/vol1/home/iweinzierl/tmp/test.svg"); tim@335: ChartExportHelper.exportSVG( tim@335: toFile, tim@335: chart.generateChart(), tim@335: null, tim@335: 600, 400 tim@335: ); tim@335: toFile.flush(); tim@335: toFile.close(); tim@335: } tim@335: catch(Exception e) { log.debug("ERROR WHLILE TEST."); } sascha@439: */ 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: 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: 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: 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: } tim@335: } tim@335: tim@335: /** tim@335: * @param collectionName tim@335: * @return tim@335: */ tim@335: protected Collection getCollection( tim@335: String collectionName, tim@335: String uuid) { tim@335: Iterator it = this.getDescibeData(uuid).iterator(); tim@335: while (it.hasNext()) { tim@335: tim@335: Object o = it.next(); tim@335: tim@335: if (o instanceof NamedCollection) { tim@335: NamedCollection nc = (NamedCollection) o; tim@335: if (nc.getName().equals(collectionName)) { tim@335: return nc; tim@335: } tim@335: } tim@335: } tim@335: return null; tim@335: } tim@335: } tim@335: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :