001package org.javasimon.utils;
002
003import org.javasimon.CounterSample;
004import org.javasimon.Sample;
005import org.javasimon.StopwatchSample;
006
007import java.util.Arrays;
008
009/**
010 * Generates HTML table for the provided {@link org.javasimon.Sample}s. Lines are separated by the default line separator
011 * (current value of {@code System.getProperty("line.separator")}).
012 */
013@SuppressWarnings("JavaDoc")
014public class SampleHtmlGenerator {
015
016        private static String lineSeparator = System.getProperty("line.separator");
017
018        private final Iterable<Sample> samples;
019        private final StringBuilder builder;
020
021        private SampleHtmlGenerator(Iterable<Sample> samples) {
022                this.samples = samples;
023                builder = new StringBuilder();
024        }
025
026        /**
027         * Generates HTML table for the provided {@link Sample}s.
028         *
029         * @param samples vararg array of {@link Sample}s
030         * @return HTML output for the samples
031         */
032        public static String generate(Sample... samples) {
033                return new SampleHtmlGenerator(Arrays.asList(samples)).toHtmlTable();
034        }
035
036        /**
037         * Generates HTML table for the provided {@link Sample}s.
038         *
039         * @param samples iterable of {@link Sample}s
040         * @return HTML output for the samples
041         */
042        public static String generate(Iterable<Sample> samples) {
043                return new SampleHtmlGenerator(samples).toHtmlTable();
044        }
045
046        /**
047         * Generates HTML table for the provided {@link Sample}s.
048         *
049         * @return HTML output for the samples
050         */
051        private String toHtmlTable() {
052                buildHeader();
053                for (Sample sample : this.samples) {
054                        buildRowForSample(sample);
055                }
056                builder.append("</table>");
057                return builder.toString();
058        }
059
060        private void buildHeader() {
061                builder.append("<table class=\"javasimon-samples-table\">").append(lineSeparator);
062                indent(1).append("<tr>").append(lineSeparator);
063                indent(2).append("<th>Name</th>").append(lineSeparator);
064                indent(2).append("<th>Active</th>").append(lineSeparator);
065                indent(2).append("<th>Counter</th>").append(lineSeparator);
066                indent(2).append("<th>Min</th>").append(lineSeparator);
067                indent(2).append("<th>Max</th>").append(lineSeparator);
068                indent(2).append("<th>Mean</th>").append(lineSeparator);
069                indent(2).append("<th>Total</th>").append(lineSeparator);
070                indent(1).append("</tr>").append(lineSeparator);
071        }
072
073        private void buildRowForSample(Sample sample) {
074                indent(1).append("<tr>").append(lineSeparator);
075                indent(2).append("<td>").append(sample.getName()).append("</td>").append(lineSeparator);
076
077                if (sample instanceof StopwatchSample) {
078                        StopwatchSample stopwatchSample = (StopwatchSample) sample;
079
080                        indent(2).append("<td>").append(stopwatchSample.getActive()).append("</td>").append(lineSeparator);
081                        indent(2).append("<td>").append(stopwatchSample.getCounter()).append("</td>").append(lineSeparator);
082                        indent(2).append("<td>").append(SimonUtils.presentNanoTime(stopwatchSample.getMin())).append("</td>").append(lineSeparator);
083                        indent(2).append("<td>").append(SimonUtils.presentNanoTime(stopwatchSample.getMax())).append("</td>").append(lineSeparator);
084                        indent(2).append("<td>").append(SimonUtils.presentNanoTime(stopwatchSample.getMean())).append("</td>").append(lineSeparator);
085                        indent(2).append("<td>").append(SimonUtils.presentNanoTime(stopwatchSample.getTotal())).append("</td>").append(lineSeparator);
086                } else {
087                        CounterSample counterSample = (CounterSample) sample;
088                        indent(2).append("<td>-</td>").append(lineSeparator);
089                        indent(2).append("<td>").append(counterSample.getCounter()).append("</td>").append(lineSeparator);
090                        indent(2).append("<td>").append(SimonUtils.presentMinMaxCount(counterSample.getMin())).append("</td>").append(lineSeparator);
091                        indent(2).append("<td>").append(SimonUtils.presentMinMaxCount(counterSample.getMax())).append("</td>").append(lineSeparator);
092                        indent(2).append("<td>-</td>").append(lineSeparator);
093                        indent(2).append("<td>").append("+").append(SimonUtils.presentMinMaxCount(counterSample.getIncrementSum())).
094                                append("/-").append(SimonUtils.presentMinMaxCount(counterSample.getDecrementSum())).append("</td>").append(lineSeparator);
095                }
096                indent(1).append("</tr>").append(lineSeparator);
097        }
098
099        private StringBuilder indent(int count) {
100                for (int i = 0; i < count; i++) {
101                        builder.append("    ");
102                }
103                return builder;
104        }
105
106        /**
107         * Sets the line separator to desired string. Default value is {@code System.getProperty("line.separator")}.
108         *
109         * @param newLineSeparator new line separator string
110         */
111        public static void setLineSeparator(String newLineSeparator) {
112                lineSeparator = newLineSeparator;
113        }
114}