package org.atomnuke.atom.io.writer.stax; import java.net.URI; import java.util.List; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.atomnuke.atom.io.cfg.NamespaceLevel; import org.atomnuke.atom.model.Category; import org.atomnuke.atom.model.Content; import org.atomnuke.atom.model.DateConstruct; import org.atomnuke.atom.model.Entry; import org.atomnuke.atom.model.Feed; import org.atomnuke.atom.model.Generator; import org.atomnuke.atom.model.Id; import org.atomnuke.atom.model.Icon; import org.atomnuke.atom.model.Link; import org.atomnuke.atom.model.Logo; import org.atomnuke.atom.model.PersonConstruct; import org.atomnuke.atom.model.Published; import org.atomnuke.atom.model.Rights; import org.atomnuke.atom.model.Source; import org.atomnuke.atom.model.Subtitle; import org.atomnuke.atom.model.Summary; import org.atomnuke.atom.model.TypedContent; import org.atomnuke.atom.model.Title; import org.atomnuke.atom.model.Type; import org.atomnuke.atom.model.Updated; import org.atomnuke.atom.xml.AtomNamespaceContext; /** * * @author zinic */ public final class Writer { private static final Writer INSTANCE = new Writer(); public static Writer instance() { return INSTANCE; } private Writer() { } private static void writeStartElement(WriterContext context, String ns, String element) throws XMLStreamException { if (element == null) { return; } switch (context.getConfiguration().getNamespaceLevel()) { case PREFXIED: context.getWriter().writeStartElement(ns, element); break; case NONE: default: context.getWriter().writeStartElement(element); } } private static void writeEndElement(WriterContext context) throws XMLStreamException { context.getWriter().writeEndElement(); } private static void writeAttribute(WriterContext context, String ns, String localName, String value) throws XMLStreamException { if (value == null) { return; } switch (context.getConfiguration().getNamespaceLevel()) { case PREFXIED: context.getWriter().writeAttribute(ns, localName, value); break; case NONE: default: context.getWriter().writeAttribute(localName, value); } } private static void writeLang(WriterContext context, String lang) throws XMLStreamException { writeAttribute(context, AtomNamespaceContext.XML_NAMESPACE, "lang", lang); } private static void writeBase(WriterContext context, URI uri) throws XMLStreamException { if (uri == null) { return; } writeAttribute(context, AtomNamespaceContext.XML_NAMESPACE, "base", uri.toString()); } private static void writeStringElement(WriterContext context, String element, String value) throws XMLStreamException { if (value == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, element); context.getWriter().writeCharacters(value); writeEndElement(context); } private static void writeType(WriterContext context, Type type) throws XMLStreamException { writeType(context, type != null ? type.toString().toLowerCase() : null); } private static void writeType(WriterContext context, String type) throws XMLStreamException { writeAttribute(context, AtomNamespaceContext.XML_NAMESPACE, "type", type); } private static void writeSrc(WriterContext context, String src) throws XMLStreamException { writeAttribute(context, AtomNamespaceContext.XML_NAMESPACE, "src", src); } private static void writeUriElement(WriterContext context, String uri) throws XMLStreamException { writeStringElement(context, "uri", uri); } private static void writePersonConstructs(WriterContext context, String element, List<? extends PersonConstruct> people) throws XMLStreamException { for (PersonConstruct person : people) { writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, element); writeLang(context, person.lang()); writeBase(context, person.base()); writeStringElement(context, "name", person.name()); writeStringElement(context, "email", person.email()); writeUriElement(context, person.uri()); writeEndElement(context); } } private static void writeAuthors(WriterContext context, List<? extends PersonConstruct> people) throws XMLStreamException { writePersonConstructs(context, "author", people); } private static void writeContributors(WriterContext context, List<? extends PersonConstruct> people) throws XMLStreamException { writePersonConstructs(context, "contributor", people); } private static void writeLinks(WriterContext context, List<Link> links) throws XMLStreamException { for (Link link : links) { writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "link"); writeLang(context, link.lang()); writeBase(context, link.base()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "href", link.href()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "hreflang", link.hreflang()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "rel", link.rel()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "title", link.title()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "type", link.type()); final Integer length = link.length(); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "length", length == null ? null : length.toString()); writeEndElement(context); } } private static void writeCategories(WriterContext context, List<Category> categories) throws XMLStreamException { for (Category category : categories) { writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "category"); writeLang(context, category.lang()); writeBase(context, category.base()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "label", category.label()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "scheme", category.scheme()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "term", category.term()); writeEndElement(context); } } private static void writeGenerator(WriterContext context, Generator generator) throws XMLStreamException { if (generator == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "generator"); writeLang(context, generator.lang()); writeBase(context, generator.base()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "uri", generator.uri()); writeAttribute(context, AtomNamespaceContext.ATOM_NAMESPACE, "version", generator.version()); context.getWriter().writeCharacters(generator.toString()); writeEndElement(context); } private static void writeIcon(WriterContext context, Icon icon) throws XMLStreamException { if (icon == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "icon"); writeLang(context, icon.lang()); writeBase(context, icon.base()); context.getWriter().writeCharacters(icon.toString()); writeEndElement(context); } private static void writeId(WriterContext context, Id id) throws XMLStreamException { if (id == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "id"); writeLang(context, id.lang()); writeBase(context, id.base()); context.getWriter().writeCharacters(id.toString()); writeEndElement(context); } private static void writeLogo(WriterContext context, Logo logo) throws XMLStreamException { if (logo == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "logo"); writeLang(context, logo.lang()); writeBase(context, logo.base()); context.getWriter().writeCharacters(logo.toString()); writeEndElement(context); } private static void writeTextConstruct(WriterContext context, String element, TypedContent text) throws XMLStreamException { if (text == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, element); writeLang(context, text.lang()); writeBase(context, text.base()); writeType(context, text.type()); context.getWriter().writeCharacters(text.toString()); writeEndElement(context); } private static void writeRights(WriterContext context, Rights rights) throws XMLStreamException { writeTextConstruct(context, "rights", rights); } private static void writeTitle(WriterContext context, Title title) throws XMLStreamException { writeTextConstruct(context, "title", title); } private static void writeSubtitle(WriterContext context, Subtitle subtitle) throws XMLStreamException { writeTextConstruct(context, "subtitle", subtitle); } private static void writeSummary(WriterContext context, Summary summary) throws XMLStreamException { writeTextConstruct(context, "summary", summary); } private static void writeDateConstruct(WriterContext context, String element, DateConstruct dateConstruct) throws XMLStreamException { if (dateConstruct == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, element); writeLang(context, dateConstruct.lang()); writeBase(context, dateConstruct.base()); context.getWriter().writeCharacters(dateConstruct.toString()); writeEndElement(context); } private static void writeUpdated(WriterContext context, Updated updated) throws XMLStreamException { writeDateConstruct(context, "updated", updated); } private static void writePublished(WriterContext context, Published published) throws XMLStreamException { writeDateConstruct(context, "published", published); } private static void writeSource(WriterContext context, Source source) throws XMLStreamException { if (source == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "source"); writeLang(context, source.lang()); writeBase(context, source.base()); writeAuthors(context, source.authors()); writeLinks(context, source.links()); writeCategories(context, source.categories()); writeGenerator(context, source.generator()); writeIcon(context, source.icon()); writeId(context, source.id()); writeLogo(context, source.logo()); writeRights(context, source.rights()); writeSubtitle(context, source.subtitle()); writeTitle(context, source.title()); writeUpdated(context, source.updated()); writeEndElement(context); } private static void writeContent(WriterContext context, Content content) throws XMLStreamException { if (content == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "content"); writeLang(context, content.lang()); writeBase(context, content.base()); writeType(context, content.type()); writeSrc(context, content.src()); context.getWriter().writeCharacters(content.toString()); writeEndElement(context); } private static void writeEntries(WriterContext context, List<Entry> entries) throws XMLStreamException { for (Entry entry : entries) { writeNonNamespacedEntry(context, entry); } } private static void writeEntry(WriterContext context, Entry entry) throws XMLStreamException { if (entry == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "entry"); bindNamespaces(context); writeLang(context, entry.lang()); writeBase(context, entry.base()); writeAuthors(context, entry.authors()); writeContributors(context, entry.contributors()); writeLinks(context, entry.links()); writeCategories(context, entry.categories()); writeId(context, entry.id()); writeRights(context, entry.rights()); writeTitle(context, entry.title()); writePublished(context, entry.published()); writeUpdated(context, entry.updated()); writeSummary(context, entry.summary()); writeSource(context, entry.source()); writeContent(context, entry.content()); writeEndElement(context); } private static void writeNonNamespacedEntry(WriterContext context, Entry entry) throws XMLStreamException { if (entry == null) { return; } writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "entry"); writeLang(context, entry.lang()); writeBase(context, entry.base()); writeAuthors(context, entry.authors()); writeContributors(context, entry.contributors()); writeLinks(context, entry.links()); writeCategories(context, entry.categories()); writeId(context, entry.id()); writeRights(context, entry.rights()); writeTitle(context, entry.title()); writePublished(context, entry.published()); writeUpdated(context, entry.updated()); writeSummary(context, entry.summary()); writeSource(context, entry.source()); writeContent(context, entry.content()); writeEndElement(context); } private static void writeFeed(WriterContext context, Feed feed) throws XMLStreamException { writeStartElement(context, AtomNamespaceContext.ATOM_NAMESPACE, "feed"); bindNamespaces(context); writeLang(context, feed.lang()); writeBase(context, feed.base()); writeAuthors(context, feed.authors()); writeContributors(context, feed.contributors()); writeLinks(context, feed.links()); writeCategories(context, feed.categories()); writeGenerator(context, feed.generator()); writeIcon(context, feed.icon()); writeId(context, feed.id()); writeLogo(context, feed.logo()); writeRights(context, feed.rights()); writeSubtitle(context, feed.subtitle()); writeTitle(context, feed.title()); writeUpdated(context, feed.updated()); writeEntries(context, feed.entries()); writeEndElement(context); } private static void bindNamespaces(WriterContext context) throws XMLStreamException { final XMLStreamWriter writer = context.getWriter(); if (context.getConfiguration().getNamespaceLevel() == NamespaceLevel.PREFXIED) { writer.writeNamespace(AtomNamespaceContext.ATOM_PREFIX, AtomNamespaceContext.ATOM_NAMESPACE); writer.writeNamespace(AtomNamespaceContext.XML_PREFIX, AtomNamespaceContext.XML_NAMESPACE); } else { writer.writeNamespace("", AtomNamespaceContext.ATOM_NAMESPACE); } } public void write(WriterContext context, Feed f) throws XMLStreamException { final XMLStreamWriter writer = context.getWriter(); writer.setNamespaceContext(AtomNamespaceContext.instance()); writer.writeStartDocument(); writeFeed(context, f); writer.writeEndDocument(); } public void write(WriterContext context, Entry e) throws XMLStreamException { final XMLStreamWriter writer = context.getWriter(); writer.setNamespaceContext(AtomNamespaceContext.instance()); writer.writeStartDocument(); writeEntry(context, e); writer.writeEndDocument(); } }