/* Copyright (c) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gdata.model.atom;
import com.google.common.collect.Lists;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.IGenerator;
import com.google.gdata.model.AttributeKey;
import com.google.gdata.model.Element;
import com.google.gdata.model.ElementCreator;
import com.google.gdata.model.ElementKey;
import com.google.gdata.model.MetadataRegistry;
import com.google.gdata.model.QName;
import com.google.gdata.util.Namespaces;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* The Source class represents an Atom feed source object primarily on the data
* model for an {@code <atom:source>} element.
*
* <p>Here is the Relax-NG schema that represents an Atom 1.0 Source:
*
* <p><pre>
* atomSource =
* element atom:source {
* atomCommonAttributes,
* (atomAuthor*
* & atomCategory*
* & atomContributor*
* & atomGenerator?
* & atomIcon?
* & atomId?
* & atomLink*
* & atomLogo?
* & atomRights?
* & atomSubtitle?
* & atomTitle?
* & atomUpdated?
* & extensionElement*)
* }
* </pre>
*/
public class Source extends Element {
/**
* The key for Source used as a construct. This will apply to all uses
* of Source regardless of QName, in particular to Feed.
*/
public static final ElementKey<Void, Source> CONSTRUCT =
ElementKey.of(null, Source.class);
/**
* The key for this element.
*/
public static final ElementKey<Void, Source> KEY = ElementKey.of(
new QName(Namespaces.atomNs, "source"), Void.class, Source.class);
/**
* The atom:id element.
* somewhere else.
*/
public static final ElementKey<String, Element> ID = ElementKey.of(
new QName(Namespaces.atomNs, "id"));
/**
* atom:updated
*/
public static final ElementKey<DateTime, Element> UPDATED = ElementKey.of(
new QName(Namespaces.atomNs, "updated"), DateTime.class, Element.class);
/**
* atom:title
*/
public static final ElementKey<String, TextContent> TITLE = ElementKey.of(
new QName(Namespaces.atomNs, "title"), String.class, TextContent.class);
/**
* atom:subtitle
*/
public static final ElementKey<String, TextContent> SUBTITLE = ElementKey.of(
new QName(Namespaces.atomNs, "subtitle"), String.class,
TextContent.class);
/**
* atom:rights
*/
public static final ElementKey<String, TextContent> RIGHTS = ElementKey.of(
new QName(Namespaces.atomNs, "rights"), String.class, TextContent.class);
/**
* atom:icon
*/
public static final ElementKey<URI, Element> ICON = ElementKey.of(
new QName(Namespaces.atomNs, "icon"), URI.class, Element.class);
/**
* atom:logo
*/
public static final ElementKey<URI, Element> LOGO = ElementKey.of(
new QName(Namespaces.atomNs, "logo"), URI.class, Element.class);
/**
* Registers the metadata for this element.
*/
public static void registerMetadata(MetadataRegistry registry) {
if (registry.isRegistered(CONSTRUCT)) {
return;
}
// Build the default metadata for all of our directly included elements.
registry.build(ID);
registry.build(UPDATED);
registry.build(TITLE);
registry.build(SUBTITLE);
registry.build(RIGHTS);
registry.build(ICON);
registry.build(LOGO);
// The builder for this element
ElementCreator builder = registry.build(CONSTRUCT);
// Local properties
builder.addElement(ID);
builder.addElement(UPDATED);
builder.addElement(Category.KEY);
builder.addElement(TITLE);
builder.addElement(SUBTITLE);
builder.addElement(RIGHTS);
builder.addElement(ICON);
builder.addElement(LOGO);
builder.addElement(Link.KEY);
builder.addElement(Author.KEY);
builder.addElement(Contributor.KEY);
builder.addElement(Generator.KEY);
// Build atom:source based on the source construct.
registry.build(KEY);
}
/**
* Class representing atom:generator.
*/
public static class Generator extends Element implements IGenerator {
/**
* The key for this element.
*/
@SuppressWarnings("hiding")
public static final ElementKey<String, Generator> KEY = ElementKey.of(
new QName(Namespaces.atomNs, "generator"), String.class, Generator.class);
/**
* Metadata for the version attribute.
*/
public static final AttributeKey<String> VERSION = AttributeKey.of(
new QName("version"));
/**
* Metadata for the uri attribute.
*/
public static final AttributeKey<URI> URI = AttributeKey.of(
new QName("uri"), URI.class);
/**
* Registers the metadata for this element.
*/
public static void registerMetadata(MetadataRegistry registry) {
if (registry.isRegistered(KEY)) {
return;
}
ElementCreator builder = registry.build(KEY);
builder.addAttribute(VERSION);
builder.addAttribute(URI);
}
/**
* Constructs a new instance using the default metadata.
*/
public Generator() {
super(KEY);
}
/**
* Constructs a new instance using the specified element metadata.
*
* @param key element key for this element.
*/
public Generator(ElementKey<?, ? extends Generator> key) {
super(key);
}
/** Version. */
public String getVersion() {
return getAttributeValue(VERSION);
}
public void setVersion(String v) {
setAttributeValue(VERSION, v);
}
/**
* Gets URI associated with source.
*
* @deprecated Use {@link #getUriUri()} instead.
*
* @return URI
*/
@Deprecated
public String getHref() {
URI uri = getUriUri();
if (uri == null) {
return null;
}
return uri.toString();
}
/**
* Gets URI associated with source.
*
* @return URI
*/
public URI getUriUri() {
return getAttributeValue(URI);
}
/**
* Sets URI associated with source.
*
* @deprecated Use {@link #setUri(URI)} instead.
*
* @param v URI
*/
@Deprecated
public void setUri(String v) {
try {
setUri(v == null ? null : new URI(v));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Sets URI associated with source.
*
* @param v URI
*/
public void setUri(URI v) {
setAttributeValue(URI, v);
}
/** Generator name. */
public String getName() {
return (String) getTextValue();
}
public void setName(String v) {
setTextValue(v);
}
}
/**
* Constructs a new instance using the default metadata.
*/
public Source() {
super(KEY);
}
/**
* Constructs a new instance using the specified element metadata.
*
* @param key element key for this element.
*/
protected Source(ElementKey<?, ? extends Source> key) {
super(key);
}
/**
* Copy constructor that initializes a new Source instance to have identical
* contents to another instance, using a shared reference to the same child
* element instances. Default metadata is used.
*/
protected Source(Source sourceSource) {
this(KEY, sourceSource);
}
/**
* Copy constructor that initializes a new Source instance to have identical
* contents to another element, using a shared state. The element key is given
* by the caller.
*
* @param key element key to associate with copy
* @param source source to copy data from
*/
protected Source(ElementKey<?, ? extends Source> key, Element source) {
super(key, source);
}
public String getId() {
return getElementValue(ID);
}
public void setId(String v) {
setElement(ID, (v == null) ? null : new Element(ID).setTextValue(v));
}
public DateTime getUpdated() {
return getElementValue(UPDATED);
}
public void setUpdated(DateTime v) {
setElement(UPDATED,
(v == null) ? null : new Element(UPDATED).setTextValue(v));
}
public Set<Category> getCategories() {
return getElementSet(Category.KEY);
}
public void addCategory(Category v) {
addElement(Category.KEY, v);
}
public void clearCategories() {
removeElement(Category.KEY);
}
public TextContent getTitle() {
return getElement(TITLE);
}
public void setTitle(TextContent v) {
setElement(TITLE, v);
}
public TextContent getSubtitle() {
return getElement(SUBTITLE);
}
public void setSubtitle(TextContent v) {
setElement(SUBTITLE, v);
}
public TextContent getRights() {
return getElement(RIGHTS);
}
public void setRights(TextContent v) {
setElement(RIGHTS, v);
}
/**
* Gets icon URI associated with source.
*
* @deprecated Use {@link #getIconUri()} instead.
*
* @return icon URI
*/
@Deprecated
public String getIcon() {
URI uri = getIconUri();
if (uri == null) {
return null;
}
return uri.toString();
}
/**
* Gets icon URI associated with source.
*
* @return icon URI
*/
public URI getIconUri() {
return getElementValue(ICON);
}
/**
* Sets icon URI associated with source.
*
* @deprecated Use {@link #setIcon(URI)} instead.
*
* @param v icon URI
*/
@Deprecated
public void setIcon(String v) {
try {
setIcon(v == null ? null : new URI(v));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Sets icon URI associated with source.
*
* @param v icon URI
*/
public void setIcon(URI v) {
setElement(ICON, (v == null) ? null : new Element(ICON).setTextValue(v));
}
/**
* Gets logo URI associated with source.
*
* @deprecated Use {@link #getLogoUri()} instead.
*
* @return logo URI
*/
@Deprecated
public String getLogo() {
URI uri = getLogoUri();
if (uri == null) {
return null;
}
return uri.toString();
}
/**
* Gets logo URI associated with source.
*
* @return logo URI
*/
public URI getLogoUri() {
return getElementValue(LOGO);
}
/**
* Sets logo URI associated with source.
*
* @deprecated Use {@link #setLogo(URI)} instead.
*
* @param v logo URI
*/
@Deprecated
public void setLogo(String v) {
try {
setLogo(v == null ? null : new URI(v));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Sets logo URI associated with source.
*
* @param v logo URI
*/
public void setLogo(URI v) {
setElement(LOGO, (v == null) ? null : new Element(LOGO).setTextValue(v));
}
public List<Link> getLinks() {
return getElements(Link.KEY);
}
public void addLink(Link v) {
addElement(Link.KEY, v);
}
public Link addLink(String rel, String type, String href) {
try {
Link link = new Link(rel, type, new URI(href));
addLink(link);
return link;
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
public boolean removeLink(Link link) {
return removeElement(Link.KEY, link);
}
public void clearLinks() {
removeElement(Link.KEY);
}
@SuppressWarnings("unchecked")
public List<Person> getAuthors() {
return (List<Person>) (List<?>) getElements(Author.KEY);
}
public void addAuthor(Person v) {
addElement(Author.KEY, v);
}
public void addAuthors(List<Person> v) {
for (Person p : v) {
addAuthor(p);
}
}
public boolean removeAuthor(Person v) {
return removeElement(Author.KEY, v);
}
public void clearAuthors() {
removeElement(Author.KEY);
}
@SuppressWarnings("unchecked")
public List<Person> getContributors() {
return (List<Person>) (List<?>) getElements(Contributor.KEY);
}
public void addContributor(Person v) {
addElement(Contributor.KEY, v);
}
public void addContributors(List<Person> v) {
for (Person p : v) {
addContributor(p);
}
}
public boolean removeContributor(Person v) {
return removeElement(Contributor.KEY, v);
}
public void clearContributors() {
removeElement(Contributor.KEY);
}
public Generator getGenerator() {
return getElement(Generator.KEY);
}
public void setGenerator(Generator v) {
setElement(Generator.KEY, v);
}
public Generator setGenerator(String version, String uri, String name) {
Generator gen = new Generator();
gen.setVersion(version);
gen.setUri(uri);
gen.setName(name);
setGenerator(gen);
return gen;
}
/**
* Retrieves the first link with the supplied {@code rel} and/or {@code type}
* value.
* <p>
* If either parameter is {@code null}, doesn't return matches for that
* parameter.
*/
public Link getLink(String rel, String type) {
for (Link link : getLinks()) {
if (link.matches(rel, type)) {
return link;
}
}
return null;
}
/**
* Return the links that match the given {@code rel} and {@code type} values.
*
* @param relToMatch {@code rel} value to match or {@code null} to match any
* {@code rel} value.
* @param typeToMatch {@code type} value to match or {@code null} to match any
* {@code type} value.
* @return matching links.
*/
public List<Link> getLinks(String relToMatch, String typeToMatch) {
List<Link> result = new ArrayList<Link>();
for (Link link : getLinks()) {
if (link.matches(relToMatch, typeToMatch)) {
result.add(link);
}
}
return result;
}
/**
* Remove all links that match the given {@code rel} and {@code type} values.
*
* @param relToMatch {@code rel} value to match or {@code null} to match any
* {@code rel} value.
* @param typeToMatch {@code type} value to match or {@code null} to match any
* {@code type} value.
*/
public void removeLinks(String relToMatch, String typeToMatch) {
List<Link> toRemove = Lists.newArrayList();
for (Link link : getLinks()) {
if (link.matches(relToMatch, typeToMatch)) {
toRemove.add(link);
}
}
for (Link link : toRemove) {
removeLink(link);
}
}
/**
* Adds a link pointing to an HTML representation.
*
* @param htmlUrl link URL
*
* @param lang optional language code
*
* @param title optional title
*/
public void addHtmlLink(String htmlUrl, String lang, String title) {
try {
Link link =
new Link(Link.Rel.ALTERNATE, Link.Type.HTML, new URI(htmlUrl));
if (lang != null) {
link.setHrefLang(lang);
}
if (title != null) {
link.setTitle(title);
}
addElement(Link.KEY, link);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Retrieves the first HTML link.
*
* @return the link
*/
public Link getHtmlLink() {
Link htmlLink = getLink(Link.Rel.ALTERNATE, Link.Type.HTML);
return htmlLink;
}
}