package com.atlassian.labs.speakeasy.util; import com.atlassian.plugin.Plugin; import com.atlassian.plugin.osgi.util.OsgiHeaderUtil; import org.dom4j.Document; import org.dom4j.DocumentFactory; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.osgi.framework.Bundle; import java.io.IOException; import java.io.StringWriter; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import static com.atlassian.labs.speakeasy.util.Rfc3339.dateToRFC3339; import static com.google.common.collect.Maps.newHashMap; import static com.google.common.collect.Sets.newHashSet; /** * */ public class FeedBuilder { private String serverBaseUrl; private String serverName; private final Set<Entry> entries; private String profilePath; public FeedBuilder(List<Plugin> plugins, Bundle[] bundles) { Set<Entry> set = newHashSet(); Map<String,Plugin> pluginsByKey = newHashMap(); for (Plugin plugin : plugins) { pluginsByKey.put(plugin.getKey(), plugin); } for (Bundle bundle : bundles) { String pluginKey = OsgiHeaderUtil.getPluginKey(bundle); if (pluginsByKey.containsKey(pluginKey)) { set.add(new Entry(bundle, pluginsByKey.get(pluginKey))); } } this.entries = Collections.unmodifiableSet(set); } public FeedBuilder serverBaseUrl(String serverBaseUrl) { this.serverBaseUrl = serverBaseUrl; return this; } public FeedBuilder serverName(String serverName) { this.serverName = serverName; return this; } public FeedBuilder profilePath(String profilePath) { this.profilePath = profilePath; return this; } public String build() { // <feed xmlns="http://www.w3.org/2005/Atom"> // // <title> Example // Feed</title> // <subtitle>A subtitle.</subtitle> // <link href="http://example.org/feed/" rel="self" /> // <link href="http://example.org/" /> // <id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id> // <updated>2003-12-13T18:30:02Z</updated> // <author> // <name>John Doe</name> // <email>johndoe@example.com</email> // </author> // // <entry> // <title>Atom-Powered Robots Run Amok</title> // <link href="http://example.org/2003/12/13/atom03" /> // <link rel="alternate" type="text/html" href="http://example.org/2003/12/13/atom03.html"/> // <link rel="edit" href="http://example.org/2003/12/13/atom03/edit"/> // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> // <updated>2003-12-13T18:30:02Z</updated> // <summary> Some // text.</summary> // </entry> // // </feed> Document doc = DocumentFactory.getInstance().createDocument(); Element root = doc.addElement("feed"); String NS = "http://www.w3.org/2005/Atom"; root.add(new Namespace("", NS)); root.addElement("title", NS).setText("Speakeasy Extensions"); root.addElement("subtitle", NS).setText("Via " + serverName); root.addElement("link", NS).addAttribute("href", serverBaseUrl + profilePath); root.addElement("link", NS) .addAttribute("href", serverBaseUrl + "/rest/speakeasy/1/feed/extensions") .addAttribute("rel", "self"); long updated = entries.isEmpty() ? System.currentTimeMillis() : entries.iterator().next().getBundle().getLastModified(); root.addElement("updated", NS).setText(dateToRFC3339(new Date(updated))); for (Entry plugin : entries) { Element entry = root.addElement("entry", NS); entry.addElement("title", NS).setText(plugin.getName()); entry.addElement("link", NS).addAttribute("href", serverBaseUrl + profilePath); entry.addElement("id", NS).setText(plugin.getPlugin().getKey()); entry.addElement("updated", NS).setText(dateToRFC3339(new Date(plugin.getBundle().getLastModified()))); entry.addElement("summary", NS).setText(plugin.getPlugin().getPluginInformation().getDescription()); } StringWriter writer = new StringWriter(); try { new XMLWriter(writer, OutputFormat.createPrettyPrint()).write(doc); } catch (IOException e) { throw new RuntimeException("Unable to create Atom XML", e); } return writer.toString(); } private static class Entry implements Comparable<Entry> { private final Bundle bundle; private final Plugin plugin; public Entry(Bundle bundle, Plugin plugin) { this.bundle = bundle; this.plugin = plugin; } public Bundle getBundle() { return bundle; } public Plugin getPlugin() { return plugin; } public String getName() { return plugin.getName() != null ? plugin.getName() : plugin.getKey(); } public int compareTo(Entry o) { return Long.valueOf(bundle.getLastModified()).compareTo(o.getBundle().getLastModified()); } } }