There are several kind of plugins:
To add your own Gauge you have two main solutions:
What is GaugeFactory designed for? Imagine a custom gauge is parameterized. You’ll surely want to register it several times with different parameters. If you use Gauge SPI you’ll need to do N implementations (which makes the parameters useless). With GaugeFactory you just need to return the built instances:
public class MyGaugeFactory implements GaugeFactory { @Override public Gauge[] gauges() { return new Gauge[] { new MyGauge(1); new MyGauge(2); }; } }
To extend the reporting GUI just write your own org.apache.sirona.reporting.web.plugin.api.Plugin. Here too it relies on java ServiceLoader (SPI) mecanism.
Here is the Plugin interface:
public interface Plugin { String name(); Class<?> endpoints(); String mapping(); }
A plugin has basically a name (what will identify it in the webapp and in the GUI - it will be the name of the plugin tab), a mapping, ie which base subcontext it will use for its own pages (for instance /jmx, /myplugin …) and a class representing endpoints.
To make it more concrete we’ll use a sample (the standard Hello World).
So first we define our HelloPlugin:
public class HelloPlugin implements Plugin { public String name() { return "Hello"; } public Class<?> endpoints() { return HelloEndpoints.class; } public String mapping() { return "/hello"; } }
The HelloEndpoints class defines all the urls accessible for the hello plugin. It uses the org.apache.sirona.reporting.web.plugin.api.Regex annotation:
public class HelloEndpoints { @Regex // will match "/hello" public Template home() { return new Template("hello/home.vm", new MapBuilder<String, Object>().set("name", "world).build()); } @Regex("/world/([0-9]*)/([0-9]*)") // will match "/hello/world/1/2" public String jsonWorld(final long start, final long end) { return "{ \"name\": \world\", \"start\":\"" + long1 + "\",\"end\":\"" + long2 + "\"}"; } }
The first home method uses a template. The GUI relies on velocity and html templates needs to be in the classloader in templates directory.
So basically the home method will search for templates/hello/home.vm velocity template. It is only the “main” part of the GUI (the tabs are automatically added). Twitter bootstrap (3.0.0) and JQuery (2.0.3) are available.
Here is a sample:
<h1>Hello</h1> <div> Welcome to $name </div>
If you need resources put them in the classloader too in “resources” folder.
Note: if you want to do links in the template you can use $mapping variable as base context of your link. For instance: >a href=“$mapping/foo”<Foo>/a<.
If you want to filter some resources you can add a custom endpoint:
@Regex("/resources/myresource.css") public void filterCss(final TemplateHelper helper) { helper.renderPlain("/resources/myresource.css"); }
@Regex allows you to get injected path segments, here is what is handled:
For instance @Regex("/operation/([^/]*)/([^/]*)/(.*)") will match foo(String, String, String[]). If the url is /operation/a/b/c/d/e you’ll get foo("a", "b", { "c", "d", "e" }).