Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/
Table of
Contents...
Hide

Project Zero Developer’s Guide

Concepts and components
Basic concepts overview
Event processing
Writing Java handlers
Writing Groovy handlers
Firing events
Global Context
Global Context reference
Application directory layout
Virtualized directories
Assemble
PHP
Features and configuration
Configuration
Debugging
Dependencies
Packaging
Application classpath
Logging and tracing
RESTful resources
RESTful documentation
File serving
Response rendering
Validators and validation
HTTP error handling
Calling a remote resource
Using the Connection API
Sending an email using EmailConnection
Configuring destinations
Configuring protocols
Configuring connection handlers
Creating a connection handler
Creating a custom protocol transport
Simple logging connection handlers
Protocol reference
Client programming with Dojo
Runtime options
Deployment modifications
HTTP configuration
SSL configuration
Proxy configuration
Extending the CLI
Security considerations
Authentication
OpenID authentication
Extending security
Security tokens
CSRF prevention support
Extending token support
Leveraging TAI
User service
File based user service
LDAP user service
Extending user service
Security Utilities
Leveraging XOREncoder
Extensions
Atom support
RSS support
JSON support
XMLEncoder
REST to SOAP extension
URIUtils
Developer Web tools
Database setup tools
Configuring data access
Common query patterns
Advanced query patterns
Update patterns
Local database transactions
Extending data access
Configuration vendor differences
PHP data access
Resource model
Configuring ZRM
Resource model declaration
Programmatic model API
HTTP REST API
A ZRM mini tutorial
Active content filtering support
Default filters
Custom filters
Runtime management
Management commands
Zero socket opener
Other extension modules
Amazon E-commerce service
Flickr service
WeatherZero forecast service
Wikipedia service
Reference
Zero command line interface
JavaDoc - Public API
JavaDoc - Public SPI
JavaDoc - All Classes

 

Atom support

Zero provides Atom support in two forms:

  1. Implicit support in the Zero Resource Model model-driven development
  2. Explicit support with Apache Abdera and an Atom renderer for simplified serialization

This page describes the latter, which is available in the zero.atom extension.

Adding zero.atom to your application

You must resolve a dependency in order to add zero.atom to your application. Start by adding the following line to the dependencies element in your config/ivy.xml file:
      <dependency org="zero" name="zero.atom" rev="1.0+"/>

If you're using Eclipse, then the dependency is automatically resolved when you save the modified ivy.xml file. Steps to resolve from the command line are outlined on the dependencies page.


HELP Advanced Abdera supports XPath as an alternative to Feed Object Model navigation, but zero.atom does not include XPath support for Abdera. You may add XPath support using the standard Abdera mechanisms.

Output handling: Atom renderer

The Atom renderer simplifies serialization to Atom entry, feed, and service documents. Using a simple convention, the renderer serializes Maps to entries and Map arrays and List<Map> to feeds. The renderer also serializes Abdera elements (Entry, Feed, and Service) for consistency.

The general syntax for invoking the Atom renderer within Groovy scripts is similar to the core renderers:

request.view = 'atom'
request.atom.output = object
render() 

The following sections describe the specific behavior for various object types.

Rendering a Map as an Entry

A simple convention is used to convert a Map to an entry.

Example: Rendering an Entry

Example: Groovy-based resource handler

def onRetrieve() {
entry = [
  // Required
  id : '1',
  title : 'title',
  updated : new Date(0),
  authorname : 'name',
  content : 'content',
  contenttype : 'TEXT',
      
  // Optional
  categorylabel : 'label',
  categoryterm : 'term',
  summary : 'summary',
  summarytype : 'TEXT',
      
  // Extensions
  f1 : 'v1'
]

request.view = 'atom'
request.atom.output = entry
render()
}

Resultant Atom entry document

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:zero="http://projectzero.com/namespace" xmlns="http://www.w3.org/2005/Atom">
  <id>http://localhost:8081/resources/custom/1</id>
  <link href="http://localhost:8081/resources/custom/1" rel="edit"></link>
  <title type="text">title</title>
  <updated>1970-01-01T00:00:00.000Z</updated>
  <author><name>name</name></author>
  <content type="text">content</content>
  <summary type="text">summary</summary>
  <category term="term" label="label"></category>
  <zero:f1 xmlns:zero="http://projectzero.com/namespace">v1</zero:f1>
</entry>

Example: Custom feed URI

By default, the request URI is used to construct the id and link values. The convention assumes that the request URI is of the form /{id}, which is probably correct in cases when dealing with resource handlers. If some situations (e.g. indirect access from a script in the public folder), you can specify a value for by setting the /request/atom/feedUri property for the renderer, as shown in Groovy syntax:

request.view = 'atom'
request.atom.output = textEntry
request.atom.feedUri = 'http://other.host.com/custom'

