Index: xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/graphviz/GraphVizMacro.java
===================================================================
--- xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/graphviz/GraphVizMacro.java (revision 11289)
+++ xwiki-platform-core/xwiki-core/src/main/java/com/xpn/xwiki/plugin/graphviz/GraphVizMacro.java (working copy)
@@ -23,6 +23,9 @@
import java.io.IOException;
import java.io.Writer;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.radeox.api.engine.RenderEngine;
import org.radeox.api.engine.context.RenderContext;
@@ -33,49 +36,175 @@
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.render.XWikiRadeoxRenderEngine;
-public class GraphVizMacro extends BaseLocaleMacro
-{
- public String getLocaleKey()
- {
- return "macro.graphviz";
- }
+/**
+ *
+ * Macro used to invoke GraphViz and render its output on a XWiki page.
+ *
+ *
+ * For it to work properly, you must have the GraphViz plugin enabled and
+ * configured.
+ *
+ *
+ * The content of the macro is the source code for the graph, using GraphViz DOT language.
+ *
+ * The parameters are as follows:
+ *
+ * - type: [dot] or neato. Specifies which engine will be used to
+ * produce the graph.
+ * - text: Text attribute for the image (floating text box when you
+ * hover it). Do not specify it if you want to use GraphViz tooltip
+ * attribute. With the tooltip attributes you can generate different text
+ * values for different regions of the image.
+ * - height: Image height in pixels.
+ * - width: Image width in pixels.
+ * - alt: Alternative text (alt attribute) for the image, in case it
+ * cannot be rendered by the browser.
+ * - format: This attribute specifies what will be GraphViz output
+ * and also how it will be rendered in the HTML.
The HTML output of the
+ * macro will be one of the following, depending on this attribute:
+ *
+ * - EMBED html tag for: svg, svgz.
+ * - The text as output by GraphViz for: canon, dot, xdot, imap, cmapx,
+ * imap_np, cmpax_np, plain, plain-ext. Remember that for some of these formats,
+ * like cmpax and cmapx_np, the text will actually be HTML code.
+ * - IMG html tag for anything else. Caution: Not all formats supported by
+ * GraphViz can be referenced by an IMG tag. Depending on the format you
+ * choose this macro may not produce a valid result.
+ *
+ *
+ * - clickable: If present and not false indicates that the IMG tag
+ * must reference the link map produced by GraphViz ("cmapx" format). This
+ * parameter will have no effect if format specifies anything different
+ * from an IMG tag to be rendered - what doesn't mean you can't have clickable
+ * SVG images, you just don't need an extra map tag for that.
+ *
+ *
+ */
+public class GraphVizMacro extends BaseLocaleMacro {
+ public String getLocaleKey() {
+ return "macro.graphviz";
+ }
- @Override
- public void execute(Writer writer, MacroParameter params) throws IllegalArgumentException, IOException
- {
+ @Override
+ public void execute(Writer writer, MacroParameter params)
+ throws IllegalArgumentException, IOException {
- RenderContext context = params.getContext();
- RenderEngine engine = context.getRenderEngine();
+ RenderContext context = params.getContext();
+ RenderEngine engine = context.getRenderEngine();
- XWikiContext xcontext = ((XWikiRadeoxRenderEngine) engine).getXWikiContext();
- XWiki xwiki = xcontext.getWiki();
+ XWikiContext xcontext = ((XWikiRadeoxRenderEngine) engine)
+ .getXWikiContext();
+ XWiki xwiki = xcontext.getWiki();
- GraphVizPlugin plugin = (GraphVizPlugin) xwiki.getPlugin("graphviz", xcontext);
- // If the plugin is not loaded
- if (plugin == null) {
- writer.write("Plugin not loaded");
- return;
- }
+ GraphVizPlugin plugin = (GraphVizPlugin) xwiki.getPlugin("graphviz",
+ xcontext);
+ // If the plugin is not loaded
+ if (plugin == null) {
+ writer.write("Plugin not loaded");
+ return;
+ }
- boolean dot = !("neato").equals(params.get("type"));
- StringBuffer str = new StringBuffer();
- String img = params.get("text", 0);
- String height = params.get("height", 1);
- String width = params.get("width", 2);
+ boolean dot = !("neato").equals(params.get("type"));
+ String text = nullifyBadParameter(params.get("text", 0));
+ String height = nullifyBadParameter(params.get("height", 1));
+ String width = nullifyBadParameter(params.get("width", 2));
+ String alt = nullifyBadParameter(params.get("alt", 3));
+ String format = nullifyBadParameter(params.get("format", 4));
+ if (format == null)
+ format = "png";
+ String clickableStr = nullifyBadParameter(params.get("clickable", 5));
+ boolean clickable = clickableStr != null
+ && !"false".equals(clickableStr);
+ String dottext = params.getContent();
- String dottext = params.getContent();
- str.append("");
- writer.write(str.toString());
- }
+ /* please KEEP THE ARRAYS SORTED */
+ final String[] embedTagFormats = new String[] { "svg", "svgz" };
+ final String[] plainTextFormats = new String[] { "canon", "cmapx",
+ "cmapx_np", "dot", "imap", "imap_np", "plain", "plain-ext",
+ "xdot" };
+
+ if (Arrays.binarySearch(plainTextFormats, format) >= 0) {
+ /* producing plain text output */
+ byte[] graphvizOutput = plugin.getDotImage(dottext, format, dot);
+ writer.write(new String(graphvizOutput));
+ } else if (Arrays.binarySearch(embedTagFormats, format) >= 0) {
+ /* producing embed tag output */
+ writer.write("