Level of experience: Beginner
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'beginner' level, so you can follow it even if you have never developed a plugin or gadget before.
This tutorial shows you how to write a gadget that lists the most recent changes which have been committed to the repositories monitored by a Fisheye instance.
After completing this tutorial you will know how to:
Your gadget will be a 'plugin' gadget. That means that it will be embedded within an Atlassian plugin. The plugin will consist of the following parts:
All these components will be contained within a single JAR file. We will discuss each component in the examples below.
If you are interested, you can compare standalone gadgets and gadgets embedded in plugins.
Use the appropriate atlas-create-
application
-plugin
command to create your plugin. For example, atlas-create-jira-plugin
or atlas-create-confluence-plugin
.
When you run atlas-create-fecru-plugin
you'll be asked to supply a groupId
and an artifactId
- use com.atlassian.tutorial.fisheye
and recentchangesgadget
respectively. When you create a plugin of your own, you should use a groupId
based on your company's domain.
You need to make sure that your project is using Fisheye 2.2.0 or later. Edit your pom.xml
and set the fecru.version
property to the build number of the version of Fisheye you want to use, e.g.:
1 2<properties> <fecru.version>2.2.0-465</fecru.version> ... </properties>
pom.xml
Here are the parts of pom.xml
which you may wish to change:
1 2... <organization> <name>Example Company</name> <url>http://www.example.com/</url> </organization> ... <description>This is the com.atlassian.tutorial.fisheye:recentchangesgadget plugin for Atlassian Fisheye/Crucible.</description> ...
You should change the organization
name
and url
attributes to those of your company, and the description
to a description of your plugin.
These values are copied to your atlassian-plugin.xml
plugin descriptor file, and are displayed on the plugin administration page of Fisheye when your plugin is loaded.
Here is a basic gadget specification using the Atlassian Gadgets JavaScript Framework:
1 2<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="Recent Changes" directory_title="Recent Changes" description="Recent Changes in Fisheye repositories"> <Require feature="dynamic-height" /> <Optional feature="auth-refresh"/> <Require feature="setprefs" /> <Require feature="settitle" /> <Require feature="views" /> <Optional feature="atlassian.util" /> <Optional feature="gadget-directory"> <Param name="categories">FishEye</Param> </Optional> </ModulePrefs> <Content type="html"> <![CDATA[ <!-- The #-directive below will include all required JavaScript and CSS resources needed to use the Atlassian Gadgets JavaScript Framework. --> #requireResource("com.atlassian.gadgets.publisher:ajs-gadgets") #includeResources() <script type="text/javascript"> (function () { /* (2) Construct and initialise the gadget */ var gadget = AJS.Gadget({ baseUrl: "__ATLASSIAN_BASE_URL__", /* (3) Used to make the application's base URL available to the gadget */ view: { /* (4) Defines the view logic and initialises the view */ enableReload: true, onResizeReload: false, onResizeAdjustHeight: true, template: function (args) { this.getView().html("<div>Hello World</div>"); }, args: [] } }); })(); </script> ]]> </Content> </Module>
Copy the XML code from the above gadget specification and put it in a new file named gadget.xml
in the src/main/resources
directory.
Add the <gadget>
the plugin module to your plugin descriptor, atlassian-plugin.xml
.
1 2<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.artifactId}" plugins-version="2"> <plugin-info> <description>${project.description}</description> <version>${project.version}</version> <vendor name="${project.organization.name}" url="${project.organization.url}" /> </plugin-info> <gadget key="gadget" location="gadget.xml"/> </atlassian-plugin>
Follow these steps to build and install your plugin, so that you can test your code. If you have not already started the application, start it now:
pom.xml
is located).atlas-run
(or atlas-debug
if you might want to launch the debugger in your IDE).From this point onwards, you can use QuickReload to reinstall your plugin behind the scenes as you work, simply by rebuilding your plugin.
FastDev and atlas-cli have been deprecated. Please use Automatic Plugin Reinstallation with QuickReload instead.
1 2To trigger the reinstallation of your plugin: 1. Make the changes to your plugin module. 2. Open the Developer Toolbar. <img src="/server/fisheye-crucible/images/fastdev1.png" width="600" /> 3. Press the FastDev icon. <img src="/server/fisheye-crucible/images/fastdev2.png" width="600" /> The system rebuilds and reloads your plugin: <img src="/server/fisheye-crucible/images/fastdev3.png" width="600" /> Use live reload to view real-time updates to templates and other resources: 1. Open the Developer Toolbar. 2. Press the live reload icon. The icon starts to revolve indicating it is on. 3. Edit your project resources. 4. Save your changes: Back in the host application, your plugin displays any user visible changes you make. Go back to the browser. The updated plugin has been installed into the application, and you can test your changes. The full instructions are in the [SDK guide](https://developer.atlassian.com/display/DOCS/Working+with+the+SDK).
The gadget you are creating in this tutorial will be 'served' by a Fisheye instance, but 'hosted' on a JIRA dashboard. That is, the HTTP requests which serve the plugin descriptor you created above, and the plugin's data and resources will go to a Fisheye instance in which the plugin is installed, but the gadget will be displayed on a JIRA dashboard.
You will need an instance of JIRA on which you have administrative privileges. This JIRA instance must also be able to 'see' the Fisheye instance serving the plugin. A JIRA instance outside your firewall will not be able to see a Fisheye instance running on your desktop development machine without special network configuration, for instance.
To add the plugin you will need to:
Start up your Fisheye instance with the plugin SDK command atlas-run
. This builds your plugin and starts a Fisheye instance with the plugin installed in it.
Go to localhost:3990/fecru/admin/viewplugins.do and check that your plugin has loaded successfully. You should see this:
Add the plugin to your JIRA dashboard:
Log in as an administrator.
Select Tools, Create Dashboard... and create a new, blank dashboard.
When your new dashboard displays, click 'add a new gadget'
Click the 'Add Gadget to Directory' button and type gadget.xml and click 'Add Gadget'.
Your gadget will appear highlighted in yellow. Clock the 'Add it Now' button, and then the 'Finished' button.
You should see a new gadget containing the text 'Hello World' appear on your dashboard.
If you see the error message Error loading gadget: org.apache.shindig.gadgets.GadgetException: Unable to retrieve gadget xml. HTTP error 504
try stopping and starting JIRA.
JIRA sometimes caches your gadget, so you'll need to restart JIRA when you change your gadget.xml
file, otherwise you won't see your changes.
Now you will write the JavaScript and HTML code to retrieve recent changes data from Fisheye and display the information in the gadget. As you can see below, using the built-in REST interfaces of Fisheye to retrieve the information we want for this gadget involves many REST calls. If this did not perform satisfactorily you would need to consider writing your own REST endpoint to retrieve exactly the data you need in a single call. See this REST Service Plugin Module tutorial for an example of creating your own REST endpoint.
Because your gadget is embedded in a plugin, you can use the Atlassian Gadgets JavaScript Framework in addition to the OpenSocial JavaScript API.
We are going to build up the HTML displayed in the gadget as we go, so first we will remove its contents:
1 2var gadget = this; gadget.getView().html("<div class='main'><h1>Recent Changesets</h1></div>");
gadget.getView()
returns a jQuery object representing the body of the Gadget. We replace any existing contents with a div
which will contain all our content, and a h1
containing our heading.
First the gadget retrieves a list of all the repositories in the Fisheye instance.
1 2... var reportError = function(request, textStatus, errorThrown) { console.log("Request:"); console.log(request); console.log("TextStatus:"); console.log(textStatus); console.log("ErrorThrown:"); console.log(errorThrown); }; ... AJS.$.ajax({ url: "/rest-service-fe/repositories-v1", type: "GET", dataType: "xml", success: function(msg){ AJS.$(msg).find('repository').each(function() { var name = AJS.$(this).attr('name'); loadChangesetsForRepo(name); }); }, error: reportError // this function just dumps the error to the FireBug console }); ...
Some things to notice in the code above:
AJS
, so the jQuery $
function name becomes AJS.$
.reportError
function uses the Firebug console
to report errors.loadChangesetsForRepo
function, which we will write in the next step.Now we make another REST call for each repository, getting the recent changesets from the repository:
1 2... var loadChangesetsForRepo = function(repoName, repoDiv) { var repoDiv = AJS.$("<div class='repo'><h2>" + repoName + "</h2></div>"); gadget.getView().find("div.main").append(repoDiv); AJS.$.ajax({ url: "/rest-service-fe/revisionData-v1/changesetList/" + repoName + "?maxReturn=10", type: "GET", dataType: "xml", success: function(msg){ AJS.$(msg).find('csid').each(function() { var csid = AJS.$(this).text(); addChangesetData(repoName, csid, repoDiv) }); }, error: reportError }); }; ...
jQuery
to create a div
to hold the changesets from this repository. The div is added as a child element to the div
with the class
main
which was created at the start.jQuery
to find each csid
element in the XML response. Each csid
value is passed to the addChangesetData
function to load the details for that changeset.For each changeset, we make a REST call to get its details - in this tutorial we only display the id and the comment.
1 2... var addChangesetData = function(repoName, csid, repoDiv) { AJS.$.ajax({ url: "/rest-service-fe/revisionData-v1/changeset/" + repoName + "/" + csid, type: "GET", dataType: "xml", success: function(msg){ console.log(AJS.$(msg).find("comment")); var comment = AJS.$(msg).find("comment").text(); repoDiv.append("<div class='changeset'>" + csid + ": " + comment + "</div>"); }, error: reportError }); }; ...
Follow these steps to build and install your plugin, so that you can test your code. If you have not already started the application, start it now:
pom.xml
is located).atlas-run
(or atlas-debug
if you might want to launch the debugger in your IDE).From this point onwards, you can use QuickReload to reinstall your plugin behind the scenes as you work, simply by rebuilding your plugin.
FastDev and atlas-cli have been deprecated. Please use Automatic Plugin Reinstallation with QuickReload instead.
To trigger the reinstallation of your plugin:
Use live reload to view real-time updates to templates and other resources:
Open the Developer Toolbar.
Press the live reload icon. The icon starts to revolve indicating it is on.
Edit your project resources.
Save your changes:
Back in the host application, your plugin displays any user visible changes you make.
Go back to the browser. The updated plugin has been installed into the application, and you can test your changes.
The full instructions are in the SDK guide.
Congratulations, that's it
Your gadget is complete. Have a chocolate!
Rate this page: