1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package net.objectlab.qalab.parser;
40
41 import net.objectlab.qalab.util.QALabTags;
42 import net.objectlab.qalab.util.TaskLogger;
43 import net.objectlab.qalab.util.Util;
44
45 import org.jfree.chart.ChartColor;
46 import org.jfree.chart.ChartFactory;
47 import org.jfree.chart.ChartUtilities;
48 import org.jfree.chart.JFreeChart;
49 import org.jfree.chart.axis.DateAxis;
50 import org.jfree.chart.plot.XYPlot;
51 import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
52 import org.jfree.chart.renderer.xy.XYItemRenderer;
53 import org.jfree.chart.title.TextTitle;
54 import org.jfree.data.time.FixedMillisecond;
55 import org.jfree.data.time.MovingAverage;
56 import org.jfree.data.time.TimeSeries;
57 import org.jfree.data.time.TimeSeriesCollection;
58 import org.jfree.ui.Align;
59 import org.jfree.ui.HorizontalAlignment;
60 import org.jfree.ui.RectangleEdge;
61 import org.xml.sax.Attributes;
62 import org.xml.sax.SAXException;
63 import org.xml.sax.SAXParseException;
64 import org.xml.sax.helpers.DefaultHandler;
65
66 import javax.swing.ImageIcon;
67
68 import java.awt.BasicStroke;
69 import java.awt.Color;
70 import java.awt.Font;
71 import java.awt.GradientPaint;
72 import java.awt.Image;
73 import java.awt.Paint;
74 import java.awt.Stroke;
75
76 import java.io.File;
77 import java.io.IOException;
78
79 import java.net.URL;
80
81 import java.text.ParseException;
82
83 import java.util.ArrayList;
84 import java.util.Calendar;
85 import java.util.Collections;
86 import java.util.Date;
87 import java.util.HashMap;
88 import java.util.Iterator;
89 import java.util.List;
90 import java.util.Map;
91
92 /**
93 * This is the parser for generating the charts from qalab.xml.
94 *
95 * Created by IntelliJ IDEA. User: xhensevalb Date: 09-Feb-2004 Time: 17:14:25
96 *
97 * @version $Revision: 253 $
98 */
99 public class BuildStatForChartParser extends DefaultHandler {
100
101
102
103 private static final int NUM_HOURS_BEFORE_LAST_DATE = -28;
104
105 private static final long ONE_DAY_IN_MS = 24L * 60L * 60L * 1000L;
106
107 /** Default Summary Types */
108 private static final String DEFAULT_SUMMARY_TYPES = "checkstyle,pmd,findbugs,simian";
109
110 /** Default Types */
111 private static final String DEFAULT_TYPES = "checkstyle,pmd,findbugs,simian,cobertura-branch,cobertura-line";
112
113 /** footer font size. */
114 private static final int DEFAULT_FONT_SIZE = 9;
115
116 /** Chart parameters for fading the logo in. */
117 private static final float ALPHA = 0.70f;
118
119 /** Max Widths for chart. */
120 private static final int MAX_WIDTH = 1000;
121
122 /** Colours per type. */
123 private static final Map COLOURS = new HashMap();
124
125 /** Stroke per type. */
126 private static final Map STROKES = new HashMap();
127
128 static {
129 COLOURS.put("findbugs", ChartColor.RED);
130 COLOURS.put("pmd", new Color(0x55, 0x55, 0xFF));
131 COLOURS.put("checkstyle", new Color(0x55, 0xFF, 0x55));
132 COLOURS.put("pmd-cpd", new Color(0xFF, 0x55, 0xFF));
133 COLOURS.put("simian", ChartColor.GRAY);
134 COLOURS.put("cobertura-line", ChartColor.PINK);
135 COLOURS.put("cobertura-branch", ChartColor.DARK_CYAN);
136
137 STROKES.put("checkstyle", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f, new float[] { 2.0f,
138 6.0f }, 0.0f));
139 STROKES.put("findbugs", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f, new float[] { 2.0f,
140 3.0f }, 1.0f));
141 STROKES.put("cobertura-branch", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
142 STROKES.put("cobertura-line", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
143 STROKES.put("simian", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
144 STROKES.put("pmd-cpd", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
145 STROKES.put("pmd", new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
146 }
147
148
149
150
151 /** the logger to use. */
152 private TaskLogger parentTask;
153
154 /** true if the current element is a summary one. */
155 private boolean currentElementisSummary = false;
156
157 /** output directory. */
158 private String toDir = "";
159
160 /** chart width in pixels. */
161 private int chartWidth;
162
163 /** chart height. */
164 private int chartHeight;
165
166 /** moving average for second line, none if <=0. */
167 private int movingAverage = 0;
168
169 /** if true, generate only the summary chart. */
170 private boolean summaryOnly = true;
171
172 /** current element name. */
173 private String currentName;
174
175 /** true if current statistics relates to file. */
176 private boolean fileStat = false;
177
178 /** series of dates per types. */
179 private Map dates = new HashMap();
180
181 /** series of statistics per types. */
182 private Map errors = new HashMap();
183
184 /** the accepted styles as a List of Strings. */
185 private List types = Collections.EMPTY_LIST;
186
187 /** the accepted styles as a List of Strings. */
188 private List summaryTypes = Collections.EMPTY_LIST;
189
190 /** The logo to put in the bottom left corner of charts. */
191 private Image logo;
192
193 /** if true, no debug output. */
194 private boolean quiet = true;
195
196 /** file prefix for the chart names. */
197 private String filePrefix = "";
198
199 /** X Axis Title */
200 private String xAxisTitle = "Dates";
201
202 /** Y Axis Title */
203 private String yAxisTitle = "Violations";
204
205 /** X Axis Title for Summary */
206 private String xAxisSummaryTitle = "Dates";
207
208 /** Y Axis Title for Summary */
209 private String yAxisSummaryTitle = "Violations";
210
211
212
213
214 /**
215 * constructor, accepts the logger.
216 *
217 * @param logger
218 * the looger for this task, will vary if ant/maven/other.
219 */
220 public BuildStatForChartParser(final TaskLogger logger) {
221 parentTask = logger;
222 setAcceptedStyle(DEFAULT_TYPES);
223 setSummaryStyle(DEFAULT_SUMMARY_TYPES);
224 }
225
226
227
228
229 /**
230 * set the accepted styles for charts, each type will be a line/series on
231 * the chart. Accepted as a comma separated string, eg checkstyle,pmd for
232 * both PMD and Checkstyle.
233 *
234 * @param acceptedStyleStr
235 * a comma separated string with styles.
236 */
237 public final void setAcceptedStyle(final String acceptedStyleStr) {
238 types = Util.listify(acceptedStyleStr, ",");
239 }
240
241 /**
242 * set the accepted styles for SUMMARY charts, each type will be a
243 * line/series on the chart. Accepted as a comma separated string, eg
244 * checkstyle,pmd for both PMD and Checkstyle.
245 *
246 * @param acceptedStyleStr
247 * a comma separated string with styles.
248 */
249 public final void setSummaryStyle(final String acceptedStyleStr) {
250 summaryTypes = Util.listify(acceptedStyleStr, ",");
251 if (!quiet) {
252 parentTask.log("Summary Styles: " + summaryTypes);
253 }
254 }
255
256
257
258
259
260 /**
261 * Start element, called when each new tag is encountered.
262 *
263 * @param ignoreUri
264 * ignore, this is due to sax interface.
265 * @param local
266 * local name of the tag.
267 * @param ignoreRaw
268 * ignore, this is due to sax interface.
269 * @param attrs
270 * the element attributes.
271 * @throws SAXException
272 * any SAX parser exception.
273 */
274 public final void startElement(final String ignoreNamespaceURI,
275 final String localname, final String qualifiedname, final Attributes attrs) throws SAXException {
276 String local = localname;
277
278 if ("".equals(local)) {
279 local = qualifiedname;
280 }
281
282 if (!currentElementisSummary && QALabTags.SUMMARY_TAG.equals(local)) {
283 currentElementisSummary = true;
284 currentName = QALabTags.SUMMARY_TAG;
285 }
286
287 if (!currentElementisSummary && !fileStat && QALabTags.FILE_TAG.equals(local)) {
288 fileStat = true;
289 currentName = getFileName(attrs);
290 dates.clear();
291 errors.clear();
292 }
293
294 if (currentElementisSummary) {
295 processSummaryResult(local, attrs);
296 } else if (!isSummaryOnly() && fileStat) {
297 processFileResult(local, attrs);
298 }
299 }
300
301 /**
302 * Process a file result.
303 *
304 * @param local
305 * name of element.
306 * @param attrs
307 * attributes of element.
308 */
309 private void processFileResult(final String local, final Attributes attrs) {
310 if (!QALabTags.RESULT_TAG.equals(local)) {
311 return;
312 }
313
314 processResult(attrs);
315 }
316
317 /**
318 * Helper method that add a non-null value to an array in a map for the
319 * given type. The map contains pairs string-array.
320 *
321 * @param map
322 * where the item will be stored if val!=null
323 * @param type
324 * the key in the map
325 * @param val
326 * the value (to be added to an array).
327 */
328 private void add(final Map map, final String type, final Object val) {
329 if (val == null) {
330 return;
331 }
332
333 List list = (List) map.get(type);
334
335 if (list == null) {
336 list = new ArrayList();
337 map.put(type, list);
338 }
339
340 list.add(val);
341 }
342
343 /**
344 * Extract the file name (id) from an element.
345 *
346 * @param attrs
347 * XML attributes
348 * @return null if id attribute is not found.
349 */
350 private String getFileName(final Attributes attrs) {
351 String fileName = null;
352 final int attrCount = attrs.getLength();
353
354 for (int i = 0; i < attrCount; i++) {
355 final String attribute = attrs.getQName(i);
356
357 if (QALabTags.ID_ATTRIBUTE.equals(attribute)) {
358 fileName = attrs.getValue(i).replace('/', '_');
359
360 break;
361 }
362 }
363
364 return fileName;
365 }
366
367 /**
368 * Process a summary result.
369 *
370 * @param local
371 * name of element.
372 * @param attrs
373 * attributes of element.
374 */
375 private void processSummaryResult(final String local, final Attributes attrs) {
376 if (!QALabTags.SUMMARY_RESULT_TAG.equals(local)) {
377 return;
378 }
379
380 processResult(attrs);
381 }
382
383 /**
384 * Both summary and file results are actually quite similar with the
385 * attributes 'type', 'date' and 'statvalue' being extracted for charting.
386 *
387 * @param attrs
388 * list of attributes.
389 */
390 private void processResult(final Attributes attrs) {
391 final int attrCount = attrs.getLength();
392 Date date = null;
393 boolean accepted = false;
394 Integer error = null;
395 String type = null;
396
397
398
399
400 for (int i = 0; i < attrCount; i++) {
401 final String attribute = attrs.getQName(i);
402
403 final String value = attrs.getValue(i);
404 if (QALabTags.TYPE_ATTRIBUTE.equals(attribute)) {
405 type = value;
406 if (currentElementisSummary) {
407 if (!quiet) {
408 parentTask.log("Check that the summary " + value + " is accepted in " + summaryTypes);
409 }
410 accepted = summaryTypes.contains(value);
411 } else {
412 accepted = types.contains(value);
413 }
414 } else if (QALabTags.STATVALUE_ATTRIBUTE.equals(attribute)) {
415 error = Integer.valueOf(value);
416 } else if (QALabTags.DATE_ATTRIBUTE.equals(attribute)) {
417 try {
418 if (value != null && value.length() > QALabTags.DATE_ONLY_SIZE) {
419 date = QALabTags.DEFAULT_DATETIME_FORMAT.parse(value);
420 } else if (value != null && value.length() == QALabTags.DATE_ONLY_SIZE) {
421 date = QALabTags.DEFAULT_DATE_FORMAT.parse(value);
422 } else {
423 throw new IllegalArgumentException("OUCH -> date size = " + (value != null ? value.length() : 0) + " ["
424 + value + "]");
425 }
426 } catch (ParseException e) {
427 parentTask.log(e.getMessage());
428 }
429 }
430 }
431
432
433 if (accepted) {
434 add(dates, type, date);
435 add(errors, type, error);
436 }
437 }
438
439
440
441
442
443 /**
444 * Warning.
445 *
446 * @param ex
447 * the SAX Parser Exception.
448 * @throws SAXException
449 * any SAX Parser Exception.
450 */
451 public final void warning(final SAXParseException ex) throws SAXException {
452 printError("Warning", ex);
453 }
454
455 /**
456 * Error.
457 *
458 * @param ex
459 * the SAX Parser Exception.
460 * @throws SAXException
461 * any SAX Parser Exception.
462 */
463 public final void error(final SAXParseException ex) throws SAXException {
464 printError("Error", ex);
465 }
466
467 /**
468 * Fatal error.
469 *
470 * @param ex
471 * the SAX Parser Exception.
472 * @throws SAXException
473 * any SAX Parser Exception.
474 */
475 public final void fatalError(final SAXParseException ex) throws SAXException {
476 printError("Fatal Error", ex);
477 }
478
479 /**
480 * Common handling of SAX errors & warnings, log it to the given logger.
481 *
482 * @param errorType
483 * warning/error/fatal
484 * @param ex
485 * the SAX exception
486 */
487 private void printError(final String errorType, final SAXParseException ex) {
488 final StringBuffer buf = new StringBuffer();
489
490 buf.append("[").append(errorType).append("] ");
491
492 if (ex == null) {
493 buf.append("!!!");
494 }
495
496 if (ex != null) {
497 String systemId = ex.getSystemId();
498
499 if (systemId != null) {
500 final int index = systemId.lastIndexOf('/');
501
502 if (index != -1) {
503 systemId = systemId.substring(index + 1);
504 }
505
506 buf.append(systemId);
507 }
508
509 buf.append(':');
510 buf.append(ex.getLineNumber());
511 buf.append(':');
512 buf.append(ex.getColumnNumber());
513 buf.append(": ");
514 buf.append(ex.getMessage());
515 }
516
517 parentTask.log(buf.toString());
518 }
519
520 /**
521 * Called when a closing element tag is encountered, it generates the chart
522 * each time it moves from a file or summary.
523 *
524 * @param ignoreUri
525 * ignore, this is due to sax interface.
526 * @param localName
527 * local name of the tag.
528 * @param ignoreQName
529 * ignore, this is due to sax interface.
530 * @throws SAXException
531 * any SAX exceptions.
532 */
533 public final void endElement(final String ignoreNamespaceURI,
534 final String localName, final String qualifiedname)
535 throws SAXException {
536 String local = localName;
537 if ("".equals(local)) {
538 local = qualifiedname;
539 }
540 if (currentElementisSummary && QALabTags.SUMMARY_TAG.equals(local)) {
541 currentElementisSummary = false;
542
543 if (!quiet) {
544 parentTask.log("Summary Found Dates:" + dates + " / errors " + errors);
545 }
546
547 chart("summary", dates, errors, true, true);
548 } else if (!isSummaryOnly() && fileStat && QALabTags.FILE_TAG.equals(local)) {
549 fileStat = false;
550
551 if (!quiet) {
552 parentTask.log("Found " + currentName + " Dates:" + dates + " / errors " + errors);
553 }
554
555 chart(currentName, dates, errors, false, false);
556 }
557 }
558
559 /**
560 * Generates the chart using jFreeChart, each type will generate a series. The chart
561 * will check the LATEST date on record across all types, if the last day of a given type
562 * is AT LEAST 28h before the latest date and there are NO records afterwards, we shall
563 * assume that the statistics have fallen to 0 and draw a line down to 0 for the day after.
564 *
565 * @param name
566 * name of the chart either summary or the file name.
567 * @param theDates
568 * the map of dates available per type.
569 * @param theErrors
570 * the map of error counts available per type.
571 * @param withAverage
572 * if true, generate a second series showing. moving average.
573 */
574 private void chart(final String name, final Map theDates, final Map theErrors, final boolean withAverage,
575 final boolean summaryChart) {
576 try {
577 if (theDates.size() == 0) {
578 return;
579 }
580
581 List availableTypes = new ArrayList();
582 final TimeSeriesCollection series = new TimeSeriesCollection();
583 buildTimeSeries(theDates, theErrors, withAverage, availableTypes, series);
584
585 StringBuffer existingTypes = new StringBuffer();
586 for (Iterator it = availableTypes.iterator(); it.hasNext();) {
587 existingTypes.append(it.next()).append(" ");
588 }
589
590 String title = existingTypes.toString() + " Stats " + name;
591
592 String yTitle = getYAxisTitle();
593 String xTitle = getXAxisTitle();
594 if (summaryChart) {
595 yTitle = getYAxisSummaryTitle();
596 xTitle = getXAxisSummaryTitle();
597 }
598 final JFreeChart chart = ChartFactory.createTimeSeriesChart(title, xTitle, yTitle, series, true, false, false);
599
600 final TextTitle copyright = new TextTitle("QALab 2004+,ObjectLab.co.uk Generated "
601 + QALabTags.DEFAULT_DATETIME_FORMAT.format(new Date()), new Font("SansSerif", Font.PLAIN, DEFAULT_FONT_SIZE));
602
603 copyright.setPosition(RectangleEdge.BOTTOM);
604 copyright.setHorizontalAlignment(HorizontalAlignment.RIGHT);
605 chart.addSubtitle(copyright);
606
607 chart.setBackgroundImage(getLogo());
608 chart.setBackgroundImageAlpha(ALPHA);
609 chart.setBackgroundImageAlignment(Align.BOTTOM_LEFT);
610 chart.setBackgroundPaint(new GradientPaint(0, 0, Color.white, 0, MAX_WIDTH, Color.blue));
611
612 final XYPlot xyPlot = chart.getXYPlot();
613 final XYItemRenderer renderer = xyPlot.getRenderer();
614 if (!withAverage && renderer instanceof StandardXYItemRenderer) {
615 final StandardXYItemRenderer rr = (StandardXYItemRenderer) renderer;
616
617 rr.setPlotImages(true);
618 rr.setShapesFilled(Boolean.TRUE);
619 }
620
621 int index = 0;
622 for (Iterator it = availableTypes.iterator(); it.hasNext(); index++) {
623 final String type = (String) it.next();
624
625 renderer.setSeriesPaint(index, (Paint) COLOURS.get(type));
626 Stroke stroke = (Stroke) STROKES.get(type);
627 if (stroke != null) {
628 renderer.setSeriesStroke(index, stroke);
629 }
630 }
631
632 final DateAxis axis = (DateAxis) xyPlot.getDomainAxis();
633
634 axis.setVerticalTickLabels(true);
635
636 final File file2 = new File(getToDir() + getFilePrefix() + name + ".png");
637
638 ChartUtilities.saveChartAsPNG(file2, chart, getChartWidth(), getChartHeight());
639 } catch (IOException e) {
640 parentTask.log(e.toString());
641 }
642 }
643
644 private void buildTimeSeries(final Map theDates, final Map theErrors, final boolean withAverage,
645 final List availableTypes, final TimeSeriesCollection series) {
646 final Iterator typeIter = theDates.entrySet().iterator();
647 final Date max = findMaxDate(theDates);
648 final Calendar cal = Calendar.getInstance();
649 cal.setTime(max);
650 cal.add(Calendar.HOUR_OF_DAY, NUM_HOURS_BEFORE_LAST_DATE);
651 final Date zeroDeadline = cal.getTime();
652
653 while (typeIter.hasNext()) {
654 final Map.Entry pairTypeDates = (Map.Entry) typeIter.next();
655 final String type = (String) pairTypeDates.getKey();
656 availableTypes.add(type);
657 final TimeSeries ts = new TimeSeries(type, "bla", "bli", FixedMillisecond.class);
658
659 final List typeDates = (List) pairTypeDates.getValue();
660 final List typeErrors = (List) theErrors.get(type);
661
662 if ((typeDates != null) && (typeErrors != null)) {
663 addDataToTimeSeries(zeroDeadline, ts, typeDates, typeErrors);
664 }
665
666 series.addSeries(ts);
667
668 if (withAverage && (getMovingAverage() > 0)) {
669 series.addSeries(MovingAverage.createPointMovingAverage(ts, type + " " + getMovingAverage()
670 + "-run Moving Average", getMovingAverage()));
671 }
672 }
673 }
674
675 private void addDataToTimeSeries(final Date zeroDeadline, final TimeSeries ts, final List typeDates, final List typeErrors) {
676 final Iterator dateIter = typeDates.iterator();
677 final Iterator errorsIter = typeErrors.iterator();
678
679 Date lastDateForThisType = null;
680 while (dateIter.hasNext() && errorsIter.hasNext()) {
681 lastDateForThisType = (Date) dateIter.next();
682 final Integer count = (Integer) errorsIter.next();
683
684 ts.addOrUpdate(new FixedMillisecond(lastDateForThisType), count);
685 }
686
687
688 if (lastDateForThisType != null && zeroDeadline != null && zeroDeadline.after(lastDateForThisType)) {
689 ts.addOrUpdate(new FixedMillisecond(lastDateForThisType.getTime() + ONE_DAY_IN_MS), 0);
690 }
691 }
692
693 private Date findMaxDate(Map theDates) {
694 Date maxDate = null;
695 final Iterator typeIter = theDates.entrySet().iterator();
696 while (typeIter.hasNext()) {
697 final Map.Entry pairTypeDates = (Map.Entry) typeIter.next();
698 final List typeDates = (List) pairTypeDates.getValue();
699
700 if (typeDates != null) {
701 for (Iterator it = typeDates.iterator(); it.hasNext();) {
702 Date date = (Date) it.next();
703 if (maxDate != null) {
704 maxDate = (maxDate.before(date) ? date : maxDate);
705 } else {
706 maxDate = date;
707 }
708 }
709 }
710 }
711 return maxDate;
712 }
713
714 /**
715 * @return Returns the yAxisSummaryTitle.
716 */
717 public String getYAxisSummaryTitle() {
718 return yAxisSummaryTitle;
719 }
720
721 /**
722 * @param axisSummaryTitle
723 * The yAxisSummaryTitle to set.
724 */
725 public void setYAxisSummaryTitle(String axisSummaryTitle) {
726 yAxisSummaryTitle = axisSummaryTitle;
727 }
728
729 /**
730 * Include a logo for the bottom left corner.
731 *
732 * @return Image, the logo to include.
733 */
734 private Image getLogo() {
735 if (logo == null) {
736 final URL url = BuildStatForChartParser.class.getResource("/net/objectlab/qalab/objectlab.gif");
737
738
739 final ImageIcon temp = new ImageIcon(url);
740
741 logo = temp.getImage();
742 }
743
744 return logo;
745 }
746
747 /**
748 * @return chart width in pixels.
749 */
750 public final int getChartWidth() {
751 return chartWidth;
752 }
753
754 /**
755 * @param width
756 * in pixels.
757 */
758 public final void setChartWidth(final int width) {
759 this.chartWidth = width;
760 }
761
762 /**
763 * @return chart height in pixels.
764 */
765 public final int getChartHeight() {
766 return chartHeight;
767 }
768
769 /**
770 * @param height
771 * in pixels.
772 */
773 public final void setChartHeight(final int height) {
774 this.chartHeight = height;
775 }
776
777 /**
778 * @return output directory.
779 */
780 public final String getToDir() {
781 return toDir;
782 }
783
784 /**
785 * @param outputDirectory
786 * output directory.
787 */
788 public final void setToDir(final String outputDirectory) {
789 this.toDir = outputDirectory;
790 }
791
792 /**
793 * @return number of point to take into account for moving average.
794 */
795 public final int getMovingAverage() {
796 return movingAverage;
797 }
798
799 /**
800 * @param average
801 * number of points to take into account in moving average, no
802 * moving average if <= 0.
803 */
804 public final void setMovingAverage(final int average) {
805 this.movingAverage = average;
806 }
807
808 /**
809 * @return Returns the xAxisSummaryTitle.
810 */
811 public String getXAxisSummaryTitle() {
812 return xAxisSummaryTitle;
813 }
814
815 /**
816 * @param axisSummaryTitle
817 * The xAxisSummaryTitle to set.
818 */
819 public void setXAxisSummaryTitle(String axisSummaryTitle) {
820 xAxisSummaryTitle = axisSummaryTitle;
821 }
822
823 /**
824 * @return true if only summary chart required.
825 */
826 public final boolean isSummaryOnly() {
827 return summaryOnly;
828 }
829
830 /**
831 * @param summary
832 * true if we require only summary chart.
833 */
834 public final void setSummaryOnly(final boolean summary) {
835 this.summaryOnly = summary;
836 }
837
838 /**
839 * @return true if no debug log required.
840 */
841 public final boolean isQuiet() {
842 return quiet;
843 }
844
845 /**
846 * @param noLog
847 * true if no debug log required.
848 */
849 public final void setQuiet(final boolean noLog) {
850 this.quiet = noLog;
851 }
852
853 /**
854 * @return Returns the filePrefix.
855 */
856 public String getFilePrefix() {
857 if (filePrefix == null) {
858 return "";
859 } else {
860 return filePrefix;
861 }
862 }
863
864 /**
865 * @param filePrefix
866 * The filePrefix to set.
867 */
868 public void setFilePrefix(String filePrefix) {
869 this.filePrefix = filePrefix;
870 }
871
872 /**
873 * @return Returns the xAxisTitle.
874 */
875 public String getXAxisTitle() {
876 return xAxisTitle;
877 }
878
879 /**
880 * @param axisTitle
881 * The xAxisTitle to set.
882 */
883 public void setXAxisTitle(String axisTitle) {
884 xAxisTitle = axisTitle;
885 }
886
887 /**
888 * @return Returns the yAxisTitle.
889 */
890 public String getYAxisTitle() {
891 return yAxisTitle;
892 }
893
894 /**
895 * @param axisTitle
896 * The yAxisTitle to set.
897 */
898 public void setYAxisTitle(String axisTitle) {
899 yAxisTitle = axisTitle;
900 }
901 }
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917