Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | 078ba6799bd2 |
children | dde7f51dbe1e |
comparison
equal
deleted
inserted
replaced
590:5f5f273c8566 | 657:af3f56758f59 |
---|---|
1 package de.intevation.gnv.state.timeseries; | |
2 | |
3 import au.com.bytecode.opencsv.CSVWriter; | |
4 | |
5 import de.intevation.artifactdatabase.Config; | |
6 import de.intevation.artifactdatabase.XMLUtils; | |
7 | |
8 import de.intevation.artifacts.ArtifactNamespaceContext; | |
9 import de.intevation.artifacts.CallContext; | |
10 import de.intevation.artifacts.CallMeta; | |
11 | |
12 import de.intevation.gnv.artifacts.context.GNVArtifactContext; | |
13 | |
14 import de.intevation.gnv.artifacts.ressource.RessourceFactory; | |
15 | |
16 import de.intevation.gnv.chart.Chart; | |
17 import de.intevation.gnv.chart.ChartLabels; | |
18 import de.intevation.gnv.chart.DefaultHistogram; | |
19 import de.intevation.gnv.chart.TimeSeriesChart; | |
20 import de.intevation.gnv.chart.XMLChartTheme; | |
21 | |
22 import de.intevation.gnv.chart.exception.TechnicalChartException; | |
23 | |
24 import de.intevation.gnv.exports.ChartExportHelper; | |
25 import de.intevation.gnv.exports.DefaultDataCollector; | |
26 import de.intevation.gnv.exports.DefaultExport; | |
27 import de.intevation.gnv.exports.DefaultProfile; | |
28 | |
29 import de.intevation.gnv.exports.Export.Profile; | |
30 | |
31 import de.intevation.gnv.exports.SimpleOdvDataCollector; | |
32 | |
33 import de.intevation.gnv.geobackend.base.Result; | |
34 | |
35 import de.intevation.gnv.histogram.HistogramHelper; | |
36 | |
37 import de.intevation.gnv.state.InputData; | |
38 import de.intevation.gnv.state.OutputStateBase; | |
39 | |
40 import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; | |
41 import de.intevation.gnv.state.describedata.KeyValueDescibeData; | |
42 import de.intevation.gnv.state.describedata.NamedArrayList; | |
43 import de.intevation.gnv.state.describedata.NamedCollection; | |
44 | |
45 import de.intevation.gnv.state.exception.StateException; | |
46 | |
47 import de.intevation.gnv.statistics.Statistic; | |
48 import de.intevation.gnv.statistics.StatisticSet; | |
49 import de.intevation.gnv.statistics.Statistics; | |
50 import de.intevation.gnv.statistics.TimeseriesStatistics; | |
51 | |
52 import de.intevation.gnv.statistics.exception.StatisticsException; | |
53 | |
54 import de.intevation.gnv.timeseries.gap.DefaultTimeGap; | |
55 import de.intevation.gnv.timeseries.gap.TimeGap; | |
56 | |
57 import de.intevation.gnv.utils.ArtifactXMLUtilities; | |
58 | |
59 import java.io.File; | |
60 import java.io.IOException; | |
61 import java.io.OutputStream; | |
62 import java.io.UnsupportedEncodingException; | |
63 | |
64 import java.util.ArrayList; | |
65 import java.util.Collection; | |
66 import java.util.HashMap; | |
67 import java.util.Iterator; | |
68 import java.util.List; | |
69 import java.util.Locale; | |
70 import java.util.Map; | |
71 import java.util.Vector; | |
72 | |
73 import org.apache.log4j.Logger; | |
74 | |
75 import org.jfree.chart.ChartTheme; | |
76 | |
77 import org.w3c.dom.Document; | |
78 import org.w3c.dom.Element; | |
79 import org.w3c.dom.Node; | |
80 import org.w3c.dom.NodeList; | |
81 | |
82 /** | |
83 * @author Tim Englich (tim.englich@intevation.de) | |
84 * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) | |
85 */ | |
86 public class TimeSeriesOutputState extends OutputStateBase { | |
87 | |
88 protected static final boolean CACHE_CHART = | |
89 Boolean.parseBoolean(System.getProperty("cache.chart", "false")); | |
90 | |
91 protected static final boolean PDF_FORMAT_LANDSCAPE = | |
92 Boolean.parseBoolean(System.getProperty("export.pdf.landscape","true")); | |
93 | |
94 protected static final String[] IMG_EXPORT_FORMAT = { | |
95 "PNG", "JPEG", "GIF" | |
96 }; | |
97 | |
98 /** | |
99 * The UID of this Class | |
100 */ | |
101 private static final long serialVersionUID = 4178407570503098858L; | |
102 | |
103 /** | |
104 * the logger, used to log exceptions and additonaly information | |
105 */ | |
106 private static Logger log = Logger | |
107 .getLogger(TimeSeriesOutputState.class); | |
108 | |
109 private static List<TimeGap> timeGapDefinitions = null; | |
110 | |
111 protected String domainLable = "chart.timeseries.title.xaxis"; | |
112 | |
113 protected String featureValuesName = "featureid"; | |
114 protected String parameterValuesName = "parameterid"; | |
115 protected String measuremenValueName = "measurementid"; | |
116 protected String dateValueName = "dateid"; | |
117 | |
118 public static final String [] TIMESERIES_CSV_PROFILE_COLUMNS = { | |
119 "XORDINATE", | |
120 "YORDINATE", | |
121 "GROUP1", | |
122 "GROUP2", | |
123 "GROUP3" | |
124 }; | |
125 | |
126 | |
127 public static final String [] TIMESERIES_TIMESERIES_CSV_COLUMN_LABEL = { | |
128 "Date/Time", | |
129 "Value", | |
130 "ParameterID", | |
131 "MeasurementID", | |
132 "TimeseriesID" | |
133 }; | |
134 | |
135 public static final String [] TIMESERIES_MESH_CSV_COLUMN_LABEL = { | |
136 "Date/Time", | |
137 "Value", | |
138 "ParameterID", | |
139 "FeatureID", | |
140 "MeshID" | |
141 }; | |
142 | |
143 public static final String [] TIMESERIES_ODV_PROFILE_NAMES = { | |
144 "CRUISE", | |
145 "STATION", | |
146 "TYPE", | |
147 "SHAPE", | |
148 "BOTDEPTH", | |
149 "DEPTH", | |
150 "TIMEVALUE", | |
151 "DATAVALUE", | |
152 "PARAMETER" | |
153 }; | |
154 | |
155 | |
156 public static final String [] ODV_COLUMN_HEADER = { | |
157 "Cruise", | |
158 "Station", | |
159 "Type", | |
160 "Longitude [deegrees_east]", | |
161 "Latitude [deegrees_north]", | |
162 "Bot. Depth [m]", | |
163 "Depth [m]", | |
164 "Date/Time", | |
165 "Value", | |
166 "Parameterid" | |
167 }; | |
168 | |
169 /** | |
170 * Profile for exporting data to odv | |
171 * TODO Change TIMESERIES_PROFILE_NAMES, which belong to CSV exports | |
172 */ | |
173 public static final Profile TIMESERIES_ODV_PROFILE = | |
174 new DefaultProfile( | |
175 ODV_COLUMN_HEADER, | |
176 '\t', | |
177 CSVWriter.NO_QUOTE_CHARACTER, | |
178 CSVWriter.NO_ESCAPE_CHARACTER, | |
179 "ODV", | |
180 "ISO-8859-1"); | |
181 | |
182 /** | |
183 * Constructor | |
184 */ | |
185 public TimeSeriesOutputState() { | |
186 super(); | |
187 } | |
188 | |
189 | |
190 @Override | |
191 public void initialize(String uuid, CallContext context) | |
192 throws StateException | |
193 { | |
194 getChartResult(uuid, context); | |
195 } | |
196 | |
197 | |
198 /** | |
199 * @see de.intevation.gnv.transition.OutputTransition#out(java.lang.String, | |
200 * java.util.Collection, java.io.OutputStream, java.lang.String, | |
201 * de.intevation.artifacts.CallMeta) | |
202 */ | |
203 public void out( | |
204 Document format, | |
205 Collection<InputData> inputData, | |
206 OutputStream outputStream, | |
207 String uuid, | |
208 CallContext callContext | |
209 ) throws StateException | |
210 { | |
211 log.debug("TimeSeriesOutputTransition.out"); | |
212 | |
213 String outputMode = XMLUtils.xpathString( | |
214 format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); | |
215 | |
216 String mode = XMLUtils.xpathString( | |
217 format, XPATH_EXPORT_MODE, ArtifactNamespaceContext.INSTANCE); | |
218 | |
219 if (mode == null || mode.equals("")) { | |
220 mode = "img"; | |
221 } | |
222 | |
223 String mimeType = XMLUtils.xpathString( | |
224 format, XPATH_MIME_TYPE, ArtifactNamespaceContext.INSTANCE); | |
225 | |
226 CallMeta callMeta = callContext.getMeta(); | |
227 | |
228 int chartWidth = 600; | |
229 int chartHeight = 400; | |
230 boolean sVisible = false; | |
231 int binCount = 0; | |
232 int binWidth = 0; | |
233 | |
234 Map requestParameter = new HashMap(); | |
235 | |
236 // lines are always visible. if lines should be configurable we need a | |
237 // parameter in the user interface | |
238 boolean lVisible = true; | |
239 | |
240 try { | |
241 if (inputData != null) { | |
242 Iterator<InputData> it = inputData.iterator(); | |
243 while (it.hasNext()) { | |
244 InputData ip = it.next(); | |
245 String optionName = ip.getName().trim(); | |
246 requestParameter.put(optionName, ip.getValue()); | |
247 | |
248 if (optionName.equals("width")) { | |
249 chartWidth = Integer.parseInt(ip.getValue()); | |
250 } | |
251 else if (optionName.equals("height")) { | |
252 chartHeight = Integer.parseInt(ip.getValue()); | |
253 } | |
254 else if (optionName.equals("points")) { | |
255 sVisible = Boolean.parseBoolean(ip.getValue()); | |
256 } | |
257 } | |
258 } | |
259 } catch (NumberFormatException e) { | |
260 log.error(e, e); | |
261 throw new StateException(e); | |
262 } | |
263 | |
264 try { | |
265 Collection<KeyValueDescibeData> parameters = | |
266 getParameters(uuid); | |
267 Collection<KeyValueDescibeData> measurements = | |
268 getMeasurements(uuid); | |
269 Collection<KeyValueDescibeData> dates = | |
270 getDates(uuid); | |
271 | |
272 Locale[] serverLocales = | |
273 RessourceFactory.getInstance().getLocales(); | |
274 Locale locale = | |
275 callMeta.getPreferredLocale(serverLocales); | |
276 | |
277 ChartLabels chartLables = createChartLabels(locale, uuid); | |
278 | |
279 log.debug( | |
280 "Best locale - regarding intersection of server and " + | |
281 "browser locales - is " + locale.toString() | |
282 ); | |
283 | |
284 String exportFormat = getExportFormat(mimeType); | |
285 | |
286 // CHART | |
287 if (outputMode.equalsIgnoreCase("chart")) { | |
288 log.debug("Chart will be generated."); | |
289 | |
290 if (mode.equalsIgnoreCase("img")) { | |
291 createChart( | |
292 outputStream, | |
293 parameters, | |
294 measurements, | |
295 dates, | |
296 chartLables, | |
297 callContext, | |
298 uuid, | |
299 exportFormat, | |
300 locale, | |
301 chartWidth, | |
302 chartHeight, | |
303 lVisible, | |
304 sVisible, | |
305 callContext | |
306 ); | |
307 } | |
308 else if (mode.equalsIgnoreCase("pdf")) { | |
309 createPDF( | |
310 outputStream, | |
311 parameters, | |
312 measurements, | |
313 dates, | |
314 chartLables, | |
315 uuid, | |
316 "A4", | |
317 true, | |
318 lVisible, | |
319 sVisible, | |
320 locale, | |
321 callContext | |
322 ); | |
323 } | |
324 else if (mode.equalsIgnoreCase("svg")) { | |
325 createSVG( | |
326 outputStream, | |
327 getParameters(uuid), | |
328 getMeasurements(uuid), | |
329 getDates(uuid), | |
330 createChartLabels(locale, uuid), | |
331 uuid, | |
332 locale, | |
333 chartWidth, | |
334 chartHeight, | |
335 lVisible, | |
336 sVisible, | |
337 callContext | |
338 ); | |
339 } | |
340 } | |
341 // HISTOGRAM | |
342 else if (outputMode.equalsIgnoreCase("histogram")) { | |
343 Collection results = (Collection) getChartResult(uuid, callContext); | |
344 requestParameter.put("locale", locale); | |
345 | |
346 Object[][] data = HistogramHelper.prepareHistogramData( | |
347 results, parameters, measurements, dates); | |
348 | |
349 int size = data.length; | |
350 Chart[] histograms = new Chart[size]; | |
351 | |
352 for (int i = 0; i < size; i++) { | |
353 ChartLabels labels = createHistogramLabels( | |
354 uuid, callContext, data[i]); | |
355 | |
356 ChartTheme theme = createStyle(callContext); | |
357 | |
358 histograms[i] = new DefaultHistogram( | |
359 labels, data[i], theme, requestParameter); | |
360 } | |
361 | |
362 if (mode.equalsIgnoreCase("img")) { | |
363 ChartExportHelper.exportHistograms( | |
364 outputStream, | |
365 histograms, | |
366 exportFormat, | |
367 chartWidth, | |
368 chartHeight | |
369 ); | |
370 } | |
371 else if (mode.equalsIgnoreCase("pdf")) { | |
372 ChartExportHelper.exportHistogramsAsPDF( | |
373 outputStream, | |
374 histograms, | |
375 "A4", | |
376 PDF_FORMAT_LANDSCAPE, | |
377 50F, 50F, 50F, 50F | |
378 ); | |
379 } | |
380 else if (mode.equalsIgnoreCase("svg")) { | |
381 ChartExportHelper.exportHistogramsAsSVG( | |
382 outputStream, | |
383 histograms, | |
384 null, | |
385 chartWidth, | |
386 chartHeight | |
387 ); | |
388 } | |
389 } | |
390 else if (outputMode.equalsIgnoreCase("csv")) { | |
391 log.debug("CSV-File will be generated."); | |
392 Object result = getChartResult(uuid, callContext); | |
393 if (result instanceof Collection) { | |
394 this.createCSV( | |
395 outputStream, | |
396 (Collection<Result>)result); | |
397 } | |
398 } else if (outputMode.equalsIgnoreCase("statistics")) { | |
399 log.debug("Statistics will be generated."); | |
400 | |
401 Collection<StatisticSet> statistics; | |
402 | |
403 Statistics s = getStatisticsGenerator(); | |
404 Object result = getChartResult(uuid, callContext); | |
405 | |
406 if (result != null && s != null) { | |
407 statistics = s.calculateStatistics( | |
408 result, | |
409 parameters, | |
410 measurements, | |
411 dates); | |
412 } | |
413 else { | |
414 statistics = new ArrayList<StatisticSet>(); | |
415 } | |
416 | |
417 Document doc = writeStatistics2XML(statistics); | |
418 | |
419 XMLUtils.toStream(doc, outputStream); | |
420 | |
421 } | |
422 else if (outputMode.equalsIgnoreCase("odv")) { | |
423 Collection<Result> odvResult = this.getODVResult(uuid); | |
424 this.createODV(outputStream, odvResult); | |
425 } | |
426 } catch (IOException e) { | |
427 log.error(e, e); | |
428 throw new StateException(e); | |
429 } catch (TechnicalChartException e) { | |
430 log.error(e, e); | |
431 throw new StateException(e); | |
432 } catch (StatisticsException e) { | |
433 log.error(e, e); | |
434 throw new StateException(e); | |
435 } | |
436 } | |
437 | |
438 | |
439 protected String getExportFormat(String mime) { | |
440 for(int i = 0; i < IMG_EXPORT_FORMAT.length; i++) { | |
441 if (mime.trim().toUpperCase().indexOf(IMG_EXPORT_FORMAT[i]) > 0) | |
442 return IMG_EXPORT_FORMAT[i]; | |
443 } | |
444 | |
445 // no format found relating to mimeType, default export as PNG | |
446 return IMG_EXPORT_FORMAT[0]; | |
447 } | |
448 | |
449 | |
450 protected Collection getCleanedParameters(Collection parameters) { | |
451 Iterator iter = parameters.iterator(); | |
452 Collection parameter = new Vector(parameters); | |
453 while (iter.hasNext()) { | |
454 KeyValueDescibeData data = (KeyValueDescibeData)iter.next(); | |
455 if (!data.isSelected()) | |
456 parameter.remove(data); | |
457 } | |
458 | |
459 return parameter; | |
460 } | |
461 | |
462 | |
463 protected Collection getCleanedParameters(String uuid) { | |
464 return getCleanedParameters(getParameters(uuid)); | |
465 } | |
466 | |
467 | |
468 protected void createCSV(OutputStream out, Collection<Result> results) | |
469 throws UnsupportedEncodingException, IOException, StateException | |
470 { | |
471 Iterator iter = results.iterator(); | |
472 Result res = iter.hasNext() ? (Result) iter.next() : null; | |
473 | |
474 if (res == null) | |
475 return; | |
476 | |
477 Profile profile = null; | |
478 int dataid = res.getInteger("DATAID").intValue(); | |
479 | |
480 // on meshes | |
481 if (dataid == 2) { | |
482 profile = new DefaultProfile( | |
483 TIMESERIES_MESH_CSV_COLUMN_LABEL, | |
484 ',', | |
485 '"', | |
486 '"', | |
487 "CSV", | |
488 "ISO-8859-1"); | |
489 } | |
490 | |
491 // on timeseries | |
492 else { | |
493 profile = new DefaultProfile( | |
494 TIMESERIES_TIMESERIES_CSV_COLUMN_LABEL, | |
495 ',', | |
496 '"', | |
497 '"', | |
498 "CSV", | |
499 "ISO-8859-1"); | |
500 } | |
501 | |
502 DefaultExport export = new DefaultExport( | |
503 new DefaultDataCollector(TIMESERIES_CSV_PROFILE_COLUMNS)); | |
504 export.create(profile, out, results); | |
505 } | |
506 | |
507 | |
508 /** | |
509 * TODO Result is not used at the moment. Change result with correct data. | |
510 */ | |
511 protected void createODV(OutputStream outputStream, Collection result) | |
512 throws IOException, StateException { | |
513 | |
514 DefaultExport export = new DefaultExport(new SimpleOdvDataCollector( | |
515 TIMESERIES_ODV_PROFILE_NAMES)); | |
516 | |
517 if (result == null) | |
518 log.error("#################### RESULT == NULL #################"); | |
519 export.create(TIMESERIES_ODV_PROFILE, outputStream, result); | |
520 } | |
521 | |
522 /** | |
523 * @return | |
524 */ | |
525 protected Statistics getStatisticsGenerator() { | |
526 Statistics s = new TimeseriesStatistics(); | |
527 return s; | |
528 } | |
529 | |
530 protected Document writeStatistics2XML( Collection<StatisticSet> statistic) { | |
531 ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); | |
532 Document doc = XMLUtils.newDocument(); | |
533 if (statistic != null) { | |
534 Node statisticResults = xmlUtilities.createArtifactElement(doc, | |
535 "statistics"); | |
536 doc.appendChild(statisticResults); | |
537 Iterator<StatisticSet> it = statistic.iterator(); | |
538 while (it.hasNext()) { | |
539 StatisticSet set = it.next(); | |
540 Element setElement = xmlUtilities.createArtifactElement(doc, | |
541 "statistic"); | |
542 setElement.setAttribute("name", set.getName()); | |
543 | |
544 Iterator<Statistic> sit = set.getStatistics().iterator(); | |
545 while (sit.hasNext()){ | |
546 Statistic s = sit.next(); | |
547 Element result = xmlUtilities.createArtifactElement(doc, | |
548 "statistic-value"); | |
549 result.setAttribute("name", s.getKey()); | |
550 result.setAttribute("value", s.getStringValue()); | |
551 setElement.appendChild(result); | |
552 } | |
553 statisticResults.appendChild(setElement); | |
554 } | |
555 | |
556 } | |
557 return doc; | |
558 } | |
559 | |
560 | |
561 protected String getSelectedFeatureName(String uuid) { | |
562 Collection values = getCollection(featureValuesName, uuid); | |
563 | |
564 if (values != null) { | |
565 Iterator it = values.iterator(); | |
566 | |
567 while (it.hasNext()) { | |
568 KeyValueDescibeData data = (KeyValueDescibeData) it.next(); | |
569 return data.getValue(); | |
570 } | |
571 | |
572 return ""; | |
573 } | |
574 return ""; | |
575 } | |
576 | |
577 | |
578 /** | |
579 * @param outputStream | |
580 * @param parameters | |
581 * @param measurements | |
582 * @param timeSeriesName | |
583 * @param chartStyle | |
584 * @param chartLables | |
585 * @throws IOException | |
586 * @throws TechnicalChartException | |
587 */ | |
588 protected void createChart( | |
589 OutputStream outputStream, | |
590 Collection parameters, | |
591 Collection measurements, | |
592 Collection dates, | |
593 ChartLabels chartLables, | |
594 CallContext context, | |
595 String uuid, | |
596 String exportFormat, | |
597 Locale locale, | |
598 int width, | |
599 int height, | |
600 boolean linesVisible, | |
601 boolean shapesVisible, | |
602 CallContext callContext | |
603 ) | |
604 throws IOException, TechnicalChartException | |
605 { | |
606 log.debug("Create chart."); | |
607 Chart chart = getChart( | |
608 chartLables, | |
609 createStyle(context), | |
610 parameters, | |
611 measurements, | |
612 dates, | |
613 getChartResult(uuid, callContext), | |
614 locale, // Locale | |
615 uuid, | |
616 linesVisible, | |
617 shapesVisible, | |
618 callContext | |
619 ); | |
620 | |
621 if (chart == null) { | |
622 log.error("Could not initialize chart."); | |
623 return; | |
624 } | |
625 | |
626 log.debug( | |
627 "export chart as " + exportFormat + | |
628 " in " + width + "x" + height | |
629 ); | |
630 | |
631 ChartExportHelper.exportImage( | |
632 outputStream, | |
633 chart.generateChart(), | |
634 exportFormat, | |
635 width, | |
636 height | |
637 ); | |
638 } | |
639 | |
640 | |
641 protected void createPDF( | |
642 OutputStream outputStream, | |
643 Collection parameters, | |
644 Collection measurements, | |
645 Collection dates, | |
646 ChartLabels chartLables, | |
647 String uuid, | |
648 String exportFormat, | |
649 boolean landscape, | |
650 boolean linesVisible, | |
651 boolean shapesVisible, | |
652 Locale locale, | |
653 CallContext context | |
654 ) { | |
655 Chart chart = getChart( | |
656 chartLables, | |
657 createStyle(context), | |
658 parameters, | |
659 measurements, | |
660 dates, | |
661 getChartResult(uuid, context), | |
662 locale, | |
663 uuid, | |
664 linesVisible, | |
665 shapesVisible, | |
666 context | |
667 ); | |
668 | |
669 if (chart == null) { | |
670 log.error("Could not initialize chart."); | |
671 return; | |
672 } | |
673 | |
674 ChartExportHelper.exportPDF( | |
675 outputStream, | |
676 chart.generateChart(), | |
677 "A4", | |
678 PDF_FORMAT_LANDSCAPE, | |
679 50F, 50F, 50F, 50F | |
680 ); | |
681 } | |
682 | |
683 | |
684 protected void createSVG( | |
685 OutputStream outputStream, | |
686 Collection parameters, | |
687 Collection measurements, | |
688 Collection dates, | |
689 ChartLabels chartLables, | |
690 String uuid, | |
691 Locale locale, | |
692 int width, | |
693 int height, | |
694 boolean linesVisible, | |
695 boolean shapesVisible, | |
696 CallContext callContext | |
697 ) { | |
698 Chart chart = getChart( | |
699 chartLables, | |
700 createStyle(callContext), | |
701 parameters, | |
702 measurements, | |
703 dates, | |
704 getChartResult(uuid, callContext), | |
705 locale, | |
706 uuid, | |
707 linesVisible, | |
708 shapesVisible, | |
709 callContext | |
710 ); | |
711 | |
712 if (chart == null) { | |
713 log.error("Could not initialize chart."); | |
714 return; | |
715 } | |
716 | |
717 ChartExportHelper.exportSVG( | |
718 outputStream, | |
719 chart.generateChart(), | |
720 null, | |
721 600, 400 | |
722 ); | |
723 | |
724 log.debug("svg export finished."); | |
725 } | |
726 | |
727 | |
728 protected Chart getChart( | |
729 ChartLabels chartLables, | |
730 ChartTheme theme, | |
731 Collection parameters, | |
732 Collection measurements, | |
733 Collection dates, | |
734 Object result, | |
735 Locale locale, | |
736 String uuid, | |
737 boolean linesVisible, | |
738 boolean shapesVisible, | |
739 CallContext callContext | |
740 ) { | |
741 Chart chart = null; | |
742 | |
743 if (CACHE_CHART) { | |
744 log.info("Try to get timeseries chart from cache."); | |
745 chart = (Chart) getChartFromCache(uuid, callContext); | |
746 } | |
747 | |
748 if (chart != null) | |
749 return chart; | |
750 | |
751 log.info("Chart not in cache yet."); | |
752 chart = new TimeSeriesChart( | |
753 chartLables, | |
754 theme, | |
755 parameters, | |
756 measurements, | |
757 dates, | |
758 (Collection)result, | |
759 timeGapDefinitions, | |
760 locale, | |
761 linesVisible, | |
762 shapesVisible | |
763 ); | |
764 chart.generateChart(); | |
765 | |
766 if (CACHE_CHART) { | |
767 log.info("Put chart into cache."); | |
768 purifyChart(chart, uuid); | |
769 } | |
770 | |
771 return chart; | |
772 } | |
773 | |
774 protected ChartTheme createStyle(CallContext callContext) { | |
775 log.debug("Fetch chart theme from global context"); | |
776 | |
777 GNVArtifactContext context = | |
778 (GNVArtifactContext) callContext.globalContext(); | |
779 | |
780 XMLChartTheme theme = (XMLChartTheme) context.get( | |
781 GNVArtifactContext.CHART_TEMPLATE_KEY); | |
782 | |
783 return theme; | |
784 } | |
785 | |
786 protected ChartLabels createChartLabels(Locale locale, String uuid) { | |
787 return new ChartLabels( | |
788 createChartTitle(locale, uuid), | |
789 createChartSubtitle(locale, uuid), | |
790 RessourceFactory.getInstance().getRessource( | |
791 locale, | |
792 domainLable, | |
793 domainLable | |
794 ) | |
795 ); | |
796 } | |
797 | |
798 | |
799 protected String createChartTitle(Locale locale, String uuid) { | |
800 return getFisName(locale); | |
801 | |
802 } | |
803 | |
804 | |
805 protected String createChartSubtitle(Locale locale, String uuid) { | |
806 return getSelectedFeatureName(uuid); | |
807 } | |
808 | |
809 | |
810 protected ChartLabels createHistogramLabels( | |
811 String uuid, CallContext context, Object[] data) | |
812 { | |
813 return new ChartLabels((String) data[0], "", ""); | |
814 } | |
815 | |
816 | |
817 protected String getFisName(Locale locale) { | |
818 String returnValue = ""; | |
819 InputData input = inputData.get("fisname"); | |
820 | |
821 if (input != null) { | |
822 String value = input.getValue(); | |
823 | |
824 returnValue = RessourceFactory.getInstance().getRessource( | |
825 locale, | |
826 value, | |
827 value | |
828 ); | |
829 } | |
830 return returnValue; | |
831 } | |
832 | |
833 | |
834 protected String getSelectedInputDataName(String uuid, String key) { | |
835 Collection values = getCollection(key, uuid); | |
836 | |
837 if (values != null) { | |
838 Iterator it = values.iterator(); | |
839 | |
840 while (it.hasNext()) { | |
841 KeyValueDescibeData data = (KeyValueDescibeData) it.next(); | |
842 | |
843 if (data.isSelected()) { | |
844 return data.getValue(); | |
845 } | |
846 } | |
847 } | |
848 return null; | |
849 } | |
850 | |
851 | |
852 protected Collection<KeyValueDescibeData> getParameters(String uuid) { | |
853 return this.getCollection(parameterValuesName, uuid); | |
854 } | |
855 | |
856 protected Collection<KeyValueDescibeData> getMeasurements(String uuid) { | |
857 return this.getCollection(measuremenValueName, uuid); | |
858 } | |
859 protected Collection<KeyValueDescibeData> getDates(String uuid) { | |
860 return this.getCollection(dateValueName,uuid); | |
861 } | |
862 | |
863 @Override | |
864 public void setup(Node configuration) { | |
865 super.setup(configuration); | |
866 String featureNameValue = Config.getStringXPath(configuration, | |
867 "value-names/value-name[@name='feature']/@value"); | |
868 if (featureNameValue != null) { | |
869 this.featureValuesName = featureNameValue; | |
870 } | |
871 String parameterNameValue = Config.getStringXPath(configuration, | |
872 "value-names/value-name[@name='parameter']/@value"); | |
873 if (parameterNameValue != null) { | |
874 this.parameterValuesName = parameterNameValue; | |
875 } | |
876 String measurementNameValue = Config.getStringXPath(configuration, | |
877 "value-names/value-name[@name='measurement']/@value"); | |
878 if (measurementNameValue != null) { | |
879 this.measuremenValueName = measurementNameValue; | |
880 } | |
881 | |
882 String dateNameValue = Config.getStringXPath(configuration, | |
883 "value-names/value-name[@name='date']/@value"); | |
884 if (dateNameValue != null) { | |
885 this.dateValueName = dateNameValue; | |
886 } | |
887 if (timeGapDefinitions == null){ | |
888 Element gapDefinition = (Element)Config.getNodeXPath(configuration, | |
889 "time-gap-definition"); | |
890 synchronized (this.getClass()) { | |
891 if (gapDefinition != null){ | |
892 String link = gapDefinition.getAttribute("xlink:href"); | |
893 if (link != null ){ | |
894 String absolutFileName = Config.replaceConfigDir(link); | |
895 gapDefinition = (Element)new ArtifactXMLUtilities(). | |
896 readConfiguration(absolutFileName); | |
897 } | |
898 | |
899 NodeList gapDefinitions = Config.getNodeSetXPath(gapDefinition, | |
900 "/time-gaps/time-gap"); | |
901 if (gapDefinition != null){ | |
902 timeGapDefinitions = new ArrayList<TimeGap>(gapDefinitions. | |
903 getLength()); | |
904 for (int i = 0; i < gapDefinitions.getLength(); i++){ | |
905 Element gapNode = (Element)gapDefinitions.item(i); | |
906 String unit = gapNode.getAttribute("unit"); | |
907 int key = Integer.parseInt(gapNode.getAttribute("key")); | |
908 int value = Integer.parseInt(gapNode.getAttribute("gap")); | |
909 log.info("Add new Timegap: "+key+" "+value+" "+ unit); | |
910 timeGapDefinitions.add(new DefaultTimeGap(unit, | |
911 key, | |
912 value)); | |
913 } | |
914 } | |
915 } | |
916 } | |
917 } | |
918 } | |
919 | |
920 /** | |
921 * @param collectionName | |
922 * @return | |
923 */ | |
924 protected Collection<KeyValueDescibeData> getCollection( | |
925 String collectionName, | |
926 String uuid) | |
927 { | |
928 NamedCollection<KeyValueDescibeData> c = new NamedArrayList<KeyValueDescibeData>(collectionName); | |
929 | |
930 InputData data = inputData.get(collectionName); | |
931 if (data == null) { | |
932 log.warn("No collection found with name: " + collectionName); | |
933 return c; | |
934 } | |
935 | |
936 String[] descs = data.getDescription(); | |
937 String[] values = data.splitValue(); | |
938 int size = values.length; | |
939 | |
940 for (int i = 0; i < size; i++){ | |
941 c.add(new DefaultKeyValueDescribeData( | |
942 values[i], descs[i], getID())); | |
943 } | |
944 | |
945 return c; | |
946 } | |
947 } | |
948 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |