Abdera Extensions
Main Extensions
Bidi
The Atom Bidi Extension is a work in progress described by an IETF Internet-Draft. It is used to specify the base directionality of bidirection text within an Atom document.
<entry xmlns="http://www.w3.org/2005/Atom" dir="rtl"> <title>W3C? (World Wide Web Consortium)????? ?? ?????? ????? ??????? ? - ERCIM.</title> </entry>
When this text is displayed, the Unicode Bidirectional Algorithm needs to be used to display the text correctly. Unfortunately, Atom does not included a way of specifying the base directionality of text, which is why the bidi
attribute was created. See here for more information.
Entry entry = abdera.newEntry(); BidiHelper.setDirection(BidiHelper.Direction.RTL, entry); entry.setTitle("W3C? (World Wide Web Consortium)????? ?? ?????? ????? ??????? ? - ERCIM.");
The BidiHelper class can then be used to properly render the text:
System.out.println(BidiHelper.getBidiElementText(entry.getTitleElement()));
The BidiHelper class can also be used to discover the base directionality of text
BidiHelper.Direction dir = BidiHelper.getDirection(entry);
If the dir attribute has not been set, the direction may be determined by applying a variety of guessing algorithms. Such algorithms are inherently flawed in that there is no reliable means of always guessing the right direction in every case.
dir = BidiHelper.guessDirectionFromLanguage(entry); dir = BidiHelper.guessDirectionFromTextProperties(entry); dir = BidiHelper.guessDirectionFromJavaBidi(entry); dir = BidiHelper.guessDirectionFromEncoding(entry);
When guessing the text direction based on the xml:lang value, the following rules apply:
- xml:lang values whose primary language tag is "ar","fa","ur","ps","syr","dv","he", or "yi" will always be Right-To-Left
- xml:lang values whose script tag is "arab","avst","hebr","hung","lydi","mand", "mani","mero","mong","nkoo","orkh","phlv", "phnx","samr","syrc","syre","syrj","syrn", "tfng", or "thaa" will always be Right-To-Left
- All other values are considered to have unspecified direction
When guessing the text direction based on the text properties, text strings that consist primarily of Right-To-Left characters will be assumed to be Right-To-Left.
When guessing the text direction based on the character encoding, the following encodings will always be considered as Right-To-Left: "iso-8859-6", "iso-8859-6-bidi", "iso-8859-6-i", "iso-ir-127", "ecma-114", "asmo-708", "arabic", "csisolatinarabic", "windows-1256", "ibm-864", "macarabic", "macfarsi", "iso-8859-8-i", "iso-8859-8-bidi", "windows-1255", "iso-8859-8", "ibm-862", "machebrew", "asmo-449", "iso-9036", "arabic7", "iso-ir-89", "csiso89asmo449", "iso-unicode-ibm-1264", "csunicodeibm1264", "iso_8859-8:1988", "iso-ir-138", "hebrew", "csisolatinhebrew", "iso-unicode-ibm-1265", "csunicodeibm1265", "cp862", "862", "cspc862latinhebrew"
Features
The Atompub Features draft is a work-in-progress extension to the Atom Publishing Protocol Service document format that is used to describe the characteristics and behaviors implemented by a server implementation.
The API for working with the features extension is a work-in-progress.
Service service = abdera.newService(); Workspace workspace = service.addWorkspace("test"); Collection collection = workspace.addCollection("foo", "href"); Features features = FeaturesHelper.addFeaturesElement(collection); features.addFeatures( FeaturesHelper.FEATURE_SUPPORTS_DRAFTS, FeaturesHelper.FEATURE_SUPPORTS_BIDI, FeaturesHelper.FEATURE_REQUIRES_XHTML_TEXT ); FeaturesHelper.getFeatureStatus(collection, FeaturesHelper.FEATURE_SUPPORTS_BIDI); FeaturesHelper.getFeatureStatus(collection, FeaturesHelper.FEATURE_SUPPORTS_GEO);
Paging and Archiving
The Feed Paging and Archiving Extensions are defined by RFC 5005.
Feed feed = abdera.newFeed(); FeedPagingHelper.setCurrent(feed, "current"); FeedPagingHelper.setNext(feed, "next"); FeedPagingHelper.setPrevious(feed, "previous"); FeedPagingHelper.setFirst(feed, "first"); FeedPagingHelper.setLast(feed, "last"); FeedPagingHelper.setNextArchive(feed, "next-archive"); FeedPagingHelper.setPreviousArchive(feed, "prev-archive");
<feed xmlns="http://www.w3.org/2005/Atom"> <link rel="current" href="current" /> <link rel="next" href="next" /> <link rel="previous" href="previous" /> <link rel="first" href="first" /> <link rel="last" href="last" /> <link rel="next-archive" href="next-archive" /> <link rel="prev-archive" href="prev-archive" /> </feed>
The FeedPagingHelper class can also be used to indicate whether a feed is a "complete" or "archive" feed
FeedPagingHelper.setComplete(feed,true); FeedPagingHelper.setArchive(feed,true); boolean c = FeedPagingHelper.isComplete(feed); boolean a = FeedPagingHelper.isArchive(feed);
License Extensions
The Atom License Extension is defined by RFC 4946.
LicenseHelper.addLicense(entry, "http://creativecommons.org/licenses/by-nc/2.5/rdf"); List<Link> licenses = LicenseHelper.getLicense(entry);
Threading Extensions
The Atom Threading Extensions are defined by RFC 4685
// this entry is a reply to entry "http://example.org/entries/1") ThreadHelper.addInReplyTo(entry, "http://example.org/entries/1"); List<InReplyTo> irt = ThreadHelper.getInReplyTo(entry);
GeoRSS Extensions
The GeoRSS extension allows geospatial data to be added to Atom entries.
Entry entry = abdera.newEntry(); Point point = new Point(36.331445,-119.64592); GeoHelper.addPosition(entry, point);
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss/10"> <georss:point>36.331445 -119.64592</georss:point> </entry>
Points, Lines and Polygons can be added to an entry.
Position[] positions = GeoHelper.getPositions(entry);
OpenSearch Extensions
Abdera supports a subset of the OpenSearch extensions
Feed feed = abdera.newFeed(); IntegerElement ie = feed.addExtension(OpenSearchConstants.ITEMS_PER_PAGE); ie.setValue(10); ie = feed.addExtension(OpenSearchConstants.START_INDEX); ie.setValue(0); ie = feed.addExtension(OpenSearchConstants.TOTAL_RESULTS); ie.setValue(100);
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/"> <os:itemsPerPage>10</os:itemsPerPage> <os:startIndex>0</os:startIndex> <os:totalResults>100</os:totalResults> </feed>
MediaRSS Extensions
Abdera supports an experimental implementation of the MediaRSS extensions that can be used to add extended media metadata to an entry.
MediaTitle mtitle = entry.addExtension(MediaConstants.TITLE); mtitle.setText("Media title"); MediaRestriction mrestriction = entry.addExtension(MediaConstants.RESTRICTION); mrestriction.setType(RestrictionType.COUNTRY); mrestriction.setRelationship(Relationship.ALLOW); mrestriction.setText("au us");
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"> <media:title>Media title</media:title> <media:restriction type="country" relationship="allow">au us</media:restriction> </entry>
Auth Extenions
GoogleLogin
Abdera provides a limited implementation of the GooleLogin authentication scheme used by GData.
GoogleLoginAuthScheme.register(); AbderaClient client = new CommonsClient(); client.addCredentials( "http://beta.blogger.com", null, "GoogleLogin", new UsernamePasswordCredentials("email","password") );
The example above has the downside of performing the GoogleLogin authentication on each request. The code below performs the authentication once and reuses it for each subsequent request.
GoogleLoginAuthCredentials credentials = new GoogleLoginAuthCredentials("email", "password", "blogger"); client.addCredentials( "http://beta.blogger.com", null, null, credentials );
WSSE Login
Abdera also provides an implementation of the WSSE authentication mechanism
AbderaClient client = new AbderaClient(); WSSEAuthScheme.register(client,true); client.addCredentials( "http://example.org", null, "WSSE", new UsernamePasswordCredentials("email","password")
OAuth
Abdera also provides a client implementation of the OAuth authorization scheme
AbderaClient client = new AbderaClient(); OAuthScheme.register(client, true); OAuthCredentials credentials = new OAuthCredentials("consumer_key", "token", "signature_method", "realm"); client.addCredentials("http://example.org", null, "OAuth", credentials);
Simple Sharing Extensions
Abdera supports an experimental implementation of the Simple Sharing Extensions. The following examples shows a minimal example of using SSE to merge entries from one feed into another.
Feed f1 = abdera.newFeed(); f1.newId(); Entry e1 = f1.addEntry(); e1.newId(); e1.setTitle("Test"); SharingHelper.getSharing(f1,true); Sync sync = SharingHelper.getSync(e1,true); sync.setId(e1.getId().toString()); Feed f2 = abdera.newFeed(); f2.newId(); SharingHelper.getSharing(f2,true); Entry e2 = f2.addEntry(); e2.newId(); sync = SharingHelper.getSync(e2,true); SharingHelper.mergeFeeds(f1, f2); System.out.println(f2);
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:sx="http://www.microsoft.com/schemas/sse"> <id>urn:uuid:83BD1E87EE96454DF21193779431187</id> <sx:sharing /> <entry> <id>urn:uuid:83BD1E87EE96454DF21193779431228</id> <sx:sync /> </entry> <entry> <id>urn:uuid:83BD1E87EE96454DF21193779431115</id> <title type="text">Test</title> <sx:sync id="urn:uuid:83BD1E87EE96454DF21193779431115" /> </entry> </feed>
The Sharing Extensions implementation also provides a means of resolving merge conflicts.
ConflictResolver resolver = new ConflictResolver() { public Entry resolve(Entry entry, List<Entry> conflicts) { // resolve the conflicts in the entry return entry; } }; for (Entry entry : f2.getEntries()) { if (SharingHelper.hasConflicts(entry)) { Entry resolved = SharingHelper.resolveConflicts(entry, resolver, "jms"); } }
JSON Writer
Abdera supports the ability to serialize Abdera objects out to a JSON representation. The JSON representation is documented here.
Entry entry = abdera.newEntry(); entry.setTitle("Title"); entry.setRightsAsHtml("<p>Copyright © 2007</p>"); entry.newId(); entry.addAuthor("John Doe"); entry.setContentAsXhtml("<p>This is a <b>test</b></p>"); Writer json = abdera.getWriterFactory().getWriter("json"); entry.writeTo(json, System.out);
{ "id":"urn:uuid:5B32E821725995E5DE1193780060026", "title":"Title", "rights":{ "attributes":{ "type":"html" }, "children":[{ "name":"p", "attributes":{}, "children":["Copyright \u00a9 2007"] } ] }, "content":{ "attributes":{ "type":"xhtml" }, "children":[{ "name":"p", "attributes":{}, "children":[ "This is a ", { "name":"b", "attributes":{}, "children":["test"] } ] } ] }, "authors":[{ "name":"John Doe" } ] }