The resultant Atom entry document:

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns:zero="http://projectzero.com/namespace" xmlns="http://www.w3.org/2005/Atom">
  <id>http://other.host.com/custom/1</id>
  <link href="http://other.host.com/custom/1" rel="edit"></link>
  <title type="text">title</title>
  <updated>1970-01-01T00:00:00.000Z</updated>
  <author><name>name</name></author>
  <content type="text">content</content>
  <summary type="text">summary</summary>
  <category term="term" label="label"></category>
  <zero:f1 xmlns:zero="http://projectzero.com/namespace">v1</zero:f1>
</entry>

Details about the entry conventions

Instances of Map are serialized by first forming equivalent Abdera Entry types, based upon the following mappings of properties to Atom elements.

Required properties
Map Key Expected Data Type Atom element Contents
id int or String atom:id uri: http://{hostname:port}/... {requestUri}/{id}
atom:link uri: http://{hostname:port}/... {requestUri}/{id} (rel=edit)
title String atom:title text: {title}
authorname String atom:name of atom:author text: {authorname}
updated Date atom:updated date: {updated}
contenttype String ("TEXT" or "HTML" or "XHTML") atom:type of atom:content text: {contenttype}
content String atom:content text: {content}
Optional properties
Map Key Expected Data Type Atom element Contents
categoryterm String atom:term of atom:category text: {categoryterm}
categorylabel String atom:label of atom:category text: {categorylabel}
summary String atom:summary text: {summary}
summarytype String ("TEXT" or "HTML" or "XHTML") atom:type of atom:content text: {summarytype}
Extensions
{key} Object simpleExtensionElement text: {object}.toString()

The Atom simpleExtensionElement is an XML element appended to the Atom entry with the following characteristics:

  • element name: {key}
  • element namespace: "http://projectzero.com/namespace"
  • element name prefix: "zero"
  • element value: {object}.toString

Rendering a List<Map> or Map array as a feed

A simple convention is used to convert List and Map array to a feed.

Example: Rendering a feed

Example: Groovy-based resource handler

def onList() {
  entry = [
    // Required
    id : '1',
    title : 'title',
    updated : new Date(0),
    authorname : 'name',
    content : 'content',
    contenttype : 'TEXT'
  ]

  request.view = 'atom'
  request.atom.output = [entry]
  render() 
}

Resultant Atom feed document

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://localhost:8081/resources/custom</id>
  <title type="text">http://localhost:8081/resources/custom</title>
  <link href="http://localhost:8081/resources/custom" rel="self"></link>
  <updated>1970-01-01T00:00:00.000Z</updated>
  <entry>
    <id>http://localhost:8081/resources/custom/1</id>
    <title type="text">title</title>
    <updated>1970-01-01T00:00:00.000Z</updated>
    <author><name>name</name></author>
    <content type="text">content</content>
    <link href="http://localhost:8081/resources/custom/1" rel="edit"></link>
  </entry>
</feed>

Example: Custom feed URI and title

The convention assumes that the request URI for a feed is the feed URI, which is used to construct entry elements (id and link) and feed elements (id, link, and title). This is probably suitable for cases involving resource handlers, but might not be correct for situation involving indirect access (e.g. a resource served optionally via a script in public folder). In such cases, you can specify the feed URI and title directly with additional properties to the renderer, as shown in Groovy syntax:

request.view = 'atom'
request.atom.output = textEntry
request.atom.feedUri = 'http://other.host.com/custom'
request.atom.feedTitle = 'my feed'

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://other.host.com/custom</id>
  <title type="text">my feed</title>
  <link href="http://other.host.com/custom" rel="self"></link>
  <updated>1970-01-01T00:00:00.000Z</updated>
  <entry>
    <id>http://other.host.com/custom/1</id>
    <title type="text">title</title>
    <updated>1970-01-01T00:00:00.000Z</updated>
    <author><name>name</name></author>
    <content type="text">content</content>
    <link href="http://other.host.com/custom/1" rel="edit"></link>
  </entry>
</feed>

Details about the feed conventions

Instances of List<Map> and Map array are serialized in two steps. The first step is to form an Entry instance for each Map instance. The Feed instance is then the collection of the Entry objects and additional feed elements:

Atom element Contents
atom:id uri: http://{hostname:port}/{requestUri}
atom:link uri: http://{hostname:port}/{requestUri} (rel=self)
atom:title text: "http://{hostname:port}/{requestUri}"
atom:updated most recent atom:updated value from entry list

Input handling: Parsing Atom entry

Use the Abdera APIs to parse an incoming Atom entry (e.g. in a POST body):

Example: Groovy snippet

import org.apache.abdera.Abdera;
...
Entry entry = Abdera.getNewParser().parse(request.input[]).getRoot();

Example: Java snippet

import java.io.InputStream;
import org.apache.abdera.Abdera;
...
InputStream is = GlobalContext.<InputStream>zget("/request/input");
Entry entry = Abdera.getNewParser().parse(is).getRoot();

r22 - 22 Jan 2008 - 14:19:58 - paynel
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site