SlideShare ist ein Scribd-Unternehmen logo
1 von 56
Downloaden Sie, um offline zu lesen
Understanding the Atlassian Platform
Tim Pettersen, Atlassian
Atlassian
Plugin
Development
Platform
Targeted at You!
Features
Dedicated Team
Documentation
Focus on Backwards
Compatibility
Overview...
Atlassian
Plugin
DEMO
src - http://bit.ly/hovers-svn
Have you ever?
... needed to communicate with a remote
application?
... wanted an easy way to provide JSON data for
an AJAXy UI?
... wanted to expose your plugin's data via web
services?
REST
Atlassian
Plugin
Depending on REST ...
<dependency>
<groupId>com.atlassian.plugins.rest</groupId>
<artifactId>atlassian-rest-common</artifactId>
<version>${rest.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugins.rest</groupId>
<artifactId>atlassian-rest-module</artifactId>
<version>${rest.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
Atlassian annotations & utilities
JAX-RS annotations & jersey
JAXB annotations
Quick departure - versioning
Easy - Dependency Management POM
Custom - Specify versions per module
more info: http://bit.ly/platform-versions
Depending on REST ...
<atlassian-plugin>
<rest
key="some-key"
path="/some-path"
version="1.0"
description="Initialise REST resources for my plugin" />
<component-import
key="restUrlBuilder"
interface="com.atlassian.plugins.rest.common.util.RestUrlBuilder" />
</atlassian-plugin>
http://jira.atlassian.com/REST/some-path/1.0/
Using REST ... creating a resource
@Path("/hello/")
@Consumes(APPLICATION_XML, APPLICATION_JSON)
@Produces(APPLICATION_XML, APPLICATION_JSON)
public class MyResource {
@Path("/my-name-is/{name}")
@GET
@AnonymousAllowed
public Response hello(@PathParam("name") String name) {
return ok(
new MessageEntity("Hello, " + name + "!")
);
}
}
http://.../REST/some-path/1.0/hello
http://.../REST/some-path/1.0/hello/my-name-is/tim
Using REST ... creating an entity
@XmlAccessorType(FIELD)
@XmlRootElement(name = "message")
public class MessageEntity {
private String body;
public MessageEntity(String body) {
this.body = body;
}
}
http://.../REST/some-path/1.0/hello/my-name-is/Tim.xml
<message>
<body>Hello, Tim!</body>
</message>
http://.../REST/some-path/1.0/hello/my-name-is/Tim.json
{body:"Hello, world!"}
Poster: http://bit.ly/poster-ff
Using REST ... generating a resource URL
public class MyClient {
public void doGet() {
String baseUrl = "http://jira.atlassian.com";
String restUrl = restUrlBuilder
.getUrlFor(baseUrl, MyResource.class)
.hello("Tim")
.toString();
...
}
}
// generated restUrl = "http://.../REST/some-path/1.0/hello/my-name-is/Tim"
Using REST ... unmarshalling an entity
Request request = requestFactory
.createRequest(MethodType.GET, restUrl);
request.execute(new ResponseHandler<Response>() {
public void handle(Response response) {
if (response.isSuccessful()) {
}
}
});
// unmarshall the entity
MessageEntity m = response.getEntity(MessageEntity.class);
Using REST ... marshalling an entity
Request request = requestFactory.createRequest(PUT, restUrl);
MessageEntity entity = new MessageEntity("some-value");
request.setEntity(entity);
request.execute();
@PUT
public Response submit(MessageEntity message) {
System.out.println("Received: " + message.getBody());
}
Client
Server
Have you ever?
... wanted to launch a modal dialog from your
plugin?
... wanted to add rich tooltips to your content?
... wished someone else would write your CSS
and javascript for you?
... wanted your plugin to look and behave a little
bit more like the host application?
User Interface
Atlassian
Plugin
Depending on AUI ...
public class MyServlet extends HttpServlet {
public void doGet() {
webResourceManager
.requireResource("com.atlassian.auiplugin:ajs");
}
}
<html>
<head>
#webResourceManager.getRequiredResources()
</head>
<body ... />
</html>
Depending on AUI ...
<atlassian-plugin>
<web-resource key="some-web-resource">
<resource name="my-script.js" ... />
<resource name="my-styles.css" ... />
<dependency>com.atlassian.auiplugin:ajs</dependency>
</web-resource>
</atlassian-plugin>
public class MyServlet extends HttpServlet {
public void doGet() {
webResourceManager
.requireResource("com.my.plugin:some-web-resource");
}
}
Using AUI ... dropdowns
Using AUI ... dropdowns
<script type="text/javascript">
// create drop-down
AJS.$("#my-dropdown")
.dropDown("standard", {alignment: "right"});
</script>
<!-- the list to display as a dropdown -->
<ul id="my-dropdown">
<li class="paper-clip">Item One</li>
<li class="clock">Item Two</li>
<li class="envelope">Item Three</li>
</ul>
Using AUI ... tooltips
Using AUI ... tooltips
<script type="text/javascript">
// assign URL for retrieving AJAX content
var contentUrl = AJS.params.baseUrl + "/rest/myplugin/1.0/tooltip";
// bind hovers to DOM elements
AJS.InlineDialog(".tooltip-link", "tooltip", contentUrl, {
onHover: true,
width: 300,
cacheContent: true
});
</script>
<!-- an anchor that the tooltip will be applied to -->
<a class='.hover-link'>Hover over me!</a>
Using AUI ... more!
Have you ever?
... wanted to include a piece of javascript or CSS
on every page in Confluence?
... wanted to make your plugin, pluggable?
... wanted to build a single plugin that can be
deployed in multiple applications?
Plugins Framework
Atlassian
Depending on plugins ...
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-webresource</artifactId>
<version>${atlassian.plugins.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-core</artifactId>
<version>${atlassian.plugins.version}</version>
<scope>provided</scope>
</dependency>
<atlassian-plugin>
<!-- Unnecessary! -->
<component-import ... />
</atlassian-plugin>
Using plugins ... web-resource contexts
<atlassian-plugin>
<web-resource key="some-web-resource">
<context>atl.general</context>
<resource name="my-script.js" ... />
<resource name="my-styles.css" ... />
</web-resource>
</atlassian-plugin>
atl.general
atl.admin
atl.userprofile
Custom Plugin Modules
Using plugins ... custom module types
public class MyDescriptor extends AbstractModuleDescriptor<MyModule> {
public void init(Plugin plugin, Element element);
public MyModule getModule() {
// initialize the module specified by the descriptor's class attribute
return moduleFactory.createModule(moduleClassName, this);
}
}
<atlassian-plugin>
<module-type key="my-descriptor"
class="com.myplugin.MyDescriptor" />
<my-descriptor class="com.myplugin.ModuleOne" />
<my-descriptor class="com.myplugin.ModuleTwo" />
</atlassian-plugin>
Using plugins ... custom module types
public class MyService {
private PluginAccessor pluginAccessor;
public MyService(PluginAccessor pluginAccessor) {
this.pluginAccessor = pluginAccessor;
}
public void executeInstalledModules() {
for (MyModule module :
pluginAccessor.getEnabledModulesByClass(MyModule.class)) {
module.execute();
}
}
}
Using plugins ... descriptor application scopes
<atlassian-plugin>
<web-resource key="some-web-resource" application="confluence">
<context>atl.general</context>
<resource name="page-integration.js" ... />
</web-resource>
<web-resource key="some-web-resource" application="jira">
<context>atl.general</context>
<resource name="issue-integration.js" ... />
</web-resource>
<!-- depends on Confluence's API -->
<component key="some-component" application="confluence"
class="com.myplugin.PageHandler" />
<!-- depends on JIRA's API -->
<component key="some-component" application="jira"
class="com.myplugin.IssueHandler" />
</atlassian-plugin>
Have you ever?
... needed to render HTML outside of a JIRA or
Confluence action?
... needed to pass back rendered HTML to use
in an AJAX UI?
... wished you could use something a little more
modern than Velocity 1.4 in JIRA?
Template Renderer
Atlassian
Depending on ATR ...
<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<version>${template.renderer.version}</version>
<scope>provided</scope>
</dependency>
<atlassian-plugin>
<component-import key="templateRenderer"
interface="com.atlassian.templaterenderer.TemplateRenderer" />
</atlassian-plugin>
Using ATR ...
public class MyServlet extends HttpServlet {
private TemplateRenderer templateRenderer; // constructor-injected
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
Map<String, Object> context = createContext();
templateRenderer.render("templates/view.vm", context,
resp.getWriter()
);
}
}
Have you ever?
... needed to persist some simple data for your
plugin?
... wanted to i18n your plugin?
... needed to write an upgrade task?
... wanted to schedule a recurring job?
Shared Application Layer
Atlassian
Plugin
Depending on SAL ...
<dependency>
<groupId>com.atlassian.sal</groupId>
<artifactId>sal-api</artifactId>
<version>${sal.version}</version>
<scope>provided</scope>
</dependency>
Depending on SAL ...
<atlassian-plugin>
<component-import
key="[someSalComponent]"
interface="com.atlassian.sal.api.[someSalComponent]" />
</atlassian-plugin>
AuthenticationControlle
r
LoginUriProvider
ComponentLocator
I18nResolver
LocaleResolver
RequestFactory
SearchProvider
PluginUpgradeManage
r
UserManager
ApplicationProperties
PluginSettingsFactory
ProjectManager
PluginScheduler
More!
Using SAL ... upgrade tasks
public interface PluginUpgradeTask {
int getNumber();
String getShortDescription();
Collection<Message> doUpgrade();
String getPluginKey();
}
<atlassian-plugin>
<component key="my-upgrade-task" public="true"
class="com.myplugin.MyUpgradeTask">
<interface>com.atlassian.sal.api.upgrade.PluginUpgradeTask</interface>
</component>
</atlassian-plugin>
Using SAL ... i18n
<atlassian-plugin>
<component-import
key="i18nResolver"
interface="com.atlassian.sal.api.message.I18nResolver" />
<resource key="my-i18n" type="i18n" location="i18n" />
</atlassian-plugin>
hello.world = Hello World! (i18n.properties)
hello.world: Hola a todos! (i18n_es.properties)
hello.world Hallo Welt! (i18n_de.properties)
Using SAL ... i18n
Map<String, Object> context = new HashMap<String, Object>();
context.put("i18n", i18nResolver);
templateRenderer.render("templates/view.vm", context, writer);
<html>
<head>
<title>#i18n.getText('hello.world')</title>
</head>
<body ... />
</html>
Using SAL ... job scheduling
// simple very-contrived job
public class MyPluginJob implements PluginJob {
public void execute(Map<String, Object> data) {
int count = data.get("jobExecutionCount");
count++;
data.put("jobExecutionCount", count);
}
}
Using SAL ... job scheduling
public class MyComponent implements LifecycleAware {
private PluginScheduler scheduler; // autowired
public void onStart() {
scheduler.scheduleJob(
"my-plugin-job",
MyPluginJob.class,
new HashMap<String, Object>(),
new Date(),
10000 // milliseconds
);
}
}
Targeted at You!
Features
Dedicated Team
Documentation
Backwards Compatibility
Open Source :D
Go use it!
Shared Application Layer
Unified Application Links
Template Renderer
Plugins Framework
Atlassian User Interface
REST
Questions?
more info - http://bit.ly/best-thing-ever

Weitere ähnliche Inhalte

Was ist angesagt?

Templates
TemplatesTemplates
Templates
soon
 
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
Tieturi Oy
 
【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践
taobao.com
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Masashi Shibata
 
Simple blog wall creation on Java
Simple blog wall creation on JavaSimple blog wall creation on Java
Simple blog wall creation on Java
Max Titov
 

Was ist angesagt? (20)

Templates
TemplatesTemplates
Templates
 
Different way to share data between controllers in angular js
Different way to share data between controllers in angular jsDifferent way to share data between controllers in angular js
Different way to share data between controllers in angular js
 
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5TechDays 2013 Jari Kallonen: What's New WebForms 4.5
TechDays 2013 Jari Kallonen: What's New WebForms 4.5
 
Why You Should be Using Web Components Right Now. And How. ForwardJS July 2015
Why You Should be Using Web Components Right Now. And How. ForwardJS July 2015Why You Should be Using Web Components Right Now. And How. ForwardJS July 2015
Why You Should be Using Web Components Right Now. And How. ForwardJS July 2015
 
【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践
 
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
 
Mobile themes, QR codes, and shortURLs
Mobile themes, QR codes, and shortURLsMobile themes, QR codes, and shortURLs
Mobile themes, QR codes, and shortURLs
 
More Than You Ever Wanted to Know About Resource Hints - Harry Roberts (CSS W...
More Than You Ever Wanted to Know About Resource Hints - Harry Roberts (CSS W...More Than You Ever Wanted to Know About Resource Hints - Harry Roberts (CSS W...
More Than You Ever Wanted to Know About Resource Hints - Harry Roberts (CSS W...
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
 
Java Web Programming on Google Cloud Platform [2/3] : Datastore
Java Web Programming on Google Cloud Platform [2/3] : DatastoreJava Web Programming on Google Cloud Platform [2/3] : Datastore
Java Web Programming on Google Cloud Platform [2/3] : Datastore
 
Trustparency web doc spring 2.5 & hibernate
Trustparency web doc   spring 2.5 & hibernateTrustparency web doc   spring 2.5 & hibernate
Trustparency web doc spring 2.5 & hibernate
 
Securing Java EE apps using WildFly Elytron
Securing Java EE apps using WildFly ElytronSecuring Java EE apps using WildFly Elytron
Securing Java EE apps using WildFly Elytron
 
Javascript Frameworks for Well Architected, Immersive Web Apps
Javascript Frameworks for Well Architected, Immersive Web AppsJavascript Frameworks for Well Architected, Immersive Web Apps
Javascript Frameworks for Well Architected, Immersive Web Apps
 
AspNetWhitePaper
AspNetWhitePaperAspNetWhitePaper
AspNetWhitePaper
 
4. jsp
4. jsp4. jsp
4. jsp
 
jQuery Mobile: Progressive Enhancement with HTML5
jQuery Mobile: Progressive Enhancement with HTML5jQuery Mobile: Progressive Enhancement with HTML5
jQuery Mobile: Progressive Enhancement with HTML5
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django application
 
Simple blog wall creation on Java
Simple blog wall creation on JavaSimple blog wall creation on Java
Simple blog wall creation on Java
 
Ajax Rails
Ajax RailsAjax Rails
Ajax Rails
 
WebGUI Developers Workshop
WebGUI Developers WorkshopWebGUI Developers Workshop
WebGUI Developers Workshop
 

Andere mochten auch

Project Management With Atlassian Confluence
Project Management With Atlassian ConfluenceProject Management With Atlassian Confluence
Project Management With Atlassian Confluence
Telekom MMS
 

Andere mochten auch (18)

Atlassian Overview
Atlassian OverviewAtlassian Overview
Atlassian Overview
 
Introduction to Force.com
Introduction to Force.comIntroduction to Force.com
Introduction to Force.com
 
JIRA Introduction | JIRA Tutorial | Atlassian JIRA Training | H2kinfosys
JIRA Introduction | JIRA Tutorial | Atlassian JIRA Training | H2kinfosysJIRA Introduction | JIRA Tutorial | Atlassian JIRA Training | H2kinfosys
JIRA Introduction | JIRA Tutorial | Atlassian JIRA Training | H2kinfosys
 
Dreamforce'12 - Automate Business Processes with Force.com
Dreamforce'12 - Automate Business Processes with Force.comDreamforce'12 - Automate Business Processes with Force.com
Dreamforce'12 - Automate Business Processes with Force.com
 
Architecting Composite Applications With Force.com and Heroku
Architecting Composite Applications With Force.com and HerokuArchitecting Composite Applications With Force.com and Heroku
Architecting Composite Applications With Force.com and Heroku
 
Cloud Computing in Practice: Fast Application Development and Delivery on For...
Cloud Computing in Practice: Fast Application Development and Delivery on For...Cloud Computing in Practice: Fast Application Development and Delivery on For...
Cloud Computing in Practice: Fast Application Development and Delivery on For...
 
What you need to know on Force.com in 10 slides
What you need to know on Force.com in 10 slidesWhat you need to know on Force.com in 10 slides
What you need to know on Force.com in 10 slides
 
Intro to Force.com Webinar presentation
Intro to Force.com Webinar presentationIntro to Force.com Webinar presentation
Intro to Force.com Webinar presentation
 
Force.com Canvas - a Quick Introduction
Force.com Canvas - a Quick IntroductionForce.com Canvas - a Quick Introduction
Force.com Canvas - a Quick Introduction
 
What is force.com?
What is force.com?What is force.com?
What is force.com?
 
Do Agile Right - Lessons Learned from an Atlassian Product Manager - Sherif M...
Do Agile Right - Lessons Learned from an Atlassian Product Manager - Sherif M...Do Agile Right - Lessons Learned from an Atlassian Product Manager - Sherif M...
Do Agile Right - Lessons Learned from an Atlassian Product Manager - Sherif M...
 
Jira fundamentals
Jira fundamentalsJira fundamentals
Jira fundamentals
 
Atlassian Confluence: как сделать работу комфортной
Atlassian Confluence: как сделать работу комфортнойAtlassian Confluence: как сделать работу комфортной
Atlassian Confluence: как сделать работу комфортной
 
Scaling Atlassian - What's New in Data Center
Scaling Atlassian - What's New in Data CenterScaling Atlassian - What's New in Data Center
Scaling Atlassian - What's New in Data Center
 
Project Management With Atlassian Confluence
Project Management With Atlassian ConfluenceProject Management With Atlassian Confluence
Project Management With Atlassian Confluence
 
Automate Your Business with Atlassian
Automate Your Business with AtlassianAutomate Your Business with Atlassian
Automate Your Business with Atlassian
 
A Habit of Innovation
A Habit of InnovationA Habit of Innovation
A Habit of Innovation
 
Salesforce Presentation
Salesforce PresentationSalesforce Presentation
Salesforce Presentation
 

Ähnlich wie AtlasCamp 2010: Understanding the Atlassian Platform - Tim Pettersen

JavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオンJavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオン
haruki ueno
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Atlassian
 
ASP.NET Overview - Alvin Lau
ASP.NET Overview - Alvin LauASP.NET Overview - Alvin Lau
ASP.NET Overview - Alvin Lau
Spiffy
 

Ähnlich wie AtlasCamp 2010: Understanding the Atlassian Platform - Tim Pettersen (20)

Google app engine by example
Google app engine by exampleGoogle app engine by example
Google app engine by example
 
RequireJS
RequireJSRequireJS
RequireJS
 
JavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオンJavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオン
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
 
Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paper
 
Catalyst patterns-yapc-eu-2016
Catalyst patterns-yapc-eu-2016Catalyst patterns-yapc-eu-2016
Catalyst patterns-yapc-eu-2016
 
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
Servlets 3.0 - Asynchronous, Extensibility, Ease-of-use @ JavaOne Brazil 2010
 
RoR 101: Session 6
RoR 101: Session 6RoR 101: Session 6
RoR 101: Session 6
 
RoR 101: Session 6
RoR 101: Session 6RoR 101: Session 6
RoR 101: Session 6
 
Pom configuration java xml
Pom configuration java xmlPom configuration java xml
Pom configuration java xml
 
Dandelion 0.10.0
Dandelion 0.10.0Dandelion 0.10.0
Dandelion 0.10.0
 
Sviluppare applicazioni cross-platform con Xamarin Forms e il framework Prism...
Sviluppare applicazioni cross-platform con Xamarin Forms e il framework Prism...Sviluppare applicazioni cross-platform con Xamarin Forms e il framework Prism...
Sviluppare applicazioni cross-platform con Xamarin Forms e il framework Prism...
 
Struts 1
Struts 1Struts 1
Struts 1
 
ASP.NET Overview - Alvin Lau
ASP.NET Overview - Alvin LauASP.NET Overview - Alvin Lau
ASP.NET Overview - Alvin Lau
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
Spring WebApplication development
Spring WebApplication developmentSpring WebApplication development
Spring WebApplication development
 
SharePoint Saturday Atlanta 2015
SharePoint Saturday Atlanta 2015SharePoint Saturday Atlanta 2015
SharePoint Saturday Atlanta 2015
 
Custom directive and scopes
Custom directive and scopesCustom directive and scopes
Custom directive and scopes
 
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component DevelopmentEVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
 
20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final
 

Mehr von Atlassian

Design Your Next App with the Atlassian Vendor Sketch Plugin
Design Your Next App with the Atlassian Vendor Sketch PluginDesign Your Next App with the Atlassian Vendor Sketch Plugin
Design Your Next App with the Atlassian Vendor Sketch Plugin
Atlassian
 

Mehr von Atlassian (20)

International Women's Day 2020
International Women's Day 2020International Women's Day 2020
International Women's Day 2020
 
10 emerging trends that will unbreak your workplace in 2020
10 emerging trends that will unbreak your workplace in 202010 emerging trends that will unbreak your workplace in 2020
10 emerging trends that will unbreak your workplace in 2020
 
Forge App Showcase
Forge App ShowcaseForge App Showcase
Forge App Showcase
 
Let's Build an Editor Macro with Forge UI
Let's Build an Editor Macro with Forge UILet's Build an Editor Macro with Forge UI
Let's Build an Editor Macro with Forge UI
 
Meet the Forge Runtime
Meet the Forge RuntimeMeet the Forge Runtime
Meet the Forge Runtime
 
Forge UI: A New Way to Customize the Atlassian User Experience
Forge UI: A New Way to Customize the Atlassian User ExperienceForge UI: A New Way to Customize the Atlassian User Experience
Forge UI: A New Way to Customize the Atlassian User Experience
 
Take Action with Forge Triggers
Take Action with Forge TriggersTake Action with Forge Triggers
Take Action with Forge Triggers
 
Observability and Troubleshooting in Forge
Observability and Troubleshooting in ForgeObservability and Troubleshooting in Forge
Observability and Troubleshooting in Forge
 
Trusted by Default: The Forge Security & Privacy Model
Trusted by Default: The Forge Security & Privacy ModelTrusted by Default: The Forge Security & Privacy Model
Trusted by Default: The Forge Security & Privacy Model
 
Designing Forge UI: A Story of Designing an App UI System
Designing Forge UI: A Story of Designing an App UI SystemDesigning Forge UI: A Story of Designing an App UI System
Designing Forge UI: A Story of Designing an App UI System
 
Forge: Under the Hood
Forge: Under the HoodForge: Under the Hood
Forge: Under the Hood
 
Access to User Activities - Activity Platform APIs
Access to User Activities - Activity Platform APIsAccess to User Activities - Activity Platform APIs
Access to User Activities - Activity Platform APIs
 
Design Your Next App with the Atlassian Vendor Sketch Plugin
Design Your Next App with the Atlassian Vendor Sketch PluginDesign Your Next App with the Atlassian Vendor Sketch Plugin
Design Your Next App with the Atlassian Vendor Sketch Plugin
 
Tear Up Your Roadmap and Get Out of the Building
Tear Up Your Roadmap and Get Out of the BuildingTear Up Your Roadmap and Get Out of the Building
Tear Up Your Roadmap and Get Out of the Building
 
Nailing Measurement: a Framework for Measuring Metrics that Matter
Nailing Measurement: a Framework for Measuring Metrics that MatterNailing Measurement: a Framework for Measuring Metrics that Matter
Nailing Measurement: a Framework for Measuring Metrics that Matter
 
Building Apps With Color Blind Users in Mind
Building Apps With Color Blind Users in MindBuilding Apps With Color Blind Users in Mind
Building Apps With Color Blind Users in Mind
 
Creating Inclusive Experiences: Balancing Personality and Accessibility in UX...
Creating Inclusive Experiences: Balancing Personality and Accessibility in UX...Creating Inclusive Experiences: Balancing Personality and Accessibility in UX...
Creating Inclusive Experiences: Balancing Personality and Accessibility in UX...
 
Beyond Diversity: A Guide to Building Balanced Teams
Beyond Diversity: A Guide to Building Balanced TeamsBeyond Diversity: A Guide to Building Balanced Teams
Beyond Diversity: A Guide to Building Balanced Teams
 
The Road(map) to Las Vegas - The Story of an Emerging Self-Managed Team
The Road(map) to Las Vegas - The Story of an Emerging Self-Managed TeamThe Road(map) to Las Vegas - The Story of an Emerging Self-Managed Team
The Road(map) to Las Vegas - The Story of an Emerging Self-Managed Team
 
Building Apps With Enterprise in Mind
Building Apps With Enterprise in MindBuilding Apps With Enterprise in Mind
Building Apps With Enterprise in Mind
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Kürzlich hochgeladen (20)

Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

AtlasCamp 2010: Understanding the Atlassian Platform - Tim Pettersen

  • 1. Understanding the Atlassian Platform Tim Pettersen, Atlassian
  • 2.
  • 3. Atlassian Plugin Development Platform Targeted at You! Features Dedicated Team Documentation Focus on Backwards Compatibility
  • 6. Have you ever? ... needed to communicate with a remote application? ... wanted an easy way to provide JSON data for an AJAXy UI? ... wanted to expose your plugin's data via web services?
  • 8. Depending on REST ... <dependency> <groupId>com.atlassian.plugins.rest</groupId> <artifactId>atlassian-rest-common</artifactId> <version>${rest.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.atlassian.plugins.rest</groupId> <artifactId>atlassian-rest-module</artifactId> <version>${rest.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> Atlassian annotations & utilities JAX-RS annotations & jersey JAXB annotations
  • 9. Quick departure - versioning Easy - Dependency Management POM Custom - Specify versions per module more info: http://bit.ly/platform-versions
  • 10. Depending on REST ... <atlassian-plugin> <rest key="some-key" path="/some-path" version="1.0" description="Initialise REST resources for my plugin" /> <component-import key="restUrlBuilder" interface="com.atlassian.plugins.rest.common.util.RestUrlBuilder" /> </atlassian-plugin> http://jira.atlassian.com/REST/some-path/1.0/
  • 11. Using REST ... creating a resource @Path("/hello/") @Consumes(APPLICATION_XML, APPLICATION_JSON) @Produces(APPLICATION_XML, APPLICATION_JSON) public class MyResource { @Path("/my-name-is/{name}") @GET @AnonymousAllowed public Response hello(@PathParam("name") String name) { return ok( new MessageEntity("Hello, " + name + "!") ); } } http://.../REST/some-path/1.0/hello http://.../REST/some-path/1.0/hello/my-name-is/tim
  • 12. Using REST ... creating an entity @XmlAccessorType(FIELD) @XmlRootElement(name = "message") public class MessageEntity { private String body; public MessageEntity(String body) { this.body = body; } } http://.../REST/some-path/1.0/hello/my-name-is/Tim.xml <message> <body>Hello, Tim!</body> </message> http://.../REST/some-path/1.0/hello/my-name-is/Tim.json {body:"Hello, world!"} Poster: http://bit.ly/poster-ff
  • 13. Using REST ... generating a resource URL public class MyClient { public void doGet() { String baseUrl = "http://jira.atlassian.com"; String restUrl = restUrlBuilder .getUrlFor(baseUrl, MyResource.class) .hello("Tim") .toString(); ... } } // generated restUrl = "http://.../REST/some-path/1.0/hello/my-name-is/Tim"
  • 14. Using REST ... unmarshalling an entity Request request = requestFactory .createRequest(MethodType.GET, restUrl); request.execute(new ResponseHandler<Response>() { public void handle(Response response) { if (response.isSuccessful()) { } } }); // unmarshall the entity MessageEntity m = response.getEntity(MessageEntity.class);
  • 15. Using REST ... marshalling an entity Request request = requestFactory.createRequest(PUT, restUrl); MessageEntity entity = new MessageEntity("some-value"); request.setEntity(entity); request.execute(); @PUT public Response submit(MessageEntity message) { System.out.println("Received: " + message.getBody()); } Client Server
  • 16.
  • 17. Have you ever? ... wanted to launch a modal dialog from your plugin? ... wanted to add rich tooltips to your content? ... wished someone else would write your CSS and javascript for you? ... wanted your plugin to look and behave a little bit more like the host application?
  • 19. Depending on AUI ... public class MyServlet extends HttpServlet { public void doGet() { webResourceManager .requireResource("com.atlassian.auiplugin:ajs"); } } <html> <head> #webResourceManager.getRequiredResources() </head> <body ... /> </html>
  • 20. Depending on AUI ... <atlassian-plugin> <web-resource key="some-web-resource"> <resource name="my-script.js" ... /> <resource name="my-styles.css" ... /> <dependency>com.atlassian.auiplugin:ajs</dependency> </web-resource> </atlassian-plugin> public class MyServlet extends HttpServlet { public void doGet() { webResourceManager .requireResource("com.my.plugin:some-web-resource"); } }
  • 21. Using AUI ... dropdowns
  • 22. Using AUI ... dropdowns <script type="text/javascript"> // create drop-down AJS.$("#my-dropdown") .dropDown("standard", {alignment: "right"}); </script> <!-- the list to display as a dropdown --> <ul id="my-dropdown"> <li class="paper-clip">Item One</li> <li class="clock">Item Two</li> <li class="envelope">Item Three</li> </ul>
  • 23. Using AUI ... tooltips
  • 24. Using AUI ... tooltips <script type="text/javascript"> // assign URL for retrieving AJAX content var contentUrl = AJS.params.baseUrl + "/rest/myplugin/1.0/tooltip"; // bind hovers to DOM elements AJS.InlineDialog(".tooltip-link", "tooltip", contentUrl, { onHover: true, width: 300, cacheContent: true }); </script> <!-- an anchor that the tooltip will be applied to --> <a class='.hover-link'>Hover over me!</a>
  • 25. Using AUI ... more!
  • 26.
  • 27. Have you ever? ... wanted to include a piece of javascript or CSS on every page in Confluence? ... wanted to make your plugin, pluggable? ... wanted to build a single plugin that can be deployed in multiple applications?
  • 29. Depending on plugins ... <dependency> <groupId>com.atlassian.plugins</groupId> <artifactId>atlassian-plugins-webresource</artifactId> <version>${atlassian.plugins.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.atlassian.plugins</groupId> <artifactId>atlassian-plugins-core</artifactId> <version>${atlassian.plugins.version}</version> <scope>provided</scope> </dependency> <atlassian-plugin> <!-- Unnecessary! --> <component-import ... /> </atlassian-plugin>
  • 30. Using plugins ... web-resource contexts <atlassian-plugin> <web-resource key="some-web-resource"> <context>atl.general</context> <resource name="my-script.js" ... /> <resource name="my-styles.css" ... /> </web-resource> </atlassian-plugin> atl.general atl.admin atl.userprofile
  • 32. Using plugins ... custom module types public class MyDescriptor extends AbstractModuleDescriptor<MyModule> { public void init(Plugin plugin, Element element); public MyModule getModule() { // initialize the module specified by the descriptor's class attribute return moduleFactory.createModule(moduleClassName, this); } } <atlassian-plugin> <module-type key="my-descriptor" class="com.myplugin.MyDescriptor" /> <my-descriptor class="com.myplugin.ModuleOne" /> <my-descriptor class="com.myplugin.ModuleTwo" /> </atlassian-plugin>
  • 33. Using plugins ... custom module types public class MyService { private PluginAccessor pluginAccessor; public MyService(PluginAccessor pluginAccessor) { this.pluginAccessor = pluginAccessor; } public void executeInstalledModules() { for (MyModule module : pluginAccessor.getEnabledModulesByClass(MyModule.class)) { module.execute(); } } }
  • 34. Using plugins ... descriptor application scopes <atlassian-plugin> <web-resource key="some-web-resource" application="confluence"> <context>atl.general</context> <resource name="page-integration.js" ... /> </web-resource> <web-resource key="some-web-resource" application="jira"> <context>atl.general</context> <resource name="issue-integration.js" ... /> </web-resource> <!-- depends on Confluence's API --> <component key="some-component" application="confluence" class="com.myplugin.PageHandler" /> <!-- depends on JIRA's API --> <component key="some-component" application="jira" class="com.myplugin.IssueHandler" /> </atlassian-plugin>
  • 35.
  • 36.
  • 37.
  • 38.
  • 39. Have you ever? ... needed to render HTML outside of a JIRA or Confluence action? ... needed to pass back rendered HTML to use in an AJAX UI? ... wished you could use something a little more modern than Velocity 1.4 in JIRA?
  • 41. Depending on ATR ... <dependency> <groupId>com.atlassian.templaterenderer</groupId> <artifactId>atlassian-template-renderer-api</artifactId> <version>${template.renderer.version}</version> <scope>provided</scope> </dependency> <atlassian-plugin> <component-import key="templateRenderer" interface="com.atlassian.templaterenderer.TemplateRenderer" /> </atlassian-plugin>
  • 42. Using ATR ... public class MyServlet extends HttpServlet { private TemplateRenderer templateRenderer; // constructor-injected public void doGet(HttpServletRequest req, HttpServletResponse resp) { Map<String, Object> context = createContext(); templateRenderer.render("templates/view.vm", context, resp.getWriter() ); } }
  • 43.
  • 44. Have you ever? ... needed to persist some simple data for your plugin? ... wanted to i18n your plugin? ... needed to write an upgrade task? ... wanted to schedule a recurring job?
  • 46. Depending on SAL ... <dependency> <groupId>com.atlassian.sal</groupId> <artifactId>sal-api</artifactId> <version>${sal.version}</version> <scope>provided</scope> </dependency>
  • 47. Depending on SAL ... <atlassian-plugin> <component-import key="[someSalComponent]" interface="com.atlassian.sal.api.[someSalComponent]" /> </atlassian-plugin> AuthenticationControlle r LoginUriProvider ComponentLocator I18nResolver LocaleResolver RequestFactory SearchProvider PluginUpgradeManage r UserManager ApplicationProperties PluginSettingsFactory ProjectManager PluginScheduler More!
  • 48. Using SAL ... upgrade tasks public interface PluginUpgradeTask { int getNumber(); String getShortDescription(); Collection<Message> doUpgrade(); String getPluginKey(); } <atlassian-plugin> <component key="my-upgrade-task" public="true" class="com.myplugin.MyUpgradeTask"> <interface>com.atlassian.sal.api.upgrade.PluginUpgradeTask</interface> </component> </atlassian-plugin>
  • 49. Using SAL ... i18n <atlassian-plugin> <component-import key="i18nResolver" interface="com.atlassian.sal.api.message.I18nResolver" /> <resource key="my-i18n" type="i18n" location="i18n" /> </atlassian-plugin> hello.world = Hello World! (i18n.properties) hello.world: Hola a todos! (i18n_es.properties) hello.world Hallo Welt! (i18n_de.properties)
  • 50. Using SAL ... i18n Map<String, Object> context = new HashMap<String, Object>(); context.put("i18n", i18nResolver); templateRenderer.render("templates/view.vm", context, writer); <html> <head> <title>#i18n.getText('hello.world')</title> </head> <body ... /> </html>
  • 51. Using SAL ... job scheduling // simple very-contrived job public class MyPluginJob implements PluginJob { public void execute(Map<String, Object> data) { int count = data.get("jobExecutionCount"); count++; data.put("jobExecutionCount", count); } }
  • 52. Using SAL ... job scheduling public class MyComponent implements LifecycleAware { private PluginScheduler scheduler; // autowired public void onStart() { scheduler.scheduleJob( "my-plugin-job", MyPluginJob.class, new HashMap<String, Object>(), new Date(), 10000 // milliseconds ); } }
  • 53. Targeted at You! Features Dedicated Team Documentation Backwards Compatibility Open Source :D
  • 54. Go use it! Shared Application Layer Unified Application Links Template Renderer Plugins Framework Atlassian User Interface REST
  • 55.
  • 56. Questions? more info - http://bit.ly/best-thing-ever