]> source.dussan.org Git - gitblit.git/commitdiff
Retrieve summary and metric charts over https (issue-61)
authorJames Moger <james.moger@gitblit.com>
Wed, 3 Jul 2013 14:01:49 +0000 (10:01 -0400)
committerJames Moger <james.moger@gitblit.com>
Wed, 3 Jul 2013 14:01:49 +0000 (10:01 -0400)
releases.moxie
src/main/java/com/gitblit/wicket/charting/SecureChart.java [new file with mode: 0644]
src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java [new file with mode: 0644]
src/main/java/com/gitblit/wicket/pages/MetricsPage.java
src/main/java/com/gitblit/wicket/pages/SummaryPage.java

index 5cfae90e6eab1cb2063183ee9ca2579fbd1aff1d..8567979848046d9fa4f796a2850b8ab9ec9987be 100644 (file)
@@ -36,6 +36,7 @@ r17: {
         - Fixed submodule diff display\r
 \r
        changes:\r
+        - Retrieve summary and metric graphs from Google over https (issue-61)\r
         - Persist originRepository (for forks) in the repository config instead of relying on parsing origin urls which are susceptible to filesystem relocation (issue 190) \r
         - Improved error logging for servlet containers which provide a null contextFolder (issue 199)\r
         - Improve Gerrit change ref decoration in the refs panel (issue 206)\r
diff --git a/src/main/java/com/gitblit/wicket/charting/SecureChart.java b/src/main/java/com/gitblit/wicket/charting/SecureChart.java
new file mode 100644 (file)
index 0000000..60dae4b
--- /dev/null
@@ -0,0 +1,633 @@
+/*\r
+ * Copyright 2007 Daniel Spiewak.\r
+ * Copyright 2013 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.charting;\r
+\r
+import java.awt.Color;\r
+import java.awt.Dimension;\r
+import java.io.Serializable;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.concurrent.locks.ReadWriteLock;\r
+import java.util.concurrent.locks.ReentrantReadWriteLock;\r
+\r
+import org.apache.wicket.markup.ComponentTag;\r
+import org.apache.wicket.markup.html.WebComponent;\r
+import org.wicketstuff.googlecharts.ChartDataEncoding;\r
+import org.wicketstuff.googlecharts.IChartAxis;\r
+import org.wicketstuff.googlecharts.IChartData;\r
+import org.wicketstuff.googlecharts.IChartFill;\r
+import org.wicketstuff.googlecharts.IChartGrid;\r
+import org.wicketstuff.googlecharts.IChartProvider;\r
+import org.wicketstuff.googlecharts.IFillArea;\r
+import org.wicketstuff.googlecharts.ILineStyle;\r
+import org.wicketstuff.googlecharts.ILinearGradientFill;\r
+import org.wicketstuff.googlecharts.ILinearStripesFill;\r
+import org.wicketstuff.googlecharts.IRangeMarker;\r
+import org.wicketstuff.googlecharts.IShapeMarker;\r
+import org.wicketstuff.googlecharts.ISolidFill;\r
+import org.wicketstuff.googlecharts.Range;\r
+\r
+/**\r
+ * This is a fork of org.wicketstuff.googlecharts.Chart whose only purpose\r
+ * is to build https urls instead of http urls.\r
+ * \r
+ * @author Daniel Spiewak\r
+ * @author James Moger\r
+ */\r
+public class SecureChart extends WebComponent implements Serializable {\r
+\r
+    private static final long serialVersionUID = 6286305912682861488L;\r
+    private IChartProvider provider;\r
+    private StringBuilder url;\r
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();\r
+\r
+    public SecureChart(String id, IChartProvider provider) {\r
+        super(id);\r
+\r
+        this.provider = provider;\r
+    }\r
+\r
+    public void invalidate() {\r
+        lock.writeLock().lock();\r
+        try {\r
+            url = null;\r
+        } finally {\r
+            lock.writeLock().unlock();\r
+        }\r
+    }\r
+\r
+    public CharSequence constructURL() {\r
+        lock.writeLock().lock();\r
+        try {\r
+            if (url != null) {\r
+                return url;\r
+            }\r
+\r
+            url = new StringBuilder("https://chart.googleapis.com/chart?");\r
+\r
+            addParameter(url, "chs", render(provider.getSize()));\r
+            addParameter(url, "chd", render(provider.getData()));\r
+            addParameter(url, "cht", render(provider.getType()));\r
+            addParameter(url, "chbh", render(provider.getBarWidth(), provider.getBarGroupSpacing()));\r
+            addParameter(url, "chtt", render(provider.getTitle()));\r
+            addParameter(url, "chdl", render(provider.getLegend()));\r
+            addParameter(url, "chco", render(provider.getColors()));\r
+\r
+            IChartFill bgFill = provider.getBackgroundFill();\r
+            IChartFill fgFill = provider.getChartFill();\r
+\r
+            StringBuilder fillParam = new StringBuilder();\r
+\r
+            if (bgFill != null) {\r
+                fillParam.append("bg,").append(render(bgFill));\r
+            }\r
+\r
+            if (fgFill != null) {\r
+                if (fillParam.length() > 0) {\r
+                    fillParam.append('|');\r
+                }\r
+\r
+                fillParam.append("c,").append(render(fgFill));\r
+            }\r
+\r
+            if (fillParam.toString().trim().equals("")) {\r
+                fillParam = null;\r
+            }\r
+\r
+            addParameter(url, "chf", fillParam);\r
+\r
+            IChartAxis[] axes = provider.getAxes();\r
+            addParameter(url, "chxt", renderTypes(axes));\r
+            addParameter(url, "chxl", renderLabels(axes));\r
+            addParameter(url, "chxp", renderPositions(axes));\r
+            addParameter(url, "chxr", renderRanges(axes));\r
+            addParameter(url, "chxs", renderStyles(axes));\r
+\r
+            addParameter(url, "chg", render(provider.getGrid()));\r
+            addParameter(url, "chm", render(provider.getShapeMarkers()));\r
+            addParameter(url, "chm", render(provider.getRangeMarkers()));\r
+            addParameter(url, "chls", render(provider.getLineStyles()));\r
+            addParameter(url, "chm", render(provider.getFillAreas()));\r
+            addParameter(url, "chl", render(provider.getPieLabels()));\r
+\r
+            return url;\r
+        } finally {\r
+            lock.writeLock().unlock();\r
+        }\r
+    }\r
+\r
+    private void addParameter(StringBuilder url, CharSequence param, CharSequence value) {\r
+        if (value == null || value.length() == 0) {\r
+            return;\r
+        }\r
+\r
+        if (url.charAt(url.length() - 1) != '?') {\r
+            url.append('&');\r
+        }\r
+\r
+        url.append(param).append('=').append(value);\r
+    }\r
+    \r
+    private CharSequence convert(ChartDataEncoding encoding, double value, double max) {\r
+       switch (encoding) {\r
+       case TEXT:\r
+               return SecureChartDataEncoding.TEXT.convert(value, max);\r
+       case EXTENDED:\r
+               return SecureChartDataEncoding.EXTENDED.convert(value, max);\r
+       case SIMPLE:\r
+       default:\r
+               return SecureChartDataEncoding.SIMPLE.convert(value, max);\r
+       }\r
+    }\r
+\r
+    private CharSequence render(Dimension dim) {\r
+        if (dim == null) {\r
+            return null;\r
+        }\r
+\r
+        return new StringBuilder().append(dim.width).append('x').append(dim.height);\r
+    }\r
+\r
+    private CharSequence render(IChartData data) {\r
+        if (data == null) {\r
+            return null;\r
+        }\r
+\r
+        ChartDataEncoding encoding = data.getEncoding();\r
+\r
+        StringBuilder back = new StringBuilder();\r
+        back.append(render(encoding)).append(':');\r
+\r
+        for (double[] set : data.getData()) {\r
+            if (set == null || set.length == 0) {\r
+                back.append(convert(encoding, -1, data.getMax()));\r
+            } else {\r
+                for (double value : set) {\r
+                    back.append(convert(encoding, value, data.getMax())).append(encoding.getValueSeparator());\r
+                }\r
+\r
+                if (back.substring(back.length() - encoding.getValueSeparator().length(),\r
+                        back.length()).equals(encoding.getValueSeparator())) {\r
+                    back.setLength(back.length() - encoding.getValueSeparator().length());\r
+                }\r
+            }\r
+\r
+            back.append(encoding.getSetSeparator());\r
+        }\r
+\r
+        if (back.substring(back.length() - encoding.getSetSeparator().length(),\r
+                back.length()).equals(encoding.getSetSeparator())) {\r
+            back.setLength(back.length() - encoding.getSetSeparator().length());\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(Enum<?> value) {\r
+        if (value == null) {\r
+            return null;\r
+        }\r
+\r
+        try {\r
+            Object back = value.getClass().getMethod("getRendering").invoke(value);\r
+\r
+            if (back != null) {\r
+                return back.toString();\r
+            }\r
+        } catch (IllegalArgumentException e) {\r
+        } catch (SecurityException e) {\r
+        } catch (IllegalAccessException e) {\r
+        } catch (InvocationTargetException e) {\r
+        } catch (NoSuchMethodException e) {\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    private CharSequence render(int barWidth, int groupSpacing) {\r
+        if (barWidth == -1) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder(barWidth);\r
+\r
+        if (groupSpacing >= 0) {\r
+            back.append(',').append(groupSpacing);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(String[] values) {\r
+        if (values == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (String value : values) {\r
+            CharSequence toRender = render(value);\r
+            if (toRender == null) {\r
+                toRender = "";\r
+            }\r
+\r
+            back.append(toRender).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(String value) {\r
+        if (value == null) {\r
+            return value;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (char c : value.toCharArray()) {\r
+            if (c == ' ') {\r
+                back.append('+');\r
+            } else {\r
+                back.append(c);\r
+            }\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(Color[] values) {\r
+        if (values == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (Color value : values) {\r
+            CharSequence toRender = render(value);\r
+            if (toRender == null) {\r
+                toRender = "";\r
+            }\r
+\r
+            back.append(toRender).append(',');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(Color value) {\r
+        if (value == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        {\r
+            String toPad = Integer.toHexString(value.getRed());\r
+\r
+            if (toPad.length() == 1) {\r
+                back.append(0);\r
+            }\r
+            back.append(toPad);\r
+        }\r
+\r
+        {\r
+            String toPad = Integer.toHexString(value.getGreen());\r
+\r
+            if (toPad.length() == 1) {\r
+                back.append(0);\r
+            }\r
+            back.append(toPad);\r
+        }\r
+\r
+        {\r
+            String toPad = Integer.toHexString(value.getBlue());\r
+\r
+            if (toPad.length() == 1) {\r
+                back.append(0);\r
+            }\r
+            back.append(toPad);\r
+        }\r
+\r
+        {\r
+            String toPad = Integer.toHexString(value.getAlpha());\r
+\r
+            if (toPad.length() == 1) {\r
+                back.append(0);\r
+            }\r
+            back.append(toPad);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(IChartFill fill) {\r
+        if (fill == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        if (fill instanceof ISolidFill) {\r
+            ISolidFill solidFill = (ISolidFill) fill;\r
+\r
+            back.append("s,");\r
+            back.append(render(solidFill.getColor()));\r
+        } else if (fill instanceof ILinearGradientFill) {\r
+            ILinearGradientFill gradientFill = (ILinearGradientFill) fill;\r
+\r
+            back.append("lg,").append(gradientFill.getAngle()).append(',');\r
+\r
+            Color[] colors = gradientFill.getColors();\r
+            double[] offsets = gradientFill.getOffsets();\r
+            for (int i = 0; i < colors.length; i++) {\r
+                back.append(render(colors[i])).append(',').append(offsets[i]).append(',');\r
+            }\r
+\r
+            back.setLength(back.length() - 1);\r
+        } else if (fill instanceof ILinearStripesFill) {\r
+            ILinearStripesFill stripesFill = (ILinearStripesFill) fill;\r
+\r
+            back.append("ls,").append(stripesFill.getAngle()).append(',');\r
+\r
+            Color[] colors = stripesFill.getColors();\r
+            double[] widths = stripesFill.getWidths();\r
+            for (int i = 0; i < colors.length; i++) {\r
+                back.append(render(colors[i])).append(',').append(widths[i]).append(',');\r
+            }\r
+\r
+            back.setLength(back.length() - 1);\r
+        } else {\r
+            return null;\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence renderTypes(IChartAxis[] axes) {\r
+        if (axes == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (IChartAxis axis : axes) {\r
+            back.append(render(axis.getType())).append(',');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence renderLabels(IChartAxis[] axes) {\r
+        if (axes == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (int i = 0; i < axes.length; i++) {\r
+            if (axes[i] == null || axes[i].getLabels() == null) {\r
+                continue;\r
+            }\r
+\r
+            back.append(i).append(":|");\r
+\r
+            for (String label : axes[i].getLabels()) {\r
+                if (label == null) {\r
+                    back.append('|');\r
+                    continue;\r
+                }\r
+\r
+                back.append(render(label)).append('|');\r
+            }\r
+\r
+            if (i == axes.length - 1) {\r
+                back.setLength(back.length() - 1);\r
+            }\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence renderPositions(IChartAxis[] axes) {\r
+        if (axes == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (int i = 0; i < axes.length; i++) {\r
+            if (axes[i] == null || axes[i].getPositions() == null) {\r
+                continue;\r
+            }\r
+\r
+            back.append(i).append(',');\r
+\r
+            for (double position : axes[i].getPositions()) {\r
+                back.append(position).append(',');\r
+            }\r
+\r
+            back.setLength(back.length() - 1);\r
+\r
+            back.append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence renderRanges(IChartAxis[] axes) {\r
+        if (axes == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (int i = 0; i < axes.length; i++) {\r
+            if (axes[i] == null || axes[i].getRange() == null) {\r
+                continue;\r
+            }\r
+\r
+            back.append(i).append(',');\r
+\r
+            Range range = axes[i].getRange();\r
+            back.append(range.getStart()).append(',').append(range.getEnd()).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence renderStyles(IChartAxis[] axes) {\r
+        if (axes == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (int i = 0; i < axes.length; i++) {\r
+            if (axes[i] == null || axes[i].getColor() == null\r
+                    || axes[i].getFontSize() < 0 || axes[i].getAlignment() == null) {\r
+                continue;\r
+            }\r
+\r
+            back.append(i).append(',');\r
+            back.append(render(axes[i].getColor())).append(',');\r
+            back.append(axes[i].getFontSize()).append(',');\r
+            back.append(render(axes[i].getAlignment())).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(IChartGrid grid) {\r
+        if (grid == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        back.append(grid.getXStepSize()).append(',');\r
+        back.append(grid.getYStepSize());\r
+\r
+        if (grid.getSegmentLength() >= 0) {\r
+            back.append(',').append(grid.getSegmentLength());\r
+            back.append(',').append(grid.getBlankLength());\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(IShapeMarker[] markers) {\r
+        if (markers == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (IShapeMarker marker : markers) {\r
+            back.append(render(marker.getType())).append(',');\r
+            back.append(render(marker.getColor())).append(',');\r
+            back.append(marker.getIndex()).append(',');\r
+            back.append(marker.getPoint()).append(',');\r
+            back.append(marker.getSize()).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(IRangeMarker[] markers) {\r
+        if (markers == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (IRangeMarker marker : markers) {\r
+            back.append(render(marker.getType())).append(',');\r
+            back.append(render(marker.getColor())).append(',');\r
+            back.append(0).append(',');\r
+            back.append(marker.getStart()).append(',');\r
+            back.append(marker.getEnd()).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(IFillArea[] areas) {\r
+        if (areas == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (IFillArea area : areas) {\r
+            back.append(render(area.getType())).append(',');\r
+            back.append(render(area.getColor())).append(',');\r
+            back.append(area.getStartIndex()).append(',');\r
+            back.append(area.getEndIndex()).append(',');\r
+            back.append(0).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    private CharSequence render(ILineStyle[] styles) {\r
+        if (styles == null) {\r
+            return null;\r
+        }\r
+\r
+        StringBuilder back = new StringBuilder();\r
+\r
+        for (ILineStyle style : styles) {\r
+            if (style == null) {\r
+                back.append('|');\r
+                continue;\r
+            }\r
+\r
+            back.append(style.getThickness()).append(',');\r
+            back.append(style.getSegmentLength()).append(',');\r
+            back.append(style.getBlankLength()).append('|');\r
+        }\r
+\r
+        if (back.length() > 0) {\r
+            back.setLength(back.length() - 1);\r
+        }\r
+\r
+        return back;\r
+    }\r
+\r
+    @Override\r
+    protected void onComponentTag(ComponentTag tag) {\r
+        checkComponentTag(tag, "img");\r
+        super.onComponentTag(tag);\r
+\r
+        tag.put("src", constructURL());\r
+    }\r
+}\r
diff --git a/src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java b/src/main/java/com/gitblit/wicket/charting/SecureChartDataEncoding.java
new file mode 100644 (file)
index 0000000..90a0596
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+ * Copyright 2007 Daniel Spiewak.\r
+ * Copyright 2013 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.charting;\r
+\r
+/**\r
+ * This class is a pristine fork of org.wicketstuff.googlecharts.ChartDataEncoding\r
+ * to bring the package-protected convert methods to SecureChart.\r
+ * \r
+ * @author Daniel Spiewak\r
+ */\r
+public enum SecureChartDataEncoding {\r
+\r
+    SIMPLE("s", "", ",") {\r
+\r
+        CharSequence convert(double value, double max) {\r
+            if (value < 0) {\r
+                return "_";\r
+            }\r
+\r
+            value = Math.round((CHARS.length() - 1) * value / max);\r
+\r
+            if (value > CHARS.length() - 1) {\r
+                throw new IllegalArgumentException(value + " is out of range for SIMPLE encoding");\r
+            }\r
+\r
+            return Character.toString(CHARS.charAt((int) value));\r
+        }\r
+    },\r
+    TEXT("t", ",", "|") {\r
+\r
+       CharSequence convert(double value, double max) {\r
+            if (value < 0) {\r
+                value = -1;\r
+            }\r
+\r
+            if (value > 100) {\r
+                throw new IllegalArgumentException(value + " is out of range for TEXT encoding");\r
+            }\r
+\r
+            return Double.toString(value);\r
+        }\r
+    },\r
+    EXTENDED("e", "", ",") {\r
+\r
+       CharSequence convert(double value, double max) {\r
+            if (value < 0) {\r
+                return "__";\r
+            }\r
+\r
+            value = Math.round(value);\r
+\r
+            if (value > (EXT_CHARS.length() - 1) * (EXT_CHARS.length() - 1)) {\r
+                throw new IllegalArgumentException(value + " is out of range for EXTENDED encoding");\r
+            }\r
+\r
+            int rem = (int) (value % EXT_CHARS.length());\r
+            int exp = (int) (value / EXT_CHARS.length());\r
+\r
+            return new StringBuilder().append(EXT_CHARS.charAt(exp)).append(EXT_CHARS.charAt(rem));\r
+        }\r
+    };\r
+    private static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";\r
+    private static final String EXT_CHARS = CHARS + "-_.";\r
+    private final String rendering, valueSeparator, setSeparator;\r
+\r
+    private SecureChartDataEncoding(String rendering, String valueSeparator, String setSeparator) {\r
+        this.rendering = rendering;\r
+        this.valueSeparator = valueSeparator;\r
+        this.setSeparator = setSeparator;\r
+    }\r
+\r
+    public String getRendering() {\r
+        return rendering;\r
+    }\r
+\r
+    public String getValueSeparator() {\r
+        return valueSeparator;\r
+    }\r
+\r
+    public String getSetSeparator() {\r
+        return setSeparator;\r
+    }\r
+\r
+    abstract CharSequence convert(double value, double max);\r
+}\r
index ce75f537f7bbfb545bdbeb33f1ce27bf444f15e7..3195020df6cb30e7983e4b8bfbd4f2edcd5dcbef 100644 (file)
@@ -28,7 +28,6 @@ import java.util.List;
 import org.apache.wicket.PageParameters;\r
 import org.apache.wicket.markup.html.basic.Label;\r
 import org.eclipse.jgit.lib.Repository;\r
-import org.wicketstuff.googlecharts.Chart;\r
 import org.wicketstuff.googlecharts.ChartAxis;\r
 import org.wicketstuff.googlecharts.ChartAxisType;\r
 import org.wicketstuff.googlecharts.ChartProvider;\r
@@ -42,6 +41,7 @@ import com.gitblit.models.Metric;
 import com.gitblit.utils.MetricUtils;\r
 import com.gitblit.utils.StringUtils;\r
 import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.charting.SecureChart;\r
 \r
 public class MetricsPage extends RepositoryPage {\r
 \r
@@ -87,7 +87,7 @@ public class MetricsPage extends RepositoryPage {
                        provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) });\r
                        provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.decode("#002060"), 1, -1, 5));\r
 \r
-                       add(new Chart(wicketId, provider));\r
+                       add(new SecureChart(wicketId, provider));\r
                } else {\r
                        add(WicketUtils.newBlankImage(wicketId));\r
                }\r
@@ -112,7 +112,7 @@ public class MetricsPage extends RepositoryPage {
                                        String.valueOf((int) WicketUtils.maxValue(metrics)) });\r
                        provider.addAxis(commitAxis);\r
 \r
-                       add(new Chart(wicketId, provider));\r
+                       add(new SecureChart(wicketId, provider));\r
                } else {\r
                        add(WicketUtils.newBlankImage(wicketId));\r
                }\r
@@ -127,7 +127,7 @@ public class MetricsPage extends RepositoryPage {
                        }\r
                        ChartProvider provider = new ChartProvider(new Dimension(800, 200), ChartType.PIE, data);\r
                        provider.setPieLabels(labels.toArray(new String[labels.size()]));\r
-                       add(new Chart(wicketId, provider));\r
+                       add(new SecureChart(wicketId, provider));\r
                } else {\r
                        add(WicketUtils.newBlankImage(wicketId));\r
                }\r
index 19346826ffafcf891288657eb05917764710a1ff..1afa967a1140b8af3e0a00d5226da9cfb64d77d0 100644 (file)
@@ -32,7 +32,6 @@ import org.apache.wicket.markup.repeater.data.DataView;
 import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
 import org.eclipse.jgit.lib.Repository;\r
 import org.eclipse.jgit.revwalk.RevCommit;\r
-import org.wicketstuff.googlecharts.Chart;\r
 import org.wicketstuff.googlecharts.ChartAxis;\r
 import org.wicketstuff.googlecharts.ChartAxisType;\r
 import org.wicketstuff.googlecharts.ChartProvider;\r
@@ -53,6 +52,7 @@ import com.gitblit.utils.MarkdownUtils;
 import com.gitblit.utils.StringUtils;\r
 import com.gitblit.wicket.GitBlitWebSession;\r
 import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.charting.SecureChart;\r
 import com.gitblit.wicket.panels.BranchesPanel;\r
 import com.gitblit.wicket.panels.LinkPanel;\r
 import com.gitblit.wicket.panels.LogPanel;\r
@@ -204,7 +204,7 @@ public class SummaryPage extends RepositoryPage {
                        provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) });\r
                        provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.decode("#002060"), 1, -1, 5));\r
 \r
-                       add(new Chart("commitsChart", provider));\r
+                       add(new SecureChart("commitsChart", provider));\r
                } else {\r
                        add(WicketUtils.newBlankImage("commitsChart"));\r
                }\r