<chapter id="Atom">
   <title>Resteasy Atom Support</title>
   <para>
      From W3.org (http://tools.ietf.org/html/rfc4287):
   </para>
   <para>
      "Atom is an XML-based document format that describes lists of related
      information known as "feeds". Feeds are composed of a number of
      items, known as "entries", each with an extensible set of attached
      metadata. For example, each entry has a title.

      The primary use case that Atom addresses is the syndication of Web
      content such as weblogs and news headlines to Web sites as well as
      directly to user agents."
   </para>
   <para>
      Atom is the next-gen RSS feed. Although it is used primarily for the syndication of blogs and news, many
      are starting to use this format as the envelope for Web Services, for example, distributed notifications, job
      queues, or simply a nice format for sending or receiving data in bulk from a service.
   </para>
   <sect1 id="resteasy_atom">
      <title>Resteasy Atom API and Provider</title>
      <para>RESTEasy has defined a simple object model in Java to represent Atom and uses JAXB to marshal and unmarshal
         it. The
         main classes are in the org.jboss.resteasy.plugins.providers.atom package and are Feed, Entry, Content, and
         Link. If you
         look at the source, you'd see that these are annotated with JAXB annotations. The distribution contains
         the javadocs for this project and are a must to learn the model. Here is a simple example of sending
         an atom feed using the Resteasy API.
      </para>
      <programlisting><![CDATA[
import org.jboss.resteasy.plugins.providers.atom.Content;
import org.jboss.resteasy.plugins.providers.atom.Entry;
import org.jboss.resteasy.plugins.providers.atom.Feed;
import org.jboss.resteasy.plugins.providers.atom.Link;
import org.jboss.resteasy.plugins.providers.atom.Person;

@Path("atom")
public class MyAtomService
{
    @GET
    @Path("feed")
    @Produces("application/atom+xml")
    public Feed getFeed() throws URISyntaxException
    {
        Feed feed = new Feed();
        feed.setId(new URI("http://example.com/42"));
        feed.setTitle("My Feed");
        feed.setUpdated(new Date());
        Link link = new Link();
        link.setHref(new URI("http://localhost"));
        link.setRel("edit");
        feed.getLinks().add(link);
        feed.getAuthors().add(new Person("Bill Burke"));
        Entry entry = new Entry();
        entry.setTitle("Hello World");
        Content content = new Content();
        content.setType(MediaType.TEXT_HTML_TYPE);
        content.setText("Nothing much");
        entry.setContent(content);
        feed.getEntries().add(entry);
        return feed;
    }
}]]></programlisting>
      <para>Because Resteasy's atom provider is JAXB based, you are not limited to sending atom objects using XML.
         You can automatically re-use all the other JAXB providers that Resteasy has like JSON and fastinfoset.
         All you have to do is have "atom+" in front of the main subtype. i.e. @Produces("application/atom+json") or
         @Consumes("application/atom+fastinfoset")
      </para>
   </sect1>
   <sect1 id="jaxb_atom">
      <title>Using JAXB with the Atom Provider</title>
      <para>
         The org.jboss.resteasy.plugins.providers.atom.Content class allows you to unmarshal and marshal JAXB
         annotated objects that are the body of the content. Here's an example of sending an Entry with
         a Customer object attached as the body of the entry's content.
      </para>
      <programlisting><![CDATA[
@XmlRootElement(namespace = "http://jboss.org/Customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer
{
    @XmlElement
    private String name;

    public Customer()
    {
    }

    public Customer(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }
}

@Path("atom")
public static class AtomServer
{
    @GET
    @Path("entry")
    @Produces("application/atom+xml")
    public Entry getEntry()
    {
        Entry entry = new Entry();
        entry.setTitle("Hello World");
        Content content = new Content();
        content.setJAXBObject(new Customer("bill"));
        entry.setContent(content);
        return entry;
    }
}]]></programlisting>
      <para>
         The Content.setJAXBObject() method is used to tell the content object you are sending back
         a Java JAXB object and want it marshalled appropriately. If you are using a different base
         format other than XML, i.e. "application/atom+json", this attached JAXB object will be marshalled
         into that same format.
      </para>
      <para>
         If you have an atom document as your input, you can also extract JAXB objects from Content using the
         Content.getJAXBObject(Class clazz) method. Here is an example of an input atom document and extracting
         a Customer object from the content.
      </para>
      <programlisting><![CDATA[
@Path("atom")
public static class AtomServer
{
    @PUT
    @Path("entry")
    @Produces("application/atom+xml")
    public void putCustomer(Entry entry)
    {
        Content content = entry.getContent();
        Customer cust = content.getJAXBObject(Customer.class);
    }
}
]]></programlisting>
   </sect1>

</chapter>
