Reformatting and cleaning up code (step 1/2)

This commit is contained in:
Patrick Gotthard 2013-10-03 22:32:00 +02:00
parent f84f0ae10e
commit 95b9121a77
156 changed files with 10329 additions and 8629 deletions

View file

@ -25,9 +25,10 @@ public interface CopyFrom<T> {
/** /**
* Returns the interface the copyFrom works on. * Returns the interface the copyFrom works on.
* <p> * <p>
* This is useful when dealing with properties that may have multiple implementations. * This is useful when dealing with properties that may have multiple
* For example, Module. * implementations. For example, Module.
* <p> * <p>
*
* @return the interface the copyFrom works on. * @return the interface the copyFrom works on.
*/ */
public Class<? extends CopyFrom> getInterface(); public Class<? extends CopyFrom> getInterface();
@ -37,11 +38,13 @@ public interface CopyFrom<T> {
* <p> * <p>
* Any existing properties in this bean are lost. * Any existing properties in this bean are lost.
* <p> * <p>
* This method is useful for moving from one implementation of a bean interface to another. * This method is useful for moving from one implementation of a bean
* For example from the default SyndFeed bean implementation to a Hibernate ready implementation. * interface to another. For example from the default SyndFeed bean
* implementation to a Hibernate ready implementation.
* <p> * <p>
*
* @param obj the instance to copy properties from. * @param obj the instance to copy properties from.
* *
*/ */
public void copyFrom(CopyFrom obj); public void copyFrom(CopyFrom obj);

View file

@ -17,32 +17,33 @@
*/ */
package com.sun.syndication.feed; package com.sun.syndication.feed;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.module.Extendable;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.jdom2.Element; import org.jdom2.Element;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
/** /**
* Parent class of the RSS (Channel) and Atom (Feed) feed beans. * Parent class of the RSS (Channel) and Atom (Feed) feed beans.
* <p> * <p>
* NOTE: We don't like this class at this package level but the alternative would have * NOTE: We don't like this class at this package level but the alternative
* been a proliferation of packages (one more level to hold atom and rss package with * would have been a proliferation of packages (one more level to hold atom and
* this class just in that package). * rss package with this class just in that package).
* <p> * <p>
* The format of the 'type' property must be [FEEDNAME]_[FEEDVERSION] with the FEEDNAME in lower case, * The format of the 'type' property must be [FEEDNAME]_[FEEDVERSION] with the
* for example: rss_0.9, rss_0.93, atom_0.3 * FEEDNAME in lower case, for example: rss_0.9, rss_0.93, atom_0.3
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public abstract class WireFeed implements Cloneable, Serializable, Extendable { public abstract class WireFeed implements Cloneable, Serializable, Extendable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _feedType; private String _feedType;
private String _encoding; private String _encoding;
private List<Module> _modules; private List<Module> _modules;
@ -51,54 +52,59 @@ public abstract class WireFeed implements Cloneable, Serializable, Extendable {
/** /**
* Default constructor, for bean cloning purposes only. * Default constructor, for bean cloning purposes only.
* <p> * <p>
* *
*/ */
protected WireFeed() { protected WireFeed() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a feed for a given type. * Creates a feed for a given type.
* <p> * <p>
*
* @param type of the feed to create. * @param type of the feed to create.
* *
*/ */
protected WireFeed(String type) { protected WireFeed(final String type) {
this(); this();
_feedType = type; this._feedType = type;
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if (other == null) { if (other == null) {
return false; return false;
} }
if (!(other instanceof WireFeed)){ if (!(other instanceof WireFeed)) {
return false; return false;
} }
// can't use foreign markup in equals, due to JDOM equals impl // can't use foreign markup in equals, due to JDOM equals impl
List<Element> fm = getForeignMarkup(); final List<Element> fm = getForeignMarkup();
setForeignMarkup(((WireFeed)other).getForeignMarkup()); setForeignMarkup(((WireFeed) other).getForeignMarkup());
boolean ret = _objBean.equals(other); final boolean ret = this._objBean.equals(other);
// restore foreign markup // restore foreign markup
setForeignMarkup(fm); setForeignMarkup(fm);
return ret; return ret;
@ -109,124 +115,133 @@ public abstract class WireFeed implements Cloneable, Serializable, Extendable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Sets the feedType of a the feed. <b>Do not use</b>, for bean cloning purposes only. * Sets the feedType of a the feed. <b>Do not use</b>, for bean cloning
* purposes only.
* <p> * <p>
*
* @param feedType the feedType of the feed. * @param feedType the feedType of the feed.
* *
*/ */
public void setFeedType(String feedType) { public void setFeedType(final String feedType) {
_feedType = feedType; this._feedType = feedType;
} }
/** /**
* Returns the type of the feed. * Returns the type of the feed.
* *
* @return the type of the feed. * @return the type of the feed.
*/ */
public String getFeedType() { public String getFeedType() {
return _feedType; return this._feedType;
} }
/** /**
* Returns the charset encoding of a the feed. * Returns the charset encoding of a the feed.
* <p> * <p>
* This property is not set by feed parsers. But it is used by feed generators * This property is not set by feed parsers. But it is used by feed
* to set the encoding in the XML prolog. * generators to set the encoding in the XML prolog.
* <p> * <p>
*
* @return the charset encoding of the feed. * @return the charset encoding of the feed.
* *
*/ */
public String getEncoding() { public String getEncoding() {
return _encoding; return this._encoding;
} }
/** /**
* Sets the charset encoding of a the feed. * Sets the charset encoding of a the feed.
* <p> * <p>
* This property is not set by feed parsers. But it is used by feed generators * This property is not set by feed parsers. But it is used by feed
* to set the encoding in the XML prolog. * generators to set the encoding in the XML prolog.
* <p> * <p>
*
* @param encoding the charset encoding of the feed. * @param encoding the charset encoding of the feed.
* *
*/ */
public void setEncoding(String encoding) { public void setEncoding(final String encoding) {
_encoding = encoding; this._encoding = encoding;
} }
/** /**
* Returns the channel modules. * Returns the channel modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the channel modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the channel modules, an empty
* * list if none.
*
*/ */
@Override
public List<Module> getModules() { public List<Module> getModules() {
return (_modules==null) ? (_modules=new ArrayList<Module>()) : _modules; return this._modules == null ? (this._modules = new ArrayList<Module>()) : this._modules;
} }
/** /**
* Sets the channel modules. * Sets the channel modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the channel modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the channel modules
* * to set, an empty list or <b>null</b> if none.
*
*/ */
public void setModules(List<Module> modules) { @Override
_modules = modules; public void setModules(final List<Module> modules) {
this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
public Module getModule(String uri) { @Override
return ModuleUtils.getModule(_modules,uri); public Module getModule(final String uri) {
return ModuleUtils.getModule(this._modules, uri);
} }
/** /**
* Returns foreign markup found at channel level. * Returns foreign markup found at channel level.
* <p> * <p>
*
* @return Opaque object to discourage use * @return Opaque object to discourage use
* *
*/ */
public List<Element> getForeignMarkup() { public List<Element> getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList<Element>()) : _foreignMarkup; return this._foreignMarkup == null ? (this._foreignMarkup = new ArrayList<Element>()) : this._foreignMarkup;
} }
/** /**
* Sets foreign markup found at channel level. * Sets foreign markup found at channel level.
* <p> * <p>
*
* @param foreignMarkup Opaque object to discourage use * @param foreignMarkup Opaque object to discourage use
* *
*/ */
public void setForeignMarkup(List<Element> foreignMarkup) { public void setForeignMarkup(final List<Element> foreignMarkup) {
_foreignMarkup = (List<Element>)foreignMarkup; this._foreignMarkup = foreignMarkup;
} }
} }

View file

@ -16,58 +16,63 @@
*/ */
package com.sun.syndication.feed.atom; package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for category elements of Atom feeds. * Bean for category elements of Atom feeds.
* <p> * <p>
*
* @author Dave Johnson (added for Atom 1.0) * @author Dave Johnson (added for Atom 1.0)
*/ */
public class Category implements Cloneable, Serializable { public class Category implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _term; private String _term;
private String _scheme; private String _scheme;
private String _schemeResolved; private String _schemeResolved;
private String _label; private String _label;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Category() { public Category() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Category)){ if (!(other instanceof Category)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -75,84 +80,92 @@ public class Category implements Cloneable, Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Get label for category. * Get label for category.
* <p> * <p>
*
* @return Label for category. * @return Label for category.
*/ */
public String getLabel() { public String getLabel() {
return _label; return this._label;
} }
/** /**
* Set label for category. * Set label for category.
* <p> * <p>
*
* @param label Label for category. * @param label Label for category.
*/ */
public void setLabel(String label) { public void setLabel(final String label) {
this._label = label; this._label = label;
} }
/** /**
* Get Scheme URI for category. * Get Scheme URI for category.
* <p> * <p>
*
* @return Scheme URI for category. * @return Scheme URI for category.
*/ */
public String getScheme() { public String getScheme() {
return _scheme; return this._scheme;
} }
/** /**
* Set scheme URI for category. * Set scheme URI for category.
* <p> * <p>
*
* @param scheme Scheme URI for category. * @param scheme Scheme URI for category.
*/ */
public void setScheme(String scheme) { public void setScheme(final String scheme) {
this._scheme = scheme; this._scheme = scheme;
} }
public void setSchemeResolved(String schemeResolved) { public void setSchemeResolved(final String schemeResolved) {
_schemeResolved = schemeResolved; this._schemeResolved = schemeResolved;
} }
public String getSchemeResolved() { public String getSchemeResolved() {
return _schemeResolved != null ? _schemeResolved : _scheme; return this._schemeResolved != null ? this._schemeResolved : this._scheme;
} }
/** /**
* Return term for category. * Return term for category.
* <p> * <p>
*
* @return Term for category. * @return Term for category.
*/ */
public String getTerm() { public String getTerm() {
return _term; return this._term;
} }
/** /**
* Set term for category. * Set term for category.
* <p> * <p>
*
* @param term Term for category. * @param term Term for category.
*/ */
public void setTerm(String term) { public void setTerm(final String term) {
this._term = term; this._term = term;
} }
} }

View file

@ -16,45 +16,46 @@
*/ */
package com.sun.syndication.feed.atom; package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for content elements of Atom feeds. * Bean for content elements of Atom feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
*/ */
public class Content implements Cloneable,Serializable { public class Content implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _type; private String _type;
private String _value; private String _value;
private String _src; private String _src;
/** @since Atom 1.0 */ /** @since Atom 1.0 */
public static final String TEXT = "text"; public static final String TEXT = "text";
/** @since Atom 1.0 */ /** @since Atom 1.0 */
public static final String HTML = "html"; public static final String HTML = "html";
/** @since Atom 1.0 */ /** @since Atom 1.0 */
public static final String XHTML = "xhtml"; public static final String XHTML = "xhtml";
/** Atom 0.3 only */ /** Atom 0.3 only */
public static final String XML = "xml"; public static final String XML = "xml";
/** Atom 0.3 only */
public static final String BASE64 = "base64";
/** Atom 0.3 only */
public static final String ESCAPED = "escaped";
private String _mode; /** Atom 0.3 only */
public static final String BASE64 = "base64";
/** Atom 0.3 only */
public static final String ESCAPED = "escaped";
private String _mode;
private static final Set<String> MODES = new HashSet<String>(); private static final Set<String> MODES = new HashSet<String>();
static { static {
MODES.add(XML); MODES.add(XML);
@ -62,41 +63,44 @@ public class Content implements Cloneable,Serializable {
MODES.add(ESCAPED); MODES.add(ESCAPED);
} }
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Content() { public Content() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Content)){ if (!(other instanceof Content)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -104,23 +108,25 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
@ -128,10 +134,11 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* The type indicates how the value was/will-be encoded in the XML feed. * The type indicates how the value was/will-be encoded in the XML feed.
* </p> * </p>
*
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
@ -139,10 +146,11 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* The type indicates how the value was/will-be encoded in the XML feed. * The type indicates how the value was/will-be encoded in the XML feed.
* </p> * </p>
*
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setType(String type) { public void setType(final String type) {
_type = type; this._type = type;
} }
/** /**
@ -150,10 +158,11 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* The mode indicates how the value was/will-be encoded in the XML feed. * The mode indicates how the value was/will-be encoded in the XML feed.
* <p> * <p>
*
* @return the content mode, <b>null</b> if none. * @return the content mode, <b>null</b> if none.
*/ */
public String getMode() { public String getMode() {
return _mode; return this._mode;
} }
/** /**
@ -161,14 +170,15 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* The mode indicates how the value was/will-be encoded in the XML feed. * The mode indicates how the value was/will-be encoded in the XML feed.
* <p> * <p>
*
* @param mode the content mode, <b>null</b> if none. * @param mode the content mode, <b>null</b> if none.
*/ */
public void setMode(String mode) { public void setMode(String mode) {
mode = (mode!=null) ? mode.toLowerCase() : null; mode = mode != null ? mode.toLowerCase() : null;
if (mode==null || !MODES.contains(mode)) { if (mode == null || !MODES.contains(mode)) {
throw new IllegalArgumentException("Invalid mode ["+mode+"]"); throw new IllegalArgumentException("Invalid mode [" + mode + "]");
} }
_mode = mode; this._mode = mode;
} }
/** /**
@ -176,11 +186,12 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* The return value should be decoded. * The return value should be decoded.
* <p> * <p>
*
* @return the content value, <b>null</b> if none. * @return the content value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
@ -188,32 +199,33 @@ public class Content implements Cloneable,Serializable {
* <p> * <p>
* The value being set should be decoded. * The value being set should be decoded.
* <p> * <p>
*
* @param value the content value, <b>null</b> if none. * @param value the content value, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
/** /**
* Returns the src * Returns the src
* <p> * <p>
*
* @return Returns the src. * @return Returns the src.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getSrc() { public String getSrc() {
return _src; return this._src;
} }
/** /**
* Set the src * Set the src
* <p> * <p>
*
* @param src The src to set. * @param src The src to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setSrc(String src) { public void setSrc(final String src) {
_src = src; this._src = src;
} }
} }

View file

@ -19,7 +19,6 @@ package com.sun.syndication.feed.atom;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jdom2.Element; import org.jdom2.Element;
@ -29,10 +28,10 @@ import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils; import com.sun.syndication.feed.module.impl.ModuleUtils;
/** /**
* Bean for entry elements of Atom feeds. * Bean for entry elements of Atom feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
*/ */
@ -40,7 +39,7 @@ public class Entry implements Cloneable, Serializable, Extendable {
private Content _summary; private Content _summary;
private Content _title; private Content _title;
private Date _created; // Atom 0.3 only private Date _created; // Atom 0.3 only
private Date _published; // AKA issued private Date _published; // AKA issued
private Date _updated; // AKA modified private Date _updated; // AKA modified
private Feed _source; private Feed _source;
private List<Link> _alternateLinks; private List<Link> _alternateLinks;
@ -51,7 +50,7 @@ public class Entry implements Cloneable, Serializable, Extendable {
private List<Element> _foreignMarkup; private List<Element> _foreignMarkup;
private List<Module> _modules; private List<Module> _modules;
private List<Link> _otherLinks; private List<Link> _otherLinks;
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _id; private String _id;
private String _rights; private String _rights;
private String _xmlBase; private String _xmlBase;
@ -59,201 +58,220 @@ public class Entry implements Cloneable, Serializable, Extendable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Entry() { public Entry() {
_objBean = new ObjectBean(this.getClass(), this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Sets the entry alternate links. * Sets the entry alternate links.
* <p> * <p>
* @param alternateLinks the list of Link elements with the entry alternate links to set, *
* an empty list or <b>null</b> if none. * @param alternateLinks the list of Link elements with the entry alternate
* links to set, an empty list or <b>null</b> if none.
*/ */
public void setAlternateLinks(List<Link> alternateLinks) { public void setAlternateLinks(final List<Link> alternateLinks) {
_alternateLinks = alternateLinks; this._alternateLinks = alternateLinks;
} }
/** /**
* Returns the entry alternate links. * Returns the entry alternate links.
* <p> * <p>
* @return a list of Link elements with the entry alternate links, an empty list if none. *
* @return a list of Link elements with the entry alternate links, an empty
* list if none.
*/ */
public List<Link> getAlternateLinks() { public List<Link> getAlternateLinks() {
return (_alternateLinks == null) ? (_alternateLinks = new ArrayList<Link>()) : _alternateLinks; return this._alternateLinks == null ? (this._alternateLinks = new ArrayList<Link>()) : this._alternateLinks;
} }
/** /**
* Sets the author of the entry. * Sets the author of the entry.
* <p> * <p>
*
* @param authors the author of the entry, <b>null</b> if none. * @param authors the author of the entry, <b>null</b> if none.
* *
*/ */
public void setAuthors(List<Person> authors) { public void setAuthors(final List<Person> authors) {
_authors = authors; this._authors = authors;
} }
/** /**
* Returns the entry author. * Returns the entry author.
* <p> * <p>
*
* @return the entry author, <b>null</b> if none. * @return the entry author, <b>null</b> if none.
* *
*/ */
public List<Person> getAuthors() { public List<Person> getAuthors() {
return (_authors == null) ? (_authors = new ArrayList<Person>()) : _authors; return this._authors == null ? (this._authors = new ArrayList<Person>()) : this._authors;
} }
/** /**
* Set the categories * Set the categories
* <p> * <p>
*
* @param categories The categories to set. * @param categories The categories to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setCategories(List<Category> categories) { public void setCategories(final List<Category> categories) {
_categories = categories; this._categories = categories;
} }
/** /**
* Returns the categories * Returns the categories
* <p> * <p>
*
* @return Returns the categories. * @return Returns the categories.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public List<Category> getCategories() { public List<Category> getCategories() {
return (_categories == null) ? (_categories = new ArrayList<Category>()) : _categories; return this._categories == null ? (this._categories = new ArrayList<Category>()) : this._categories;
} }
/** /**
* Sets the entry contents. * Sets the entry contents.
* <p> * <p>
* @param contents the list of Content elements with the entry contents to set, *
* an empty list or <b>null</b> if none. * @param contents the list of Content elements with the entry contents to
* set, an empty list or <b>null</b> if none.
*/ */
public void setContents(List<Content> contents) { public void setContents(final List<Content> contents) {
_contents = contents; this._contents = contents;
} }
/** /**
* Returns the entry contents. * Returns the entry contents.
* <p> * <p>
* @return a list of Content elements with the entry contents, *
* an empty list if none. * @return a list of Content elements with the entry contents, an empty list
* if none.
*/ */
public List<Content> getContents() { public List<Content> getContents() {
return (_contents == null) ? (_contents = new ArrayList<Content>()) : _contents; return this._contents == null ? (this._contents = new ArrayList<Content>()) : this._contents;
} }
/** /**
* Sets the entry contributors. * Sets the entry contributors.
* <p> * <p>
* @param contributors the list of Person elements with the entry contributors to set, *
* an empty list or <b>null</b> if none. * @param contributors the list of Person elements with the entry
* * contributors to set, an empty list or <b>null</b> if none.
*
*/ */
public void setContributors(List<Person> contributors) { public void setContributors(final List<Person> contributors) {
_contributors = contributors; this._contributors = contributors;
} }
/** /**
* Returns the entry contributors. * Returns the entry contributors.
* <p> * <p>
* @return a list of Person elements with the entry contributors, *
* an empty list if none. * @return a list of Person elements with the entry contributors, an empty
* * list if none.
*
*/ */
public List<Person> getContributors() { public List<Person> getContributors() {
return (_contributors == null) ? (_contributors = new ArrayList<Person>()) : _contributors; return this._contributors == null ? (this._contributors = new ArrayList<Person>()) : this._contributors;
} }
/** /**
* Sets the entry created date (Atom 0.3 only) * Sets the entry created date (Atom 0.3 only)
* <p> * <p>
*
* @param created the entry created date, <b>null</b> if none. * @param created the entry created date, <b>null</b> if none.
*/ */
public void setCreated(Date created) { public void setCreated(final Date created) {
_created = new Date(created.getTime()); this._created = new Date(created.getTime());
} }
/** /**
* Returns the entry created date (Atom 0.3 only) * Returns the entry created date (Atom 0.3 only)
* <p> * <p>
*
* @return the entry created date, <b>null</b> if none. * @return the entry created date, <b>null</b> if none.
*/ */
public Date getCreated() { public Date getCreated() {
return _created == null ? null : new Date(_created.getTime()); return this._created == null ? null : new Date(this._created.getTime());
} }
/** /**
* Sets foreign markup found at entry level. * Sets foreign markup found at entry level.
* <p> * <p>
*
* @param foreignMarkup Opaque object to discourage use * @param foreignMarkup Opaque object to discourage use
* *
*/ */
public void setForeignMarkup(List<Element> foreignMarkup) { public void setForeignMarkup(final List<Element> foreignMarkup) {
_foreignMarkup = (List<Element>) foreignMarkup; this._foreignMarkup = foreignMarkup;
} }
/** /**
* Returns foreign markup found at entry level. * Returns foreign markup found at entry level.
* <p> * <p>
*
* @return list of Opaque object to discourage use * @return list of Opaque object to discourage use
* *
*/ */
public List<Element> getForeignMarkup() { public List<Element> getForeignMarkup() {
return (_foreignMarkup == null) ? (_foreignMarkup = new ArrayList<Element>()) : _foreignMarkup; return this._foreignMarkup == null ? (this._foreignMarkup = new ArrayList<Element>()) : this._foreignMarkup;
} }
/** /**
* Sets the entry ID. * Sets the entry ID.
* <p> * <p>
*
* @param id the entry ID, <b>null</b> if none. * @param id the entry ID, <b>null</b> if none.
* *
*/ */
public void setId(String id) { public void setId(final String id) {
_id = id; this._id = id;
} }
/** /**
* Returns the entry ID. * Returns the entry ID.
* <p> * <p>
*
* @return the entry ID, <b>null</b> if none. * @return the entry ID, <b>null</b> if none.
* *
*/ */
public String getId() { public String getId() {
return _id; return this._id;
} }
/** /**
* Sets the entry issued date (Atom 0.3, maps to {@link #setPublished(java.util.Date)}). * Sets the entry issued date (Atom 0.3, maps to
* {@link #setPublished(java.util.Date)}).
* <p> * <p>
*
* @param issued the entry issued date, <b>null</b> if none. * @param issued the entry issued date, <b>null</b> if none.
*/ */
public void setIssued(Date issued) { public void setIssued(final Date issued) {
_published = issued == null ? null : new Date(issued.getTime()); this._published = issued == null ? null : new Date(issued.getTime());
} }
/** /**
* Returns the entry issued date (Atom 0.3, maps to {@link #getPublished()}). * Returns the entry issued date (Atom 0.3, maps to {@link #getPublished()}
* ).
* <p> * <p>
*
* @return the entry issued date, <b>null</b> if none. * @return the entry issued date, <b>null</b> if none.
*/ */
public Date getIssued() { public Date getIssued() {
return _published == null ? null : new Date(_published.getTime()); return this._published == null ? null : new Date(this._published.getTime());
} }
/** /**
* Returns true if entry is a media entry, i.e. has rel="edit-media". * Returns true if entry is a media entry, i.e. has rel="edit-media".
* *
* @return true if entry is a media entry * @return true if entry is a media entry
*/ */
public boolean isMediaEntry() { public boolean isMediaEntry() {
boolean mediaEntry = false; boolean mediaEntry = false;
List<Link> links = getOtherLinks(); final List<Link> links = getOtherLinks();
for (Iterator<Link> it = links.iterator(); it.hasNext();) {
Link link = it.next();
for (final Link link : links) {
if ("edit-media".equals(link.getRel())) { if ("edit-media".equals(link.getRel())) {
mediaEntry = true; mediaEntry = true;
@ -265,176 +283,198 @@ public class Entry implements Cloneable, Serializable, Extendable {
} }
/** /**
* Sets the entry modified date (Atom 0.3, maps to {@link #setUpdated(java.util.Date)}). * Sets the entry modified date (Atom 0.3, maps to
* {@link #setUpdated(java.util.Date)}).
* <p> * <p>
*
* @param modified the entry modified date, <b>null</b> if none. * @param modified the entry modified date, <b>null</b> if none.
*/ */
public void setModified(Date modified) { public void setModified(final Date modified) {
_updated = modified == null ? null : new Date(modified.getTime()); this._updated = modified == null ? null : new Date(modified.getTime());
} }
/** /**
* Returns the entry modified date (Atom 0.3, maps to {@link #getUpdated()}). * Returns the entry modified date (Atom 0.3, maps to {@link #getUpdated()}
* ).
* <p> * <p>
*
* @return the entry modified date, <b>null</b> if none. * @return the entry modified date, <b>null</b> if none.
*/ */
public Date getModified() { public Date getModified() {
return _updated == null ? null : new Date(_updated.getTime()); return this._updated == null ? null : new Date(this._updated.getTime());
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
public Module getModule(String uri) { @Override
return ModuleUtils.getModule(_modules, uri); public Module getModule(final String uri) {
return ModuleUtils.getModule(this._modules, uri);
} }
/** /**
* Sets the entry modules. * Sets the entry modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the entry modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the entry modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
public void setModules(List<Module> modules) { @Override
_modules = modules; public void setModules(final List<Module> modules) {
this._modules = modules;
} }
/** /**
* Returns the entry modules. * Returns the entry modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the entry modules, *
* an emtpy list if none. * @return a list of ModuleImpl elements with the entry modules, an emtpy
* * list if none.
*
*/ */
@Override
public List<Module> getModules() { public List<Module> getModules() {
return (_modules == null) ? (_modules = new ArrayList<Module>()) : _modules; return this._modules == null ? (this._modules = new ArrayList<Module>()) : this._modules;
} }
/** /**
* Sets the entry non-alternate links. * Sets the entry non-alternate links.
* <p> * <p>
* @param otherLinks the list Link elements with the entry non-alternate links to set, *
* an empty list or <b>null</b> if none. * @param otherLinks the list Link elements with the entry non-alternate
* links to set, an empty list or <b>null</b> if none.
*/ */
public void setOtherLinks(List<Link> otherLinks) { public void setOtherLinks(final List<Link> otherLinks) {
_otherLinks = otherLinks; this._otherLinks = otherLinks;
} }
/** /**
* Returns the entry non-alternate links. * Returns the entry non-alternate links.
* <p> * <p>
* @return the list of Link elements with the entry non-alternate links to set, *
* an empty list if none. * @return the list of Link elements with the entry non-alternate links to
* set, an empty list if none.
*/ */
public List<Link> getOtherLinks() { public List<Link> getOtherLinks() {
return (_otherLinks == null) ? (_otherLinks = new ArrayList<Link>()) : _otherLinks; return this._otherLinks == null ? (this._otherLinks = new ArrayList<Link>()) : this._otherLinks;
} }
/** /**
* Set the published * Set the published
* <p> * <p>
*
* @param published The published to set. * @param published The published to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setPublished(Date published) { public void setPublished(final Date published) {
_published = published == null ? null : new Date(published.getTime()); this._published = published == null ? null : new Date(published.getTime());
} }
/** /**
* Returns the published * Returns the published
* <p> * <p>
*
* @return Returns the published. * @return Returns the published.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public Date getPublished() { public Date getPublished() {
return _published == null ? null : new Date(_published.getTime()); return this._published == null ? null : new Date(this._published.getTime());
} }
/** /**
* Set the rights * Set the rights
* <p> * <p>
*
* @param rights The rights to set. * @param rights The rights to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setRights(String rights) { public void setRights(final String rights) {
_rights = rights; this._rights = rights;
} }
/** /**
* Returns the rights * Returns the rights
* <p> * <p>
*
* @return Returns the rights. * @return Returns the rights.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getRights() { public String getRights() {
return _rights; return this._rights;
} }
/** /**
* Set the source * Set the source
* <p> * <p>
*
* @param source The source to set. * @param source The source to set.
*/ */
public void setSource(Feed source) { public void setSource(final Feed source) {
_source = source; this._source = source;
} }
/** /**
* Returns the source * Returns the source
* <p> * <p>
*
* @return Returns the source. * @return Returns the source.
*/ */
public Feed getSource() { public Feed getSource() {
return _source; return this._source;
} }
/** /**
* Sets the entry summary. * Sets the entry summary.
* <p> * <p>
*
* @param summary the entry summary, <b>null</b> if none. * @param summary the entry summary, <b>null</b> if none.
* *
*/ */
public void setSummary(Content summary) { public void setSummary(final Content summary) {
_summary = summary; this._summary = summary;
} }
/** /**
* Returns the entry summary. * Returns the entry summary.
* <p> * <p>
* @return the entry summary, <b>null</b> if none. *
* * @return the entry summary, <b>null</b> if none.
*
*/ */
public Content getSummary() { public Content getSummary() {
return _summary; return this._summary;
} }
/** /**
* Sets the entry title. * Sets the entry title.
* <p> * <p>
*
* @param title the entry title, <b>null</b> if none. * @param title the entry title, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
if (_title == null) { if (this._title == null) {
_title = new Content(); this._title = new Content();
} }
_title.setValue(title); this._title.setValue(title);
} }
/** /**
* Returns the entry title. * Returns the entry title.
* <p> * <p>
*
* @return the entry title, <b>null</b> if none. * @return the entry title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
if (_title != null) { if (this._title != null) {
return _title.getValue(); return this._title.getValue();
} }
return null; return null;
@ -443,95 +483,105 @@ public class Entry implements Cloneable, Serializable, Extendable {
/** /**
* Sets the entry title as a text construct. * Sets the entry title as a text construct.
* <p> * <p>
*
* @param title the entry title, <b>null</b> if none. * @param title the entry title, <b>null</b> if none.
* *
*/ */
public void setTitleEx(Content title) { public void setTitleEx(final Content title) {
_title = title; this._title = title;
} }
/** /**
* Returns the entry title as a text construct. * Returns the entry title as a text construct.
* <p> * <p>
*
* @return the entry title, <b>null</b> if none. * @return the entry title, <b>null</b> if none.
* *
*/ */
public Content getTitleEx() { public Content getTitleEx() {
return _title; return this._title;
} }
/** /**
* Set the updated * Set the updated
* <p> * <p>
*
* @param updated The updated to set. * @param updated The updated to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setUpdated(Date updated) { public void setUpdated(final Date updated) {
_updated = updated == null? null : new Date(updated.getTime()); this._updated = updated == null ? null : new Date(updated.getTime());
} }
/** /**
* Returns the updated * Returns the updated
* <p> * <p>
*
* @return Returns the updated. * @return Returns the updated.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public Date getUpdated() { public Date getUpdated() {
return _updated == null ? null : new Date(_updated.getTime()); return this._updated == null ? null : new Date(this._updated.getTime());
} }
/** /**
* Set the xmlBase * Set the xmlBase
* <p> * <p>
*
* @param xmlBase The xmlBase to set. * @param xmlBase The xmlBase to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setXmlBase(String xmlBase) { public void setXmlBase(final String xmlBase) {
_xmlBase = xmlBase; this._xmlBase = xmlBase;
} }
/** /**
* Returns the xmlBase * Returns the xmlBase
* <p> * <p>
*
* @return Returns the xmlBase. * @return Returns the xmlBase.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getXmlBase() { public String getXmlBase() {
return _xmlBase; return this._xmlBase;
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if (other == null) { if (other == null) {
return false; return false;
} }
if(!(other instanceof Entry)){ if (!(other instanceof Entry)) {
return false; return false;
} }
// can't use foreign markup in equals, due to JDOM equals impl // can't use foreign markup in equals, due to JDOM equals impl
List<Element> fm = getForeignMarkup(); final List<Element> fm = getForeignMarkup();
setForeignMarkup(((Entry) other).getForeignMarkup()); setForeignMarkup(((Entry) other).getForeignMarkup());
boolean ret = _objBean.equals(other); final boolean ret = this._objBean.equals(other);
// restore foreign markup // restore foreign markup
setForeignMarkup(fm); setForeignMarkup(fm);
@ -543,29 +593,30 @@ public class Entry implements Cloneable, Serializable, Extendable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
public Link findRelatedLink(final String relation) {
public Link findRelatedLink(String relation){ for (final Link l : this._otherLinks) {
for(Link l : this._otherLinks){ if (relation.equals(l.getRel())) {
if(relation.equals(l.getRel())){
return l; return l;
} }
} }

View file

@ -16,512 +16,568 @@
*/ */
package com.sun.syndication.feed.atom; package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
/** /**
* Bean for Atom feeds. * Bean for Atom feeds.
* <p> * <p>
* It handles Atom feeds version 0.3 without loosing any feed information. * It handles Atom feeds version 0.3 without loosing any feed information.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
*/ */
public class Feed extends WireFeed { public class Feed extends WireFeed {
private String _xmlBase; private String _xmlBase;
private List<Category> _categories; private List<Category> _categories;
private List<Person> _authors; private List<Person> _authors;
private List<Person> _contributors; private List<Person> _contributors;
private Generator _generator; private Generator _generator;
private String _icon; private String _icon;
private String _id; private String _id;
private String _logo; private String _logo;
private String _rights; // AKA copyright private String _rights; // AKA copyright
private Content _subtitle; // AKA tagline private Content _subtitle; // AKA tagline
private Content _title; private Content _title;
private Date _updated; // AKA modified private Date _updated; // AKA modified
private List<Link> _alternateLinks; private List<Link> _alternateLinks;
private List<Link> _otherLinks; private List<Link> _otherLinks;
private List<Entry> _entries; private List<Entry> _entries;
private List<Module> _modules; private List<Module> _modules;
private Content _info; // Atom 0.3 only private Content _info; // Atom 0.3 only
private String _language; // Atom 0.3 only private String _language; // Atom 0.3 only
/** /**
* Default constructor, for bean cloning purposes only. * Default constructor, for bean cloning purposes only.
* *
*/ */
public Feed() { public Feed() {
} }
/** /**
* Feed Constructor. All properties, except the type, are set to <b>null</b>. * Feed Constructor. All properties, except the type, are set to
* <b>null</b>.
* <p> * <p>
*
* @param type the type of the Atom feed. * @param type the type of the Atom feed.
* *
*/ */
public Feed(String type) { public Feed(final String type) {
super(type); super(type);
} }
/** /**
* Returns the feed language (Atom 0.3 only) * Returns the feed language (Atom 0.3 only)
* <p> * <p>
*
* @return the feed language, <b>null</b> if none. * @return the feed language, <b>null</b> if none.
* *
*/ */
public String getLanguage() { public String getLanguage() {
return _language; return this._language;
} }
/** /**
* Sets the feed language (Atom 0.3 only) * Sets the feed language (Atom 0.3 only)
* <p> * <p>
*
* @param language the feed language to set, <b>null</b> if none. * @param language the feed language to set, <b>null</b> if none.
* *
*/ */
public void setLanguage(String language) { public void setLanguage(final String language) {
_language = language; this._language = language;
} }
/** /**
* Returns the feed title. * Returns the feed title.
* <p> * <p>
*
* @return the feed title, <b>null</b> if none. * @return the feed title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
if (_title != null) return _title.getValue(); if (this._title != null) {
return this._title.getValue();
}
return null; return null;
} }
/** /**
* Sets the feed title. * Sets the feed title.
* <p> * <p>
*
* @param title the feed title to set, <b>null</b> if none. * @param title the feed title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
if (_title == null) _title = new Content(); if (this._title == null) {
_title.setValue(title); this._title = new Content();
}
this._title.setValue(title);
} }
/** /**
* Returns the feed title. * Returns the feed title.
* <p> * <p>
*
* @return the feed title, <b>null</b> if none. * @return the feed title, <b>null</b> if none.
* *
*/ */
public Content getTitleEx() { public Content getTitleEx() {
return _title; return this._title;
} }
/** /**
* Sets the feed title. * Sets the feed title.
* <p> * <p>
*
* @param title the feed title to set, <b>null</b> if none. * @param title the feed title to set, <b>null</b> if none.
* *
*/ */
public void setTitleEx(Content title) { public void setTitleEx(final Content title) {
_title = title; this._title = title;
} }
/** /**
* Returns the feed alternate links. * Returns the feed alternate links.
* <p> * <p>
* @return a list of Link elements with the feed alternate links, *
* an empty list if none. * @return a list of Link elements with the feed alternate links, an empty
* list if none.
*/ */
public List<Link> getAlternateLinks() { public List<Link> getAlternateLinks() {
return (_alternateLinks==null) ? (_alternateLinks=new ArrayList<Link>()) : _alternateLinks; return this._alternateLinks == null ? (this._alternateLinks = new ArrayList<Link>()) : this._alternateLinks;
} }
/** /**
* Sets the feed alternate links. * Sets the feed alternate links.
* <p> * <p>
* @param alternateLinks the list of Link elements with the feed alternate links to set, *
* an empty list or <b>null</b> if none. * @param alternateLinks the list of Link elements with the feed alternate
* links to set, an empty list or <b>null</b> if none.
*/ */
public void setAlternateLinks(List<Link> alternateLinks) { public void setAlternateLinks(final List<Link> alternateLinks) {
_alternateLinks = alternateLinks; this._alternateLinks = alternateLinks;
} }
/** /**
* Returns the feed other links (non-alternate ones). * Returns the feed other links (non-alternate ones).
* <p> * <p>
* @return a list of Link elements with the feed other links (non-alternate ones), *
* an empty list if none. * @return a list of Link elements with the feed other links (non-alternate
* ones), an empty list if none.
*/ */
public List<Link> getOtherLinks() { public List<Link> getOtherLinks() {
return (_otherLinks==null) ? (_otherLinks=new ArrayList<Link>()) : _otherLinks; return this._otherLinks == null ? (this._otherLinks = new ArrayList<Link>()) : this._otherLinks;
} }
/** /**
* Sets the feed other links (non-alternate ones). * Sets the feed other links (non-alternate ones).
* <p> * <p>
* @param otherLinks the list of Link elements with the feed other links (non-alternate ones) to set, *
* an empty list or <b>null</b> if none. * @param otherLinks the list of Link elements with the feed other links
* (non-alternate ones) to set, an empty list or <b>null</b> if
* none.
*/ */
public void setOtherLinks(List<Link> otherLinks) { public void setOtherLinks(final List<Link> otherLinks) {
_otherLinks = otherLinks; this._otherLinks = otherLinks;
} }
/** /**
* Returns the feed author. * Returns the feed author.
* <p> * <p>
*
* @return the feed author, <b>null</b> if none. * @return the feed author, <b>null</b> if none.
* *
*/ */
public List<Person> getAuthors() { public List<Person> getAuthors() {
return (_authors==null) ? (_authors=new ArrayList<Person>()) : _authors; return this._authors == null ? (this._authors = new ArrayList<Person>()) : this._authors;
} }
/** /**
* Sets the feed author. * Sets the feed author.
* <p> * <p>
*
* @param authors the feed author to set, <b>null</b> if none. * @param authors the feed author to set, <b>null</b> if none.
* *
*/ */
public void setAuthors(List<Person> authors) { public void setAuthors(final List<Person> authors) {
_authors = authors; this._authors = authors;
} }
/** /**
* Returns the feed contributors. * Returns the feed contributors.
* <p> * <p>
* @return a list of Person elements with the feed contributors, *
* an empty list if none. * @return a list of Person elements with the feed contributors, an empty
* * list if none.
*
*/ */
public List<Person> getContributors() { public List<Person> getContributors() {
return (_contributors==null) ? (_contributors=new ArrayList<Person>()) : _contributors; return this._contributors == null ? (this._contributors = new ArrayList<Person>()) : this._contributors;
} }
/** /**
* Sets the feed contributors. * Sets the feed contributors.
* <p> * <p>
* @param contributors the list of Person elements with the feed contributors to set, *
* an empty list or <b>null</b> if none. * @param contributors the list of Person elements with the feed
* * contributors to set, an empty list or <b>null</b> if none.
*
*/ */
public void setContributors(List<Person> contributors) { public void setContributors(final List<Person> contributors) {
_contributors = contributors; this._contributors = contributors;
} }
/** /**
* Returns the feed tag line (Atom 0.3, maps to {@link #getSubtitle()}). * Returns the feed tag line (Atom 0.3, maps to {@link #getSubtitle()}).
* <p> * <p>
*
* @return the feed tag line, <b>null</b> if none. * @return the feed tag line, <b>null</b> if none.
*/ */
public Content getTagline() { public Content getTagline() {
return _subtitle; return this._subtitle;
} }
/** /**
* Sets the feed tagline (Atom 0.3, maps to {@link #setSubtitle(com.sun.syndication.feed.atom.Content)}). * Sets the feed tagline (Atom 0.3, maps to
* {@link #setSubtitle(com.sun.syndication.feed.atom.Content)}).
* <p> * <p>
*
* @param tagline the feed tagline to set, <b>null</b> if none. * @param tagline the feed tagline to set, <b>null</b> if none.
*/ */
public void setTagline(Content tagline) { public void setTagline(final Content tagline) {
_subtitle = tagline; this._subtitle = tagline;
} }
/** /**
* Returns the feed ID. * Returns the feed ID.
* <p> * <p>
*
* @return the feed ID, <b>null</b> if none. * @return the feed ID, <b>null</b> if none.
* *
*/ */
public String getId() { public String getId() {
return _id; return this._id;
} }
/** /**
* Sets the feed ID. * Sets the feed ID.
* <p> * <p>
*
* @param id the feed ID to set, <b>null</b> if none. * @param id the feed ID to set, <b>null</b> if none.
* *
*/ */
public void setId(String id) { public void setId(final String id) {
_id = id; this._id = id;
} }
/** /**
* Returns the feed generator. * Returns the feed generator.
* <p> * <p>
*
* @return the feed generator, <b>null</b> if none. * @return the feed generator, <b>null</b> if none.
* *
*/ */
public Generator getGenerator() { public Generator getGenerator() {
return _generator; return this._generator;
} }
/** /**
* Sets the feed generator. * Sets the feed generator.
* <p> * <p>
*
* @param generator the feed generator to set, <b>null</b> if none. * @param generator the feed generator to set, <b>null</b> if none.
* *
*/ */
public void setGenerator(Generator generator) { public void setGenerator(final Generator generator) {
_generator = generator; this._generator = generator;
} }
/** /**
* Returns the feed copyright (Atom 0.3, maps to {@link #getRights()}). * Returns the feed copyright (Atom 0.3, maps to {@link #getRights()}).
* <p> * <p>
*
* @return the feed copyright, <b>null</b> if none. * @return the feed copyright, <b>null</b> if none.
*/ */
public String getCopyright() { public String getCopyright() {
return _rights; return this._rights;
} }
/** /**
* Sets the feed copyright (Atom 0.3, maps to {@link #setRights(java.lang.String)}). * Sets the feed copyright (Atom 0.3, maps to
* {@link #setRights(java.lang.String)}).
* <p> * <p>
*
* @param copyright the feed copyright to set, <b>null</b> if none. * @param copyright the feed copyright to set, <b>null</b> if none.
*/ */
public void setCopyright(String copyright) { public void setCopyright(final String copyright) {
_rights = copyright; this._rights = copyright;
} }
/** /**
* Returns the feed info (Atom 0.3 only) * Returns the feed info (Atom 0.3 only)
* <p> * <p>
*
* @return the feed info, <b>null</b> if none. * @return the feed info, <b>null</b> if none.
*/ */
public Content getInfo() { public Content getInfo() {
return _info; return this._info;
} }
/** /**
* Sets the feed info (Atom 0.3 only) * Sets the feed info (Atom 0.3 only)
* <p> * <p>
*
* @param info the feed info to set, <b>null</b> if none. * @param info the feed info to set, <b>null</b> if none.
*/ */
public void setInfo(Content info) { public void setInfo(final Content info) {
_info = info; this._info = info;
} }
/** /**
* Returns the feed modified date (Atom 0.3, maps to {@link #getUpdated()}). * Returns the feed modified date (Atom 0.3, maps to {@link #getUpdated()}).
* <p> * <p>
*
* @return the feed modified date, <b>null</b> if none. * @return the feed modified date, <b>null</b> if none.
*/ */
public Date getModified() { public Date getModified() {
return _updated; return this._updated;
} }
/** /**
* Sets the feed modified date (Atom 0.3, maps to {@link #setUpdated(java.util.Date)}). * Sets the feed modified date (Atom 0.3, maps to
* {@link #setUpdated(java.util.Date)}).
* <p> * <p>
*
* @param modified the feed modified date to set, <b>null</b> if none. * @param modified the feed modified date to set, <b>null</b> if none.
*/ */
public void setModified(Date modified) { public void setModified(final Date modified) {
_updated = modified; this._updated = modified;
} }
/** /**
* Returns the feed entries. * Returns the feed entries.
* <p> * <p>
* @return a list of Entry elements with the feed entries, *
* an empty list if none. * @return a list of Entry elements with the feed entries, an empty list if
* * none.
*
*/ */
public List<Entry> getEntries() { public List<Entry> getEntries() {
return (_entries==null) ? (_entries=new ArrayList<Entry>()) : _entries; return this._entries == null ? (this._entries = new ArrayList<Entry>()) : this._entries;
} }
/** /**
* Sets the feed entries. * Sets the feed entries.
* <p> * <p>
*
* @param entries the list of Entry elements with the feed entries to set, * @param entries the list of Entry elements with the feed entries to set,
* an empty list or <b>null</b> if none. * an empty list or <b>null</b> if none.
* *
*/ */
public void setEntries(List<Entry> entries) { public void setEntries(final List<Entry> entries) {
_entries = entries; this._entries = entries;
} }
/** /**
* Returns the feed modules. * Returns the feed modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the feed modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the feed modules, an empty
* * list if none.
*
*/ */
@Override
public List<Module> getModules() { public List<Module> getModules() {
return (_modules==null) ? (_modules=new ArrayList<Module>()) : _modules; return this._modules == null ? (this._modules = new ArrayList<Module>()) : this._modules;
} }
/** /**
* Sets the feed moduless. * Sets the feed moduless.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the feed moduless to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the feed moduless to
* * set, an empty list or <b>null</b> if none.
*
*/ */
@Override @Override
public void setModules(List<Module> modules) { public void setModules(final List<Module> modules) {
_modules = modules; this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
@Override @Override
public Module getModule(String uri) { public Module getModule(final String uri) {
return ModuleUtils.getModule(_modules,uri); return ModuleUtils.getModule(this._modules, uri);
} }
/** /**
* Returns the categories * Returns the categories
* <p> * <p>
*
* @return Returns the categories. * @return Returns the categories.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public List<Category> getCategories() { public List<Category> getCategories() {
return (_categories==null) ? (_categories=new ArrayList<Category>()) : _categories; return this._categories == null ? (this._categories = new ArrayList<Category>()) : this._categories;
} }
/** /**
* Set the categories * Set the categories
* <p> * <p>
*
* @param categories The categories to set. * @param categories The categories to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setCategories(List<Category> categories) { public void setCategories(final List<Category> categories) {
_categories = categories; this._categories = categories;
} }
/** /**
* Returns the icon * Returns the icon
* <p> * <p>
*
* @return Returns the icon. * @return Returns the icon.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getIcon() { public String getIcon() {
return _icon; return this._icon;
} }
/** /**
* Set the icon * Set the icon
* <p> * <p>
*
* @param icon The icon to set. * @param icon The icon to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setIcon(String icon) { public void setIcon(final String icon) {
_icon = icon; this._icon = icon;
} }
/** /**
* Returns the logo * Returns the logo
* <p> * <p>
*
* @return Returns the logo. * @return Returns the logo.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getLogo() { public String getLogo() {
return _logo; return this._logo;
} }
/** /**
* Set the logo * Set the logo
* <p> * <p>
*
* @param logo The logo to set. * @param logo The logo to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setLogo(String logo) { public void setLogo(final String logo) {
_logo = logo; this._logo = logo;
} }
/** /**
* Returns the rights * Returns the rights
* <p> * <p>
*
* @return Returns the rights. * @return Returns the rights.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getRights() { public String getRights() {
return _rights; return this._rights;
} }
/** /**
* Set the rights * Set the rights
* <p> * <p>
*
* @param rights The rights to set. * @param rights The rights to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setRights(String rights) { public void setRights(final String rights) {
_rights = rights; this._rights = rights;
} }
/** /**
* Returns the subtitle * Returns the subtitle
* <p> * <p>
*
* @return Returns the subtitle. * @return Returns the subtitle.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public Content getSubtitle() { public Content getSubtitle() {
return _subtitle; return this._subtitle;
} }
/** /**
* Set the subtitle * Set the subtitle
* <p> * <p>
*
* @param subtitle The subtitle to set. * @param subtitle The subtitle to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setSubtitle(Content subtitle) { public void setSubtitle(final Content subtitle) {
_subtitle = subtitle; this._subtitle = subtitle;
} }
/** /**
* Returns the updated * Returns the updated
* <p> * <p>
*
* @return Returns the updated. * @return Returns the updated.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public Date getUpdated() { public Date getUpdated() {
return _updated; return this._updated;
} }
/** /**
* Set the updated * Set the updated
* <p> * <p>
*
* @param updated The updated to set. * @param updated The updated to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setUpdated(Date updated) { public void setUpdated(final Date updated) {
_updated = updated; this._updated = updated;
} }
/** /**
* Returns the xmlBase * Returns the xmlBase
* <p> * <p>
*
* @return Returns the xmlBase. * @return Returns the xmlBase.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getXmlBase() { public String getXmlBase() {
return _xmlBase; return this._xmlBase;
} }
/** /**
* Set the xmlBase * Set the xmlBase
* <p> * <p>
*
* @param xmlBase The xmlBase to set. * @param xmlBase The xmlBase to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setXmlBase(String xmlBase) { public void setXmlBase(final String xmlBase) {
_xmlBase = xmlBase; this._xmlBase = xmlBase;
} }
} }

View file

@ -16,18 +16,19 @@
*/ */
package com.sun.syndication.feed.atom; package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for the generator element of Atom feeds. * Bean for the generator element of Atom feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Generator implements Cloneable,Serializable { public class Generator implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _url; private String _url;
private String _version; private String _version;
private String _value; private String _value;
@ -35,37 +36,41 @@ public class Generator implements Cloneable,Serializable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Generator() { public Generator() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Generator)){ if (!(other instanceof Generator)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -73,83 +78,91 @@ public class Generator implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the generator URL. * Returns the generator URL.
* <p> * <p>
* @return the generator URL, <b>null</b> if none. *
* * @return the generator URL, <b>null</b> if none.
*/ *
*/
public String getUrl() { public String getUrl() {
return _url; return this._url;
} }
/** /**
* Sets the generator URL. * Sets the generator URL.
* <p> * <p>
* @param url the generator URL, <b>null</b> if none. *
* * @param url the generator URL, <b>null</b> if none.
*/ *
public void setUrl(String url) { */
_url = url; public void setUrl(final String url) {
this._url = url;
} }
/** /**
* Returns the generator version. * Returns the generator version.
* <p> * <p>
*
* @return the generator version, <b>null</b> if none. * @return the generator version, <b>null</b> if none.
* *
*/ */
public String getVersion() { public String getVersion() {
return _version; return this._version;
} }
/** /**
* Sets the generator version. * Sets the generator version.
* <p> * <p>
*
* @param version the generator version, <b>null</b> if none. * @param version the generator version, <b>null</b> if none.
* *
*/ */
public void setVersion(String version) { public void setVersion(final String version) {
_version = version; this._version = version;
} }
/** /**
* Returns the generator value. * Returns the generator value.
* <p> * <p>
*
* @return the generator value, <b>null</b> if none. * @return the generator value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the generator value. * Sets the generator value.
* <p> * <p>
*
* @param value the generator value, <b>null</b> if none. * @param value the generator value, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
} }

View file

@ -16,59 +16,64 @@
*/ */
package com.sun.syndication.feed.atom; package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for link elements of Atom feeds. * Bean for link elements of Atom feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
*/ */
public class Link implements Cloneable,Serializable { public class Link implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _href; private String _href;
private String _hrefResolved; private String _hrefResolved;
private String _rel = "alternate"; private String _rel = "alternate";
private String _type; private String _type;
private String _hreflang; private String _hreflang;
private String _title; private String _title;
private long _length; private long _length;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Link() { public Link() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -76,149 +81,163 @@ public class Link implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the link rel. * Returns the link rel.
* <p> * <p>
*
* @return the link rel, <b>null</b> if none. * @return the link rel, <b>null</b> if none.
* *
*/ */
public String getRel() { public String getRel() {
return _rel; return this._rel;
} }
/** /**
* Sets the link rel. * Sets the link rel.
* <p> * <p>
*
* @param rel the link rel,, <b>null</b> if none. * @param rel the link rel,, <b>null</b> if none.
* *
*/ */
public void setRel(String rel) { public void setRel(final String rel) {
//TODO add check, ask P@ about the check // TODO add check, ask P@ about the check
_rel = rel; this._rel = rel;
} }
/** /**
* Returns the link type. * Returns the link type.
* <p> * <p>
*
* @return the link type, <b>null</b> if none. * @return the link type, <b>null</b> if none.
* *
*/ */
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the link type. * Sets the link type.
* <p> * <p>
*
* @param type the link type, <b>null</b> if none. * @param type the link type, <b>null</b> if none.
* *
*/ */
public void setType(String type) { public void setType(final String type) {
_type = type; this._type = type;
} }
/** /**
* Returns the link href. * Returns the link href.
* <p> * <p>
*
* @return the link href, <b>null</b> if none. * @return the link href, <b>null</b> if none.
* *
*/ */
public String getHref() { public String getHref() {
return _href; return this._href;
} }
/** /**
* Sets the link href. * Sets the link href.
* <p> * <p>
*
* @param href the link href, <b>null</b> if none. * @param href the link href, <b>null</b> if none.
* *
*/ */
public void setHref(String href) { public void setHref(final String href) {
_href = href; this._href = href;
} }
public void setHrefResolved(String hrefResolved) { public void setHrefResolved(final String hrefResolved) {
_hrefResolved = hrefResolved; this._hrefResolved = hrefResolved;
} }
public String getHrefResolved() { public String getHrefResolved() {
return _hrefResolved != null ? _hrefResolved : _href; return this._hrefResolved != null ? this._hrefResolved : this._href;
} }
/** /**
* Returns the link title. * Returns the link title.
* <p> * <p>
*
* @return the link title, <b>null</b> if none. * @return the link title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the link title. * Sets the link title.
* <p> * <p>
*
* @param title the link title, <b>null</b> if none. * @param title the link title, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
_title = title; this._title = title;
} }
/** /**
* Returns the hreflang * Returns the hreflang
* <p> * <p>
*
* @return Returns the hreflang. * @return Returns the hreflang.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getHreflang() { public String getHreflang() {
return _hreflang; return this._hreflang;
} }
/** /**
* Set the hreflang * Set the hreflang
* <p> * <p>
*
* @param hreflang The hreflang to set. * @param hreflang The hreflang to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setHreflang(String hreflang) { public void setHreflang(final String hreflang) {
_hreflang = hreflang; this._hreflang = hreflang;
} }
/** /**
* Returns the length * Returns the length
* <p> * <p>
*
* @return Returns the length. * @return Returns the length.
*/ */
public long getLength() { public long getLength() {
return _length; return this._length;
} }
/** /**
* Set the length * Set the length
* <p> * <p>
*
* @param length The length to set. * @param length The length to set.
*/ */
public void setLength(long length) { public void setLength(final long length) {
_length = length; this._length = length;
} }
} }

View file

@ -16,63 +16,67 @@
*/ */
package com.sun.syndication.feed.atom; package com.sun.syndication.feed.atom;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.sun.syndication.feed.impl.ObjectBean; import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.Extendable; import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils; import com.sun.syndication.feed.module.impl.ModuleUtils;
import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
/** /**
* Bean for person elements of Atom feeds. * Bean for person elements of Atom feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
*/ */
public class Person implements Cloneable,Serializable, Extendable public class Person implements Cloneable, Serializable, Extendable {
{
private final ObjectBean _objBean;
private ObjectBean _objBean;
private String _name; private String _name;
private String _uri; // since Atom 1.0 (was called url) private String _uri; // since Atom 1.0 (was called url)
private String _uriResolved; private String _uriResolved;
private String _email; private String _email;
private List<Module> _modules; private List<Module> _modules;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Person() { public Person() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -80,141 +84,157 @@ public class Person implements Cloneable,Serializable, Extendable
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the person name. * Returns the person name.
* <p> * <p>
* @return the person name, <b>null</b> if none. *
* * @return the person name, <b>null</b> if none.
*/ *
*/
public String getName() { public String getName() {
return _name; return this._name;
} }
/** /**
* Sets the personname. * Sets the personname.
* <p> * <p>
* @param name the person name, <b>null</b> if none. *
* * @param name the person name, <b>null</b> if none.
*/ *
public void setName(String name) { */
_name = name; public void setName(final String name) {
this._name = name;
} }
/** /**
* Returns the person URL (same as {@link #getUri()}) * Returns the person URL (same as {@link #getUri()})
* <p> * <p>
* @return the person URL, <b>null</b> if none. *
*/ * @return the person URL, <b>null</b> if none.
*/
public String getUrl() { public String getUrl() {
return _uri; return this._uri;
} }
/** /**
* Sets the person URL (same as {@link #setUri(java.lang.String)}) * Sets the person URL (same as {@link #setUri(java.lang.String)})
* <p> * <p>
* @param url the person URL, <b>null</b> if none. *
*/ * @param url the person URL, <b>null</b> if none.
public void setUrl(String url) { */
_uri = url; public void setUrl(final String url) {
this._uri = url;
} }
public void setUriResolved(String uriResolved) { public void setUriResolved(final String uriResolved) {
_uriResolved = uriResolved; this._uriResolved = uriResolved;
} }
public String getUriResolved(String resolveURI) { public String getUriResolved(final String resolveURI) {
return _uriResolved != null ? _uriResolved : _uri; return this._uriResolved != null ? this._uriResolved : this._uri;
} }
/** /**
* Returns the person email. * Returns the person email.
* <p> * <p>
* @return the person email, <b>null</b> if none. *
* * @return the person email, <b>null</b> if none.
*/ *
*/
public String getEmail() { public String getEmail() {
return _email; return this._email;
} }
/** /**
* Sets the person email. * Sets the person email.
* <p> * <p>
* @param email the person email, <b>null</b> if none. *
* * @param email the person email, <b>null</b> if none.
*/ *
public void setEmail(String email) { */
_email = email; public void setEmail(final String email) {
this._email = email;
} }
/** /**
* Returns the uri * Returns the uri
* <p> * <p>
*
* @return Returns the uri. * @return Returns the uri.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public String getUri() { public String getUri() {
return _uri; return this._uri;
} }
/** /**
* Set the uri * Set the uri
* <p> * <p>
*
* @param uri The uri to set. * @param uri The uri to set.
* @since Atom 1.0 * @since Atom 1.0
*/ */
public void setUri(String uri) { public void setUri(final String uri) {
_uri = uri; this._uri = uri;
} }
/** /**
* Returns the entry modules. * Returns the entry modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the entry modules, *
* an emtpy list if none. * @return a list of ModuleImpl elements with the entry modules, an emtpy
* * list if none.
*
*/ */
@Override
public List<Module> getModules() { public List<Module> getModules() {
return (_modules==null) ? (_modules=new ArrayList<Module>()) : _modules; return this._modules == null ? (this._modules = new ArrayList<Module>()) : this._modules;
} }
/** /**
* Sets the entry modules. * Sets the entry modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the entry modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the entry modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
public void setModules(List<Module> modules) { @Override
_modules = modules; public void setModules(final List<Module> modules) {
this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
public Module getModule(String uri) { @Override
return ModuleUtils.getModule(_modules,uri); public Module getModule(final String uri) {
return ModuleUtils.getModule(this._modules, uri);
} }
} }

View file

@ -21,35 +21,43 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* Obtains all property descriptors from a bean (interface or implementation). * Obtains all property descriptors from a bean (interface or implementation).
* <p> * <p>
* The java.beans.Introspector does not process the interfaces hierarchy chain, this one does. * The java.beans.Introspector does not process the interfaces hierarchy chain,
* this one does.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class BeanIntrospector { public class BeanIntrospector {
private static final Map _introspected = new HashMap(); private static final Map _introspected = new HashMap();
public static synchronized PropertyDescriptor[] getPropertyDescriptors(Class klass) throws IntrospectionException { public static synchronized PropertyDescriptor[] getPropertyDescriptors(final Class klass) throws IntrospectionException {
PropertyDescriptor[] descriptors = (PropertyDescriptor[]) _introspected.get(klass); PropertyDescriptor[] descriptors = (PropertyDescriptor[]) _introspected.get(klass);
if (descriptors==null) { if (descriptors == null) {
descriptors = getPDs(klass); descriptors = getPDs(klass);
_introspected.put(klass,descriptors); _introspected.put(klass, descriptors);
} }
return descriptors; return descriptors;
} }
private static PropertyDescriptor[] getPDs(Class klass) throws IntrospectionException { private static PropertyDescriptor[] getPDs(final Class klass) throws IntrospectionException {
Method[] methods = klass.getMethods(); final Method[] methods = klass.getMethods();
Map getters = getPDs(methods,false); final Map getters = getPDs(methods, false);
Map setters = getPDs(methods,true); final Map setters = getPDs(methods, true);
List pds = merge(getters,setters); final List pds = merge(getters, setters);
PropertyDescriptor[] array = new PropertyDescriptor[pds.size()]; final PropertyDescriptor[] array = new PropertyDescriptor[pds.size()];
pds.toArray(array); pds.toArray(array);
return array; return array;
} }
@ -58,63 +66,56 @@ public class BeanIntrospector {
private static final String GETTER = "get"; private static final String GETTER = "get";
private static final String BOOLEAN_GETTER = "is"; private static final String BOOLEAN_GETTER = "is";
private static Map getPDs(Method[] methods,boolean setters) throws IntrospectionException { private static Map getPDs(final Method[] methods, final boolean setters) throws IntrospectionException {
Map pds = new HashMap(); final Map pds = new HashMap();
for (int i=0;i<methods.length;i++) { for (final Method method : methods) {
String pName = null; String pName = null;
PropertyDescriptor pDescriptor = null; PropertyDescriptor pDescriptor = null;
if ((methods[i].getModifiers()&Modifier.PUBLIC)!=0) { if ((method.getModifiers() & Modifier.PUBLIC) != 0) {
if (setters) { if (setters) {
if (methods[i].getName().startsWith(SETTER) && if (method.getName().startsWith(SETTER) && method.getReturnType() == void.class && method.getParameterTypes().length == 1) {
methods[i].getReturnType()==void.class && methods[i].getParameterTypes().length==1) { pName = Introspector.decapitalize(method.getName().substring(3));
pName = Introspector.decapitalize(methods[i].getName().substring(3)); pDescriptor = new PropertyDescriptor(pName, null, method);
pDescriptor = new PropertyDescriptor(pName,null,methods[i]);
} }
} } else {
else { if (method.getName().startsWith(GETTER) && method.getReturnType() != void.class && method.getParameterTypes().length == 0) {
if (methods[i].getName().startsWith(GETTER) && pName = Introspector.decapitalize(method.getName().substring(3));
methods[i].getReturnType()!=void.class && methods[i].getParameterTypes().length==0) { pDescriptor = new PropertyDescriptor(pName, method, null);
pName = Introspector.decapitalize(methods[i].getName().substring(3)); } else if (method.getName().startsWith(BOOLEAN_GETTER) && method.getReturnType() == boolean.class && method.getParameterTypes().length == 0) {
pDescriptor = new PropertyDescriptor(pName,methods[i],null); pName = Introspector.decapitalize(method.getName().substring(2));
} pDescriptor = new PropertyDescriptor(pName, method, null);
else
if (methods[i].getName().startsWith(BOOLEAN_GETTER) &&
methods[i].getReturnType()==boolean.class && methods[i].getParameterTypes().length==0) {
pName = Introspector.decapitalize(methods[i].getName().substring(2));
pDescriptor = new PropertyDescriptor(pName,methods[i],null);
} }
} }
} }
if (pName!=null) { if (pName != null) {
pds.put(pName,pDescriptor); pds.put(pName, pDescriptor);
} }
} }
return pds; return pds;
} }
private static List merge(Map getters,Map setters) throws IntrospectionException { private static List merge(final Map getters, final Map setters) throws IntrospectionException {
List props = new ArrayList(); final List props = new ArrayList();
Set processedProps = new HashSet(); final Set processedProps = new HashSet();
Iterator gs = getters.keySet().iterator(); final Iterator gs = getters.keySet().iterator();
while (gs.hasNext()) { while (gs.hasNext()) {
String name = (String) gs.next(); final String name = (String) gs.next();
PropertyDescriptor getter = (PropertyDescriptor) getters.get(name); final PropertyDescriptor getter = (PropertyDescriptor) getters.get(name);
PropertyDescriptor setter = (PropertyDescriptor) setters.get(name); final PropertyDescriptor setter = (PropertyDescriptor) setters.get(name);
if (setter!=null) { if (setter != null) {
processedProps.add(name); processedProps.add(name);
PropertyDescriptor prop = new PropertyDescriptor(name,getter.getReadMethod(),setter.getWriteMethod()); final PropertyDescriptor prop = new PropertyDescriptor(name, getter.getReadMethod(), setter.getWriteMethod());
props.add(prop); props.add(prop);
} } else {
else {
props.add(getter); props.add(getter);
} }
} }
Set writeOnlyProps = new HashSet(setters.keySet()); final Set writeOnlyProps = new HashSet(setters.keySet());
writeOnlyProps.removeAll(processedProps); writeOnlyProps.removeAll(processedProps);
Iterator ss = writeOnlyProps.iterator(); final Iterator ss = writeOnlyProps.iterator();
while (ss.hasNext()) { while (ss.hasNext()) {
String name = (String) ss.next(); final String name = (String) ss.next();
PropertyDescriptor setter = (PropertyDescriptor) setters.get(name); final PropertyDescriptor setter = (PropertyDescriptor) setters.get(name);
props.add(setter); props.add(setter);
} }
return props; return props;

View file

@ -21,23 +21,31 @@ import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/** /**
* Provides deep <b>Bean</b> clonning support. * Provides deep <b>Bean</b> clonning support.
* <p> * <p>
* It works on all read/write properties, recursively. It support all primitive types, Strings, Collections, * It works on all read/write properties, recursively. It support all primitive
* Cloneable objects and multi-dimensional arrays of any of them. * types, Strings, Collections, Cloneable objects and multi-dimensional arrays
* of any of them.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class CloneableBean implements Serializable, Cloneable { public class CloneableBean implements Serializable, Cloneable {
private static final Class[] NO_PARAMS_DEF = new Class[0]; private static final Class[] NO_PARAMS_DEF = new Class[0];
private static final Object[] NO_PARAMS = new Object[0]; private static final Object[] NO_PARAMS = new Object[0];
private Object _obj; private final Object _obj;
private Set _ignoreProperties; private Set _ignoreProperties;
/** /**
@ -45,10 +53,10 @@ public class CloneableBean implements Serializable, Cloneable {
* <p> * <p>
* To be used by classes extending CloneableBean only. * To be used by classes extending CloneableBean only.
* <p> * <p>
* *
*/ */
protected CloneableBean() { protected CloneableBean() {
_obj = this; this._obj = this;
} }
/** /**
@ -59,55 +67,62 @@ public class CloneableBean implements Serializable, Cloneable {
* <code> * <code>
* public class Foo implements Cloneable { * public class Foo implements Cloneable {
* private CloneableBean _cloneableBean; * private CloneableBean _cloneableBean;
* *
* public Foo() { * public Foo() {
* _cloneableBean = new CloneableBean(this); * _cloneableBean = new CloneableBean(this);
* } * }
* *
* public Object clone() throws CloneNotSupportedException { * public Object clone() throws CloneNotSupportedException {
* return _cloneableBean.beanClone(); * return _cloneableBean.beanClone();
* } * }
* *
* } * }
* </code> * </code>
* <p> * <p>
*
* @param obj object bean to clone. * @param obj object bean to clone.
* *
*/ */
public CloneableBean(Object obj) { public CloneableBean(final Object obj) {
this(obj,null); this(obj, null);
} }
/** /**
* Creates a CloneableBean to be used in a delegation pattern. * Creates a CloneableBean to be used in a delegation pattern.
* <p> * <p>
* The property names in the ignoreProperties Set will not be copied into * The property names in the ignoreProperties Set will not be copied into
* the cloned instance. This is useful for cases where the Bean has convenience * the cloned instance. This is useful for cases where the Bean has
* properties (properties that are actually references to other properties or * convenience properties (properties that are actually references to other
* properties of properties). For example SyndFeed and SyndEntry beans have * properties or properties of properties). For example SyndFeed and
* convenience properties, publishedDate, author, copyright and categories all * SyndEntry beans have convenience properties, publishedDate, author,
* of them mapped to properties in the DC Module. * copyright and categories all of them mapped to properties in the DC
* Module.
* <p> * <p>
*
* @param obj object bean to clone. * @param obj object bean to clone.
* @param ignoreProperties properties to ignore when cloning. * @param ignoreProperties properties to ignore when cloning.
* *
*/ */
public CloneableBean(Object obj,Set ignoreProperties) { public CloneableBean(final Object obj, final Set ignoreProperties) {
_obj = obj; this._obj = obj;
_ignoreProperties = (ignoreProperties!=null) ? ignoreProperties : Collections.EMPTY_SET; this._ignoreProperties = ignoreProperties != null ? ignoreProperties : Collections.EMPTY_SET;
} }
/** /**
* Makes a deep bean clone of the object. * Makes a deep bean clone of the object.
* <p> * <p>
* To be used by classes extending CloneableBean. Although it works also for classes using * To be used by classes extending CloneableBean. Although it works also for
* CloneableBean in a delegation pattern, for correctness those classes should use the * classes using CloneableBean in a delegation pattern, for correctness
* those classes should use the
*
* @see #beanClone() beanClone method. * @see #beanClone() beanClone method.
* <p> * <p>
* @return a clone of the object bean. * @return a clone of the object bean.
* @throws CloneNotSupportedException thrown if the object bean could not be cloned. * @throws CloneNotSupportedException thrown if the object bean could not be
* * cloned.
*
*/ */
@Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return beanClone(); return beanClone();
} }
@ -116,111 +131,122 @@ public class CloneableBean implements Serializable, Cloneable {
* Makes a deep bean clone of the object passed in the constructor. * Makes a deep bean clone of the object passed in the constructor.
* <p> * <p>
* To be used by classes using CloneableBean in a delegation pattern, * To be used by classes using CloneableBean in a delegation pattern,
*
* @see #CloneableBean(Object) constructor. * @see #CloneableBean(Object) constructor.
* *
* @return a clone of the object bean. * @return a clone of the object bean.
* @throws CloneNotSupportedException thrown if the object bean could not be cloned. * @throws CloneNotSupportedException thrown if the object bean could not be
* * cloned.
*
*/ */
public Object beanClone() throws CloneNotSupportedException { public Object beanClone() throws CloneNotSupportedException {
Object clonedBean; Object clonedBean;
try { try {
clonedBean = _obj.getClass().newInstance(); clonedBean = this._obj.getClass().newInstance();
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_obj.getClass()); final PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(this._obj.getClass());
if (pds!=null) { if (pds != null) {
for (int i=0;i<pds.length;i++) { for (int i = 0; i < pds.length; i++) {
Method pReadMethod = pds[i].getReadMethod(); final Method pReadMethod = pds[i].getReadMethod();
Method pWriteMethod = pds[i].getWriteMethod(); final Method pWriteMethod = pds[i].getWriteMethod();
if (pReadMethod!=null && pWriteMethod!=null && // ensure it has getter and setter methods if (pReadMethod != null && pWriteMethod != null && // ensure
!_ignoreProperties.contains(pds[i].getName()) && // is not in the list of properties to ignore // it has
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods // getter
pReadMethod.getParameterTypes().length==0) { // filter getter methods that take parameters // and
Object value = pReadMethod.invoke(_obj,NO_PARAMS); // setter
if (value!=null) { // methods
!this._ignoreProperties.contains(pds[i].getName()) && // is
// not
// in
// the
// list
// of
// properties
// to
// ignore
pReadMethod.getDeclaringClass() != Object.class && // filter
// Object.class
// getter
// methods
pReadMethod.getParameterTypes().length == 0) { // filter
// getter
// methods
// that
// take
// parameters
Object value = pReadMethod.invoke(this._obj, NO_PARAMS);
if (value != null) {
value = doClone(value); value = doClone(value);
pWriteMethod.invoke(clonedBean,new Object[]{value}); pWriteMethod.invoke(clonedBean, new Object[] { value });
} }
} }
} }
} }
} } catch (final CloneNotSupportedException cnsEx) {
catch (CloneNotSupportedException cnsEx) {
throw cnsEx; throw cnsEx;
} } catch (final Exception ex) {
catch (Exception ex) {
System.out.println(ex); System.out.println(ex);
ex.printStackTrace(System.out); ex.printStackTrace(System.out);
throw new CloneNotSupportedException("Cannot clone a "+_obj.getClass()+" object"); throw new CloneNotSupportedException("Cannot clone a " + this._obj.getClass() + " object");
} }
return clonedBean; return clonedBean;
} }
private Object doClone(Object value) throws Exception { private Object doClone(Object value) throws Exception {
if (value!=null) { if (value != null) {
Class vClass = value.getClass(); final Class vClass = value.getClass();
if (vClass.isArray()) { if (vClass.isArray()) {
value = cloneArray(value); value = cloneArray(value);
} } else if (value instanceof Collection) {
else value = cloneCollection((Collection) value);
if (value instanceof Collection) { } else if (value instanceof Map) {
value = cloneCollection((Collection)value); value = cloneMap((Map) value);
} } else if (isBasicType(vClass)) {
else
if (value instanceof Map) {
value = cloneMap((Map)value);
}
else
if (isBasicType(vClass)) {
// NOTHING SPECIAL TO DO HERE, THEY ARE INMUTABLE // NOTHING SPECIAL TO DO HERE, THEY ARE INMUTABLE
} } else if (value instanceof Cloneable) {
else final Method cloneMethod = vClass.getMethod("clone", NO_PARAMS_DEF);
if (value instanceof Cloneable) {
Method cloneMethod = vClass.getMethod("clone",NO_PARAMS_DEF);
if (Modifier.isPublic(cloneMethod.getModifiers())) { if (Modifier.isPublic(cloneMethod.getModifiers())) {
value = cloneMethod.invoke(value,NO_PARAMS); value = cloneMethod.invoke(value, NO_PARAMS);
} else {
throw new CloneNotSupportedException("Cannot clone a " + value.getClass() + " object, clone() is not public");
} }
else { } else {
throw new CloneNotSupportedException("Cannot clone a "+value.getClass()+" object, clone() is not public"); throw new CloneNotSupportedException("Cannot clone a " + vClass.getName() + " object");
}
}
else {
throw new CloneNotSupportedException("Cannot clone a "+vClass.getName()+" object");
} }
} }
return value; return value;
} }
private Object cloneArray(Object array) throws Exception { private Object cloneArray(final Object array) throws Exception {
Class elementClass = array.getClass().getComponentType(); final Class elementClass = array.getClass().getComponentType();
int length = Array.getLength(array); final int length = Array.getLength(array);
Object newArray = Array.newInstance(elementClass,length); final Object newArray = Array.newInstance(elementClass, length);
for (int i=0;i<length;i++) { for (int i = 0; i < length; i++) {
Object element = doClone(Array.get(array,i)); final Object element = doClone(Array.get(array, i));
Array.set(newArray,i,element); Array.set(newArray, i, element);
} }
return newArray; return newArray;
} }
private Object cloneCollection(Collection collection) throws Exception { private Object cloneCollection(final Collection collection) throws Exception {
Class mClass = collection.getClass(); final Class mClass = collection.getClass();
Collection newColl = (Collection) mClass.newInstance(); final Collection newColl = (Collection) mClass.newInstance();
Iterator i = collection.iterator(); final Iterator i = collection.iterator();
while (i.hasNext()) { while (i.hasNext()) {
Object element = doClone(i.next()); final Object element = doClone(i.next());
newColl.add(element); newColl.add(element);
} }
return newColl; return newColl;
} }
private Object cloneMap(Map map) throws Exception { private Object cloneMap(final Map map) throws Exception {
Class mClass = map.getClass(); final Class mClass = map.getClass();
Map newMap = (Map) mClass.newInstance(); final Map newMap = (Map) mClass.newInstance();
Iterator entries = map.entrySet().iterator(); final Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) { while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next(); final Map.Entry entry = (Map.Entry) entries.next();
Object key = doClone(entry.getKey()); final Object key = doClone(entry.getKey());
Object value = doClone(entry.getValue()); final Object value = doClone(entry.getValue());
newMap.put(key,value); newMap.put(key, value);
} }
return newMap; return newMap;
} }
@ -242,31 +268,28 @@ public class CloneableBean implements Serializable, Cloneable {
private static final Map CONSTRUCTOR_BASIC_TYPES = new HashMap(); private static final Map CONSTRUCTOR_BASIC_TYPES = new HashMap();
static { static {
CONSTRUCTOR_BASIC_TYPES.put(Boolean.class,new Class[]{Boolean.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Boolean.class, new Class[] { Boolean.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Byte.class,new Class[]{Byte.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Byte.class, new Class[] { Byte.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Character.class,new Class[]{Character.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Character.class, new Class[] { Character.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Double.class,new Class[]{Double.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Double.class, new Class[] { Double.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Float.class,new Class[]{Float.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Float.class, new Class[] { Float.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Integer.class,new Class[]{Integer.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Integer.class, new Class[] { Integer.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Long.class,new Class[]{Long.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Long.class, new Class[] { Long.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(Short.class,new Class[]{Short.TYPE}); CONSTRUCTOR_BASIC_TYPES.put(Short.class, new Class[] { Short.TYPE });
CONSTRUCTOR_BASIC_TYPES.put(String.class,new Class[]{String.class}); CONSTRUCTOR_BASIC_TYPES.put(String.class, new Class[] { String.class });
} }
private boolean isBasicType(Class vClass) { private boolean isBasicType(final Class vClass) {
return BASIC_TYPES.contains(vClass); return BASIC_TYPES.contains(vClass);
} }
// THIS IS NOT NEEDED, BASIC TYPES ARE INMUTABLE, TUCU 20040710 // THIS IS NOT NEEDED, BASIC TYPES ARE INMUTABLE, TUCU 20040710
/** /**
private Object cloneBasicType(Object value) throws Exception { * private Object cloneBasicType(Object value) throws Exception { Class
Class pClass = value.getClass(); * pClass = value.getClass(); Class[] defType = (Class[])
Class[] defType = (Class[]) CONSTRUCTOR_BASIC_TYPES.get(pClass); * CONSTRUCTOR_BASIC_TYPES.get(pClass); Constructor cons =
Constructor cons = pClass.getDeclaredConstructor(defType); * pClass.getDeclaredConstructor(defType); value = cons.newInstance(new
value = cons.newInstance(new Object[]{value}); * Object[]{value}); return value; }
return value; **/
}
**/
} }

View file

@ -16,13 +16,19 @@
*/ */
package com.sun.syndication.feed.impl; package com.sun.syndication.feed.impl;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.BeanIntrospector;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.sun.syndication.feed.CopyFrom;
/** /**
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
@ -30,119 +36,127 @@ import java.util.*;
public class CopyFromHelper { public class CopyFromHelper {
private static final Object[] NO_PARAMS = new Object[0]; private static final Object[] NO_PARAMS = new Object[0];
private Class _beanInterfaceClass; private final Class _beanInterfaceClass;
private Map _baseInterfaceMap; //ENTRIES(propertyName,interface.class) private final Map _baseInterfaceMap; // ENTRIES(propertyName,interface.class)
private Map _baseImplMap; //ENTRIES(interface.class,implementation.class) private final Map _baseImplMap; // ENTRIES(interface.class,implementation.class)
public CopyFromHelper(Class beanInterfaceClass,Map basePropInterfaceMap,Map basePropClassImplMap) { public CopyFromHelper(final Class beanInterfaceClass, final Map basePropInterfaceMap, final Map basePropClassImplMap) {
_beanInterfaceClass = beanInterfaceClass; this._beanInterfaceClass = beanInterfaceClass;
_baseInterfaceMap = basePropInterfaceMap; this._baseInterfaceMap = basePropInterfaceMap;
_baseImplMap = basePropClassImplMap; this._baseImplMap = basePropClassImplMap;
} }
public void copy(Object target,Object source) { public void copy(final Object target, final Object source) {
try { try {
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanInterfaceClass); final PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(this._beanInterfaceClass);
if (pds!=null) { if (pds != null) {
for (int i=0;i<pds.length;i++) { for (final PropertyDescriptor pd : pds) {
String propertyName = pds[i].getName(); final String propertyName = pd.getName();
Method pReadMethod = pds[i].getReadMethod(); final Method pReadMethod = pd.getReadMethod();
Method pWriteMethod = pds[i].getWriteMethod(); final Method pWriteMethod = pd.getWriteMethod();
if (pReadMethod!=null && pWriteMethod!=null && // ensure it has getter and setter methods if (pReadMethod != null && pWriteMethod != null && // ensure
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods // it has
pReadMethod.getParameterTypes().length==0 && // filter getter methods that take parameters // getter
_baseInterfaceMap.containsKey(propertyName)) { // only copies properties defined as copyFrom-able // and
Object value = pReadMethod.invoke(source,NO_PARAMS); // setter
if (value!=null) { // methods
Class baseInterface = (Class) _baseInterfaceMap.get(propertyName); pReadMethod.getDeclaringClass() != Object.class && // filter
value = doCopy(value,baseInterface); // Object.class
pWriteMethod.invoke(target,new Object[]{value}); // getter
// methods
pReadMethod.getParameterTypes().length == 0 && // filter
// getter
// methods
// that
// take
// parameters
this._baseInterfaceMap.containsKey(propertyName)) { // only
// copies
// properties
// defined
// as
// copyFrom-able
Object value = pReadMethod.invoke(source, NO_PARAMS);
if (value != null) {
final Class baseInterface = (Class) this._baseInterfaceMap.get(propertyName);
value = doCopy(value, baseInterface);
pWriteMethod.invoke(target, new Object[] { value });
} }
} }
} }
} }
} } catch (final Exception ex) {
catch (Exception ex) { throw new RuntimeException("Could not do a copyFrom " + ex, ex);
throw new RuntimeException("Could not do a copyFrom "+ex, ex);
} }
} }
private CopyFrom createInstance(Class interfaceClass) throws Exception { private CopyFrom createInstance(final Class interfaceClass) throws Exception {
if( _baseImplMap.get(interfaceClass) == null ){ if (this._baseImplMap.get(interfaceClass) == null) {
return null; return null;
} } else {
else { return (CopyFrom) ((Class) this._baseImplMap.get(interfaceClass)).newInstance();
return (CopyFrom) ((Class)_baseImplMap.get(interfaceClass)).newInstance();
} }
} }
private Object doCopy(Object value,Class baseInterface) throws Exception { private Object doCopy(Object value, final Class baseInterface) throws Exception {
if (value!=null) { if (value != null) {
Class vClass = value.getClass(); final Class vClass = value.getClass();
if (vClass.isArray()) { if (vClass.isArray()) {
value = doCopyArray(value,baseInterface); value = doCopyArray(value, baseInterface);
} } else if (value instanceof Collection) {
else value = doCopyCollection((Collection) value, baseInterface);
if (value instanceof Collection) { } else if (value instanceof Map) {
value = doCopyCollection((Collection)value,baseInterface); value = doCopyMap((Map) value, baseInterface);
} } else if (isBasicType(vClass)) {
else
if (value instanceof Map) {
value = doCopyMap((Map)value,baseInterface);
}
else
if (isBasicType(vClass)) {
// value = value; // nothing to do here // value = value; // nothing to do here
if (value instanceof Date) { // because Date it is not inmutable if (value instanceof Date) { // because Date it is not inmutable
value = ((Date)value).clone(); value = ((Date) value).clone();
} }
} } else { // it goes CopyFrom
else { // it goes CopyFrom
if (value instanceof CopyFrom) { if (value instanceof CopyFrom) {
CopyFrom source = (CopyFrom) value; final CopyFrom source = (CopyFrom) value;
CopyFrom target = createInstance(source.getInterface()); CopyFrom target = createInstance(source.getInterface());
target = target == null ? (CopyFrom) value.getClass().newInstance() : target; target = target == null ? (CopyFrom) value.getClass().newInstance() : target;
target.copyFrom(source); target.copyFrom(source);
value = target; value = target;
} } else {
else { throw new Exception("unsupported class for 'copyFrom' " + value.getClass());
throw new Exception("unsupported class for 'copyFrom' "+value.getClass());
} }
} }
} }
return value; return value;
} }
private Object doCopyArray(Object array,Class baseInterface) throws Exception { private Object doCopyArray(final Object array, final Class baseInterface) throws Exception {
Class elementClass = array.getClass().getComponentType(); final Class elementClass = array.getClass().getComponentType();
int length = Array.getLength(array); final int length = Array.getLength(array);
Object newArray = Array.newInstance(elementClass,length); final Object newArray = Array.newInstance(elementClass, length);
for (int i=0;i<length;i++) { for (int i = 0; i < length; i++) {
Object element = doCopy(Array.get(array,i),baseInterface); final Object element = doCopy(Array.get(array, i), baseInterface);
Array.set(newArray,i,element); Array.set(newArray, i, element);
} }
return newArray; return newArray;
} }
private Object doCopyCollection(Collection collection,Class baseInterface) throws Exception { private Object doCopyCollection(final Collection collection, final Class baseInterface) throws Exception {
// expecting SETs or LISTs only, going default implementation of them // expecting SETs or LISTs only, going default implementation of them
Collection newColl = (collection instanceof Set) ? (Collection)new HashSet() : (Collection)new ArrayList(); final Collection newColl = collection instanceof Set ? (Collection) new HashSet() : (Collection) new ArrayList();
Iterator i = collection.iterator(); final Iterator i = collection.iterator();
while (i.hasNext()) { while (i.hasNext()) {
Object element = doCopy(i.next(),baseInterface); final Object element = doCopy(i.next(), baseInterface);
newColl.add(element); newColl.add(element);
} }
return newColl; return newColl;
} }
private Object doCopyMap(Map map,Class baseInterface) throws Exception { private Object doCopyMap(final Map map, final Class baseInterface) throws Exception {
Map newMap = new HashMap(); final Map newMap = new HashMap();
Iterator entries = map.entrySet().iterator(); final Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) { while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next(); final Map.Entry entry = (Map.Entry) entries.next();
Object key = entry.getKey(); // we are assuming string KEYS final Object key = entry.getKey(); // we are assuming string KEYS
Object element = doCopy(entry.getValue(),baseInterface); final Object element = doCopy(entry.getValue(), baseInterface);
newMap.put(key,element); newMap.put(key, element);
} }
return newMap; return newMap;
} }
@ -162,7 +176,7 @@ public class CopyFromHelper {
BASIC_TYPES.add(Date.class); BASIC_TYPES.add(Date.class);
} }
private boolean isBasicType(Class vClass) { private boolean isBasicType(final Class vClass) {
return BASIC_TYPES.contains(vClass); return BASIC_TYPES.contains(vClass);
} }

View file

@ -17,39 +17,44 @@
package com.sun.syndication.feed.impl; package com.sun.syndication.feed.impl;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.io.Serializable;
/** /**
* Provides deep <b>Bean</b> equals() and hashCode() functionality for Java Beans. * Provides deep <b>Bean</b> equals() and hashCode() functionality for Java
* Beans.
* <p> * <p>
* It works on all read/write properties, recursively. It support all primitive types, Strings, Collections, * It works on all read/write properties, recursively. It support all primitive
* bean-like objects and multi-dimensional arrays of any of them. * types, Strings, Collections, bean-like objects and multi-dimensional arrays
* of any of them.
* <p> * <p>
* The hashcode is calculated by getting the hashcode of the Bean String representation. * The hashcode is calculated by getting the hashcode of the Bean String
* representation.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class EqualsBean implements Serializable { public class EqualsBean implements Serializable {
private static final Object[] NO_PARAMS = new Object[0]; private static final Object[] NO_PARAMS = new Object[0];
private Class _beanClass; private final Class _beanClass;
private Object _obj; private final Object _obj;
/** /**
* Default constructor. * Default constructor.
* <p> * <p>
* To be used by classes extending EqualsBean only. * To be used by classes extending EqualsBean only.
* <p> * <p>
*
* @param beanClass the class/interface to be used for property scanning. * @param beanClass the class/interface to be used for property scanning.
* *
*/ */
protected EqualsBean(Class beanClass) { protected EqualsBean(final Class beanClass) {
_beanClass = beanClass; this._beanClass = beanClass;
_obj = this; this._obj = this;
} }
/** /**
@ -60,97 +65,108 @@ public class EqualsBean implements Serializable {
* <code> * <code>
* public class Foo implements FooI { * public class Foo implements FooI {
* private EqualsBean _equalsBean; * private EqualsBean _equalsBean;
* *
* public Foo() { * public Foo() {
* _equalsBean = new EqualsBean(FooI.class); * _equalsBean = new EqualsBean(FooI.class);
* } * }
* *
* public boolean equals(Object obj) { * public boolean equals(Object obj) {
* return _equalsBean.beanEquals(obj); * return _equalsBean.beanEquals(obj);
* } * }
* *
* public int hashCode() { * public int hashCode() {
* return _equalsBean.beanHashCode(); * return _equalsBean.beanHashCode();
* } * }
* *
* } * }
* </code> * </code>
* <p> * <p>
*
* @param beanClass the class/interface to be used for property scanning. * @param beanClass the class/interface to be used for property scanning.
* @param obj object bean to test equality. * @param obj object bean to test equality.
* *
*/ */
public EqualsBean(Class beanClass,Object obj) { public EqualsBean(final Class beanClass, final Object obj) {
if (!beanClass.isInstance(obj)) { if (!beanClass.isInstance(obj)) {
throw new IllegalArgumentException(obj.getClass()+" is not instance of "+beanClass); throw new IllegalArgumentException(obj.getClass() + " is not instance of " + beanClass);
} }
_beanClass = beanClass; this._beanClass = beanClass;
_obj = obj; this._obj = obj;
} }
/** /**
* Indicates whether some other object is "equal to" this object as defined by the Object equals() method. * Indicates whether some other object is "equal to" this object as defined
* by the Object equals() method.
* <p> * <p>
* To be used by classes extending EqualsBean. Although it works also for classes using * To be used by classes extending EqualsBean. Although it works also for
* EqualsBean in a delegation pattern, for correctness those classes should use the * classes using EqualsBean in a delegation pattern, for correctness those
* classes should use the
*
* @see #beanEquals(Object) beanEquals method. * @see #beanEquals(Object) beanEquals method.
* <p> * <p>
* @param obj he reference object with which to compare. * @param obj he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
public boolean equals(Object obj) { @Override
public boolean equals(final Object obj) {
return beanEquals(obj); return beanEquals(obj);
} }
/** /**
* Indicates whether some other object is "equal to" the object passed in the constructor, * Indicates whether some other object is "equal to" the object passed in
* as defined by the Object equals() method. * the constructor, as defined by the Object equals() method.
* <p> * <p>
* To be used by classes using EqualsBean in a delegation pattern, * To be used by classes using EqualsBean in a delegation pattern,
*
* @see #EqualsBean(Class,Object) constructor. * @see #EqualsBean(Class,Object) constructor.
* <p> * <p>
* @param obj he reference object with which to compare. * @param obj he reference object with which to compare.
* @return <b>true</b> if the object passed in the constructor is equal to the 'obj' object. * @return <b>true</b> if the object passed in the constructor is equal to
* * the 'obj' object.
*
*/ */
public boolean beanEquals(Object obj) { public boolean beanEquals(final Object obj) {
Object bean1 = _obj; final Object bean1 = this._obj;
Object bean2 = obj; final Object bean2 = obj;
boolean eq; boolean eq;
if (bean1==null && bean2==null) { if (bean1 == null && bean2 == null) {
eq = true; eq = true;
} } else if (bean1 == null || bean2 == null) {
else eq = false;
if (bean1==null || bean2==null) { } else {
if (!this._beanClass.isInstance(bean2)) {
eq = false; eq = false;
} } else {
else { eq = true;
if (!_beanClass.isInstance(bean2)) { try {
eq = false; final PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(this._beanClass);
} if (pds != null) {
else { for (int i = 0; eq && i < pds.length; i++) {
eq = true; final Method pReadMethod = pds[i].getReadMethod();
try { if (pReadMethod != null && // ensure it has a getter
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanClass); // method
if (pds!=null) { pReadMethod.getDeclaringClass() != Object.class && // filter
for (int i = 0; eq && i<pds.length; i++) { // Object.class
Method pReadMethod = pds[i].getReadMethod(); // getter
if (pReadMethod!=null && // ensure it has a getter method // methods
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods pReadMethod.getParameterTypes().length == 0) { // filter
pReadMethod.getParameterTypes().length==0) { // filter getter methods that take parameters // getter
Object value1 = pReadMethod.invoke(bean1, NO_PARAMS); // methods
Object value2 = pReadMethod.invoke(bean2, NO_PARAMS); // that
eq = doEquals(value1, value2); // take
} // parameters
final Object value1 = pReadMethod.invoke(bean1, NO_PARAMS);
final Object value2 = pReadMethod.invoke(bean2, NO_PARAMS);
eq = doEquals(value1, value2);
} }
} }
} }
catch (Exception ex) { } catch (final Exception ex) {
throw new RuntimeException("Could not execute equals()", ex); throw new RuntimeException("Could not execute equals()", ex);
}
} }
} }
}
return eq; return eq;
} }
@ -159,15 +175,19 @@ public class EqualsBean implements Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
* The hashcode is calculated by getting the hashcode of the Bean String representation. * The hashcode is calculated by getting the hashcode of the Bean String
* representation.
* <p> * <p>
* To be used by classes extending EqualsBean. Although it works also for classes using * To be used by classes extending EqualsBean. Although it works also for
* EqualsBean in a delegation pattern, for correctness those classes should use the * classes using EqualsBean in a delegation pattern, for correctness those
* classes should use the
*
* @see #beanHashCode() beanHashCode method. * @see #beanHashCode() beanHashCode method.
* <p> * <p>
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override
public int hashCode() { public int hashCode() {
return beanHashCode(); return beanHashCode();
} }
@ -177,51 +197,49 @@ public class EqualsBean implements Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
* The hashcode is calculated by getting the hashcode of the Bean String representation. * The hashcode is calculated by getting the hashcode of the Bean String
* representation.
* <p> * <p>
* To be used by classes using EqualsBean in a delegation pattern, * To be used by classes using EqualsBean in a delegation pattern,
*
* @see #EqualsBean(Class,Object) constructor. * @see #EqualsBean(Class,Object) constructor.
* <p> * <p>
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
public int beanHashCode() { public int beanHashCode() {
return _obj.toString().hashCode(); return this._obj.toString().hashCode();
} }
private boolean doEquals(final Object obj1, final Object obj2) {
private boolean doEquals(Object obj1, Object obj2) { boolean eq = obj1 == obj2;
boolean eq = obj1==obj2; if (!eq && obj1 != null && obj2 != null) {
if (!eq && obj1!=null && obj2!=null) { final Class classObj1 = obj1.getClass();
Class classObj1 = obj1.getClass(); final Class classObj2 = obj2.getClass();
Class classObj2 = obj2.getClass();
if (classObj1.isArray() && classObj2.isArray()) { if (classObj1.isArray() && classObj2.isArray()) {
eq = equalsArray(obj1, obj2); eq = equalsArray(obj1, obj2);
} } else {
else {
eq = obj1.equals(obj2); eq = obj1.equals(obj2);
} }
} }
return eq; return eq;
} }
private boolean equalsArray(Object array1, Object array2) { private boolean equalsArray(final Object array1, final Object array2) {
boolean eq; boolean eq;
int length1 = Array.getLength(array1); final int length1 = Array.getLength(array1);
int length2 = Array.getLength(array2); final int length2 = Array.getLength(array2);
if (length1==length2) { if (length1 == length2) {
eq = true; eq = true;
for (int i = 0; eq && i<length1; i++) { for (int i = 0; eq && i < length1; i++) {
Object e1 = Array.get(array1, i); final Object e1 = Array.get(array1, i);
Object e2 = Array.get(array2, i); final Object e2 = Array.get(array2, i);
eq = doEquals(e1, e2); eq = doEquals(e1, e2);
} }
} } else {
else {
eq = false; eq = false;
} }
return eq; return eq;
} }
} }

View file

@ -16,86 +16,96 @@
*/ */
package com.sun.syndication.feed.impl; package com.sun.syndication.feed.impl;
import com.sun.syndication.feed.impl.CloneableBean;
import com.sun.syndication.feed.impl.EqualsBean;
import java.io.Serializable; import java.io.Serializable;
import java.util.Set; import java.util.Set;
/** /**
* Convenience class providing clone(), toString(), equals() and hashCode() functionality for Java Beans. * Convenience class providing clone(), toString(), equals() and hashCode()
* functionality for Java Beans.
* <p> * <p>
* It works on all read/write properties, recursively. * It works on all read/write properties, recursively.
* <p> * <p>
* It uses the CloneableBean, EqualsBean and ToStringBean classes in a delegation pattern. * It uses the CloneableBean, EqualsBean and ToStringBean classes in a
* delegation pattern.
* <p> * <p>
* <h3>ObjectBean programming conventions</h3> * <h3>ObjectBean programming conventions</h3>
* <P> * <P>
* All ObjectBean subclasses having properties that return collections they should never * All ObjectBean subclasses having properties that return collections they
* return null if the property has been set to <b>null</b> or if a collection has not been set. * should never return null if the property has been set to <b>null</b> or if a
* They should create and return an empty collection, this empty collection instance should * collection has not been set. They should create and return an empty
* also be set to the corresponding property. * collection, this empty collection instance should also be set to the
* corresponding property.
* <P> * <P>
* All ObjectBean subclasses properties should be live references. * All ObjectBean subclasses properties should be live references.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class ObjectBean implements Serializable, Cloneable { public class ObjectBean implements Serializable, Cloneable {
private EqualsBean _equalsBean; private final EqualsBean _equalsBean;
private ToStringBean _toStringBean; private final ToStringBean _toStringBean;
private CloneableBean _cloneableBean; private final CloneableBean _cloneableBean;
/** /**
* Constructor. * Constructor.
* <p> * <p>
*
* @param beanClass the class/interface to be used for property scanning. * @param beanClass the class/interface to be used for property scanning.
* *
*/ */
public ObjectBean(Class beanClass,Object obj) { public ObjectBean(final Class beanClass, final Object obj) {
this(beanClass,obj,null); this(beanClass, obj, null);
} }
/** /**
* Constructor. * Constructor.
* <p> * <p>
* The property names in the ignoreProperties Set will not be copied into * The property names in the ignoreProperties Set will not be copied into
* the cloned instance. This is useful for cases where the Bean has convenience * the cloned instance. This is useful for cases where the Bean has
* properties (properties that are actually references to other properties or * convenience properties (properties that are actually references to other
* properties of properties). For example SyndFeed and SyndEntry beans have * properties or properties of properties). For example SyndFeed and
* convenience properties, publishedDate, author, copyright and categories all * SyndEntry beans have convenience properties, publishedDate, author,
* of them mapped to properties in the DC Module. * copyright and categories all of them mapped to properties in the DC
* Module.
* <p> * <p>
*
* @param beanClass the class/interface to be used for property scanning. * @param beanClass the class/interface to be used for property scanning.
* @param ignoreProperties properties to ignore when cloning. * @param ignoreProperties properties to ignore when cloning.
* *
*/ */
public ObjectBean(Class beanClass,Object obj,Set ignoreProperties) { public ObjectBean(final Class beanClass, final Object obj, final Set ignoreProperties) {
_equalsBean = new EqualsBean(beanClass,obj); this._equalsBean = new EqualsBean(beanClass, obj);
_toStringBean = new ToStringBean(beanClass,obj); this._toStringBean = new ToStringBean(beanClass, obj);
_cloneableBean = new CloneableBean(obj,ignoreProperties); this._cloneableBean = new CloneableBean(obj, ignoreProperties);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _cloneableBean.beanClone(); return this._cloneableBean.beanClone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
public boolean equals(Object other) { @Override
return _equalsBean.beanEquals(other); public boolean equals(final Object other) {
return this._equalsBean.beanEquals(other);
} }
/** /**
@ -103,22 +113,25 @@ public class ObjectBean implements Serializable, Cloneable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override
public int hashCode() { public int hashCode() {
return _equalsBean.beanHashCode(); return this._equalsBean.beanHashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override
public String toString() { public String toString() {
return _toStringBean.toString(); return this._toStringBean.toString();
} }
} }

View file

@ -17,28 +17,31 @@
package com.sun.syndication.feed.impl; package com.sun.syndication.feed.impl;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
import java.io.Serializable;
/** /**
* Provides deep <b>Bean</b> toString support. * Provides deep <b>Bean</b> toString support.
* <p> * <p>
* It works on all read/write properties, recursively. It support all primitive types, Strings, Collections, * It works on all read/write properties, recursively. It support all primitive
* ToString objects and multi-dimensional arrays of any of them. * types, Strings, Collections, ToString objects and multi-dimensional arrays of
* any of them.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class ToStringBean implements Serializable { public class ToStringBean implements Serializable {
private static final ThreadLocal PREFIX_TL = new ThreadLocal() { private static final ThreadLocal PREFIX_TL = new ThreadLocal() {
@Override
public Object get() { public Object get() {
Object o = super.get(); Object o = super.get();
if (o==null) { if (o == null) {
o = new Stack(); o = new Stack();
set(o); set(o);
} }
@ -48,20 +51,22 @@ public class ToStringBean implements Serializable {
private static final Object[] NO_PARAMS = new Object[0]; private static final Object[] NO_PARAMS = new Object[0];
private Class _beanClass; private final Class _beanClass;
private Object _obj; private final Object _obj;
/** /**
* Default constructor. * Default constructor.
* <p> * <p>
* To be used by classes extending ToStringBean only. * To be used by classes extending ToStringBean only.
* <p> * <p>
* @param beanClass indicates the class to scan for properties, normally an interface class. *
* * @param beanClass indicates the class to scan for properties, normally an
* interface class.
*
*/ */
protected ToStringBean(Class beanClass) { protected ToStringBean(final Class beanClass) {
_beanClass = beanClass; this._beanClass = beanClass;
_obj = this; this._obj = this;
} }
/** /**
@ -71,26 +76,28 @@ public class ToStringBean implements Serializable {
* <p> * <p>
* <code> * <code>
* public class Foo implements ToString { * public class Foo implements ToString {
* *
* public String toString(String prefix) { * public String toString(String prefix) {
* ToStringBean tsb = new ToStringBean(this); * ToStringBean tsb = new ToStringBean(this);
* return tsb.toString(prefix); * return tsb.toString(prefix);
* } * }
* *
* public String toString() { * public String toString() {
* return toString("Foo"); * return toString("Foo");
* } * }
* *
* } * }
* </code> * </code>
* <p> * <p>
* @param beanClass indicates the class to scan for properties, normally an interface class. *
* @param beanClass indicates the class to scan for properties, normally an
* interface class.
* @param obj object bean to create String representation. * @param obj object bean to create String representation.
* *
*/ */
public ToStringBean(Class beanClass,Object obj) { public ToStringBean(final Class beanClass, final Object obj) {
_beanClass = beanClass; this._beanClass = beanClass;
_obj = obj; this._obj = obj;
} }
/** /**
@ -98,143 +105,139 @@ public class ToStringBean implements Serializable {
* <p> * <p>
* It uses the Class name as the prefix. * It uses the Class name as the prefix.
* <p> * <p>
*
* @return bean object String representation. * @return bean object String representation.
* *
*/ */
@Override
public String toString() { public String toString() {
Stack stack = (Stack) PREFIX_TL.get(); final Stack stack = (Stack) PREFIX_TL.get();
String[] tsInfo = (String[]) ((stack.isEmpty()) ? null : stack.peek()); final String[] tsInfo = (String[]) (stack.isEmpty() ? null : stack.peek());
String prefix; String prefix;
if (tsInfo==null) { if (tsInfo == null) {
String className = _obj.getClass().getName(); final String className = this._obj.getClass().getName();
prefix = className.substring(className.lastIndexOf(".")+1); prefix = className.substring(className.lastIndexOf(".") + 1);
} } else {
else {
prefix = tsInfo[0]; prefix = tsInfo[0];
tsInfo[1] = prefix; tsInfo[1] = prefix;
} }
return toString(prefix); return this.toString(prefix);
} }
/** /**
* Returns the String representation of the bean given in the constructor. * Returns the String representation of the bean given in the constructor.
* <p> * <p>
*
* @param prefix to use for bean properties. * @param prefix to use for bean properties.
* @return bean object String representation. * @return bean object String representation.
* *
*/ */
private String toString(String prefix) { private String toString(final String prefix) {
StringBuffer sb = new StringBuffer(128); final StringBuffer sb = new StringBuffer(128);
try { try {
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanClass); final PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(this._beanClass);
if (pds!=null) { if (pds != null) {
for (int i=0;i<pds.length;i++) { for (final PropertyDescriptor pd : pds) {
String pName = pds[i].getName(); final String pName = pd.getName();
Method pReadMethod = pds[i].getReadMethod(); final Method pReadMethod = pd.getReadMethod();
if (pReadMethod!=null && // ensure it has a getter method if (pReadMethod != null && // ensure it has a getter method
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods pReadMethod.getDeclaringClass() != Object.class && // filter
pReadMethod.getParameterTypes().length==0) { // filter getter methods that take parameters // Object.class
Object value = pReadMethod.invoke(_obj,NO_PARAMS); // getter
printProperty(sb,prefix+"."+pName,value); // methods
pReadMethod.getParameterTypes().length == 0) { // filter
// getter
// methods
// that
// take
// parameters
final Object value = pReadMethod.invoke(this._obj, NO_PARAMS);
printProperty(sb, prefix + "." + pName, value);
} }
} }
} }
} } catch (final Exception ex) {
catch (Exception ex) { sb.append("\n\nEXCEPTION: Could not complete " + this._obj.getClass() + ".toString(): " + ex.getMessage() + "\n");
sb.append("\n\nEXCEPTION: Could not complete "+_obj.getClass()+".toString(): "+ex.getMessage()+"\n");
} }
return sb.toString(); return sb.toString();
} }
private void printProperty(StringBuffer sb,String prefix,Object value) { private void printProperty(final StringBuffer sb, final String prefix, final Object value) {
if (value==null) { if (value == null) {
sb.append(prefix).append("=null\n"); sb.append(prefix).append("=null\n");
} } else if (value.getClass().isArray()) {
else printArrayProperty(sb, prefix, value);
if (value.getClass().isArray()) { } else if (value instanceof Map) {
printArrayProperty(sb,prefix,value); final Map map = (Map) value;
} final Iterator i = map.entrySet().iterator();
else
if (value instanceof Map) {
Map map = (Map) value;
Iterator i = map.entrySet().iterator();
if (i.hasNext()) { if (i.hasNext()) {
while (i.hasNext()) { while (i.hasNext()) {
Map.Entry me = (Map.Entry) i.next(); final Map.Entry me = (Map.Entry) i.next();
String ePrefix = prefix+"["+me.getKey()+"]"; final String ePrefix = prefix + "[" + me.getKey() + "]";
Object eValue = me.getValue(); final Object eValue = me.getValue();
//NEW // NEW
String[] tsInfo = new String[2]; final String[] tsInfo = new String[2];
tsInfo[0] = ePrefix; tsInfo[0] = ePrefix;
Stack stack = (Stack) PREFIX_TL.get(); final Stack stack = (Stack) PREFIX_TL.get();
stack.push(tsInfo); stack.push(tsInfo);
String s = (eValue!=null) ? eValue.toString() : "null"; final String s = eValue != null ? eValue.toString() : "null";
stack.pop(); stack.pop();
if (tsInfo[1]==null) { if (tsInfo[1] == null) {
sb.append(ePrefix).append("=").append(s).append("\n"); sb.append(ePrefix).append("=").append(s).append("\n");
} } else {
else {
sb.append(s); sb.append(s);
} }
} }
} } else {
else {
sb.append(prefix).append("=[]\n"); sb.append(prefix).append("=[]\n");
} }
} } else if (value instanceof Collection) {
else final Collection collection = (Collection) value;
if (value instanceof Collection) { final Iterator i = collection.iterator();
Collection collection = (Collection) value;
Iterator i = collection.iterator();
if (i.hasNext()) { if (i.hasNext()) {
int c = 0; int c = 0;
while (i.hasNext()) { while (i.hasNext()) {
String cPrefix = prefix+"["+(c++)+"]"; final String cPrefix = prefix + "[" + c++ + "]";
Object cValue = i.next(); final Object cValue = i.next();
//NEW // NEW
String[] tsInfo = new String[2]; final String[] tsInfo = new String[2];
tsInfo[0] = cPrefix; tsInfo[0] = cPrefix;
Stack stack = (Stack) PREFIX_TL.get(); final Stack stack = (Stack) PREFIX_TL.get();
stack.push(tsInfo); stack.push(tsInfo);
String s = (cValue!=null) ? cValue.toString() : "null"; final String s = cValue != null ? cValue.toString() : "null";
stack.pop(); stack.pop();
if (tsInfo[1]==null) { if (tsInfo[1] == null) {
sb.append(cPrefix).append("=").append(s).append("\n"); sb.append(cPrefix).append("=").append(s).append("\n");
} } else {
else {
sb.append(s); sb.append(s);
} }
} }
} } else {
else {
sb.append(prefix).append("=[]\n"); sb.append(prefix).append("=[]\n");
} }
} } else {
else { final String[] tsInfo = new String[2];
String[] tsInfo = new String[2];
tsInfo[0] = prefix; tsInfo[0] = prefix;
Stack stack = (Stack) PREFIX_TL.get(); final Stack stack = (Stack) PREFIX_TL.get();
stack.push(tsInfo); stack.push(tsInfo);
String s = value.toString(); final String s = value.toString();
stack.pop(); stack.pop();
if (tsInfo[1]==null) { if (tsInfo[1] == null) {
sb.append(prefix).append("=").append(s).append("\n"); sb.append(prefix).append("=").append(s).append("\n");
} } else {
else {
sb.append(s); sb.append(s);
} }
} }
} }
private void printArrayProperty(StringBuffer sb, String prefix,Object array) { private void printArrayProperty(final StringBuffer sb, final String prefix, final Object array) {
int length = Array.getLength(array); final int length = Array.getLength(array);
for (int i=0;i<length;i++) { for (int i = 0; i < length; i++) {
Object obj = Array.get(array,i); final Object obj = Array.get(array, i);
printProperty(sb,prefix+"["+i+"]",obj); printProperty(sb, prefix + "[" + i + "]", obj);
} }
} }
} }

View file

@ -16,48 +16,53 @@
*/ */
package com.sun.syndication.feed.module; package com.sun.syndication.feed.module;
import com.sun.syndication.feed.CopyFrom;
import java.util.List;
import java.util.Date; import java.util.Date;
import java.util.List;
import com.sun.syndication.feed.CopyFrom;
/** /**
* Dublin Core Module. * Dublin Core Module.
* <p> * <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>. *
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core
* module</a>.
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface DCModule extends Module, CopyFrom { public interface DCModule extends Module, CopyFrom {
/** /**
* URI of the Dublin Core Module (http://purl.org/dc/elements/1.1/). * URI of the Dublin Core Module (http://purl.org/dc/elements/1.1/).
* *
*/ */
String URI = "http://purl.org/dc/elements/1.1/"; String URI = "http://purl.org/dc/elements/1.1/";
/** /**
* Returns the DublinCore module titles. * Returns the DublinCore module titles.
* <p> * <p>
* @return a list of Strings representing the DublinCore module title, *
* an empty list if none. * @return a list of Strings representing the DublinCore module title, an
* * empty list if none.
*
*/ */
List<String> getTitles(); List<String> getTitles();
/** /**
* Sets the DublinCore module titles. * Sets the DublinCore module titles.
* <p> * <p>
* @param titles the list of String representing the DublinCore module titles *
* to set, an empty list or <b>null</b> if none. * @param titles the list of String representing the DublinCore module
* * titles to set, an empty list or <b>null</b> if none.
*
*/ */
void setTitles(List<String> titles); void setTitles(List<String> titles);
/** /**
* Gets the DublinCore module title. Convenience method that can be used * Gets the DublinCore module title. Convenience method that can be used to
* to obtain the first item, <b>null</b> if none. * obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module title, <b>null</b> if none. * @return the first DublinCore module title, <b>null</b> if none.
*/ */
String getTitle(); String getTitle();
@ -66,26 +71,29 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module title. Convenience method that can be used * Sets the DublinCore module title. Convenience method that can be used
* when there is only one title to set. * when there is only one title to set.
* <p> * <p>
*
* @param title the DublinCore module title to set, <b>null</b> if none. * @param title the DublinCore module title to set, <b>null</b> if none.
* *
*/ */
void setTitle(String title); void setTitle(String title);
/** /**
* Returns the DublinCore module creator. * Returns the DublinCore module creator.
* <p> * <p>
* @return a list of Strings representing the DublinCore module creator, *
* an empty list if none. * @return a list of Strings representing the DublinCore module creator, an
* * empty list if none.
*
*/ */
List<String> getCreators(); List<String> getCreators();
/** /**
* Sets the DublinCore module creators. * Sets the DublinCore module creators.
* <p> * <p>
*
* @param creators the list of String representing the DublinCore module * @param creators the list of String representing the DublinCore module
* creators to set, an empty list or <b>null</b> if none. * creators to set, an empty list or <b>null</b> if none.
* *
*/ */
void setCreators(List<String> creators); void setCreators(List<String> creators);
@ -93,34 +101,38 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module creator. Convenience method that can be used * Gets the DublinCore module creator. Convenience method that can be used
* to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module creator, <b>null</b> if none. * @return the first DublinCore module creator, <b>null</b> if none.
*/ */
String getCreator(); String getCreator();
/** /**
* Sets the DublinCore module creator. Convenience method that can be used * Sets the DublinCore module creator. Convenience method that can be used
* when there is only one creator to set. * when there is only one creator to set.
* <p> * <p>
*
* @param creator the DublinCore module creator to set, <b>null</b> if none. * @param creator the DublinCore module creator to set, <b>null</b> if none.
* *
*/ */
void setCreator(String creator); void setCreator(String creator);
/** /**
* Returns the DublinCore module subjects. * Returns the DublinCore module subjects.
* <p> * <p>
*
* @return a list of DCSubject elements with the DublinCore module subjects, * @return a list of DCSubject elements with the DublinCore module subjects,
* an empty list if none. * an empty list if none.
* *
*/ */
List<DCSubject> getSubjects(); List<DCSubject> getSubjects();
/** /**
* Sets the DublinCore module subjects. * Sets the DublinCore module subjects.
* <p> * <p>
* @param subjects the list of DCSubject elements with the DublinCore *
* module subjects to set, an empty list or <b>null</b> if none. * @param subjects the list of DCSubject elements with the DublinCore module
* * subjects to set, an empty list or <b>null</b> if none.
*
*/ */
void setSubjects(List<DCSubject> subjects); void setSubjects(List<DCSubject> subjects);
@ -128,6 +140,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module subject. Convenience method that can be used * Gets the DublinCore module subject. Convenience method that can be used
* to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module subject, <b>null</b> if none. * @return the first DublinCore module subject, <b>null</b> if none.
*/ */
DCSubject getSubject(); DCSubject getSubject();
@ -136,26 +149,29 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DCSubject element. Convenience method that can be used when * Sets the DCSubject element. Convenience method that can be used when
* there is only one subject to set. * there is only one subject to set.
* <p> * <p>
*
* @param subject the DublinCore module subject to set, <b>null</b> if none. * @param subject the DublinCore module subject to set, <b>null</b> if none.
* *
*/ */
void setSubject(DCSubject subject); void setSubject(DCSubject subject);
/** /**
* Returns the DublinCore module description. * Returns the DublinCore module description.
* <p> * <p>
*
* @return a list of Strings representing the DublinCore module description, * @return a list of Strings representing the DublinCore module description,
* an empty list if none. * an empty list if none.
* *
*/ */
List<String> getDescriptions(); List<String> getDescriptions();
/** /**
* Sets the DublinCore module descriptions. * Sets the DublinCore module descriptions.
* <p> * <p>
* @param descriptions the list of String representing the DublinCore *
* module descriptions to set, an empty list or <b>null</b> if none. * @param descriptions the list of String representing the DublinCore module
* * descriptions to set, an empty list or <b>null</b> if none.
*
*/ */
void setDescriptions(List<String> descriptions); void setDescriptions(List<String> descriptions);
@ -163,6 +179,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module description. Convenience method that can be * Gets the DublinCore module description. Convenience method that can be
* used to obtain the first item, <b>null</b> if none. * used to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module description, <b>null</b> if none. * @return the first DublinCore module description, <b>null</b> if none.
*/ */
String getDescription(); String getDescription();
@ -171,61 +188,70 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module description. Convenience method that can be * Sets the DublinCore module description. Convenience method that can be
* used when there is only one description to set. * used when there is only one description to set.
* <p> * <p>
* @param description the DublinCore module description to set, <b>null</b> if none. *
* * @param description the DublinCore module description to set, <b>null</b>
* if none.
*
*/ */
void setDescription(String description); void setDescription(String description);
/** /**
* Returns the DublinCore module publisher. * Returns the DublinCore module publisher.
* <p> * <p>
*
* @return a list of Strings representing the DublinCore module publisher, * @return a list of Strings representing the DublinCore module publisher,
* an empty list if none. * an empty list if none.
* *
*/ */
List<String> getPublishers(); List<String> getPublishers();
/** /**
* Sets the DublinCore module publishers. * Sets the DublinCore module publishers.
* <p> * <p>
*
* @param publishers the list of String representing the DublinCore module * @param publishers the list of String representing the DublinCore module
* publishers to set, an empty list or <b>null</b> if none. * publishers to set, an empty list or <b>null</b> if none.
* *
*/ */
void setPublishers(List<String> publishers); void setPublishers(List<String> publishers);
/** /**
* Gets the DublinCore module publisher. Convenience method that can be * Gets the DublinCore module publisher. Convenience method that can be used
* used to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module publisher, <b>null</b> if none. * @return the first DublinCore module publisher, <b>null</b> if none.
*/ */
String getPublisher(); String getPublisher();
/** /**
* Sets the DublinCore module publisher. Convenience method that can be used when * Sets the DublinCore module publisher. Convenience method that can be used
* there is only one publisher to set. * when there is only one publisher to set.
* <p> * <p>
* @param publisher the DublinCore module publisher to set, <b>null</b> if none. *
* * @param publisher the DublinCore module publisher to set, <b>null</b> if
* none.
*
*/ */
void setPublisher(String publisher); void setPublisher(String publisher);
/** /**
* Returns the DublinCore module contributor. * Returns the DublinCore module contributor.
* <p> * <p>
*
* @return a list of Strings representing the DublinCore module contributor, * @return a list of Strings representing the DublinCore module contributor,
* an empty list if none. * an empty list if none.
* *
*/ */
List<String> getContributors(); List<String> getContributors();
/** /**
* Sets the DublinCore module contributors. * Sets the DublinCore module contributors.
* <p> * <p>
*
* @param contributors the list of String representing the DublinCore module * @param contributors the list of String representing the DublinCore module
* contributors to set, an empty list or <b>null</b> if none. * contributors to set, an empty list or <b>null</b> if none.
* *
*/ */
void setContributors(List<String> contributors); void setContributors(List<String> contributors);
@ -233,6 +259,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module contributor. Convenience method that can be * Gets the DublinCore module contributor. Convenience method that can be
* used to obtain the first item, <b>null</b> if none. * used to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module contributor, <b>null</b> if none. * @return the first DublinCore module contributor, <b>null</b> if none.
*/ */
String getContributor(); String getContributor();
@ -241,26 +268,30 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module contributor. Convenience method that can be * Sets the DublinCore module contributor. Convenience method that can be
* used when there is only one contributor to set. * used when there is only one contributor to set.
* <p> * <p>
* @param contributor the DublinCore module contributor to set, <b>null</b> if none. *
* * @param contributor the DublinCore module contributor to set, <b>null</b>
* if none.
*
*/ */
void setContributor(String contributor); void setContributor(String contributor);
/** /**
* Returns the DublinCore module date. * Returns the DublinCore module date.
* <p> * <p>
* @return a list of Strings representing the DublinCore module date, *
* an empty list if none. * @return a list of Strings representing the DublinCore module date, an
* * empty list if none.
*
*/ */
List<Date> getDates(); List<Date> getDates();
/** /**
* Sets the DublinCore module dates. * Sets the DublinCore module dates.
* <p> * <p>
* @param dates the list of Date representing the DublinCore module dates to set, *
* an empty list or <b>null</b> if none. * @param dates the list of Date representing the DublinCore module dates to
* * set, an empty list or <b>null</b> if none.
*
*/ */
void setDates(List<Date> dates); void setDates(List<Date> dates);
@ -268,76 +299,85 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module date. Convenience method that can be used to * Gets the DublinCore module date. Convenience method that can be used to
* obtain the first item, <b>null</b> if none. * obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module date, <b>null</b> if none. * @return the first DublinCore module date, <b>null</b> if none.
*/ */
Date getDate(); Date getDate();
/** /**
* Sets the DublinCore module date. Convenience method that can be used * Sets the DublinCore module date. Convenience method that can be used when
* when there is only one date to set. * there is only one date to set.
* <p> * <p>
*
* @param date the DublinCore module date to set, <b>null</b> if none. * @param date the DublinCore module date to set, <b>null</b> if none.
* *
*/ */
void setDate(Date date); void setDate(Date date);
/** /**
* Returns the DublinCore module type. * Returns the DublinCore module type.
* <p> * <p>
* @return a list of Strings representing the DublinCore module type, *
* an empty list if none. * @return a list of Strings representing the DublinCore module type, an
* * empty list if none.
*
*/ */
List<String> getTypes(); List<String> getTypes();
/** /**
* Sets the DublinCore module types. * Sets the DublinCore module types.
* <p> * <p>
* @param types the list of String representing the DublinCore module types to set, *
* an empty list or <b>null</b> if none. * @param types the list of String representing the DublinCore module types
* * to set, an empty list or <b>null</b> if none.
*
*/ */
void setTypes(List<String> types); void setTypes(List<String> types);
/** /**
* Gets the DublinCore module type. Convenience method that can be used * Gets the DublinCore module type. Convenience method that can be used to
* to obtain the first item, <b>null</b> if none. * obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module type, <b>null</b> if none. * @return the first DublinCore module type, <b>null</b> if none.
*/ */
String getType(); String getType();
/** /**
* Sets the DublinCore module type. Convenience method that can be used * Sets the DublinCore module type. Convenience method that can be used when
* when there is only one type to set. * there is only one type to set.
* <p> * <p>
*
* @param type the DublinCore module type to set, <b>null</b> if none. * @param type the DublinCore module type to set, <b>null</b> if none.
* *
*/ */
void setType(String type); void setType(String type);
/** /**
* Returns the DublinCore module format. * Returns the DublinCore module format.
* <p> * <p>
* @return a list of Strings representing the DublinCore module format, *
* an empty list if none. * @return a list of Strings representing the DublinCore module format, an
* * empty list if none.
*
*/ */
List<String> getFormats(); List<String> getFormats();
/** /**
* Sets the DublinCore module formats. * Sets the DublinCore module formats.
* <p> * <p>
*
* @param formats the list of String representing the DublinCore module * @param formats the list of String representing the DublinCore module
* formats to set, an empty list or <b>null</b> if none. * formats to set, an empty list or <b>null</b> if none.
* *
*/ */
void setFormats(List<String> formats); void setFormats(List<String> formats);
/** /**
* Gets the DublinCore module format. Convenience method that can be used * Gets the DublinCore module format. Convenience method that can be used to
* to obtain the first item, <b>null</b> if none. * obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module format, <b>null</b> if none. * @return the first DublinCore module format, <b>null</b> if none.
*/ */
String getFormat(); String getFormat();
@ -346,26 +386,29 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module format. Convenience method that can be used * Sets the DublinCore module format. Convenience method that can be used
* when there is only one format to set. * when there is only one format to set.
* <p> * <p>
*
* @param format the DublinCore module format to set, <b>null</b> if none. * @param format the DublinCore module format to set, <b>null</b> if none.
* *
*/ */
void setFormat(String format); void setFormat(String format);
/** /**
* Returns the DublinCore module identifier. * Returns the DublinCore module identifier.
* <p> * <p>
*
* @return a list of Strings representing the DublinCore module identifier, * @return a list of Strings representing the DublinCore module identifier,
* an empty list if none. * an empty list if none.
* *
*/ */
List<String> getIdentifiers(); List<String> getIdentifiers();
/** /**
* Sets the DublinCore module identifiers. * Sets the DublinCore module identifiers.
* <p> * <p>
*
* @param identifiers the list of String representing the DublinCore module * @param identifiers the list of String representing the DublinCore module
* identifiers to set, an empty list or <b>null</b> if none. * identifiers to set, an empty list or <b>null</b> if none.
* *
*/ */
void setIdentifiers(List<String> identifiers); void setIdentifiers(List<String> identifiers);
@ -373,6 +416,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module identifier. Convenience method that can be * Gets the DublinCore module identifier. Convenience method that can be
* used to obtain the first item, <b>null</b> if none. * used to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module identifier, <b>null</b> if none. * @return the first DublinCore module identifier, <b>null</b> if none.
*/ */
String getIdentifier(); String getIdentifier();
@ -381,26 +425,30 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module identifier. Convenience method that can be * Sets the DublinCore module identifier. Convenience method that can be
* used when there is only one identifier to set. * used when there is only one identifier to set.
* <p> * <p>
* @param identifier the DublinCore module identifier to set, <b>null</b> if none. *
* * @param identifier the DublinCore module identifier to set, <b>null</b> if
* none.
*
*/ */
void setIdentifier(String identifier); void setIdentifier(String identifier);
/** /**
* Returns the DublinCore module source. * Returns the DublinCore module source.
* <p> * <p>
* @return a list of Strings representing the DublinCore module source, *
* an empty list if none. * @return a list of Strings representing the DublinCore module source, an
* * empty list if none.
*
*/ */
List<String> getSources(); List<String> getSources();
/** /**
* Sets the DublinCore module sources. * Sets the DublinCore module sources.
* <p> * <p>
*
* @param sources the list of String representing the DublinCore module * @param sources the list of String representing the DublinCore module
* sources to set, an empty list or <b>null</b> if none. * sources to set, an empty list or <b>null</b> if none.
* *
*/ */
void setSources(List<String> sources); void setSources(List<String> sources);
@ -408,6 +456,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module subject. Convenience method that can be used * Gets the DublinCore module subject. Convenience method that can be used
* to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module creator, <b>null</b> if none. * @return the first DublinCore module creator, <b>null</b> if none.
*/ */
String getSource(); String getSource();
@ -416,26 +465,29 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module source. Convenience method that can be used * Sets the DublinCore module source. Convenience method that can be used
* when there is only one source to set. * when there is only one source to set.
* <p> * <p>
*
* @param source the DublinCore module source to set, <b>null</b> if none. * @param source the DublinCore module source to set, <b>null</b> if none.
* *
*/ */
void setSource(String source); void setSource(String source);
/** /**
* Returns the DublinCore module language. * Returns the DublinCore module language.
* <p> * <p>
* @return a list of Strings representing the DublinCore module language, *
* an empty list if none. * @return a list of Strings representing the DublinCore module language, an
* * empty list if none.
*
*/ */
List<String> getLanguages(); List<String> getLanguages();
/** /**
* Sets the DublinCore module languages. * Sets the DublinCore module languages.
* <p> * <p>
*
* @param languages the list of String representing the DublinCore module * @param languages the list of String representing the DublinCore module
* languages to set, an empty list or <b>null</b> if none. * languages to set, an empty list or <b>null</b> if none.
* *
*/ */
void setLanguages(List<String> languages); void setLanguages(List<String> languages);
@ -443,6 +495,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module language. Convenience method that can be used * Gets the DublinCore module language. Convenience method that can be used
* to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module language, <b>null</b> if none. * @return the first DublinCore module language, <b>null</b> if none.
*/ */
String getLanguage(); String getLanguage();
@ -451,26 +504,30 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module language. Convenience method that can be used * Sets the DublinCore module language. Convenience method that can be used
* when there is only one language to set. * when there is only one language to set.
* <p> * <p>
* @param language the DublinCore module language to set, <b>null</b> if none. *
* * @param language the DublinCore module language to set, <b>null</b> if
* none.
*
*/ */
void setLanguage(String language); void setLanguage(String language);
/** /**
* Returns the DublinCore module relation. * Returns the DublinCore module relation.
* <p> * <p>
* @return a list of Strings representing the DublinCore module relation, *
* an empty list if none. * @return a list of Strings representing the DublinCore module relation, an
* * empty list if none.
*
*/ */
List<String> getRelations(); List<String> getRelations();
/** /**
* Sets the DublinCore module relations. * Sets the DublinCore module relations.
* <p> * <p>
*
* @param relations the list of String representing the DublinCore module * @param relations the list of String representing the DublinCore module
* relations to set, an empty list or <b>null</b> if none. * relations to set, an empty list or <b>null</b> if none.
* *
*/ */
void setRelations(List<String> relations); void setRelations(List<String> relations);
@ -478,6 +535,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module relation. Convenience method that can be used * Gets the DublinCore module relation. Convenience method that can be used
* to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module relation, <b>null</b> if none. * @return the first DublinCore module relation, <b>null</b> if none.
*/ */
String getRelation(); String getRelation();
@ -486,26 +544,30 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module relation. Convenience method that can be used * Sets the DublinCore module relation. Convenience method that can be used
* when there is only one relation to set. * when there is only one relation to set.
* <p> * <p>
* @param relation the DublinCore module relation to set, <b>null</b> if none. *
* * @param relation the DublinCore module relation to set, <b>null</b> if
* none.
*
*/ */
void setRelation(String relation); void setRelation(String relation);
/** /**
* Returns the DublinCore module coverage. * Returns the DublinCore module coverage.
* <p> * <p>
* @return a list of Strings representing the DublinCore module coverage, *
* an empty list if none. * @return a list of Strings representing the DublinCore module coverage, an
* * empty list if none.
*
*/ */
List<String> getCoverages(); List<String> getCoverages();
/** /**
* Sets the DublinCore module coverages. * Sets the DublinCore module coverages.
* <p> * <p>
*
* @param coverages the list of String representing the DublinCore module * @param coverages the list of String representing the DublinCore module
* coverages to set, an empty list or <b>null</b> if none. * coverages to set, an empty list or <b>null</b> if none.
* *
*/ */
void setCoverages(List<String> coverages); void setCoverages(List<String> coverages);
@ -513,6 +575,7 @@ public interface DCModule extends Module, CopyFrom {
* Gets the DublinCore module coverage. Convenience method that can be used * Gets the DublinCore module coverage. Convenience method that can be used
* to obtain the first item, <b>null</b> if none. * to obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module coverage, <b>null</b> if none. * @return the first DublinCore module coverage, <b>null</b> if none.
*/ */
String getCoverage(); String getCoverage();
@ -521,33 +584,38 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module coverage. Convenience method that can be used * Sets the DublinCore module coverage. Convenience method that can be used
* when there is only one coverage to set. * when there is only one coverage to set.
* <p> * <p>
* @param coverage the DublinCore module coverage to set, <b>null</b> if none. *
* * @param coverage the DublinCore module coverage to set, <b>null</b> if
* none.
*
*/ */
void setCoverage(String coverage); void setCoverage(String coverage);
/** /**
* Returns the DublinCore module rights. * Returns the DublinCore module rights.
* <p> * <p>
* @return a list of Strings representing the DublinCore module rights, *
* an empty list if none. * @return a list of Strings representing the DublinCore module rights, an
* * empty list if none.
*
*/ */
List<String> getRightsList(); List<String> getRightsList();
/** /**
* Sets the DublinCore module rightss. * Sets the DublinCore module rightss.
* <p> * <p>
*
* @param rights the list of String representing the DublinCore module * @param rights the list of String representing the DublinCore module
* rights to set, an empty list or <b>null</b> if none. * rights to set, an empty list or <b>null</b> if none.
* *
*/ */
void setRightsList(List<String> rights); void setRightsList(List<String> rights);
/** /**
* Gets the DublinCore module right. Convenience method that can be used * Gets the DublinCore module right. Convenience method that can be used to
* to obtain the first item, <b>null</b> if none. * obtain the first item, <b>null</b> if none.
* <p> * <p>
*
* @return the first DublinCore module right, <b>null</b> if none. * @return the first DublinCore module right, <b>null</b> if none.
*/ */
String getRights(); String getRights();
@ -556,8 +624,9 @@ public interface DCModule extends Module, CopyFrom {
* Sets the DublinCore module rights. Convenience method that can be used * Sets the DublinCore module rights. Convenience method that can be used
* when there is only one rights to set. * when there is only one rights to set.
* <p> * <p>
*
* @param rights the DublinCore module rights to set, <b>null</b> if none. * @param rights the DublinCore module rights to set, <b>null</b> if none.
* *
*/ */
void setRights(String rights); void setRights(String rights);
} }

View file

@ -21,49 +21,58 @@ import com.sun.syndication.feed.CopyFrom;
/** /**
* Subject of the Dublin Core ModuleImpl. * Subject of the Dublin Core ModuleImpl.
* <p> * <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>. *
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core
* module</a>.
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface DCSubject extends Cloneable,CopyFrom { public interface DCSubject extends Cloneable, CopyFrom {
/** /**
* Returns the DublinCore subject taxonomy URI. * Returns the DublinCore subject taxonomy URI.
* <p> * <p>
*
* @return the DublinCore subject taxonomy URI, <b>null</b> if none. * @return the DublinCore subject taxonomy URI, <b>null</b> if none.
* *
*/ */
String getTaxonomyUri(); String getTaxonomyUri();
/** /**
* Sets the DublinCore subject taxonomy URI. * Sets the DublinCore subject taxonomy URI.
* <p> * <p>
* @param taxonomyUri the DublinCore subject taxonomy URI to set, <b>null</b> if none. *
* * @param taxonomyUri the DublinCore subject taxonomy URI to set,
* <b>null</b> if none.
*
*/ */
void setTaxonomyUri(String taxonomyUri); void setTaxonomyUri(String taxonomyUri);
/** /**
* Returns the DublinCore subject value. * Returns the DublinCore subject value.
* <p> * <p>
*
* @return the DublinCore subject value, <b>null</b> if none. * @return the DublinCore subject value, <b>null</b> if none.
* *
*/ */
String getValue(); String getValue();
/** /**
* Sets the DublinCore subject value. * Sets the DublinCore subject value.
* <p> * <p>
*
* @param value the DublinCore subject value to set, <b>null</b> if none. * @param value the DublinCore subject value to set, <b>null</b> if none.
* *
*/ */
void setValue(String value); void setValue(String value);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

View file

@ -16,61 +16,67 @@
*/ */
package com.sun.syndication.feed.module; package com.sun.syndication.feed.module;
import com.sun.syndication.feed.CopyFrom; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.io.Serializable;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Subject of the Dublin Core ModuleImpl, default implementation. * Subject of the Dublin Core ModuleImpl, default implementation.
* <p> * <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>. *
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core
* module</a>.
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class DCSubjectImpl implements Cloneable,Serializable, DCSubject { public class DCSubjectImpl implements Cloneable, Serializable, DCSubject {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _taxonomyUri; private String _taxonomyUri;
private String _value; private String _value;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public DCSubjectImpl() { public DCSubjectImpl() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof DCSubjectImpl)){ if (!(other instanceof DCSubjectImpl)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -78,83 +84,96 @@ public class DCSubjectImpl implements Cloneable,Serializable, DCSubject {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the DublinCore subject taxonomy URI. * Returns the DublinCore subject taxonomy URI.
* <p> * <p>
*
* @return the DublinCore subject taxonomy URI, <b>null</b> if none. * @return the DublinCore subject taxonomy URI, <b>null</b> if none.
* *
*/ */
@Override
public String getTaxonomyUri() { public String getTaxonomyUri() {
return _taxonomyUri; return this._taxonomyUri;
} }
/** /**
* Sets the DublinCore subject taxonomy URI. * Sets the DublinCore subject taxonomy URI.
* <p> * <p>
* @param taxonomyUri the DublinCore subject taxonomy URI to set, <b>null</b> if none. *
* * @param taxonomyUri the DublinCore subject taxonomy URI to set,
* <b>null</b> if none.
*
*/ */
public void setTaxonomyUri(String taxonomyUri) { @Override
_taxonomyUri = taxonomyUri; public void setTaxonomyUri(final String taxonomyUri) {
this._taxonomyUri = taxonomyUri;
} }
/** /**
* Returns the DublinCore subject value. * Returns the DublinCore subject value.
* <p> * <p>
*
* @return the DublinCore subject value, <b>null</b> if none. * @return the DublinCore subject value, <b>null</b> if none.
* *
*/ */
@Override
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the DublinCore subject value. * Sets the DublinCore subject value.
* <p> * <p>
*
* @param value the DublinCore subject value to set, <b>null</b> if none. * @param value the DublinCore subject value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { @Override
_value = value; public void setValue(final String value) {
this._value = value;
} }
@Override
public Class getInterface() { public Class getInterface() {
return DCSubject.class; return DCSubject.class;
} }
public void copyFrom(CopyFrom obj) { @Override
COPY_FROM_HELPER.copy(this,obj); public void copyFrom(final CopyFrom obj) {
COPY_FROM_HELPER.copy(this, obj);
} }
private static final CopyFromHelper COPY_FROM_HELPER; private static final CopyFromHelper COPY_FROM_HELPER;
static { static {
Map basePropInterfaceMap = new HashMap(); final Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("taxonomyUri",String.class); basePropInterfaceMap.put("taxonomyUri", String.class);
basePropInterfaceMap.put("value",String.class); basePropInterfaceMap.put("value", String.class);
Map basePropClassImplMap = Collections.EMPTY_MAP; final Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(DCSubject.class,basePropInterfaceMap,basePropClassImplMap); COPY_FROM_HELPER = new CopyFromHelper(DCSubject.class, basePropInterfaceMap, basePropClassImplMap);
} }
} }

View file

@ -21,13 +21,15 @@ import java.util.List;
/** /**
* Objects that can have modules are Extendable. * Objects that can have modules are Extendable.
*
* @author Dave Johnson * @author Dave Johnson
*/ */
public interface Extendable { public interface Extendable {
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
@ -36,18 +38,20 @@ public interface Extendable {
/** /**
* Returns the entry modules. * Returns the entry modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the entry modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the entry modules, an empty
* * list if none.
*
*/ */
List<Module> getModules(); List<Module> getModules();
/** /**
* Sets the entry modules. * Sets the entry modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the entry modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the entry modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
void setModules(List<Module> modules); void setModules(List<Module> modules);
} }

View file

@ -16,32 +16,37 @@
*/ */
package com.sun.syndication.feed.module; package com.sun.syndication.feed.module;
import com.sun.syndication.feed.CopyFrom;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.CopyFrom;
/** /**
* Base class for modules describing Metadata of feeds. Examples of such modules are * Base class for modules describing Metadata of feeds. Examples of such modules
* the Dublin Core and Syndication modules. * are the Dublin Core and Syndication modules.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface Module extends Cloneable,CopyFrom,Serializable{ public interface Module extends Cloneable, CopyFrom, Serializable {
/** /**
* Returns the URI of the module. * Returns the URI of the module.
* <p> * <p>
*
* @return URI of the module. * @return URI of the module.
* *
*/ */
String getUri(); String getUri();
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

View file

@ -16,57 +16,63 @@
*/ */
package com.sun.syndication.feed.module; package com.sun.syndication.feed.module;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Base class for modules describing Metadata of feeds, default implementations. * Base class for modules describing Metadata of feeds, default implementations.
* Examples of such modules are the Dublin Core and Syndication modules. * Examples of such modules are the Dublin Core and Syndication modules.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public abstract class ModuleImpl implements Cloneable,Serializable,Module { public abstract class ModuleImpl implements Cloneable, Serializable, Module {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _uri; private final String _uri;
/** /**
* Constructor. * Constructor.
* <p> * <p>
*
* @param uri URI of the module. * @param uri URI of the module.
* *
*/ */
protected ModuleImpl(Class beanClass,String uri) { protected ModuleImpl(final Class beanClass, final String uri) {
_objBean = new ObjectBean(beanClass,this); this._objBean = new ObjectBean(beanClass, this);
_uri = uri; this._uri = uri;
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof ModuleImpl)){ if (!(other instanceof ModuleImpl)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -74,33 +80,37 @@ public abstract class ModuleImpl implements Cloneable,Serializable,Module {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the URI of the module. * Returns the URI of the module.
* <p> * <p>
*
* @return URI of the module. * @return URI of the module.
* *
*/ */
@Override
public String getUri() { public String getUri() {
return _uri; return this._uri;
} }
} }

View file

@ -21,69 +21,82 @@ import java.util.Date;
/** /**
* Syndication ModuleImpl. * Syndication ModuleImpl.
* <p> * <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/syndication/">Syndication module</a>. *
* @see <a
* href="http://web.resource.org/rss/1.0/modules/syndication/">Syndication
* module</a>.
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface SyModule extends Module { public interface SyModule extends Module {
/** /**
* URI of the Syndication ModuleImpl (http://purl.org/rss/1.0/modules/syndication/). * URI of the Syndication ModuleImpl
* * (http://purl.org/rss/1.0/modules/syndication/).
*
*/ */
static final String URI = "http://purl.org/rss/1.0/modules/syndication/"; static final String URI = "http://purl.org/rss/1.0/modules/syndication/";
static final String HOURLY = "hourly"; static final String HOURLY = "hourly";
static final String DAILY = "daily"; static final String DAILY = "daily";
static final String WEEKLY = "weekly"; static final String WEEKLY = "weekly";
static final String MONTHLY = "monthly"; static final String MONTHLY = "monthly";
static final String YEARLY = "yearly"; static final String YEARLY = "yearly";
/** /**
* Returns the Syndication module update period. * Returns the Syndication module update period.
* <p> * <p>
*
* @return the Syndication module update period, <b>null</b> if none. * @return the Syndication module update period, <b>null</b> if none.
* *
*/ */
String getUpdatePeriod(); String getUpdatePeriod();
/** /**
* Sets the Syndication module update period. * Sets the Syndication module update period.
* <p> * <p>
* @param updatePeriod the Syndication module update period to set, <b>null</b> if none. *
* * @param updatePeriod the Syndication module update period to set,
* <b>null</b> if none.
*
*/ */
void setUpdatePeriod(String updatePeriod); void setUpdatePeriod(String updatePeriod);
/** /**
* Returns the Syndication module update frequency. * Returns the Syndication module update frequency.
* <p> * <p>
*
* @return the Syndication module update frequency, <b>null</b> if none. * @return the Syndication module update frequency, <b>null</b> if none.
* *
*/ */
int getUpdateFrequency(); int getUpdateFrequency();
/** /**
* Sets the Syndication module update frequency. * Sets the Syndication module update frequency.
* <p> * <p>
* @param updateFrequency the Syndication module update frequency to set, <b>null</b> if none. *
* * @param updateFrequency the Syndication module update frequency to set,
* <b>null</b> if none.
*
*/ */
void setUpdateFrequency(int updateFrequency); void setUpdateFrequency(int updateFrequency);
/** /**
* Returns the Syndication module update base date. * Returns the Syndication module update base date.
* <p> * <p>
*
* @return the Syndication module update base date, <b>null</b> if none. * @return the Syndication module update base date, <b>null</b> if none.
* *
*/ */
Date getUpdateBase(); Date getUpdateBase();
/** /**
* Sets the Syndication module update base date. * Sets the Syndication module update base date.
* <p> * <p>
* @param updateBase the Syndication module update base date to set, <b>null</b> if none. *
* * @param updateBase the Syndication module update base date to set,
* <b>null</b> if none.
*
*/ */
void setUpdateBase(Date updateBase); void setUpdateBase(Date updateBase);

View file

@ -16,30 +16,37 @@
*/ */
package com.sun.syndication.feed.module; package com.sun.syndication.feed.module;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sun.syndication.feed.CopyFrom; import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.CopyFromHelper; import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.*;
/** /**
* Syndication ModuleImpl, default implementation. * Syndication ModuleImpl, default implementation.
* <p> * <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/syndication/">Syndication module</a>. *
* @see <a
* href="http://web.resource.org/rss/1.0/modules/syndication/">Syndication
* module</a>.
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyModuleImpl extends ModuleImpl implements SyModule { public class SyModuleImpl extends ModuleImpl implements SyModule {
private static final Set<String> PERIODS = new HashSet<String>(); private static final Set<String> PERIODS = new HashSet<String>();
static { static {
PERIODS.add(HOURLY ); PERIODS.add(HOURLY);
PERIODS.add(DAILY ); PERIODS.add(DAILY);
PERIODS.add(WEEKLY ); PERIODS.add(WEEKLY);
PERIODS.add(MONTHLY); PERIODS.add(MONTHLY);
PERIODS.add(YEARLY ); PERIODS.add(YEARLY);
} }
private String _updatePeriod; private String _updatePeriod;
private int _updateFrequency; private int _updateFrequency;
private Date _updateBase; private Date _updateBase;
@ -47,94 +54,111 @@ public class SyModuleImpl extends ModuleImpl implements SyModule {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyModuleImpl() { public SyModuleImpl() {
super(SyModule.class,URI); super(SyModule.class, URI);
} }
/** /**
* Returns the Syndication module update period. * Returns the Syndication module update period.
* <p> * <p>
*
* @return the Syndication module update period, <b>null</b> if none. * @return the Syndication module update period, <b>null</b> if none.
* *
*/ */
@Override
public String getUpdatePeriod() { public String getUpdatePeriod() {
return _updatePeriod; return this._updatePeriod;
} }
/** /**
* Sets the Syndication module update period. * Sets the Syndication module update period.
* <p> * <p>
* @param updatePeriod the Syndication module update period to set, <b>null</b> if none. *
* * @param updatePeriod the Syndication module update period to set,
* <b>null</b> if none.
*
*/ */
public void setUpdatePeriod(String updatePeriod) { @Override
public void setUpdatePeriod(final String updatePeriod) {
if (!PERIODS.contains(updatePeriod)) { if (!PERIODS.contains(updatePeriod)) {
throw new IllegalArgumentException("Invalid period ["+updatePeriod+"]"); throw new IllegalArgumentException("Invalid period [" + updatePeriod + "]");
} }
_updatePeriod = updatePeriod; this._updatePeriod = updatePeriod;
} }
/** /**
* Returns the Syndication module update frequency. * Returns the Syndication module update frequency.
* <p> * <p>
*
* @return the Syndication module update frequency, <b>null</b> if none. * @return the Syndication module update frequency, <b>null</b> if none.
* *
*/ */
@Override
public int getUpdateFrequency() { public int getUpdateFrequency() {
return _updateFrequency; return this._updateFrequency;
} }
/** /**
* Sets the Syndication module update frequency. * Sets the Syndication module update frequency.
* <p> * <p>
* @param updateFrequency the Syndication module update frequency to set, <b>null</b> if none. *
* * @param updateFrequency the Syndication module update frequency to set,
* <b>null</b> if none.
*
*/ */
public void setUpdateFrequency(int updateFrequency) { @Override
_updateFrequency = updateFrequency; public void setUpdateFrequency(final int updateFrequency) {
this._updateFrequency = updateFrequency;
} }
/** /**
* Returns the Syndication module update base date. * Returns the Syndication module update base date.
* <p> * <p>
*
* @return the Syndication module update base date, <b>null</b> if none. * @return the Syndication module update base date, <b>null</b> if none.
* *
*/ */
@Override
public Date getUpdateBase() { public Date getUpdateBase() {
return new Date(_updateBase.getTime()); return new Date(this._updateBase.getTime());
} }
/** /**
* Sets the Syndication module update base date. * Sets the Syndication module update base date.
* <p> * <p>
* @param updateBase the Syndication module update base date to set, <b>null</b> if none. *
* * @param updateBase the Syndication module update base date to set,
* <b>null</b> if none.
*
*/ */
public void setUpdateBase(Date updateBase) { @Override
_updateBase = new Date(updateBase.getTime()); public void setUpdateBase(final Date updateBase) {
this._updateBase = new Date(updateBase.getTime());
} }
@Override
public Class<? extends Module> getInterface() { public Class<? extends Module> getInterface() {
return SyModule.class; return SyModule.class;
} }
public void copyFrom(CopyFrom obj) { @Override
COPY_FROM_HELPER.copy(this,obj); public void copyFrom(final CopyFrom obj) {
COPY_FROM_HELPER.copy(this, obj);
} }
private static final CopyFromHelper COPY_FROM_HELPER; private static final CopyFromHelper COPY_FROM_HELPER;
static { static {
Map basePropInterfaceMap = new HashMap(); final Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("updatePeriod",String.class); basePropInterfaceMap.put("updatePeriod", String.class);
basePropInterfaceMap.put("updateFrequency",Integer.TYPE); basePropInterfaceMap.put("updateFrequency", Integer.TYPE);
basePropInterfaceMap.put("updateBase",Date.class); basePropInterfaceMap.put("updateBase", Date.class);
Map basePropClassImplMap = Collections.EMPTY_MAP; final Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyModule.class,basePropInterfaceMap,basePropClassImplMap); COPY_FROM_HELPER = new CopyFromHelper(SyModule.class, basePropInterfaceMap, basePropClassImplMap);
} }
} }

View file

@ -16,26 +16,25 @@
*/ */
package com.sun.syndication.feed.module.impl; package com.sun.syndication.feed.module.impl;
import com.sun.syndication.feed.module.Module;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.sun.syndication.feed.module.Module;
/** /**
*/ */
public class ModuleUtils { public class ModuleUtils {
public static List<Module> cloneModules(List<Module> modules) { public static List<Module> cloneModules(final List<Module> modules) {
List<Module> cModules = null; List<Module> cModules = null;
if (modules!=null) { if (modules != null) {
cModules = new ArrayList<Module>(); cModules = new ArrayList<Module>();
for (Module module : modules) { for (final Module module : modules) {
try { try {
Module c = (Module) module.clone(); final Module c = (Module) module.clone();
cModules.add(c); cModules.add(c);
} } catch (final Exception ex) {
catch (Exception ex) { throw new RuntimeException("Cloning modules " + module.getUri(), ex);
throw new RuntimeException("Cloning modules "+module.getUri(),ex);
} }
} }
} }
@ -44,16 +43,16 @@ public class ModuleUtils {
/** /**
* *
* *
* @since 1.5 Changed to return the first, not the last. * @since 1.5 Changed to return the first, not the last.
* *
* @param modules * @param modules
* @param uri * @param uri
* @return * @return
*/ */
public static Module getModule(List<Module> modules,String uri) { public static Module getModule(final List<Module> modules, final String uri) {
Module module = null; Module module = null;
for (int i=0; modules!=null && i<modules.size();i++) { for (int i = 0; modules != null && i < modules.size(); i++) {
module = modules.get(i); module = modules.get(i);
if (module.getUri().equals(uri)) { if (module.getUri().equals(uri)) {
return module; return module;

View file

@ -17,55 +17,60 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for categories of RSS feeds. * Bean for categories of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Category implements Cloneable,Serializable { public class Category implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _domain; private String _domain;
private String _value; private String _value;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Category() { public Category() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Category)){ if (!(other instanceof Category)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -73,62 +78,69 @@ public class Category implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the category domain. * Returns the category domain.
* <p> * <p>
*
* @return the category domain, <b>null</b> if none. * @return the category domain, <b>null</b> if none.
* *
*/ */
public String getDomain() { public String getDomain() {
return _domain; return this._domain;
} }
/** /**
* Sets the category domain. * Sets the category domain.
* <p> * <p>
*
* @param domain the category domain to set, <b>null</b> if none. * @param domain the category domain to set, <b>null</b> if none.
* *
*/ */
public void setDomain(String domain) { public void setDomain(final String domain) {
_domain = domain; this._domain = domain;
} }
/** /**
* Returns the category value. * Returns the category value.
* <p> * <p>
*
* @return the category value, <b>null</b> if none. * @return the category value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the category value. * Sets the category value.
* <p> * <p>
*
* @param value the category value to set, <b>null</b> if none. * @param value the category value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
} }

View file

@ -17,41 +17,47 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils; import com.sun.syndication.feed.module.impl.ModuleUtils;
import java.util.*;
/** /**
* Bean for RSS feeds. * Bean for RSS feeds.
* <p> * <p>
* It handles all RSS versions (0.9, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) * It handles all RSS versions (0.9, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0)
* without losing information. * without losing information.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Channel extends WireFeed { public class Channel extends WireFeed {
public static final String SUNDAY = "sunday"; public static final String SUNDAY = "sunday";
public static final String MONDAY = "monday"; public static final String MONDAY = "monday";
public static final String TUESDAY = "tuesday"; public static final String TUESDAY = "tuesday";
public static final String WEDNESDAY = "wednesday"; public static final String WEDNESDAY = "wednesday";
public static final String THURSDAY = "thursday"; public static final String THURSDAY = "thursday";
public static final String FRIDAY = "friday"; public static final String FRIDAY = "friday";
public static final String SATURDAY = "saturday"; public static final String SATURDAY = "saturday";
private static final Set<String> DAYS; private static final Set<String> DAYS;
static { static {
HashSet<String> days = new HashSet<String>(); final HashSet<String> days = new HashSet<String>();
days.add(SUNDAY ); days.add(SUNDAY);
days.add(MONDAY ); days.add(MONDAY);
days.add(TUESDAY ); days.add(TUESDAY);
days.add(WEDNESDAY); days.add(WEDNESDAY);
days.add(THURSDAY ); days.add(THURSDAY);
days.add(FRIDAY ); days.add(FRIDAY);
days.add(SATURDAY ); days.add(SATURDAY);
DAYS = Collections.unmodifiableSet(days); DAYS = Collections.unmodifiableSet(days);
} }
@ -80,510 +86,556 @@ public class Channel extends WireFeed {
/** /**
* Default constructor, for bean cloning purposes only. * Default constructor, for bean cloning purposes only.
* *
*/ */
public Channel() { public Channel() {
} }
/** /**
* Channel Constructor. All properties, except the type, are set to <b>null</b>. * Channel Constructor. All properties, except the type, are set to
* <b>null</b>.
* <p> * <p>
*
* @param type the type of the RSS feed. * @param type the type of the RSS feed.
* *
*/ */
public Channel(String type) { public Channel(final String type) {
super(type); super(type);
} }
/** /**
* Returns the channel title. * Returns the channel title.
* <p> * <p>
*
* @return the channel title, <b>null</b> if none. * @return the channel title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the channel title. * Sets the channel title.
* <p> * <p>
*
* @param title the channel title to set, <b>null</b> if none. * @param title the channel title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
_title = title; this._title = title;
} }
/** /**
* Returns the channel description. * Returns the channel description.
* <p> * <p>
*
* @return the channel description, <b>null</b> if none. * @return the channel description, <b>null</b> if none.
* *
*/ */
public String getDescription() { public String getDescription() {
return _description; return this._description;
} }
/** /**
* Sets the channel description. * Sets the channel description.
* <p> * <p>
*
* @param description the channel description to set, <b>null</b> if none. * @param description the channel description to set, <b>null</b> if none.
* *
*/ */
public void setDescription(String description) { public void setDescription(final String description) {
_description = description; this._description = description;
} }
/** /**
* Returns the channel link. * Returns the channel link.
* <p> * <p>
*
* @return the channel link, <b>null</b> if none. * @return the channel link, <b>null</b> if none.
* *
*/ */
public String getLink() { public String getLink() {
return _link; return this._link;
} }
/** /**
* Sets the channel link. * Sets the channel link.
* <p> * <p>
*
* @param link the channel link to set, <b>null</b> if none. * @param link the channel link to set, <b>null</b> if none.
* *
*/ */
public void setLink(String link) { public void setLink(final String link) {
_link = link; this._link = link;
} }
/** /**
* Returns the channel uri. * Returns the channel uri.
* <p> * <p>
*
* @return the channel uri, <b>null</b> if none. * @return the channel uri, <b>null</b> if none.
*/ */
public String getUri() { public String getUri() {
return _uri; return this._uri;
} }
/** /**
* Sets the channel uri. * Sets the channel uri.
* <p> * <p>
*
* @param uri the channel uri, <b>null</b> if none. * @param uri the channel uri, <b>null</b> if none.
*/ */
public void setUri(String uri) { public void setUri(final String uri) {
_uri = uri; this._uri = uri;
} }
/** /**
* Returns the channel image. * Returns the channel image.
* <p> * <p>
*
* @return the channel image, <b>null</b> if none. * @return the channel image, <b>null</b> if none.
* *
*/ */
public Image getImage() { public Image getImage() {
return _image; return this._image;
} }
/** /**
* Sets the channel image. * Sets the channel image.
* <p> * <p>
*
* @param image the channel image to set, <b>null</b> if none. * @param image the channel image to set, <b>null</b> if none.
* *
*/ */
public void setImage(Image image) { public void setImage(final Image image) {
_image = image; this._image = image;
} }
/** /**
* Returns the channel items. * Returns the channel items.
* <p> * <p>
* @return a list of Item elements with the channel items, *
* an empty list if none. * @return a list of Item elements with the channel items, an empty list if
* * none.
*
*/ */
public List<Item> getItems() { public List<Item> getItems() {
return (_items==null) ? (_items=new ArrayList<Item>()) : _items; return this._items == null ? (this._items = new ArrayList<Item>()) : this._items;
} }
/** /**
* Sets the channel items. * Sets the channel items.
* <p> * <p>
* @param items the list of Item elements with the channel items to set, *
* an empty list or <b>null</b> if none. * @param items the list of Item elements with the channel items to set, an
* * empty list or <b>null</b> if none.
*
*/ */
public void setItems(List<Item> items) { public void setItems(final List<Item> items) {
_items = items; this._items = items;
} }
/** /**
* Returns the channel text input. * Returns the channel text input.
* <p> * <p>
*
* @return the channel text input, <b>null</b> if none. * @return the channel text input, <b>null</b> if none.
* *
*/ */
public TextInput getTextInput() { public TextInput getTextInput() {
return _textInput; return this._textInput;
} }
/** /**
* Sets the channel text input. * Sets the channel text input.
* <p> * <p>
*
* @param textInput the channel text input to set, <b>null</b> if none. * @param textInput the channel text input to set, <b>null</b> if none.
* *
*/ */
public void setTextInput(TextInput textInput) { public void setTextInput(final TextInput textInput) {
_textInput = textInput; this._textInput = textInput;
} }
/** /**
* Returns the channel language. * Returns the channel language.
* <p> * <p>
*
* @return the channel language, <b>null</b> if none. * @return the channel language, <b>null</b> if none.
* *
*/ */
public String getLanguage() { public String getLanguage() {
return _language; return this._language;
} }
/** /**
* Sets the channel language. * Sets the channel language.
* <p> * <p>
*
* @param language the channel language to set, <b>null</b> if none. * @param language the channel language to set, <b>null</b> if none.
* *
*/ */
public void setLanguage(String language) { public void setLanguage(final String language) {
_language = language; this._language = language;
} }
/** /**
* Returns the channel rating. * Returns the channel rating.
* <p> * <p>
*
* @return the channel rating, <b>null</b> if none. * @return the channel rating, <b>null</b> if none.
* *
*/ */
public String getRating() { public String getRating() {
return _rating; return this._rating;
} }
/** /**
* Sets the channel rating. * Sets the channel rating.
* <p> * <p>
*
* @param rating the channel rating to set, <b>null</b> if none. * @param rating the channel rating to set, <b>null</b> if none.
* *
*/ */
public void setRating(String rating) { public void setRating(final String rating) {
_rating = rating; this._rating = rating;
} }
/** /**
* Returns the channel copyright. * Returns the channel copyright.
* <p> * <p>
*
* @return the channel copyright, <b>null</b> if none. * @return the channel copyright, <b>null</b> if none.
* *
*/ */
public String getCopyright() { public String getCopyright() {
return _copyright; return this._copyright;
} }
/** /**
* Sets the channel copyright. * Sets the channel copyright.
* <p> * <p>
*
* @param copyright the channel copyright to set, <b>null</b> if none. * @param copyright the channel copyright to set, <b>null</b> if none.
* *
*/ */
public void setCopyright(String copyright) { public void setCopyright(final String copyright) {
_copyright = copyright; this._copyright = copyright;
} }
/** /**
* Returns the channel publishing date. * Returns the channel publishing date.
* <p> * <p>
*
* @return the channel publishing date, <b>null</b> if none. * @return the channel publishing date, <b>null</b> if none.
* *
*/ */
public Date getPubDate() { public Date getPubDate() {
return _pubDate == null ? null : new Date(_pubDate.getTime()); return this._pubDate == null ? null : new Date(this._pubDate.getTime());
} }
/** /**
* Sets the channel publishing date. * Sets the channel publishing date.
* <p> * <p>
*
* @param pubDate the channel publishing date to set, <b>null</b> if none. * @param pubDate the channel publishing date to set, <b>null</b> if none.
* *
*/ */
public void setPubDate(Date pubDate) { public void setPubDate(final Date pubDate) {
_pubDate = pubDate == null ? null : new Date( pubDate.getTime()); this._pubDate = pubDate == null ? null : new Date(pubDate.getTime());
} }
/** /**
* Returns the channel last build date. * Returns the channel last build date.
* <p> * <p>
*
* @return the channel last build date, <b>null</b> if none. * @return the channel last build date, <b>null</b> if none.
* *
*/ */
public Date getLastBuildDate() { public Date getLastBuildDate() {
return _lastBuildDate == null ? null : new Date(_lastBuildDate.getTime()); return this._lastBuildDate == null ? null : new Date(this._lastBuildDate.getTime());
} }
/** /**
* Sets the channel last build date. * Sets the channel last build date.
* <p> * <p>
* @param lastBuildDate the channel last build date to set, <b>null</b> if none. *
* * @param lastBuildDate the channel last build date to set, <b>null</b> if
* none.
*
*/ */
public void setLastBuildDate(Date lastBuildDate) { public void setLastBuildDate(final Date lastBuildDate) {
_lastBuildDate = lastBuildDate == null ? null : new Date( lastBuildDate.getTime()); this._lastBuildDate = lastBuildDate == null ? null : new Date(lastBuildDate.getTime());
} }
/** /**
* Returns the channel docs. * Returns the channel docs.
* <p> * <p>
*
* @return the channel docs, <b>null</b> if none. * @return the channel docs, <b>null</b> if none.
* *
*/ */
public String getDocs() { public String getDocs() {
return _docs; return this._docs;
} }
/** /**
* Sets the channel docs. * Sets the channel docs.
* <p> * <p>
*
* @param docs the channel docs to set, <b>null</b> if none. * @param docs the channel docs to set, <b>null</b> if none.
* *
*/ */
public void setDocs(String docs) { public void setDocs(final String docs) {
_docs = docs; this._docs = docs;
} }
/** /**
* Returns the channel managing editor. * Returns the channel managing editor.
* <p> * <p>
*
* @return the channel managing editor, <b>null</b> if none. * @return the channel managing editor, <b>null</b> if none.
* *
*/ */
public String getManagingEditor() { public String getManagingEditor() {
return _managingEditor; return this._managingEditor;
} }
/** /**
* Sets the channel managing editor. * Sets the channel managing editor.
* <p> * <p>
* @param managingEditor the channel managing editor to set, <b>null</b> if none. *
* * @param managingEditor the channel managing editor to set, <b>null</b> if
* none.
*
*/ */
public void setManagingEditor(String managingEditor) { public void setManagingEditor(final String managingEditor) {
_managingEditor = managingEditor; this._managingEditor = managingEditor;
} }
/** /**
* Returns the channel web master. * Returns the channel web master.
* <p> * <p>
*
* @return the channel web master, <b>null</b> if none. * @return the channel web master, <b>null</b> if none.
* *
*/ */
public String getWebMaster() { public String getWebMaster() {
return _webMaster; return this._webMaster;
} }
/** /**
* Sets the channel web master. * Sets the channel web master.
* <p> * <p>
*
* @param webMaster the channel web master to set, <b>null</b> if none. * @param webMaster the channel web master to set, <b>null</b> if none.
* *
*/ */
public void setWebMaster(String webMaster) { public void setWebMaster(final String webMaster) {
_webMaster = webMaster; this._webMaster = webMaster;
} }
/** /**
* Returns the channel skip hours. * Returns the channel skip hours.
* <p> * <p>
* @return a list of Integer elements with the channel skip hours, *
* an empty list if none. * @return a list of Integer elements with the channel skip hours, an empty
* * list if none.
*
*/ */
public List<Integer> getSkipHours() { public List<Integer> getSkipHours() {
return (_skipHours!=null) ? _skipHours : new ArrayList<Integer>(); return this._skipHours != null ? this._skipHours : new ArrayList<Integer>();
} }
/** /**
* Sets the channel skip hours. * Sets the channel skip hours.
* <p> * <p>
* @param skipHours the list of Integer elements with the channel skip hours to set, *
* an empty list or <b>null</b> if none. * @param skipHours the list of Integer elements with the channel skip hours
* * to set, an empty list or <b>null</b> if none.
*
*/ */
public void setSkipHours(List<Integer> skipHours) { public void setSkipHours(final List<Integer> skipHours) {
if (skipHours!=null) { if (skipHours != null) {
for (int i=0;i<skipHours.size();i++) { for (int i = 0; i < skipHours.size(); i++) {
Integer iHour = (Integer) skipHours.get(i); final Integer iHour = skipHours.get(i);
if (iHour!=null) { if (iHour != null) {
int hour = iHour.intValue(); final int hour = iHour.intValue();
if (hour<0 || hour>24) { if (hour < 0 || hour > 24) {
throw new IllegalArgumentException("Invalid hour ["+hour+"]"); throw new IllegalArgumentException("Invalid hour [" + hour + "]");
} }
} } else {
else {
throw new IllegalArgumentException("Invalid hour [null]"); throw new IllegalArgumentException("Invalid hour [null]");
} }
} }
} }
_skipHours = skipHours; this._skipHours = skipHours;
} }
/** /**
* Returns the channel skip days. * Returns the channel skip days.
* <p> * <p>
* @return a list of Day elements with the channel skip days, *
* an empty list if none. * @return a list of Day elements with the channel skip days, an empty list
* * if none.
*
*/ */
public List<String> getSkipDays() { public List<String> getSkipDays() {
return (_skipDays!=null) ? _skipDays : new ArrayList<String>(); return this._skipDays != null ? this._skipDays : new ArrayList<String>();
} }
/** /**
* Sets the channel skip days. * Sets the channel skip days.
* <p> * <p>
* @param skipDays the list of Day elements with the channel skip days to set, *
* an empty list or <b>null</b> if none. * @param skipDays the list of Day elements with the channel skip days to
* * set, an empty list or <b>null</b> if none.
*
*/ */
public void setSkipDays(List<String> skipDays) { public void setSkipDays(final List<String> skipDays) {
if (skipDays!=null) { if (skipDays != null) {
for (int i=0;i<skipDays.size();i++) { for (int i = 0; i < skipDays.size(); i++) {
String day = (String) skipDays.get(i); String day = skipDays.get(i);
if (day!=null) { if (day != null) {
day = day.toLowerCase(); day = day.toLowerCase();
if (!DAYS.contains(day)) { if (!DAYS.contains(day)) {
throw new IllegalArgumentException("Invalid day ["+day+"]"); throw new IllegalArgumentException("Invalid day [" + day + "]");
} }
skipDays.set(i,day); skipDays.set(i, day);
} } else {
else {
throw new IllegalArgumentException("Invalid day [null]"); throw new IllegalArgumentException("Invalid day [null]");
} }
} }
} }
_skipDays = skipDays; this._skipDays = skipDays;
} }
/** /**
* Returns the channel cloud. * Returns the channel cloud.
* <p> * <p>
*
* @return the channel cloud, <b>null</b> if none. * @return the channel cloud, <b>null</b> if none.
* *
*/ */
public Cloud getCloud() { public Cloud getCloud() {
return _cloud; return this._cloud;
} }
/** /**
* Sets the channel cloud. * Sets the channel cloud.
* <p> * <p>
*
* @param cloud the channel cloud to set, <b>null</b> if none. * @param cloud the channel cloud to set, <b>null</b> if none.
* *
*/ */
public void setCloud(Cloud cloud) { public void setCloud(final Cloud cloud) {
_cloud = cloud; this._cloud = cloud;
} }
/** /**
* Returns the channel categories. * Returns the channel categories.
* <p> * <p>
* @return a list of Category elements with the channel categories, *
* an empty list if none. * @return a list of Category elements with the channel categories, an empty
* * list if none.
*
*/ */
public List<Category> getCategories() { public List<Category> getCategories() {
return (_categories==null) ? (_categories=new ArrayList<Category>()) : _categories; return this._categories == null ? (this._categories = new ArrayList<Category>()) : this._categories;
} }
/** /**
* Sets the channel categories. * Sets the channel categories.
* <p> * <p>
* @param categories the list of Category elements with the channel categories to set, *
* an empty list or <b>null</b> if none. * @param categories the list of Category elements with the channel
* * categories to set, an empty list or <b>null</b> if none.
*
*/ */
public void setCategories(List<Category> categories) { public void setCategories(final List<Category> categories) {
_categories = categories; this._categories = categories;
} }
/** /**
* Returns the channel generator. * Returns the channel generator.
* <p> * <p>
*
* @return the channel generator, <b>null</b> if none. * @return the channel generator, <b>null</b> if none.
* *
*/ */
public String getGenerator() { public String getGenerator() {
return _generator; return this._generator;
} }
/** /**
* Sets the channel generator. * Sets the channel generator.
* <p> * <p>
*
* @param generator the channel generator to set, <b>null</b> if none. * @param generator the channel generator to set, <b>null</b> if none.
* *
*/ */
public void setGenerator(String generator) { public void setGenerator(final String generator) {
_generator = generator; this._generator = generator;
} }
/** /**
* Returns the channel time to live. * Returns the channel time to live.
* <p> * <p>
*
* @return the channel time to live, <b>null</b> if none. * @return the channel time to live, <b>null</b> if none.
* *
*/ */
public int getTtl() { public int getTtl() {
return _ttl; return this._ttl;
} }
/** /**
* Sets the channel time to live. * Sets the channel time to live.
* <p> * <p>
*
* @param ttl the channel time to live to set, <b>null</b> if none. * @param ttl the channel time to live to set, <b>null</b> if none.
* *
*/ */
public void setTtl(int ttl) { public void setTtl(final int ttl) {
_ttl = ttl; this._ttl = ttl;
} }
/** /**
* Returns the channel modules. * Returns the channel modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the channel modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the channel modules, an empty
* * list if none.
*
*/ */
@Override @Override
public List<Module> getModules() { public List<Module> getModules() {
return (_modules==null) ? (_modules=new ArrayList<Module>()) : _modules; return this._modules == null ? (this._modules = new ArrayList<Module>()) : this._modules;
} }
/** /**
* Sets the channel modules. * Sets the channel modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the channel modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the channel modules
* * to set, an empty list or <b>null</b> if none.
*
*/ */
@Override @Override
public void setModules(List<Module> modules) { public void setModules(final List<Module> modules) {
_modules = modules; this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
@Override @Override
public Module getModule(String uri) { public Module getModule(final String uri) {
return ModuleUtils.getModule(_modules,uri); return ModuleUtils.getModule(this._modules, uri);
} }
} }

View file

@ -17,18 +17,19 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for clouds of RSS feeds. * Bean for clouds of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Cloud implements Cloneable,Serializable { public class Cloud implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _domain; private String _domain;
private int _port; private int _port;
private String _path; private String _path;
@ -38,33 +39,38 @@ public class Cloud implements Cloneable,Serializable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Cloud() { public Cloud() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
public boolean equals(Object other) { @Override
return _objBean.equals(other); public boolean equals(final Object other) {
return this._objBean.equals(other);
} }
/** /**
@ -72,123 +78,136 @@ public class Cloud implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the cloud domain. * Returns the cloud domain.
* <p> * <p>
*
* @return the cloud domain, <b>null</b> if none. * @return the cloud domain, <b>null</b> if none.
* *
*/ */
public String getDomain() { public String getDomain() {
return _domain; return this._domain;
} }
/** /**
* Sets the cloud domain. * Sets the cloud domain.
* <p> * <p>
*
* @param domain the cloud domain to set, <b>null</b> if none. * @param domain the cloud domain to set, <b>null</b> if none.
* *
*/ */
public void setDomain(String domain) { public void setDomain(final String domain) {
_domain = domain; this._domain = domain;
} }
/** /**
* Returns the cloud port. * Returns the cloud port.
* <p> * <p>
*
* @return the cloud port, <b>null</b> if none. * @return the cloud port, <b>null</b> if none.
* *
*/ */
public int getPort() { public int getPort() {
return _port; return this._port;
} }
/** /**
* Sets the cloud port. * Sets the cloud port.
* <p> * <p>
*
* @param port the cloud port to set, <b>null</b> if none. * @param port the cloud port to set, <b>null</b> if none.
* *
*/ */
public void setPort(int port) { public void setPort(final int port) {
_port = port; this._port = port;
} }
/** /**
* Returns the cloud path. * Returns the cloud path.
* <p> * <p>
*
* @return the cloud path, <b>null</b> if none. * @return the cloud path, <b>null</b> if none.
* *
*/ */
public String getPath() { public String getPath() {
return _path; return this._path;
} }
/** /**
* Sets the cloud path. * Sets the cloud path.
* <p> * <p>
*
* @param path the cloud path to set, <b>null</b> if none. * @param path the cloud path to set, <b>null</b> if none.
* *
*/ */
public void setPath(String path) { public void setPath(final String path) {
_path = path; this._path = path;
} }
/** /**
* Returns the cloud register procedure. * Returns the cloud register procedure.
* <p> * <p>
*
* @return the cloud register procedure, <b>null</b> if none. * @return the cloud register procedure, <b>null</b> if none.
* *
*/ */
public String getRegisterProcedure() { public String getRegisterProcedure() {
return _registerProcedure; return this._registerProcedure;
} }
/** /**
* Sets the cloud register procedure. * Sets the cloud register procedure.
* <p> * <p>
* @param registerProcedure the cloud register procedure to set, <b>null</b> if none. *
* * @param registerProcedure the cloud register procedure to set, <b>null</b>
* if none.
*
*/ */
public void setRegisterProcedure(String registerProcedure) { public void setRegisterProcedure(final String registerProcedure) {
_registerProcedure = registerProcedure; this._registerProcedure = registerProcedure;
} }
/** /**
* Returns the cloud protocol. * Returns the cloud protocol.
* <p> * <p>
*
* @return the cloud protocol, <b>null</b> if none. * @return the cloud protocol, <b>null</b> if none.
* *
*/ */
public String getProtocol() { public String getProtocol() {
return _protocol; return this._protocol;
} }
/** /**
* Sets the cloud protocol. * Sets the cloud protocol.
* <p> * <p>
*
* @param protocol the cloud protocol to set, <b>null</b> if none. * @param protocol the cloud protocol to set, <b>null</b> if none.
* *
*/ */
public void setProtocol(String protocol) { public void setProtocol(final String protocol) {
_protocol = protocol; this._protocol = protocol;
} }
} }

View file

@ -17,99 +17,107 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for item descriptions of RSS feeds. * Bean for item descriptions of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Content implements Cloneable, Serializable { public class Content implements Cloneable, Serializable {
public static final String HTML = "html"; public static final String HTML = "html";
public static final String TEXT = "text"; public static final String TEXT = "text";
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _type; private String _type;
private String _value; private String _value;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Content() { public Content() {
_objBean = new ObjectBean(this.getClass(), this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Sets the description type. * Sets the description type.
* <p> * <p>
*
* @param type the description type to set, <b>null</b> if none. * @param type the description type to set, <b>null</b> if none.
* *
*/ */
public void setType(String type) { public void setType(final String type) {
_type = type; this._type = type;
} }
/** /**
* Returns the description type. * Returns the description type.
* <p> * <p>
*
* @return the description type, <b>null</b> if none. * @return the description type, <b>null</b> if none.
* *
*/ */
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the description value. * Sets the description value.
* <p> * <p>
*
* @param value the description value to set, <b>null</b> if none. * @param value the description value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
/** /**
* Returns the description value. * Returns the description value.
* <p> * <p>
*
* @return the description value, <b>null</b> if none. * @return the description value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if (!(other instanceof Content)) { if (!(other instanceof Content)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -117,22 +125,24 @@ public class Content implements Cloneable, Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
} }

View file

@ -17,54 +17,60 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for item descriptions of RSS feeds. * Bean for item descriptions of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Description implements Cloneable,Serializable { public class Description implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _type; private String _type;
private String _value; private String _value;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Description() { public Description() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Description)){ if (!(other instanceof Description)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -72,63 +78,69 @@ public class Description implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the description type. * Returns the description type.
* <p> * <p>
*
* @return the description type, <b>null</b> if none. * @return the description type, <b>null</b> if none.
* *
*/ */
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the description type. * Sets the description type.
* <p> * <p>
*
* @param type the description type to set, <b>null</b> if none. * @param type the description type to set, <b>null</b> if none.
* *
*/ */
public void setType(String type) { public void setType(final String type) {
_type = type; this._type = type;
} }
/** /**
* Returns the description value. * Returns the description value.
* <p> * <p>
*
* @return the description value, <b>null</b> if none. * @return the description value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the description value. * Sets the description value.
* <p> * <p>
*
* @param value the description value to set, <b>null</b> if none. * @param value the description value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
} }

View file

@ -17,18 +17,19 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for item enclosures of RSS feeds. * Bean for item enclosures of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Enclosure implements Cloneable,Serializable { public class Enclosure implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _url; private String _url;
private long _length; private long _length;
private String _type; private String _type;
@ -36,37 +37,41 @@ public class Enclosure implements Cloneable,Serializable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Enclosure() { public Enclosure() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Enclosure)){ if (!(other instanceof Enclosure)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -74,83 +79,91 @@ public class Enclosure implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the enclosure URL. * Returns the enclosure URL.
* <p> * <p>
*
* @return the enclosure URL, <b>null</b> if none. * @return the enclosure URL, <b>null</b> if none.
* *
*/ */
public String getUrl() { public String getUrl() {
return _url; return this._url;
} }
/** /**
* Sets the enclosure URL. * Sets the enclosure URL.
* <p> * <p>
*
* @param url the enclosure URL to set, <b>null</b> if none. * @param url the enclosure URL to set, <b>null</b> if none.
* *
*/ */
public void setUrl(String url) { public void setUrl(final String url) {
_url = url; this._url = url;
} }
/** /**
* Returns the enclosure length. * Returns the enclosure length.
* <p> * <p>
*
* @return the enclosure length, <b>0</b> if none. * @return the enclosure length, <b>0</b> if none.
* *
*/ */
public long getLength() { public long getLength() {
return _length; return this._length;
} }
/** /**
* Sets the enclosure length. * Sets the enclosure length.
* <p> * <p>
*
* @param length the enclosure length to set, <b>0</b> if none. * @param length the enclosure length to set, <b>0</b> if none.
* *
*/ */
public void setLength(long length) { public void setLength(final long length) {
_length = length; this._length = length;
} }
/** /**
* Returns the enclosure type. * Returns the enclosure type.
* <p> * <p>
*
* @return the enclosure type, <b>null</b> if none. * @return the enclosure type, <b>null</b> if none.
* *
*/ */
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the enclosure type. * Sets the enclosure type.
* <p> * <p>
*
* @param type the enclosure type to set, <b>null</b> if none. * @param type the enclosure type to set, <b>null</b> if none.
* *
*/ */
public void setType(String type) { public void setType(final String type) {
_type = type; this._type = type;
} }
} }

View file

@ -17,55 +17,60 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for item GUIDs of RSS feeds. * Bean for item GUIDs of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Guid implements Cloneable,Serializable { public class Guid implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private boolean _permaLink; private boolean _permaLink;
private String _value; private String _value;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Guid() { public Guid() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Guid)){ if (!(other instanceof Guid)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -73,63 +78,69 @@ public class Guid implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the guid perma link. * Returns the guid perma link.
* <p> * <p>
*
* @return the guid perma link, <b>null</b> if none. * @return the guid perma link, <b>null</b> if none.
* *
*/ */
public boolean isPermaLink() { public boolean isPermaLink() {
return _permaLink; return this._permaLink;
} }
/** /**
* Sets the guid perma link. * Sets the guid perma link.
* <p> * <p>
*
* @param permaLink the guid perma link to set, <b>null</b> if none. * @param permaLink the guid perma link to set, <b>null</b> if none.
* *
*/ */
public void setPermaLink(boolean permaLink) { public void setPermaLink(final boolean permaLink) {
_permaLink = permaLink; this._permaLink = permaLink;
} }
/** /**
* Returns the guid value. * Returns the guid value.
* <p> * <p>
*
* @return the guid value, <b>null</b> if none. * @return the guid value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the guid value. * Sets the guid value.
* <p> * <p>
*
* @param value the guid value to set, <b>null</b> if none. * @param value the guid value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
} }

View file

@ -16,18 +16,19 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for images of RSS feeds. * Bean for images of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Image implements Cloneable,Serializable { public class Image implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _title; private String _title;
private String _url; private String _url;
private String _link; private String _link;
@ -38,37 +39,41 @@ public class Image implements Cloneable,Serializable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Image() { public Image() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Image)){ if (!(other instanceof Image)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -76,143 +81,157 @@ public class Image implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the image title. * Returns the image title.
* <p> * <p>
*
* @return the image title, <b>null</b> if none. * @return the image title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the image title. * Sets the image title.
* <p> * <p>
*
* @param title the image title to set, <b>null</b> if none. * @param title the image title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
_title = title; this._title = title;
} }
/** /**
* Returns the image URL. * Returns the image URL.
* <p> * <p>
*
* @return the image URL, <b>null</b> if none. * @return the image URL, <b>null</b> if none.
* *
*/ */
public String getUrl() { public String getUrl() {
return _url; return this._url;
} }
/** /**
* Sets the image URL. * Sets the image URL.
* <p> * <p>
*
* @param url the image URL to set, <b>null</b> if none. * @param url the image URL to set, <b>null</b> if none.
* *
*/ */
public void setUrl(String url) { public void setUrl(final String url) {
_url = url; this._url = url;
} }
/** /**
* Returns the image link. * Returns the image link.
* <p> * <p>
*
* @return the image link, <b>null</b> if none. * @return the image link, <b>null</b> if none.
* *
*/ */
public String getLink() { public String getLink() {
return _link; return this._link;
} }
/** /**
* Sets the image link. * Sets the image link.
* <p> * <p>
*
* @param link the image link to set, <b>null</b> if none. * @param link the image link to set, <b>null</b> if none.
* *
*/ */
public void setLink(String link) { public void setLink(final String link) {
_link = link; this._link = link;
} }
/** /**
* Returns the image width. * Returns the image width.
* <p> * <p>
*
* @return the image width, <b>null</b> if none. * @return the image width, <b>null</b> if none.
* *
*/ */
public Integer getWidth() { public Integer getWidth() {
return _width; return this._width;
} }
/** /**
* Sets the image width. * Sets the image width.
* <p> * <p>
*
* @param width the image width to set, <b>null</b> if none. * @param width the image width to set, <b>null</b> if none.
* *
*/ */
public void setWidth(Integer width) { public void setWidth(final Integer width) {
_width = width; this._width = width;
} }
/** /**
* Returns the image height. * Returns the image height.
* <p> * <p>
*
* @return the image height, <b>null</b> if none. * @return the image height, <b>null</b> if none.
* *
*/ */
public Integer getHeight() { public Integer getHeight() {
return _height; return this._height;
} }
/** /**
* Sets the image height. * Sets the image height.
* <p> * <p>
*
* @param height the image height to set, <b>null</b> if none. * @param height the image height to set, <b>null</b> if none.
* *
*/ */
public void setHeight(Integer height) { public void setHeight(final Integer height) {
_height = height; this._height = height;
} }
/** /**
* Returns the image description. * Returns the image description.
* <p> * <p>
*
* @return the image description, <b>null</b> if none. * @return the image description, <b>null</b> if none.
* *
*/ */
public String getDescription() { public String getDescription() {
return _description; return this._description;
} }
/** /**
* Sets the image description. * Sets the image description.
* <p> * <p>
*
* @param description the image description to set, <b>null</b> if none. * @param description the image description to set, <b>null</b> if none.
* *
*/ */
public void setDescription(String description) { public void setDescription(final String description) {
_description = description; this._description = description;
} }
} }

View file

@ -17,31 +17,32 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean; import java.io.Serializable;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.module.Extendable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.io.Serializable;
import org.jdom2.Element; import org.jdom2.Element;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
/** /**
* Bean for items of RSS feeds. * Bean for items of RSS feeds.
* <p> * <p>
* It handles all RSS versions without loosing information. * It handles all RSS versions without loosing information.
* <p> * <p>
* For RSS1.0 it supports Dublin Core and Syndication modules. Note that * For RSS1.0 it supports Dublin Core and Syndication modules. Note that those
* those modules currently support simple syntax format only. * modules currently support simple syntax format only.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Item implements Cloneable, Serializable, Extendable { public class Item implements Cloneable, Serializable, Extendable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _title; private String _title;
private String _link; private String _link;
private String _uri; private String _uri;
@ -61,40 +62,44 @@ public class Item implements Cloneable, Serializable, Extendable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Item() { public Item() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if (other == null || !(other instanceof Item)) { if (other == null || !(other instanceof Item)) {
return false; return false;
} }
// can't use foreign markup in equals, due to JDOM equals impl // can't use foreign markup in equals, due to JDOM equals impl
List<Element> fm = getForeignMarkup(); final List<Element> fm = getForeignMarkup();
setForeignMarkup(((Item)other).getForeignMarkup()); setForeignMarkup(((Item) other).getForeignMarkup());
boolean ret = _objBean.equals(other); final boolean ret = this._objBean.equals(other);
// restore foreign markup // restore foreign markup
setForeignMarkup(fm); setForeignMarkup(fm);
return ret; return ret;
@ -105,338 +110,374 @@ public class Item implements Cloneable, Serializable, Extendable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the item title. * Returns the item title.
* <p> * <p>
*
* @return the item title, <b>null</b> if none. * @return the item title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the item title. * Sets the item title.
* <p> * <p>
*
* @param title the item title to set, <b>null</b> if none. * @param title the item title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
_title = title; this._title = title;
} }
/** /**
* Returns the item link. * Returns the item link.
* <p> * <p>
*
* @return the item link, <b>null</b> if none. * @return the item link, <b>null</b> if none.
* *
*/ */
public String getLink() { public String getLink() {
return _link; return this._link;
} }
/** /**
* Sets the item link. * Sets the item link.
* <p> * <p>
*
* @param link the item link to set, <b>null</b> if none. * @param link the item link to set, <b>null</b> if none.
* *
*/ */
public void setLink(String link) { public void setLink(final String link) {
_link = link; this._link = link;
} }
/** /**
* Returns the item uri. * Returns the item uri.
* <p> * <p>
*
* @return the item uri, <b>null</b> if none. * @return the item uri, <b>null</b> if none.
*/ */
public String getUri() { public String getUri() {
return _uri; return this._uri;
} }
/** /**
* Sets the item uri. * Sets the item uri.
* <p> * <p>
*
* @param uri the item uri to set, <b>null</b> if none. * @param uri the item uri to set, <b>null</b> if none.
*/ */
public void setUri(String uri) { public void setUri(final String uri) {
_uri = uri; this._uri = uri;
} }
/** /**
* Returns the item description. * Returns the item description.
* <p> * <p>
*
* @return the item description, <b>null</b> if none. * @return the item description, <b>null</b> if none.
* *
*/ */
public Description getDescription() { public Description getDescription() {
return _description; return this._description;
} }
/** /**
* Sets the item description. * Sets the item description.
* <p> * <p>
*
* @param description the item description to set, <b>null</b> if none. * @param description the item description to set, <b>null</b> if none.
* *
*/ */
public void setDescription(Description description) { public void setDescription(final Description description) {
_description = description; this._description = description;
} }
/** /**
* Returns the item content. * Returns the item content.
* <p> * <p>
*
* @return the item content, <b>null</b> if none. * @return the item content, <b>null</b> if none.
* *
*/ */
public Content getContent() { public Content getContent() {
return _content; return this._content;
} }
/** /**
* Sets the item content. * Sets the item content.
* <p> * <p>
*
* @param content the item content to set, <b>null</b> if none. * @param content the item content to set, <b>null</b> if none.
* *
*/ */
public void setContent(Content content) { public void setContent(final Content content) {
_content = content; this._content = content;
} }
/** /**
* Returns the item source. * Returns the item source.
* <p> * <p>
*
* @return the item source, <b>null</b> if none. * @return the item source, <b>null</b> if none.
* *
*/ */
public Source getSource() { public Source getSource() {
return _source; return this._source;
} }
/** /**
* Sets the item source. * Sets the item source.
* <p> * <p>
*
* @param source the item source to set, <b>null</b> if none. * @param source the item source to set, <b>null</b> if none.
* *
*/ */
public void setSource(Source source) { public void setSource(final Source source) {
_source = source; this._source = source;
} }
/** /**
* Returns the item enclosures. * Returns the item enclosures.
* <p> * <p>
* @return a list of Enclosure elements with the item enclosures, *
* an empty list if none. * @return a list of Enclosure elements with the item enclosures, an empty
* * list if none.
*
*/ */
public List<Enclosure> getEnclosures() { public List<Enclosure> getEnclosures() {
return (_enclosures==null) ? (_enclosures=new ArrayList<Enclosure>()) : _enclosures; return this._enclosures == null ? (this._enclosures = new ArrayList<Enclosure>()) : this._enclosures;
} }
/** /**
* Sets the item enclosures. * Sets the item enclosures.
* <p> * <p>
* @param enclosures the list of Enclosure elements with the item enclosures to set, *
* an empty list or <b>null</b> if none. * @param enclosures the list of Enclosure elements with the item enclosures
* * to set, an empty list or <b>null</b> if none.
*
*/ */
public void setEnclosures(List<Enclosure> enclosures) { public void setEnclosures(final List<Enclosure> enclosures) {
_enclosures = enclosures; this._enclosures = enclosures;
} }
/** /**
* Returns the item categories. * Returns the item categories.
* <p> * <p>
* @return a list of Category elements with the item categories, *
* an empty list if none. * @return a list of Category elements with the item categories, an empty
* * list if none.
*
*/ */
public List<Category> getCategories() { public List<Category> getCategories() {
return (_categories==null) ? (_categories=new ArrayList<Category>()) : _categories; return this._categories == null ? (this._categories = new ArrayList<Category>()) : this._categories;
} }
/** /**
* Sets the item categories. * Sets the item categories.
* <p> * <p>
* @param categories the list of Categories elements with the item categories to set, *
* an empty list or <b>null</b> if none. * @param categories the list of Categories elements with the item
* * categories to set, an empty list or <b>null</b> if none.
*
*/ */
public void setCategories(List<Category> categories) { public void setCategories(final List<Category> categories) {
_categories = categories; this._categories = categories;
} }
/** /**
* Returns the item GUID. * Returns the item GUID.
* <p> * <p>
*
* @return the item GUID, <b>null</b> if none. * @return the item GUID, <b>null</b> if none.
* *
*/ */
public Guid getGuid() { public Guid getGuid() {
return _guid; return this._guid;
} }
/** /**
* Sets the item GUID. * Sets the item GUID.
* <p> * <p>
*
* @param guid the item GUID to set, <b>null</b> if none. * @param guid the item GUID to set, <b>null</b> if none.
* *
*/ */
public void setGuid(Guid guid) { public void setGuid(final Guid guid) {
_guid = guid; this._guid = guid;
} }
/** /**
* Returns the item comments. * Returns the item comments.
* <p> * <p>
*
* @return the item comments, <b>null</b> if none. * @return the item comments, <b>null</b> if none.
* *
*/ */
public String getComments() { public String getComments() {
return _comments; return this._comments;
} }
/** /**
* Sets the item comments. * Sets the item comments.
* <p> * <p>
*
* @param comments the item comments to set, <b>null</b> if none. * @param comments the item comments to set, <b>null</b> if none.
* *
*/ */
public void setComments(String comments) { public void setComments(final String comments) {
_comments = comments; this._comments = comments;
} }
/** /**
* Returns the item author. * Returns the item author.
* <p> * <p>
*
* @return the item author, <b>null</b> if none. * @return the item author, <b>null</b> if none.
* *
*/ */
public String getAuthor() { public String getAuthor() {
return _author; return this._author;
} }
/** /**
* Sets the item author. * Sets the item author.
* <p> * <p>
*
* @param author the item author to set, <b>null</b> if none. * @param author the item author to set, <b>null</b> if none.
* *
*/ */
public void setAuthor(String author) { public void setAuthor(final String author) {
_author = author; this._author = author;
} }
/** /**
* Returns the item modules. * Returns the item modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the item modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the item modules, an empty
* * list if none.
*
*/ */
@Override
public List<Module> getModules() { public List<Module> getModules() {
return (_modules==null) ? (_modules=new ArrayList<Module>()) : _modules; return this._modules == null ? (this._modules = new ArrayList<Module>()) : this._modules;
} }
/** /**
* Sets the item modules. * Sets the item modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the item modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the item modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
public void setModules(List<Module> modules) { @Override
_modules = modules; public void setModules(final List<Module> modules) {
this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
public Module getModule(String uri) { @Override
return ModuleUtils.getModule(_modules,uri); public Module getModule(final String uri) {
return ModuleUtils.getModule(this._modules, uri);
} }
/** /**
* Returns the item publishing date. * Returns the item publishing date.
* <p> * <p>
*
* @return the item publishing date, <b>null</b> if none. * @return the item publishing date, <b>null</b> if none.
* *
*/ */
public Date getPubDate() { public Date getPubDate() {
return _pubDate == null ? null : new Date( _pubDate.getTime()); return this._pubDate == null ? null : new Date(this._pubDate.getTime());
} }
/** /**
* Sets the item publishing date. * Sets the item publishing date.
* <p> * <p>
*
* @param pubDate the item publishing date to set, <b>null</b> if none. * @param pubDate the item publishing date to set, <b>null</b> if none.
* *
*/ */
public void setPubDate(Date pubDate) { public void setPubDate(final Date pubDate) {
_pubDate = pubDate == null ? null : new Date( pubDate.getTime()); this._pubDate = pubDate == null ? null : new Date(pubDate.getTime());
} }
/** /**
* Returns the item expiration date. * Returns the item expiration date.
* <p> * <p>
*
* @return the item expiration date, <b>null</b> if none. * @return the item expiration date, <b>null</b> if none.
* *
*/ */
public Date getExpirationDate() { public Date getExpirationDate() {
return _expirationDate == null ? null : new Date(_expirationDate.getTime()); return this._expirationDate == null ? null : new Date(this._expirationDate.getTime());
} }
/** /**
* Sets the item expiration date. * Sets the item expiration date.
* <p> * <p>
* @param expirationDate the item expiration date to set, <b>null</b> if none. *
* * @param expirationDate the item expiration date to set, <b>null</b> if
* none.
*
*/ */
public void setExpirationDate(Date expirationDate) { public void setExpirationDate(final Date expirationDate) {
_expirationDate = expirationDate == null ? null : new Date(expirationDate.getTime()); this._expirationDate = expirationDate == null ? null : new Date(expirationDate.getTime());
} }
/** /**
* Returns foreign markup found at item level. * Returns foreign markup found at item level.
* <p> * <p>
*
* @return Opaque object to discourage use * @return Opaque object to discourage use
* *
*/ */
public List<Element> getForeignMarkup() { public List<Element> getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList<Element>()) : _foreignMarkup; return this._foreignMarkup == null ? (this._foreignMarkup = new ArrayList<Element>()) : this._foreignMarkup;
} }
/** /**
* Sets foreign markup found at item level. * Sets foreign markup found at item level.
* <p> * <p>
*
* @param foreignMarkup Opaque object to discourage use * @param foreignMarkup Opaque object to discourage use
* *
*/ */
public void setForeignMarkup(List<Element> foreignMarkup) { public void setForeignMarkup(final List<Element> foreignMarkup) {
_foreignMarkup = (List<Element>)foreignMarkup; this._foreignMarkup = foreignMarkup;
} }
} }

View file

@ -17,55 +17,60 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for item sources of RSS feeds. * Bean for item sources of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Source implements Cloneable,Serializable { public class Source implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _url; private String _url;
private String _value; private String _value;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public Source() { public Source() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof Source)){ if (!(other instanceof Source)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -73,62 +78,68 @@ public class Source implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the source URL. * Returns the source URL.
* <p> * <p>
*
* @return the source URL, <b>null</b> if none. * @return the source URL, <b>null</b> if none.
* *
*/ */
public String getUrl() { public String getUrl() {
return _url; return this._url;
} }
/** /**
* Sets the source URL. * Sets the source URL.
* <p> * <p>
*
* @param url the source URL to set, <b>null</b> if none. * @param url the source URL to set, <b>null</b> if none.
* *
*/ */
public void setUrl(String url) { public void setUrl(final String url) {
_url = url; this._url = url;
} }
/** /**
* Returns the source value. * Returns the source value.
* <p> * <p>
*
* @return the source value, <b>null</b> if none. * @return the source value, <b>null</b> if none.
* *
*/ */
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the source value. * Sets the source value.
* <p> * <p>
*
* @param value the source value to set, <b>null</b> if none. * @param value the source value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { public void setValue(final String value) {
_value = value; this._value = value;
} }
} }

View file

@ -17,18 +17,19 @@
*/ */
package com.sun.syndication.feed.rss; package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for text input of RSS feeds. * Bean for text input of RSS feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class TextInput implements Cloneable,Serializable { public class TextInput implements Cloneable, Serializable {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _title; private String _title;
private String _description; private String _description;
private String _name; private String _name;
@ -37,37 +38,41 @@ public class TextInput implements Cloneable,Serializable {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public TextInput() { public TextInput() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof TextInput)){ if (!(other instanceof TextInput)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -75,103 +80,114 @@ public class TextInput implements Cloneable,Serializable {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the text input title. * Returns the text input title.
* <p> * <p>
*
* @return the text input title, <b>null</b> if none. * @return the text input title, <b>null</b> if none.
* *
*/ */
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the text input title. * Sets the text input title.
* <p> * <p>
*
* @param title the text input title to set, <b>null</b> if none. * @param title the text input title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
_title = title; this._title = title;
} }
/** /**
* Returns the text input description. * Returns the text input description.
* <p> * <p>
*
* @return the text input description, <b>null</b> if none. * @return the text input description, <b>null</b> if none.
* *
*/ */
public String getDescription() { public String getDescription() {
return _description; return this._description;
} }
/** /**
* Sets the text input description. * Sets the text input description.
* <p> * <p>
* @param description the text input description to set, <b>null</b> if none. *
* * @param description the text input description to set, <b>null</b> if
* none.
*
*/ */
public void setDescription(String description) { public void setDescription(final String description) {
_description = description; this._description = description;
} }
/** /**
* Returns the text input name. * Returns the text input name.
* <p> * <p>
*
* @return the text input name, <b>null</b> if none. * @return the text input name, <b>null</b> if none.
* *
*/ */
public String getName() { public String getName() {
return _name; return this._name;
} }
/** /**
* Sets the text input name. * Sets the text input name.
* <p> * <p>
*
* @param name the text input name to set, <b>null</b> if none. * @param name the text input name to set, <b>null</b> if none.
* *
*/ */
public void setName(String name) { public void setName(final String name) {
_name = name; this._name = name;
} }
/** /**
* Returns the text input link. * Returns the text input link.
* <p> * <p>
*
* @return the text input link, <b>null</b> if none. * @return the text input link, <b>null</b> if none.
* *
*/ */
public String getLink() { public String getLink() {
return _link; return this._link;
} }
/** /**
* Sets the text input link. * Sets the text input link.
* <p> * <p>
*
* @param link the text input link to set, <b>null</b> if none. * @param link the text input link to set, <b>null</b> if none.
* *
*/ */
public void setLink(String link) { public void setLink(final String link) {
_link = link; this._link = link;
} }
} }

View file

@ -17,51 +17,57 @@
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.synd.SyndFeed;
/** /**
* Interface that defines the functionality to convert a SyndFeedImpl * Interface that defines the functionality to convert a SyndFeedImpl to a real
* to a real feed (RSS or Atom) and vice versa. * feed (RSS or Atom) and vice versa.
* <p> * <p>
* Each implementation knows how to deal with a specific type (version) * Each implementation knows how to deal with a specific type (version) of a
* of a real feed. * real feed.
* <p> * <p>
* Implementations must be thread safe. * Implementations must be thread safe.
* <p> * <p>
* TODO: explain how developers can plugin their own implementations. * TODO: explain how developers can plugin their own implementations.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface Converter { public interface Converter {
/** /**
* Returns the type (version) of the real feed this converter handles. * Returns the type (version) of the real feed this converter handles.
* <p> * <p>
*
* @see WireFeed for details on the format of this string. * @see WireFeed for details on the format of this string.
* <p> * <p>
* @return the real feed type. * @return the real feed type.
* *
*/ */
public String getType(); public String getType();
/** /**
* Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl. * Makes a deep copy/conversion of the values of a real feed into a
* SyndFeedImpl.
* <p> * <p>
* It assumes the given SyndFeedImpl has no properties set. * It assumes the given SyndFeedImpl has no properties set.
* <p> * <p>
*
* @param feed real feed to copy/convert. * @param feed real feed to copy/convert.
* @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real feed. * @param syndFeed the SyndFeedImpl that will contain the copied/converted
* * values of the real feed.
*
*/ */
public void copyInto(WireFeed feed,SyndFeed syndFeed); public void copyInto(WireFeed feed, SyndFeed syndFeed);
/** /**
* Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl. * Creates real feed with a deep copy/conversion of the values of a
* SyndFeedImpl.
* <p> * <p>
*
* @param syndFeed SyndFeedImpl to copy/convert value from. * @param syndFeed SyndFeedImpl to copy/convert value from.
* @return a real feed with copied/converted values of the SyndFeedImpl. * @return a real feed with copied/converted values of the SyndFeedImpl.
* *
*/ */
public WireFeed createRealFeed(SyndFeed syndFeed); public WireFeed createRealFeed(SyndFeed syndFeed);

View file

@ -17,54 +17,58 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
/** /**
* Bean interface for categories of SyndFeedImpl feeds and entries. * Bean interface for categories of SyndFeedImpl feeds and entries.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface SyndCategory extends Cloneable { public interface SyndCategory extends Cloneable {
/** /**
* Returns the category name. * Returns the category name.
* <p> * <p>
*
* @return the category name, <b>null</b> if none. * @return the category name, <b>null</b> if none.
* *
*/ */
String getName(); String getName();
/** /**
* Sets the category name. * Sets the category name.
* <p> * <p>
*
* @param name the category name to set, <b>null</b> if none. * @param name the category name to set, <b>null</b> if none.
* *
*/ */
void setName(String name); void setName(String name);
/** /**
* Returns the category taxonomy URI. * Returns the category taxonomy URI.
* <p> * <p>
*
* @return the category taxonomy URI, <b>null</b> if none. * @return the category taxonomy URI, <b>null</b> if none.
* *
*/ */
String getTaxonomyUri(); String getTaxonomyUri();
/** /**
* Sets the category taxonomy URI. * Sets the category taxonomy URI.
* <p> * <p>
*
* @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none. * @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none.
* *
*/ */
void setTaxonomyUri(String taxonomyUri); void setTaxonomyUri(String taxonomyUri);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

View file

@ -17,61 +17,67 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.DCSubjectImpl;
import com.sun.syndication.feed.module.DCSubject;
import java.util.AbstractList;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable; import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.DCSubject;
import com.sun.syndication.feed.module.DCSubjectImpl;
/** /**
* Bean for categories of SyndFeedImpl feeds and entries. * Bean for categories of SyndFeedImpl feeds and entries.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyndCategoryImpl implements Serializable, SyndCategory { public class SyndCategoryImpl implements Serializable, SyndCategory {
private ObjectBean _objBean; private final ObjectBean _objBean;
private DCSubject _subject; private final DCSubject _subject;
/** /**
* For implementations extending SyndContentImpl to be able to use the ObjectBean functionality * For implementations extending SyndContentImpl to be able to use the
* with extended interfaces. * ObjectBean functionality with extended interfaces.
* <p> * <p>
*
* @param subject the DC subject to wrap. * @param subject the DC subject to wrap.
*/ */
SyndCategoryImpl(DCSubject subject) { SyndCategoryImpl(final DCSubject subject) {
_objBean = new ObjectBean(SyndCategory.class,this); this._objBean = new ObjectBean(SyndCategory.class, this);
_subject = subject; this._subject = subject;
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof SyndCategoryImpl)){ if (!(other instanceof SyndCategoryImpl)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -79,39 +85,42 @@ public class SyndCategoryImpl implements Serializable, SyndCategory {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Package private constructor, used by SyndCategoryListFacade. * Package private constructor, used by SyndCategoryListFacade.
* <p> * <p>
*
* @return the DC subject being wrapped. * @return the DC subject being wrapped.
* *
*/ */
DCSubject getSubject() { DCSubject getSubject() {
return _subject; return this._subject;
} }
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyndCategoryImpl() { public SyndCategoryImpl() {
this(new DCSubjectImpl()); this(new DCSubjectImpl());
@ -120,64 +129,73 @@ public class SyndCategoryImpl implements Serializable, SyndCategory {
/** /**
* Returns the category name. * Returns the category name.
* <p> * <p>
*
* @return the category name, <b>null</b> if none. * @return the category name, <b>null</b> if none.
* *
*/ */
@Override
public String getName() { public String getName() {
return _subject.getValue(); return this._subject.getValue();
} }
/** /**
* Sets the category name. * Sets the category name.
* <p> * <p>
*
* @param name the category name to set, <b>null</b> if none. * @param name the category name to set, <b>null</b> if none.
* *
*/ */
public void setName(String name) { @Override
_subject.setValue(name); public void setName(final String name) {
this._subject.setValue(name);
} }
/** /**
* Returns the category taxonomy URI. * Returns the category taxonomy URI.
* <p> * <p>
*
* @return the category taxonomy URI, <b>null</b> if none. * @return the category taxonomy URI, <b>null</b> if none.
* *
*/ */
@Override
public String getTaxonomyUri() { public String getTaxonomyUri() {
return _subject.getTaxonomyUri(); return this._subject.getTaxonomyUri();
} }
/** /**
* Sets the category taxonomy URI. * Sets the category taxonomy URI.
* <p> * <p>
*
* @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none. * @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none.
* *
*/ */
public void setTaxonomyUri(String taxonomyUri) { @Override
_subject.setTaxonomyUri(taxonomyUri); public void setTaxonomyUri(final String taxonomyUri) {
this._subject.setTaxonomyUri(taxonomyUri);
} }
} }
/** /**
* List implementation for SyndCategoryImpl elements. To be directly used by the SyndFeedImpl * List implementation for SyndCategoryImpl elements. To be directly used by the
* and SyndEntryImpl classes only. * SyndFeedImpl and SyndEntryImpl classes only.
* <p> * <p>
* It acts as a facade on top of the DCSubjectImpl elements of the underlying list * It acts as a facade on top of the DCSubjectImpl elements of the underlying
* and remains in synch with it. It is possible to work on either list, the categories * list and remains in synch with it. It is possible to work on either list, the
* one or the subjects one and they remain in synch. * categories one or the subjects one and they remain in synch.
* <p> * <p>
* This is necessary because the SyndFeedImpl categories are just a convenience to access * This is necessary because the SyndFeedImpl categories are just a convenience
* the DublinCore subjects. * to access the DublinCore subjects.
* <P> * <P>
* All this mess to avoid making DCSubjectImpl implement SyndCategory (which it would be odd). * All this mess to avoid making DCSubjectImpl implement SyndCategory (which it
* would be odd).
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
class SyndCategoryListFacade extends AbstractList<SyndCategory> { class SyndCategoryListFacade extends AbstractList<SyndCategory> {
private List<DCSubject> _subjects; private final List<DCSubject> _subjects;
/** /**
* Default constructor. Creates and empty list. * Default constructor. Creates and empty list.
@ -189,93 +207,106 @@ class SyndCategoryListFacade extends AbstractList<SyndCategory> {
/** /**
* Creates a facade list of categories on top the given subject list. * Creates a facade list of categories on top the given subject list.
* <P> * <P>
*
* @param subjects the list of subjects to create the facade. * @param subjects the list of subjects to create the facade.
* *
*/ */
public SyndCategoryListFacade(List<DCSubject> subjects) { public SyndCategoryListFacade(final List<DCSubject> subjects) {
_subjects = subjects; this._subjects = subjects;
} }
/** /**
* Gets the category by index. * Gets the category by index.
* <p> * <p>
*
* @param index the index position to retrieve the category. * @param index the index position to retrieve the category.
* @return the SyndCategoryImpl in position index, <b>null</b> if none. * @return the SyndCategoryImpl in position index, <b>null</b> if none.
* *
*/ */
public SyndCategory get(int index) { @Override
return new SyndCategoryImpl((DCSubject) _subjects.get(index)); public SyndCategory get(final int index) {
return new SyndCategoryImpl(this._subjects.get(index));
} }
/** /**
* Returns the size of the list. * Returns the size of the list.
* <p> * <p>
*
* @return the size of the list. * @return the size of the list.
* *
*/ */
@Override
public int size() { public int size() {
return _subjects.size(); return this._subjects.size();
} }
/** /**
* Sets a category in an existing position in the list. * Sets a category in an existing position in the list.
* <p> * <p>
*
* @param index position to set the category. * @param index position to set the category.
* @param obj the SyndCategoryImpl object to set. * @param obj the SyndCategoryImpl object to set.
* @return the SyndCategoryImpl object that is being replaced, <b>null</b> if none. * @return the SyndCategoryImpl object that is being replaced, <b>null</b>
* * if none.
*
*/ */
@Override @Override
public SyndCategory set(int index, SyndCategory obj) { public SyndCategory set(final int index, final SyndCategory obj) {
SyndCategoryImpl sCat = (SyndCategoryImpl) obj; final SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
DCSubject subject = (sCat!=null) ? sCat.getSubject() : null; DCSubject subject = sCat != null ? sCat.getSubject() : null;
subject = (DCSubject) _subjects.set(index,subject); subject = this._subjects.set(index, subject);
return (subject!=null) ? new SyndCategoryImpl(subject) : null; return subject != null ? new SyndCategoryImpl(subject) : null;
} }
/** /**
* Adds a category to the list. * Adds a category to the list.
* <p> * <p>
* @param index position to add the category. *
* @param obj the SyndCategoryImpl object to add. * @param index position to add the category.
* * @param obj the SyndCategoryImpl object to add.
*
*/ */
@Override @Override
public void add(int index,SyndCategory obj) { public void add(final int index, final SyndCategory obj) {
SyndCategoryImpl sCat = (SyndCategoryImpl) obj; final SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
DCSubject subject = (sCat!=null) ? sCat.getSubject() : null; final DCSubject subject = sCat != null ? sCat.getSubject() : null;
_subjects.add(index,subject); this._subjects.add(index, subject);
} }
/** /**
* Removes a category element from a specific position. * Removes a category element from a specific position.
* <p> * <p>
*
* @param index position to remove the category from. * @param index position to remove the category from.
* @return the SyndCategoryImpl being removed from position index, <b>null</b> if none. * @return the SyndCategoryImpl being removed from position index,
* * <b>null</b> if none.
*
*/ */
@Override @Override
public SyndCategory remove(int index) { public SyndCategory remove(final int index) {
DCSubject subject = (DCSubject) _subjects.remove(index); final DCSubject subject = this._subjects.remove(index);
return (subject!=null) ? new SyndCategoryImpl(subject) : null; return subject != null ? new SyndCategoryImpl(subject) : null;
} }
/** /**
* Returns a list with the DCSubject elements of the SyndCategoryImpl list facade. * Returns a list with the DCSubject elements of the SyndCategoryImpl list
* To be used by the SyndFeedImpl class only. * facade. To be used by the SyndFeedImpl class only.
* <p> * <p>
* @param cList the list with SyndCategoryImpl elements to convert to subject list. *
* @return a list with DCSubject elements corresponding to the categories in the given list. * @param cList the list with SyndCategoryImpl elements to convert to
* * subject list.
* @return a list with DCSubject elements corresponding to the categories in
* the given list.
*
*/ */
public static List<DCSubject> convertElementsSyndCategoryToSubject(List<SyndCategory> cList) { public static List<DCSubject> convertElementsSyndCategoryToSubject(final List<SyndCategory> cList) {
List<DCSubject> sList = null; List<DCSubject> sList = null;
if (cList!=null) { if (cList != null) {
sList = new ArrayList<DCSubject>(); sList = new ArrayList<DCSubject>();
for (int i=0;i<cList.size();i++) { for (int i = 0; i < cList.size(); i++) {
SyndCategoryImpl sCat = (SyndCategoryImpl) cList.get(i); final SyndCategoryImpl sCat = (SyndCategoryImpl) cList.get(i);
DCSubject subject = null; DCSubject subject = null;
if (sCat!=null) { if (sCat != null) {
subject = sCat.getSubject(); subject = sCat.getSubject();
} }
sList.add(subject); sList.add(subject);

View file

@ -18,70 +18,80 @@ package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom; import com.sun.syndication.feed.CopyFrom;
/** /**
* Bean interface for content of SyndFeedImpl entries. * Bean interface for content of SyndFeedImpl entries.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface SyndContent extends Cloneable,CopyFrom<SyndContent> { public interface SyndContent extends Cloneable, CopyFrom<SyndContent> {
/** /**
* Returns the content type. * Returns the content type.
* <p> * <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed. * When used for the description of an entry, if <b>null</b> 'text/plain'
* must be assumed.
* <p> * <p>
*
* @return the content type, <b>null</b> if none. * @return the content type, <b>null</b> if none.
* *
*/ */
String getType(); String getType();
/** /**
* Sets the content type. * Sets the content type.
* <p> * <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed. * When used for the description of an entry, if <b>null</b> 'text/plain'
* must be assumed.
* <p> * <p>
*
* @param type the content type to set, <b>null</b> if none. * @param type the content type to set, <b>null</b> if none.
* *
*/ */
void setType(String type); void setType(String type);
/** /**
* Gets the content mode (needed for Atom 0.3 support). * Gets the content mode (needed for Atom 0.3 support).
*
* @return type the content, <b>null</b> if none. * @return type the content, <b>null</b> if none.
* *
*/ */
String getMode(); String getMode();
/** /**
* Sets the content mode (needed for Atom 0.3 support). * Sets the content mode (needed for Atom 0.3 support).
*
* @param mode the content mode to set, <b>null</b> if none. * @param mode the content mode to set, <b>null</b> if none.
* *
*/ */
void setMode(String mode); void setMode(String mode);
/** /**
* Returns the content value. * Returns the content value.
* <p> * <p>
*
* @return the content value, <b>null</b> if none. * @return the content value, <b>null</b> if none.
* *
*/ */
String getValue(); String getValue();
/** /**
* Sets the content value. * Sets the content value.
* <p> * <p>
*
* @param value the content value to set, <b>null</b> if none. * @param value the content value to set, <b>null</b> if none.
* *
*/ */
void setValue(String value); void setValue(String value);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

View file

@ -16,57 +16,63 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.io.Serializable;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for content of SyndFeedImpl entries. * Bean for content of SyndFeedImpl entries.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyndContentImpl implements Serializable, SyndContent { public class SyndContentImpl implements Serializable, SyndContent {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _type; private String _type;
private String _value; private String _value;
private String _mode; private String _mode;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyndContentImpl() { public SyndContentImpl() {
_objBean = new ObjectBean(SyndContent.class,this); this._objBean = new ObjectBean(SyndContent.class, this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
public boolean equals(Object other) { @Override
return _objBean.equals(other); public boolean equals(final Object other) {
return this._objBean.equals(other);
} }
/** /**
@ -74,104 +80,123 @@ public class SyndContentImpl implements Serializable, SyndContent {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the content type. * Returns the content type.
* <p> * <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed. * When used for the description of an entry, if <b>null</b> 'text/plain'
* must be assumed.
* <p> * <p>
*
* @return the content type, <b>null</b> if none. * @return the content type, <b>null</b> if none.
* *
*/ */
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the content type. * Sets the content type.
* <p> * <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed. * When used for the description of an entry, if <b>null</b> 'text/plain'
* must be assumed.
* <p> * <p>
*
* @param type the content type to set, <b>null</b> if none. * @param type the content type to set, <b>null</b> if none.
* *
*/ */
public void setType(String type) { @Override
_type = type; public void setType(final String type) {
this._type = type;
} }
/** /**
* Returns the content mode. * Returns the content mode.
*
* @return the content mode, <b>null</b> if none. * @return the content mode, <b>null</b> if none.
* *
*/ */
@Override
public String getMode() { public String getMode() {
return _mode; return this._mode;
} }
/** /**
* Sets the content mode. * Sets the content mode.
*
* @param mode the content mode to set, <b>null</b> if none. * @param mode the content mode to set, <b>null</b> if none.
* *
*/ */
public void setMode(String mode) { @Override
_mode = mode; public void setMode(final String mode) {
this._mode = mode;
} }
/** /**
* Returns the content value. * Returns the content value.
* <p> * <p>
*
* @return the content value, <b>null</b> if none. * @return the content value, <b>null</b> if none.
* *
*/ */
@Override
public String getValue() { public String getValue() {
return _value; return this._value;
} }
/** /**
* Sets the content value. * Sets the content value.
* <p> * <p>
*
* @param value the content value to set, <b>null</b> if none. * @param value the content value to set, <b>null</b> if none.
* *
*/ */
public void setValue(String value) { @Override
_value = value; public void setValue(final String value) {
this._value = value;
} }
@Override
public Class getInterface() { public Class getInterface() {
return SyndContent.class; return SyndContent.class;
} }
public void copyFrom(CopyFrom obj) { @Override
COPY_FROM_HELPER.copy(this,obj); public void copyFrom(final CopyFrom obj) {
COPY_FROM_HELPER.copy(this, obj);
} }
private static final CopyFromHelper COPY_FROM_HELPER; private static final CopyFromHelper COPY_FROM_HELPER;
static { static {
Map basePropInterfaceMap = new HashMap(); final Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("type",String.class); basePropInterfaceMap.put("type", String.class);
basePropInterfaceMap.put("value",String.class); basePropInterfaceMap.put("value", String.class);
Map basePropClassImplMap = Collections.EMPTY_MAP; final Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyndContent.class,basePropInterfaceMap,basePropClassImplMap); COPY_FROM_HELPER = new CopyFromHelper(SyndContent.class, basePropInterfaceMap, basePropClassImplMap);
} }
} }

View file

@ -9,48 +9,54 @@ public interface SyndEnclosure extends Cloneable, CopyFrom<SyndEnclosure> {
/** /**
* Returns the enclosure URL. * Returns the enclosure URL.
* <p> * <p>
*
* @return the enclosure URL, <b>null</b> if none. * @return the enclosure URL, <b>null</b> if none.
* *
*/ */
public String getUrl(); public String getUrl();
/** /**
* Sets the enclosure URL. * Sets the enclosure URL.
* <p> * <p>
*
* @param url the enclosure URL to set, <b>null</b> if none. * @param url the enclosure URL to set, <b>null</b> if none.
* *
*/ */
public void setUrl(String url); public void setUrl(String url);
/** /**
* Returns the enclosure length. * Returns the enclosure length.
* <p> * <p>
*
* @return the enclosure length, <b>0</b> if none. * @return the enclosure length, <b>0</b> if none.
* *
*/ */
public long getLength(); public long getLength();
/** /**
* Sets the enclosure length. * Sets the enclosure length.
* <p> * <p>
*
* @param length the enclosure length to set, <b>0</b> if none. * @param length the enclosure length to set, <b>0</b> if none.
* *
*/ */
public void setLength(long length); public void setLength(long length);
/** /**
* Returns the enclosure type. * Returns the enclosure type.
* <p> * <p>
*
* @return the enclosure type, <b>null</b> if none. * @return the enclosure type, <b>null</b> if none.
* *
*/ */
public String getType(); public String getType();
/** /**
* Sets the enclosure type. * Sets the enclosure type.
* <p> * <p>
*
* @param type the enclosure type to set, <b>null</b> if none. * @param type the enclosure type to set, <b>null</b> if none.
* *
*/ */
public void setType(String type); public void setType(String type);

View file

@ -1,52 +1,58 @@
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
*/ */
public class SyndEnclosureImpl implements Serializable,SyndEnclosure { public class SyndEnclosureImpl implements Serializable, SyndEnclosure {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _url; private String _url;
private String _type; private String _type;
private long _length; private long _length;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyndEnclosureImpl() { public SyndEnclosureImpl() {
_objBean = new ObjectBean(SyndEnclosure.class,this); this._objBean = new ObjectBean(SyndEnclosure.class, this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
public boolean equals(Object other) { @Override
return _objBean.equals(other); public boolean equals(final Object other) {
return this._objBean.equals(other);
} }
/** /**
@ -54,102 +60,114 @@ public class SyndEnclosureImpl implements Serializable,SyndEnclosure {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the enclosure URL. * Returns the enclosure URL.
* <p/> * <p/>
* *
* @return the enclosure URL, <b>null</b> if none. * @return the enclosure URL, <b>null</b> if none.
*/ */
@Override
public String getUrl() { public String getUrl() {
return _url; return this._url;
} }
/** /**
* Sets the enclosure URL. * Sets the enclosure URL.
* <p/> * <p/>
* *
* @param url the enclosure URL to set, <b>null</b> if none. * @param url the enclosure URL to set, <b>null</b> if none.
*/ */
public void setUrl(String url) { @Override
_url = url; public void setUrl(final String url) {
this._url = url;
} }
/** /**
* Returns the enclosure length. * Returns the enclosure length.
* <p/> * <p/>
* *
* @return the enclosure length, <b>null</b> if none. * @return the enclosure length, <b>null</b> if none.
*/ */
@Override
public long getLength() { public long getLength() {
return _length; return this._length;
} }
/** /**
* Sets the enclosure length. * Sets the enclosure length.
* <p/> * <p/>
* *
* @param length the enclosure length to set, <b>null</b> if none. * @param length the enclosure length to set, <b>null</b> if none.
*/ */
public void setLength(long length) { @Override
_length = length; public void setLength(final long length) {
this._length = length;
} }
/** /**
* Returns the enclosure type. * Returns the enclosure type.
* <p/> * <p/>
* *
* @return the enclosure type, <b>null</b> if none. * @return the enclosure type, <b>null</b> if none.
*/ */
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the enclosure type. * Sets the enclosure type.
* <p/> * <p/>
* *
* @param type the enclosure type to set, <b>null</b> if none. * @param type the enclosure type to set, <b>null</b> if none.
*/ */
public void setType(String type) { @Override
_type = type; public void setType(final String type) {
this._type = type;
} }
@Override
public Class<? extends CopyFrom> getInterface() { public Class<? extends CopyFrom> getInterface() {
return SyndEnclosure.class; return SyndEnclosure.class;
} }
public void copyFrom(CopyFrom obj) { @Override
COPY_FROM_HELPER.copy(this,obj); public void copyFrom(final CopyFrom obj) {
COPY_FROM_HELPER.copy(this, obj);
} }
private static final CopyFromHelper COPY_FROM_HELPER; private static final CopyFromHelper COPY_FROM_HELPER;
static { static {
Map basePropInterfaceMap = new HashMap(); final Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("url",String.class); basePropInterfaceMap.put("url", String.class);
basePropInterfaceMap.put("type",String.class); basePropInterfaceMap.put("type", String.class);
basePropInterfaceMap.put("length",Long.TYPE); basePropInterfaceMap.put("length", Long.TYPE);
Map basePropClassImplMap = Collections.EMPTY_MAP; final Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyndEnclosure.class,basePropInterfaceMap,basePropClassImplMap); COPY_FROM_HELPER = new CopyFromHelper(SyndEnclosure.class, basePropInterfaceMap, basePropClassImplMap);
} }
} }

View file

@ -28,8 +28,9 @@ import com.sun.syndication.feed.module.Module;
/** /**
* Bean interface for entries of SyndFeedImpl feeds. * Bean interface for entries of SyndFeedImpl feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface SyndEntry extends Cloneable, CopyFrom, Extendable { public interface SyndEntry extends Cloneable, CopyFrom, Extendable {
@ -37,13 +38,16 @@ public interface SyndEntry extends Cloneable, CopyFrom, Extendable {
* Returns the entry URI. * Returns the entry URI.
* <p> * <p>
* How the entry URI maps to a concrete feed type (RSS or Atom) depends on * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
* the concrete feed type. This is explained in detail in Rome documentation, * the concrete feed type. This is explained in detail in Rome
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>. * documentation, <a
* href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
* entry URI mapping</a>.
* <p> * <p>
* The returned URI is a normalized URI as specified in RFC 2396bis. * The returned URI is a normalized URI as specified in RFC 2396bis.
* <p> * <p>
*
* @return the entry URI, <b>null</b> if none. * @return the entry URI, <b>null</b> if none.
* *
*/ */
String getUri(); String getUri();
@ -51,221 +55,250 @@ public interface SyndEntry extends Cloneable, CopyFrom, Extendable {
* Sets the entry URI. * Sets the entry URI.
* <p> * <p>
* How the entry URI maps to a concrete feed type (RSS or Atom) depends on * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
* the concrete feed type. This is explained in detail in Rome documentation, * the concrete feed type. This is explained in detail in Rome
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>. * documentation, <a
* href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
* entry URI mapping</a>.
* <p> * <p>
*
* @param uri the entry URI to set, <b>null</b> if none. * @param uri the entry URI to set, <b>null</b> if none.
* *
*/ */
void setUri(String uri); void setUri(String uri);
/** /**
* Returns the entry title. * Returns the entry title.
* <p> * <p>
*
* @return the entry title, <b>null</b> if none. * @return the entry title, <b>null</b> if none.
* *
*/ */
String getTitle(); String getTitle();
/** /**
* Sets the entry title. * Sets the entry title.
* <p> * <p>
*
* @param title the entry title to set, <b>null</b> if none. * @param title the entry title to set, <b>null</b> if none.
* *
*/ */
void setTitle(String title); void setTitle(String title);
/** /**
* Returns the entry title as a text construct. * Returns the entry title as a text construct.
* <p> * <p>
*
* @return the entry title, <b>null</b> if none. * @return the entry title, <b>null</b> if none.
* *
*/ */
SyndContent getTitleEx(); SyndContent getTitleEx();
/** /**
* Sets the entry title as a text construct. * Sets the entry title as a text construct.
* <p> * <p>
*
* @param title the entry title to set, <b>null</b> if none. * @param title the entry title to set, <b>null</b> if none.
* *
*/ */
void setTitleEx(SyndContent title); void setTitleEx(SyndContent title);
/** /**
* Returns the entry link. * Returns the entry link.
* <p> * <p>
*
* @return the entry link, <b>null</b> if none. * @return the entry link, <b>null</b> if none.
* *
*/ */
String getLink(); String getLink();
/** /**
* Sets the entry link. * Sets the entry link.
* <p> * <p>
*
* @param link the entry link to set, <b>null</b> if none. * @param link the entry link to set, <b>null</b> if none.
* *
*/ */
void setLink(String link); void setLink(String link);
/** /**
* Returns the entry links * Returns the entry links
* <p> * <p>
*
* @return the entry links, <b>null</b> if none. * @return the entry links, <b>null</b> if none.
* *
*/ */
List<SyndLink> getLinks(); List<SyndLink> getLinks();
/** /**
* Sets the entry links. * Sets the entry links.
* <p> * <p>
*
* @param links the entry links to set, <b>null</b> if none. * @param links the entry links to set, <b>null</b> if none.
* *
*/ */
void setLinks(List<SyndLink> links); void setLinks(List<SyndLink> links);
/** /**
* Returns the entry description. * Returns the entry description.
* <p> * <p>
*
* @return the entry description, <b>null</b> if none. * @return the entry description, <b>null</b> if none.
* *
*/ */
SyndContent getDescription(); SyndContent getDescription();
/** /**
* Sets the entry description. * Sets the entry description.
* <p> * <p>
*
* @param description the entry description to set, <b>null</b> if none. * @param description the entry description to set, <b>null</b> if none.
* *
*/ */
void setDescription(SyndContent description); void setDescription(SyndContent description);
/** /**
* Returns the entry contents. * Returns the entry contents.
* <p> * <p>
* @return a list of SyndContentImpl elements with the entry contents, *
* an empty list if none. * @return a list of SyndContentImpl elements with the entry contents, an
* * empty list if none.
*
*/ */
List<SyndContent> getContents(); List<SyndContent> getContents();
/** /**
* Sets the entry contents. * Sets the entry contents.
* <p> * <p>
* @param contents the list of SyndContentImpl elements with the entry contents to set, *
* an empty list or <b>null</b> if none. * @param contents the list of SyndContentImpl elements with the entry
* * contents to set, an empty list or <b>null</b> if none.
*
*/ */
void setContents(List<SyndContent> contents); void setContents(List<SyndContent> contents);
/** /**
* Returns the entry enclosures. * Returns the entry enclosures.
* <p> * <p>
* @return a list of SyndEnclosure elements with the entry enclosures, *
* an empty list if none. * @return a list of SyndEnclosure elements with the entry enclosures, an
* * empty list if none.
*
*/ */
public List<SyndEnclosure> getEnclosures(); public List<SyndEnclosure> getEnclosures();
/** /**
* Sets the entry enclosures. * Sets the entry enclosures.
* <p> * <p>
* @param enclosures the list of SyndEnclosure elements with the entry enclosures to set, *
* an empty list or <b>null</b> if none. * @param enclosures the list of SyndEnclosure elements with the entry
* * enclosures to set, an empty list or <b>null</b> if none.
*
*/ */
public void setEnclosures(List<SyndEnclosure> enclosures); public void setEnclosures(List<SyndEnclosure> enclosures);
/** /**
* Returns the entry published date. * Returns the entry published date.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module date. * This method is a convenience method, it maps to the Dublin Core module
* date.
* <p> * <p>
*
* @return the entry published date, <b>null</b> if none. * @return the entry published date, <b>null</b> if none.
* *
*/ */
Date getPublishedDate(); Date getPublishedDate();
/** /**
* Sets the entry published date. * Sets the entry published date.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module date. * This method is a convenience method, it maps to the Dublin Core module
* date.
* <p> * <p>
* @param publishedDate the entry published date to set, <b>null</b> if none. *
* * @param publishedDate the entry published date to set, <b>null</b> if
* none.
*
*/ */
void setPublishedDate(Date publishedDate); void setPublishedDate(Date publishedDate);
/** /**
* Returns the entry updated date. * Returns the entry updated date.
* <p> * <p>
*
* @return the entry updated date, <b>null</b> if none. * @return the entry updated date, <b>null</b> if none.
* *
*/ */
Date getUpdatedDate(); Date getUpdatedDate();
/** /**
* Sets the entry updated date. * Sets the entry updated date.
* <p> * <p>
*
* @param updatedDate the entry updated date to set, <b>null</b> if none. * @param updatedDate the entry updated date to set, <b>null</b> if none.
* *
*/ */
void setUpdatedDate(Date updatedDate); void setUpdatedDate(Date updatedDate);
/** /**
* Returns the entry authors. * Returns the entry authors.
* <p> * <p>
* For Atom feeds, this returns the authors as a list of SyndPerson objects, * For Atom feeds, this returns the authors as a list of SyndPerson objects,
* for RSS feeds this method is a convenience method, it maps to the * for RSS feeds this method is a convenience method, it maps to the Dublin
* Dublin Core module creator. * Core module creator.
* <p> * <p>
*
* @return the feed author, <b>null</b> if none. * @return the feed author, <b>null</b> if none.
* *
*/ */
List<SyndPerson> getAuthors(); List<SyndPerson> getAuthors();
/** /**
* Sets the entry author. * Sets the entry author.
* <p> * <p>
* For Atom feeds, this sets the authors as a list of SyndPerson * For Atom feeds, this sets the authors as a list of SyndPerson objects,
* objects, for RSS feeds this method is a convenience method, it maps * for RSS feeds this method is a convenience method, it maps to the Dublin
* to the Dublin Core module creator. * Core module creator.
* <p> * <p>
*
* @param authors the feed author to set, <b>null</b> if none. * @param authors the feed author to set, <b>null</b> if none.
* *
*/ */
void setAuthors(List<SyndPerson> authors); void setAuthors(List<SyndPerson> authors);
/** /**
* Returns the name of the first entry author in the collection of authors. * Returns the name of the first entry author in the collection of authors.
* <p> * <p>
* For Atom feeds, this returns the authors as a list of SyndPerson objects, * For Atom feeds, this returns the authors as a list of SyndPerson objects,
* for RSS feeds this method is a convenience method, it maps to the * for RSS feeds this method is a convenience method, it maps to the Dublin
* Dublin Core module creator. * Core module creator.
* <p> * <p>
*
* @return the feed author, <b>null</b> if none. * @return the feed author, <b>null</b> if none.
* *
*/ */
String getAuthor(); String getAuthor();
/** /**
* Sets the entry author. * Sets the entry author.
* <p> * <p>
* For Atom feeds, this sets the feed author's name, for RSS feeds * For Atom feeds, this sets the feed author's name, for RSS feeds this
* this method is a convenience method, it maps to the Dublin Core * method is a convenience method, it maps to the Dublin Core module
* module creator. * creator.
* <p> * <p>
*
* @param author the feed author to set, <b>null</b> if none. * @param author the feed author to set, <b>null</b> if none.
*/ */
void setAuthor(String author); void setAuthor(String author);
/** /**
* Returns the feed author. * Returns the feed author.
* <p> * <p>
* For Atom feeds, this returns the contributors as a list of * For Atom feeds, this returns the contributors as a list of SyndPerson
* SyndPerson objects * objects
* <p> * <p>
*
* @return the feed author, <b>null</b> if none. * @return the feed author, <b>null</b> if none.
* *
*/ */
List<SyndPerson> getContributors(); List<SyndPerson> getContributors();
@ -274,118 +307,135 @@ public interface SyndEntry extends Cloneable, CopyFrom, Extendable {
* <p> * <p>
* Returns contributors as a list of SyndPerson objects. * Returns contributors as a list of SyndPerson objects.
* <p> * <p>
*
* @param contributors the feed contributors to set, <b>null</b> if none. * @param contributors the feed contributors to set, <b>null</b> if none.
* *
*/ */
void setContributors(List<SyndPerson> contributors); void setContributors(List<SyndPerson> contributors);
/** /**
* Returns the entry categories. * Returns the entry categories.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module subjects. * This method is a convenience method, it maps to the Dublin Core module
* subjects.
* <p> * <p>
* @return a list of SyndCategoryImpl elements with the entry categories, *
* an empty list if none. * @return a list of SyndCategoryImpl elements with the entry categories, an
* * empty list if none.
*
*/ */
List<SyndCategory> getCategories(); List<SyndCategory> getCategories();
/** /**
* Sets the entry categories. * Sets the entry categories.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module subjects. * This method is a convenience method, it maps to the Dublin Core module
* subjects.
* <p> * <p>
* @param categories the list of SyndCategoryImpl elements with the entry categories to set, *
* an empty list or <b>null</b> if none. * @param categories the list of SyndCategoryImpl elements with the entry
* * categories to set, an empty list or <b>null</b> if none.
*
*/ */
void setCategories(List<SyndCategory> categories); void setCategories(List<SyndCategory> categories);
/** /**
* Returns the entry source. * Returns the entry source.
* <p> * <p>
* This returns the entry source as a SyndFeed * This returns the entry source as a SyndFeed
* <p> * <p>
*
* @return the SyndFeed to which this entry is attributed * @return the SyndFeed to which this entry is attributed
* *
*/ */
SyndFeed getSource(); SyndFeed getSource();
/** /**
* Sets the entry source feed (for use if different from containing feed) * Sets the entry source feed (for use if different from containing feed)
* <p> * <p>
*
* @param source the original SyndFeed that contained this article * @param source the original SyndFeed that contained this article
* *
*/ */
void setSource(SyndFeed source); void setSource(SyndFeed source);
/** /**
* Return the original item this SyndEntry is generated from. * Return the original item this SyndEntry is generated from. The type of
* The type of the object returned depends on the original type of * the object returned depends on the original type of the feed. Atom
* the feed. Atom 0.3/1.0 will return com.sun.syndication.feed.atom.Entry, * 0.3/1.0 will return com.sun.syndication.feed.atom.Entry, while RSS will
* while RSS will return com.sun.syndication.feed.rss.Item.java. * return com.sun.syndication.feed.rss.Item.java. If this entry was not
* If this entry was not generated from a WireFeed, or the SyndFeed * generated from a WireFeed, or the SyndFeed was not set to preserve the
* was not set to preserve the WireFeed then it will return null * WireFeed then it will return null
* *
* @return the WireFeed Item or Entry this Entry is generated from, or null * @return the WireFeed Item or Entry this Entry is generated from, or null
*/ */
Object getWireEntry(); Object getWireEntry();
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
@Override
public Module getModule(String uri); public Module getModule(String uri);
/** /**
* Returns the entry modules. * Returns the entry modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the entry modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the entry modules, an empty
* * list if none.
*
*/ */
@Override
List<Module> getModules(); List<Module> getModules();
/** /**
* Sets the entry modules. * Sets the entry modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the entry modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the entry modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
@Override
void setModules(List<Module> modules); void setModules(List<Module> modules);
/** /**
* Returns foreign markup found at channel level. * Returns foreign markup found at channel level.
* <p> * <p>
*
* @return Opaque object to discourage use * @return Opaque object to discourage use
* *
*/ */
public List<Element> getForeignMarkup(); public List<Element> getForeignMarkup();
/** /**
* Sets foreign markup found at channel level. * Sets foreign markup found at channel level.
* <p> * <p>
*
* @param foreignMarkup Opaque object to discourage use * @param foreignMarkup Opaque object to discourage use
* *
*/ */
public void setForeignMarkup(List<Element> foreignMarkup); public void setForeignMarkup(List<Element> foreignMarkup);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;
/** /**
* Returns the first instance of a SyndLink with the specified relation, or null * Returns the first instance of a SyndLink with the specified relation, or
* * null
*
*/ */
public SyndLink findRelatedLink(String relation); public SyndLink findRelatedLink(String relation);

View file

@ -16,30 +16,42 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean; import java.util.ArrayList;
import com.sun.syndication.feed.module.*; import java.util.Collections;
import com.sun.syndication.feed.module.impl.ModuleUtils; import java.util.Date;
import com.sun.syndication.feed.synd.impl.URINormalizer; import java.util.HashMap;
import com.sun.syndication.feed.impl.CopyFromHelper; import java.util.HashSet;
import java.util.List;
import java.util.*; import java.util.Map;
import java.io.Serializable; import java.util.Set;
import org.jdom2.Element; import org.jdom2.Element;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.module.DCModuleImpl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.SyModule;
import com.sun.syndication.feed.module.SyModuleImpl;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.synd.impl.URINormalizer;
/** /**
* Bean for entries of SyndFeedImpl feeds. * Bean for entries of SyndFeedImpl feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyndEntryImpl implements Serializable,SyndEntry { public class SyndEntryImpl implements Serializable, SyndEntry {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _uri; private String _uri;
private String _link; private String _link;
private Date _updatedDate; private Date _updatedDate;
private SyndContent _title; private SyndContent _title;
private SyndContent _description; private SyndContent _description;
private List<SyndLink> _links; private List<SyndLink> _links;
private List<SyndContent> _contents; // deprecated by Atom 1.0 private List<SyndContent> _contents; // deprecated by Atom 1.0
@ -49,18 +61,20 @@ public class SyndEntryImpl implements Serializable,SyndEntry {
private List<SyndPerson> _contributors; private List<SyndPerson> _contributors;
private SyndFeed _source; private SyndFeed _source;
private List<Element> _foreignMarkup; private List<Element> _foreignMarkup;
private Object wireEntry; // com.sun.syndication.feed.atom.Entry or com.sun.syndication.feed.rss.Item private Object wireEntry; // com.sun.syndication.feed.atom.Entry or
// com.sun.syndication.feed.rss.Item
// ISSUE: some converters assume this is never null // ISSUE: some converters assume this is never null
private List<SyndCategory> _categories = new ArrayList<SyndCategory>(); private List<SyndCategory> _categories = new ArrayList<SyndCategory>();
private static final Set<String> IGNORE_PROPERTIES = new HashSet<String>(); private static final Set<String> IGNORE_PROPERTIES = new HashSet<String>();
/** /**
* Unmodifiable Set containing the convenience properties of this class. * Unmodifiable Set containing the convenience properties of this class.
* <p> * <p>
* Convenience properties are mapped to Modules, for cloning the convenience properties * Convenience properties are mapped to Modules, for cloning the convenience
* can be ignored as the will be copied as part of the module cloning. * properties can be ignored as the will be copied as part of the module
* cloning.
*/ */
public static final Set<String> CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES); public static final Set<String> CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
@ -70,60 +84,67 @@ public class SyndEntryImpl implements Serializable,SyndEntry {
} }
/** /**
* For implementations extending SyndEntryImpl to be able to use the ObjectBean functionality * For implementations extending SyndEntryImpl to be able to use the
* with extended interfaces. * ObjectBean functionality with extended interfaces.
* <p> * <p>
*
* @param beanClass * @param beanClass
* @param convenienceProperties set containing the convenience properties of the SyndEntryImpl * @param convenienceProperties set containing the convenience properties of
* (the are ignored during cloning, check CloneableBean for details). * the SyndEntryImpl (the are ignored during cloning, check
* * CloneableBean for details).
*
*/ */
protected SyndEntryImpl(Class beanClass,Set convenienceProperties) { protected SyndEntryImpl(final Class beanClass, final Set convenienceProperties) {
_objBean = new ObjectBean(beanClass,this,convenienceProperties); this._objBean = new ObjectBean(beanClass, this, convenienceProperties);
} }
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyndEntryImpl() { public SyndEntryImpl() {
this(SyndEntry.class,IGNORE_PROPERTIES); this(SyndEntry.class, IGNORE_PROPERTIES);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if (other == null) { if (other == null) {
return false; return false;
} }
// while ObjectBean does this check this method does a cast to obtain the foreign markup // while ObjectBean does this check this method does a cast to obtain
// the foreign markup
// so we need to check before doing so. // so we need to check before doing so.
if (!(other instanceof SyndEntryImpl)) { if (!(other instanceof SyndEntryImpl)) {
return false; return false;
} }
// can't use foreign markup in equals, due to JDOM equals impl // can't use foreign markup in equals, due to JDOM equals impl
List<Element> fm = getForeignMarkup(); final List<Element> fm = getForeignMarkup();
setForeignMarkup(((SyndEntryImpl)other).getForeignMarkup()); setForeignMarkup(((SyndEntryImpl) other).getForeignMarkup());
boolean ret = _objBean.equals(other); final boolean ret = this._objBean.equals(other);
// restore foreign markup // restore foreign markup
setForeignMarkup(fm); setForeignMarkup(fm);
return ret; return ret;
@ -134,191 +155,230 @@ public class SyndEntryImpl implements Serializable,SyndEntry {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the entry URI. * Returns the entry URI.
* <p> * <p>
* How the entry URI maps to a concrete feed type (RSS or Atom) depends on * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
* the concrete feed type. This is explained in detail in Rome documentation, * the concrete feed type. This is explained in detail in Rome
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>. * documentation, <a
* href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
* entry URI mapping</a>.
* <p> * <p>
* The returned URI is a normalized URI as specified in RFC 2396bis. * The returned URI is a normalized URI as specified in RFC 2396bis.
* <p> * <p>
*
* @return the entry URI, <b>null</b> if none. * @return the entry URI, <b>null</b> if none.
* *
*/ */
@Override
public String getUri() { public String getUri() {
return _uri; return this._uri;
} }
/** /**
* Sets the entry URI. * Sets the entry URI.
* <p> * <p>
* How the entry URI maps to a concrete feed type (RSS or Atom) depends on * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
* the concrete feed type. This is explained in detail in Rome documentation, * the concrete feed type. This is explained in detail in Rome
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>. * documentation, <a
* href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
* entry URI mapping</a>.
* <p> * <p>
*
* @param uri the entry URI to set, <b>null</b> if none. * @param uri the entry URI to set, <b>null</b> if none.
* *
*/ */
public void setUri(String uri) { @Override
_uri = URINormalizer.normalize(uri); public void setUri(final String uri) {
this._uri = URINormalizer.normalize(uri);
} }
/** /**
* Returns the entry title. * Returns the entry title.
* <p> * <p>
*
* @return the entry title, <b>null</b> if none. * @return the entry title, <b>null</b> if none.
* *
*/ */
@Override
public String getTitle() { public String getTitle() {
if (_title != null) return _title.getValue(); if (this._title != null) {
return this._title.getValue();
}
return null; return null;
} }
/** /**
* Sets the entry title. * Sets the entry title.
* <p> * <p>
*
* @param title the entry title to set, <b>null</b> if none. * @param title the entry title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { @Override
if (_title == null) _title = new SyndContentImpl(); public void setTitle(final String title) {
_title.setValue(title); if (this._title == null) {
this._title = new SyndContentImpl();
}
this._title.setValue(title);
} }
/** /**
* Returns the entry title as a text construct. * Returns the entry title as a text construct.
* <p> * <p>
*
* @return the entry title, <b>null</b> if none. * @return the entry title, <b>null</b> if none.
* *
*/ */
@Override
public SyndContent getTitleEx() { public SyndContent getTitleEx() {
return _title; return this._title;
} }
/** /**
* Sets the entry title as a text construct. * Sets the entry title as a text construct.
* <p> * <p>
*
* @param title the entry title to set, <b>null</b> if none. * @param title the entry title to set, <b>null</b> if none.
* *
*/ */
public void setTitleEx(SyndContent title) { @Override
_title = title; public void setTitleEx(final SyndContent title) {
this._title = title;
} }
/** /**
* Returns the entry link. * Returns the entry link.
* <p> * <p>
*
* @return the entry link, <b>null</b> if none. * @return the entry link, <b>null</b> if none.
* *
*/ */
@Override
public String getLink() { public String getLink() {
return _link; return this._link;
} }
/** /**
* Sets the entry link. * Sets the entry link.
* <p> * <p>
*
* @param link the entry link to set, <b>null</b> if none. * @param link the entry link to set, <b>null</b> if none.
* *
*/ */
public void setLink(String link) { @Override
_link = link; public void setLink(final String link) {
this._link = link;
} }
/** /**
* Returns the entry description. * Returns the entry description.
* <p> * <p>
*
* @return the entry description, <b>null</b> if none. * @return the entry description, <b>null</b> if none.
* *
*/ */
@Override
public SyndContent getDescription() { public SyndContent getDescription() {
return _description; return this._description;
} }
/** /**
* Sets the entry description. * Sets the entry description.
* <p> * <p>
*
* @param description the entry description to set, <b>null</b> if none. * @param description the entry description to set, <b>null</b> if none.
* *
*/ */
public void setDescription(SyndContent description) { @Override
_description = description; public void setDescription(final SyndContent description) {
this._description = description;
} }
/** /**
* Returns the entry contents. * Returns the entry contents.
* <p> * <p>
* @return a list of SyndContentImpl elements with the entry contents, *
* an empty list if none. * @return a list of SyndContentImpl elements with the entry contents, an
* * empty list if none.
*
*/ */
@Override
public List<SyndContent> getContents() { public List<SyndContent> getContents() {
return (_contents==null) ? (_contents=new ArrayList<SyndContent>()) : _contents; return this._contents == null ? (this._contents = new ArrayList<SyndContent>()) : this._contents;
} }
/** /**
* Sets the entry contents. * Sets the entry contents.
* <p> * <p>
* @param contents the list of SyndContentImpl elements with the entry contents to set, *
* an empty list or <b>null</b> if none. * @param contents the list of SyndContentImpl elements with the entry
* * contents to set, an empty list or <b>null</b> if none.
*
*/ */
public void setContents(List<SyndContent> contents) { @Override
_contents = contents; public void setContents(final List<SyndContent> contents) {
this._contents = contents;
} }
/** /**
* Returns the entry enclosures. * Returns the entry enclosures.
* <p> * <p>
* @return a list of SyndEnclosure elements with the entry enclosures, *
* an empty list if none. * @return a list of SyndEnclosure elements with the entry enclosures, an
* * empty list if none.
*
*/ */
@Override
public List<SyndEnclosure> getEnclosures() { public List<SyndEnclosure> getEnclosures() {
return (_enclosures==null) ? (_enclosures=new ArrayList<SyndEnclosure>()) : _enclosures; return this._enclosures == null ? (this._enclosures = new ArrayList<SyndEnclosure>()) : this._enclosures;
} }
/** /**
* Sets the entry enclosures. * Sets the entry enclosures.
* <p> * <p>
* @param enclosures the list of SyndEnclosure elements with the entry enclosures to set, *
* an empty list or <b>null</b> if none. * @param enclosures the list of SyndEnclosure elements with the entry
* * enclosures to set, an empty list or <b>null</b> if none.
*
*/ */
public void setEnclosures(List<SyndEnclosure> enclosures) { @Override
_enclosures = enclosures; public void setEnclosures(final List<SyndEnclosure> enclosures) {
this._enclosures = enclosures;
} }
/** /**
* Returns the entry published date. * Returns the entry published date.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module date. * This method is a convenience method, it maps to the Dublin Core module
* date.
* <p> * <p>
*
* @return the entry published date, <b>null</b> if none. * @return the entry published date, <b>null</b> if none.
* *
*/ */
@Override
public Date getPublishedDate() { public Date getPublishedDate() {
return getDCModule().getDate(); return getDCModule().getDate();
} }
@ -326,259 +386,306 @@ public class SyndEntryImpl implements Serializable,SyndEntry {
/** /**
* Sets the entry published date. * Sets the entry published date.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module date. * This method is a convenience method, it maps to the Dublin Core module
* date.
* <p> * <p>
* @param publishedDate the entry published date to set, <b>null</b> if none. *
* * @param publishedDate the entry published date to set, <b>null</b> if
* none.
*
*/ */
public void setPublishedDate(Date publishedDate) { @Override
public void setPublishedDate(final Date publishedDate) {
getDCModule().setDate(publishedDate); getDCModule().setDate(publishedDate);
} }
/** /**
* Returns the entry categories. * Returns the entry categories.
* <p> * <p>
* @return a list of SyndCategoryImpl elements with the entry categories, *
* an empty list if none. * @return a list of SyndCategoryImpl elements with the entry categories, an
* * empty list if none.
*
*/ */
@Override
public List<SyndCategory> getCategories() { public List<SyndCategory> getCategories() {
return _categories; return this._categories;
} }
/** /**
* Sets the entry categories. * Sets the entry categories.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module subjects. * This method is a convenience method, it maps to the Dublin Core module
* subjects.
* <p> * <p>
* @param categories the list of SyndCategoryImpl elements with the entry categories to set, *
* an empty list or <b>null</b> if none. * @param categories the list of SyndCategoryImpl elements with the entry
* * categories to set, an empty list or <b>null</b> if none.
*
*/ */
public void setCategories(List<SyndCategory> categories) { @Override
_categories = categories; public void setCategories(final List<SyndCategory> categories) {
this._categories = categories;
} }
/** /**
* Returns the entry modules. * Returns the entry modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the entry modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the entry modules, an empty
* * list if none.
*
*/ */
@Override
public List<Module> getModules() { public List<Module> getModules() {
if (_modules==null) { if (this._modules == null) {
_modules=new ArrayList<Module>(); this._modules = new ArrayList<Module>();
} }
if (ModuleUtils.getModule(_modules,DCModule.URI)==null) { if (ModuleUtils.getModule(this._modules, DCModule.URI) == null) {
_modules.add(new DCModuleImpl()); this._modules.add(new DCModuleImpl());
} }
return _modules; return this._modules;
} }
/** /**
* Sets the entry modules. * Sets the entry modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the entry modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the entry modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
public void setModules(List<Module> modules) { @Override
_modules = modules; public void setModules(final List<Module> modules) {
this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
public Module getModule(String uri) { @Override
return ModuleUtils.getModule(getModules(),uri); public Module getModule(final String uri) {
return ModuleUtils.getModule(getModules(), uri);
} }
/** /**
* Returns the Dublin Core module of the feed. * Returns the Dublin Core module of the feed.
*
* @return the DC module, it's never <b>null</b> * @return the DC module, it's never <b>null</b>
* *
*/ */
private DCModule getDCModule() { private DCModule getDCModule() {
return (DCModule) getModule(DCModule.URI); return (DCModule) getModule(DCModule.URI);
} }
@Override
public Class getInterface() { public Class getInterface() {
return SyndEntry.class; return SyndEntry.class;
} }
public void copyFrom(CopyFrom obj) { @Override
COPY_FROM_HELPER.copy(this,obj); public void copyFrom(final CopyFrom obj) {
COPY_FROM_HELPER.copy(this, obj);
} }
private static final CopyFromHelper COPY_FROM_HELPER; private static final CopyFromHelper COPY_FROM_HELPER;
static { static {
Map basePropInterfaceMap = new HashMap(); final Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("uri",String.class); basePropInterfaceMap.put("uri", String.class);
basePropInterfaceMap.put("title",String.class); basePropInterfaceMap.put("title", String.class);
basePropInterfaceMap.put("link",String.class); basePropInterfaceMap.put("link", String.class);
basePropInterfaceMap.put("uri",String.class); basePropInterfaceMap.put("uri", String.class);
basePropInterfaceMap.put("description",SyndContent.class); basePropInterfaceMap.put("description", SyndContent.class);
basePropInterfaceMap.put("contents",SyndContent.class); basePropInterfaceMap.put("contents", SyndContent.class);
basePropInterfaceMap.put("enclosures",SyndEnclosure.class); basePropInterfaceMap.put("enclosures", SyndEnclosure.class);
basePropInterfaceMap.put("modules",Module.class); basePropInterfaceMap.put("modules", Module.class);
Map basePropClassImplMap = new HashMap(); final Map basePropClassImplMap = new HashMap();
basePropClassImplMap.put(SyndContent.class,SyndContentImpl.class); basePropClassImplMap.put(SyndContent.class, SyndContentImpl.class);
basePropClassImplMap.put(SyndEnclosure.class,SyndEnclosureImpl.class); basePropClassImplMap.put(SyndEnclosure.class, SyndEnclosureImpl.class);
basePropClassImplMap.put(DCModule.class,DCModuleImpl.class); basePropClassImplMap.put(DCModule.class, DCModuleImpl.class);
basePropClassImplMap.put(SyModule.class,SyModuleImpl.class); basePropClassImplMap.put(SyModule.class, SyModuleImpl.class);
COPY_FROM_HELPER = new CopyFromHelper(SyndEntry.class,basePropInterfaceMap,basePropClassImplMap); COPY_FROM_HELPER = new CopyFromHelper(SyndEntry.class, basePropInterfaceMap, basePropClassImplMap);
} }
/** /**
* Returns the links * Returns the links
* <p> * <p>
*
* @return Returns the links. * @return Returns the links.
*/ */
@Override
public List<SyndLink> getLinks() { public List<SyndLink> getLinks() {
return (_links==null) ? (_links=new ArrayList<SyndLink>()) : _links; return this._links == null ? (this._links = new ArrayList<SyndLink>()) : this._links;
} }
/** /**
* Set the links * Set the links
* <p> * <p>
*
* @param links The links to set. * @param links The links to set.
*/ */
public void setLinks(List<SyndLink> links) { @Override
_links = links; public void setLinks(final List<SyndLink> links) {
} this._links = links;
}
/** /**
* Returns the updatedDate * Returns the updatedDate
* <p> * <p>
*
* @return Returns the updatedDate. * @return Returns the updatedDate.
*/ */
@Override
public Date getUpdatedDate() { public Date getUpdatedDate() {
return _updatedDate == null ? null : new Date(_updatedDate.getTime()); return this._updatedDate == null ? null : new Date(this._updatedDate.getTime());
} }
/** /**
* Set the updatedDate * Set the updatedDate
* <p> * <p>
*
* @param updatedDate The updatedDate to set. * @param updatedDate The updatedDate to set.
*/ */
public void setUpdatedDate(Date updatedDate) { @Override
_updatedDate = new Date(updatedDate.getTime()); public void setUpdatedDate(final Date updatedDate) {
this._updatedDate = new Date(updatedDate.getTime());
} }
@Override
public List<SyndPerson> getAuthors() { public List<SyndPerson> getAuthors() {
return (_authors==null) ? (_authors=new ArrayList<SyndPerson>()) : _authors; return this._authors == null ? (this._authors = new ArrayList<SyndPerson>()) : this._authors;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
* @see com.sun.syndication.feed.synd.SyndEntry#setAuthors(java.util.List) * @see com.sun.syndication.feed.synd.SyndEntry#setAuthors(java.util.List)
*/ */
public void setAuthors(List<SyndPerson> authors) { @Override
_authors = authors; public void setAuthors(final List<SyndPerson> authors) {
this._authors = authors;
} }
/** /**
* Returns the entry author. * Returns the entry author.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module creator. * This method is a convenience method, it maps to the Dublin Core module
* creator.
* <p> * <p>
*
* @return the entry author, <b>null</b> if none. * @return the entry author, <b>null</b> if none.
* *
*/ */
@Override
public String getAuthor() { public String getAuthor() {
String author; String author;
// Start out looking for one or more authors in _authors. For non-Atom // Start out looking for one or more authors in _authors. For non-Atom
// feeds, _authors may actually be null. // feeds, _authors may actually be null.
if ((_authors != null) && (_authors.size() > 0)) { if (this._authors != null && this._authors.size() > 0) {
author = ((SyndPerson)_authors.get(0)).getName(); author = this._authors.get(0).getName();
} else { } else {
author = getDCModule().getCreator(); author = getDCModule().getCreator();
} }
if (author == null) { if (author == null) {
author = ""; author = "";
} }
return author; return author;
} }
/** /**
* Sets the entry author. * Sets the entry author.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module creator. * This method is a convenience method, it maps to the Dublin Core module
* creator.
* <p> * <p>
*
* @param author the entry author to set, <b>null</b> if none. * @param author the entry author to set, <b>null</b> if none.
* *
*/ */
public void setAuthor(String author) { @Override
public void setAuthor(final String author) {
// Get the DCModule so that we can check to see if "creator" is already // Get the DCModule so that we can check to see if "creator" is already
// set. // set.
DCModule dcModule = getDCModule(); final DCModule dcModule = getDCModule();
String currentValue = dcModule.getCreator(); final String currentValue = dcModule.getCreator();
if ((currentValue == null) || (currentValue.length() == 0)) { if (currentValue == null || currentValue.length() == 0) {
getDCModule().setCreator(author); getDCModule().setCreator(author);
} }
} }
@Override
public List<SyndPerson> getContributors() { public List<SyndPerson> getContributors() {
return (_contributors==null) ? (_contributors=new ArrayList<SyndPerson>()) : _contributors; return this._contributors == null ? (this._contributors = new ArrayList<SyndPerson>()) : this._contributors;
} }
/* (non-Javadoc) /*
* @see com.sun.syndication.feed.synd.SyndEntry#setContributors(java.util.List) * (non-Javadoc)
* @see
* com.sun.syndication.feed.synd.SyndEntry#setContributors(java.util.List)
*/ */
public void setContributors(List<SyndPerson> contributors) { @Override
_contributors = contributors; public void setContributors(final List<SyndPerson> contributors) {
this._contributors = contributors;
} }
@Override
public SyndFeed getSource() { public SyndFeed getSource() {
return _source; return this._source;
} }
public void setSource(SyndFeed source) { @Override
_source = source; public void setSource(final SyndFeed source) {
this._source = source;
} }
/** /**
* Returns foreign markup found at channel level. * Returns foreign markup found at channel level.
* <p> * <p>
* @return list of JDOM nodes containing channel-level foreign markup, *
* an empty list if none. * @return list of JDOM nodes containing channel-level foreign markup, an
* * empty list if none.
*
*/ */
@Override
public List<Element> getForeignMarkup() { public List<Element> getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList<Element>()) : _foreignMarkup; return this._foreignMarkup == null ? (this._foreignMarkup = new ArrayList<Element>()) : this._foreignMarkup;
} }
/** /**
* Sets foreign markup found at channel level. * Sets foreign markup found at channel level.
* <p> * <p>
* @param foreignMarkup list of JDOM nodes containing channel-level foreign markup, *
* an empty list if none. * @param foreignMarkup list of JDOM nodes containing channel-level foreign
* * markup, an empty list if none.
*
*/ */
public void setForeignMarkup(List<Element> foreignMarkup) { @Override
_foreignMarkup = (List<Element>)foreignMarkup; public void setForeignMarkup(final List<Element> foreignMarkup) {
this._foreignMarkup = foreignMarkup;
} }
public Object getWireEntry() { @Override
return wireEntry; public Object getWireEntry() {
} return this.wireEntry;
}
public void setWireEntry(Object wireEntry) {
this.wireEntry = wireEntry;
}
public SyndLink findRelatedLink(String relation) { public void setWireEntry(final Object wireEntry) {
for(SyndLink l : this.getLinks()){ this.wireEntry = wireEntry;
if(relation.equals(l.getRel())){ }
@Override
public SyndLink findRelatedLink(final String relation) {
for (final SyndLink l : getLinks()) {
if (relation.equals(l.getRel())) {
return l; return l;
} }
} }

View file

@ -16,29 +16,33 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import org.jdom2.Element; import org.jdom2.Element;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module;
/** /**
* Bean interface for all types of feeds. * Bean interface for all types of feeds.
* <p> * <p>
* It handles all RSS versions and Atom 0.3, it normalizes all info, it may lose information. * It handles all RSS versions and Atom 0.3, it normalizes all info, it may lose
* information.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface SyndFeed extends Cloneable, CopyFrom, Extendable { public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
/** /**
* Returns the real feed types the SyndFeedImpl supports when converting from and to. * Returns the real feed types the SyndFeedImpl supports when converting
* from and to.
* <p> * <p>
*
* @return the real feed type supported. * @return the real feed type supported.
*/ */
List<String> getSupportedFeedTypes(); List<String> getSupportedFeedTypes();
@ -46,66 +50,76 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
/** /**
* Creates a real feed containing the information of the SyndFeedImpl. * Creates a real feed containing the information of the SyndFeedImpl.
* <p> * <p>
* The feed type of the created WireFeed is taken from the SyndFeedImpl feedType property. * The feed type of the created WireFeed is taken from the SyndFeedImpl
* feedType property.
* <p> * <p>
*
* @return the real feed. * @return the real feed.
* *
*/ */
WireFeed createWireFeed(); WireFeed createWireFeed();
/** /**
* Creates a real feed containing the information of the SyndFeedImpl. * Creates a real feed containing the information of the SyndFeedImpl.
* <p> * <p>
*
* @param feedType the feed type for the WireFeed to be created. * @param feedType the feed type for the WireFeed to be created.
* @return the real feed. * @return the real feed.
* *
*/ */
WireFeed createWireFeed(String feedType); WireFeed createWireFeed(String feedType);
/** /**
* Returns the WireFeed this SyndFeed was created from. * Returns the WireFeed this SyndFeed was created from. Will return null if
* Will return null if the original feed is not stored or if this SyndFeed was not created from a WireFeed * the original feed is not stored or if this SyndFeed was not created from
* a WireFeed
* *
* @return The WireFeed this was created from, or null * @return The WireFeed this was created from, or null
* *
*/ */
WireFeed originalWireFeed(); WireFeed originalWireFeed();
/** /**
* *
* @return true if this SyndFeed preserves the WireFeed it was created from * @return true if this SyndFeed preserves the WireFeed it was created from
*/ */
boolean isPreservingWireFeed(); boolean isPreservingWireFeed();
/** /**
* Returns the wire feed type the feed had/will-have when converted from/to a WireFeed. * Returns the wire feed type the feed had/will-have when converted from/to
* a WireFeed.
* <p> * <p>
*
* @return the feed type, <b>null</b> if none. * @return the feed type, <b>null</b> if none.
* *
*/ */
String getFeedType(); String getFeedType();
/** /**
* Sets the wire feed type the feed will-have when coverted to a WireFeed. * Sets the wire feed type the feed will-have when coverted to a WireFeed.
* <p> * <p>
*
* @param feedType the feed type to set, <b>null</b> if none. * @param feedType the feed type to set, <b>null</b> if none.
* *
*/ */
void setFeedType(String feedType); void setFeedType(String feedType);
/** /**
* Returns the charset encoding of a the feed. This is not set by Rome parsers. * Returns the charset encoding of a the feed. This is not set by Rome
* parsers.
* <p> * <p>
*
* @return the charset encoding of the feed. * @return the charset encoding of the feed.
* *
*/ */
public String getEncoding(); public String getEncoding();
/** /**
* Sets the charset encoding of a the feed. This is not set by Rome parsers. * Sets the charset encoding of a the feed. This is not set by Rome parsers.
* <p> * <p>
*
* @param encoding the charset encoding of the feed. * @param encoding the charset encoding of the feed.
* *
*/ */
public void setEncoding(String encoding); public void setEncoding(String encoding);
@ -113,25 +127,28 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* Returns the feed URI. * Returns the feed URI.
* <p> * <p>
* How the feed URI maps to a concrete feed type (RSS or Atom) depends on * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
* the concrete feed type. This is explained in detail in Rome documentation, * the concrete feed type. This is explained in detail in Rome
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>. * documentation, <a
* href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
* entry URI mapping</a>.
* <p> * <p>
* The returned URI is a normalized URI as specified in RFC 2396bis. * The returned URI is a normalized URI as specified in RFC 2396bis.
* <p> * <p>
* Note: The URI is the unique identifier, in the RSS 2.0/atom case this is * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
* the GUID, for RSS 1.0 this is the URI attribute of the item. The Link * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
* is the URL that the item is accessible under, the URI is the * the URL that the item is accessible under, the URI is the permanent
* permanent identifier which the aggregator should use to reference * identifier which the aggregator should use to reference this item. Often
* this item. Often the URI will use some standardized identifier scheme * the URI will use some standardized identifier scheme such as DOI's so
* such as DOI's so that items can be identified even if they appear in * that items can be identified even if they appear in multiple feeds with
* multiple feeds with different "links" (they might be on different * different "links" (they might be on different hosting platforms but be
* hosting platforms but be the same item). Also, though rare, there * the same item). Also, though rare, there could be multiple items with the
* could be multiple items with the same link but a different URI and * same link but a different URI and associated metadata which need to be
* associated metadata which need to be treated as distinct entities. * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
* In the RSS 1.0 case the URI must be a valid RDF URI reference. * RDF URI reference.
* <p> * <p>
*
* @return the feed URI, <b>null</b> if none. * @return the feed URI, <b>null</b> if none.
* *
*/ */
String getUri(); String getUri();
@ -139,55 +156,62 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* Sets the feed URI. * Sets the feed URI.
* <p> * <p>
* How the feed URI maps to a concrete feed type (RSS or Atom) depends on * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
* the concrete feed type. This is explained in detail in Rome documentation, * the concrete feed type. This is explained in detail in Rome
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>. * documentation, <a
* href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
* entry URI mapping</a>.
* <p> * <p>
* Note: The URI is the unique identifier, in the RSS 2.0/atom case this is * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
* the GUID, for RSS 1.0 this is the URI attribute of the item. The Link * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
* is the URL that the item is accessible under, the URI is the * the URL that the item is accessible under, the URI is the permanent
* permanent identifier which the aggregator should use to reference * identifier which the aggregator should use to reference this item. Often
* this item. Often the URI will use some standardized identifier scheme * the URI will use some standardized identifier scheme such as DOI's so
* such as DOI's so that items can be identified even if they appear in * that items can be identified even if they appear in multiple feeds with
* multiple feeds with different "links" (they might be on different * different "links" (they might be on different hosting platforms but be
* hosting platforms but be the same item). Also, though rare, there * the same item). Also, though rare, there could be multiple items with the
* could be multiple items with the same link but a different URI and * same link but a different URI and associated metadata which need to be
* associated metadata which need to be treated as distinct entities. * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
* In the RSS 1.0 case the URI must be a valid RDF URI reference. * RDF URI reference.
* <p> * <p>
*
* @param uri the feed URI to set, <b>null</b> if none. * @param uri the feed URI to set, <b>null</b> if none.
* *
*/ */
void setUri(String uri); void setUri(String uri);
/** /**
* Returns the feed title. * Returns the feed title.
* <p> * <p>
*
* @return the feed title, <b>null</b> if none. * @return the feed title, <b>null</b> if none.
* *
*/ */
String getTitle(); String getTitle();
/** /**
* Sets the feed title. * Sets the feed title.
* <p> * <p>
*
* @param title the feed title to set, <b>null</b> if none. * @param title the feed title to set, <b>null</b> if none.
* *
*/ */
void setTitle(String title); void setTitle(String title);
/** /**
* Returns the feed title. * Returns the feed title.
* <p> * <p>
*
* @return the feed title, <b>null</b> if none. * @return the feed title, <b>null</b> if none.
* *
*/ */
SyndContent getTitleEx(); SyndContent getTitleEx();
/** /**
* Sets the feed title. * Sets the feed title.
* <p> * <p>
*
* @param title the feed title to set, <b>null</b> if none. * @param title the feed title to set, <b>null</b> if none.
* *
*/ */
void setTitleEx(SyndContent title); void setTitleEx(SyndContent title);
@ -195,19 +219,20 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* Returns the feed link. * Returns the feed link.
* <p> * <p>
* Note: The URI is the unique identifier, in the RSS 2.0/atom case this is * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
* the GUID, for RSS 1.0 this is the URI attribute of the item. The Link * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
* is the URL that the item is accessible under, the URI is the * the URL that the item is accessible under, the URI is the permanent
* permanent identifier which the aggregator should use to reference * identifier which the aggregator should use to reference this item. Often
* this item. Often the URI will use some standardized identifier scheme * the URI will use some standardized identifier scheme such as DOI's so
* such as DOI's so that items can be identified even if they appear in * that items can be identified even if they appear in multiple feeds with
* multiple feeds with different "links" (they might be on different * different "links" (they might be on different hosting platforms but be
* hosting platforms but be the same item). Also, though rare, there * the same item). Also, though rare, there could be multiple items with the
* could be multiple items with the same link but a different URI and * same link but a different URI and associated metadata which need to be
* associated metadata which need to be treated as distinct entities. * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
* In the RSS 1.0 case the URI must be a valid RDF URI reference. * RDF URI reference.
* <p> * <p>
*
* @return the feed link, <b>null</b> if none. * @return the feed link, <b>null</b> if none.
* *
*/ */
String getLink(); String getLink();
@ -215,87 +240,98 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* Sets the feed link. * Sets the feed link.
* <p> * <p>
* Note: The URI is the unique identifier, in the RSS 2.0/atom case this is * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
* the GUID, for RSS 1.0 this is the URI attribute of the item. The Link * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
* is the URL that the item is accessible under, the URI is the * the URL that the item is accessible under, the URI is the permanent
* permanent identifier which the aggregator should use to reference * identifier which the aggregator should use to reference this item. Often
* this item. Often the URI will use some standardized identifier scheme * the URI will use some standardized identifier scheme such as DOI's so
* such as DOI's so that items can be identified even if they appear in * that items can be identified even if they appear in multiple feeds with
* multiple feeds with different "links" (they might be on different * different "links" (they might be on different hosting platforms but be
* hosting platforms but be the same item). Also, though rare, there * the same item). Also, though rare, there could be multiple items with the
* could be multiple items with the same link but a different URI and * same link but a different URI and associated metadata which need to be
* associated metadata which need to be treated as distinct entities. * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
* In the RSS 1.0 case the URI must be a valid RDF URI reference. * RDF URI reference.
* <p> * <p>
*
* @param link the feed link to set, <b>null</b> if none. * @param link the feed link to set, <b>null</b> if none.
* *
*/ */
void setLink(String link); void setLink(String link);
/** /**
* Returns the entry links * Returns the entry links
* <p> * <p>
*
* @return the entry links, <b>null</b> if none. * @return the entry links, <b>null</b> if none.
* *
*/ */
List<SyndLink> getLinks(); List<SyndLink> getLinks();
/** /**
* Sets the entry links. * Sets the entry links.
* <p> * <p>
*
* @param links the entry links to set, <b>null</b> if none. * @param links the entry links to set, <b>null</b> if none.
* *
*/ */
void setLinks(List<SyndLink> links); void setLinks(List<SyndLink> links);
/** /**
* Returns the feed description. * Returns the feed description.
* <p> * <p>
*
* @return the feed description, <b>null</b> if none. * @return the feed description, <b>null</b> if none.
* *
*/ */
String getDescription(); String getDescription();
/** /**
* Sets the feed description. * Sets the feed description.
* <p> * <p>
*
* @param description the feed description to set, <b>null</b> if none. * @param description the feed description to set, <b>null</b> if none.
* *
*/ */
void setDescription(String description); void setDescription(String description);
/** /**
* Returns the feed description as a text construct. * Returns the feed description as a text construct.
* <p> * <p>
*
* @return the feed description, <b>null</b> if none. * @return the feed description, <b>null</b> if none.
* *
*/ */
SyndContent getDescriptionEx(); SyndContent getDescriptionEx();
/** /**
* Sets the feed description as a text construct. * Sets the feed description as a text construct.
* <p> * <p>
*
* @param description the feed description to set, <b>null</b> if none. * @param description the feed description to set, <b>null</b> if none.
* *
*/ */
void setDescriptionEx(SyndContent description); void setDescriptionEx(SyndContent description);
/** /**
* Returns the feed published date. * Returns the feed published date.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module date. * This method is a convenience method, it maps to the Dublin Core module
* date.
* <p> * <p>
*
* @return the feed published date, <b>null</b> if none. * @return the feed published date, <b>null</b> if none.
* *
*/ */
Date getPublishedDate(); Date getPublishedDate();
/** /**
* Sets the feed published date. * Sets the feed published date.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module date. * This method is a convenience method, it maps to the Dublin Core module
* date.
* <p> * <p>
*
* @param publishedDate the feed published date to set, <b>null</b> if none. * @param publishedDate the feed published date to set, <b>null</b> if none.
* *
*/ */
void setPublishedDate(Date publishedDate); void setPublishedDate(Date publishedDate);
@ -303,23 +339,25 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* Returns the feed authors. * Returns the feed authors.
* <p> * <p>
* For Atom feeds, this returns the authors as a list of SyndPerson objects, * For Atom feeds, this returns the authors as a list of SyndPerson objects,
* for RSS feeds this method is a convenience method, it maps to the * for RSS feeds this method is a convenience method, it maps to the Dublin
* Dublin Core module creator. * Core module creator.
* <p> * <p>
*
* @return the feed authors, <b>null</b> if none. * @return the feed authors, <b>null</b> if none.
* *
*/ */
List<SyndPerson> getAuthors(); List<SyndPerson> getAuthors();
/** /**
* Sets the feed authors. * Sets the feed authors.
* <p> * <p>
* For Atom feeds, this sets the authors as a list of SyndPerson * For Atom feeds, this sets the authors as a list of SyndPerson objects,
* objects, for RSS feeds this method is a convenience method, it maps * for RSS feeds this method is a convenience method, it maps to the Dublin
* to the Dublin Core module creator. * Core module creator.
* <p> * <p>
*
* @param authors the feed authors to set, <b>null</b> if none. * @param authors the feed authors to set, <b>null</b> if none.
* *
*/ */
void setAuthors(List<SyndPerson> authors); void setAuthors(List<SyndPerson> authors);
@ -327,34 +365,37 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* Returns the name of the first feed author in the collection of authors. * Returns the name of the first feed author in the collection of authors.
* <p> * <p>
* For Atom feeds, this returns the authors as a list of SyndPerson objects, * For Atom feeds, this returns the authors as a list of SyndPerson objects,
* for RSS feeds this method is a convenience method, it maps to the * for RSS feeds this method is a convenience method, it maps to the Dublin
* Dublin Core module creator. * Core module creator.
* <p> * <p>
*
* @return the feed author, <b>null</b> if none. * @return the feed author, <b>null</b> if none.
* *
*/ */
String getAuthor(); String getAuthor();
/** /**
* Sets the feed author. * Sets the feed author.
* <p> * <p>
* For Atom feeds, this sets the feed author's name, for RSS feeds * For Atom feeds, this sets the feed author's name, for RSS feeds this
* this method is a convenience method, it maps to the Dublin Core * method is a convenience method, it maps to the Dublin Core module
* module creator. * creator.
* <p> * <p>
*
* @param author the feed author to set, <b>null</b> if none. * @param author the feed author to set, <b>null</b> if none.
* *
*/ */
void setAuthor(String author); void setAuthor(String author);
/** /**
* Returns the feed author. * Returns the feed author.
* <p> * <p>
* For Atom feeds, this returns the contributors as a list of * For Atom feeds, this returns the contributors as a list of SyndPerson
* SyndPerson objects * objects
* <p> * <p>
*
* @return the feed author, <b>null</b> if none. * @return the feed author, <b>null</b> if none.
* *
*/ */
public List<SyndPerson> getContributors(); public List<SyndPerson> getContributors();
@ -363,155 +404,182 @@ public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
* <p> * <p>
* Returns contributors as a list of SyndPerson objects. * Returns contributors as a list of SyndPerson objects.
* <p> * <p>
*
* @param contributors the feed contributors to set, <b>null</b> if none. * @param contributors the feed contributors to set, <b>null</b> if none.
* *
*/ */
void setContributors(List<SyndPerson> contributors); void setContributors(List<SyndPerson> contributors);
/** /**
* Returns the feed copyright. * Returns the feed copyright.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module rights. * This method is a convenience method, it maps to the Dublin Core module
* rights.
* <p> * <p>
*
* @return the feed copyright, <b>null</b> if none. * @return the feed copyright, <b>null</b> if none.
* *
*/ */
String getCopyright(); String getCopyright();
/** /**
* Sets the feed copyright. * Sets the feed copyright.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module rights. * This method is a convenience method, it maps to the Dublin Core module
* rights.
* <p> * <p>
*
* @param copyright the feed copyright to set, <b>null</b> if none. * @param copyright the feed copyright to set, <b>null</b> if none.
* *
*/ */
void setCopyright(String copyright); void setCopyright(String copyright);
/** /**
* Returns the feed image. * Returns the feed image.
* <p> * <p>
*
* @return the feed image, <b>null</b> if none. * @return the feed image, <b>null</b> if none.
* *
*/ */
SyndImage getImage(); SyndImage getImage();
/** /**
* Sets the feed image. * Sets the feed image.
* <p> * <p>
*
* @param image the feed image to set, <b>null</b> if none. * @param image the feed image to set, <b>null</b> if none.
* *
*/ */
void setImage(SyndImage image); void setImage(SyndImage image);
/** /**
* Returns the feed categories. * Returns the feed categories.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module subjects. * This method is a convenience method, it maps to the Dublin Core module
* subjects.
* <p> * <p>
* @return a list of SyndCategoryImpl elements with the feed categories, *
* an empty list if none. * @return a list of SyndCategoryImpl elements with the feed categories, an
* * empty list if none.
*
*/ */
List<SyndCategory> getCategories(); List<SyndCategory> getCategories();
/** /**
* Sets the feed categories. * Sets the feed categories.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module subjects. * This method is a convenience method, it maps to the Dublin Core module
* subjects.
* <p> * <p>
* @param categories the list of SyndCategoryImpl elements with the feed categories to set, *
* an empty list or <b>null</b> if none. * @param categories the list of SyndCategoryImpl elements with the feed
* * categories to set, an empty list or <b>null</b> if none.
*
*/ */
void setCategories(List<SyndCategory> categories); void setCategories(List<SyndCategory> categories);
/** /**
* Returns the feed entries. * Returns the feed entries.
* <p> * <p>
* @return a list of SyndEntry elements with the feed entries, *
* an empty list if none. * @return a list of SyndEntry elements with the feed entries, an empty list
* * if none.
*
*/ */
List<SyndEntry> getEntries(); List<SyndEntry> getEntries();
/** /**
* Sets the feed entries. * Sets the feed entries.
* <p> * <p>
* @param entries the list of SyndEntryImpl elements with the feed entries to set, *
* an empty list or <b>null</b> if none. * @param entries the list of SyndEntryImpl elements with the feed entries
* * to set, an empty list or <b>null</b> if none.
*
*/ */
void setEntries(List<SyndEntry> entries); void setEntries(List<SyndEntry> entries);
/** /**
* Returns the feed language. * Returns the feed language.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module language. * This method is a convenience method, it maps to the Dublin Core module
* language.
* <p> * <p>
*
* @return the feed language, <b>null</b> if none. * @return the feed language, <b>null</b> if none.
* *
*/ */
String getLanguage(); String getLanguage();
/** /**
* Sets the feed language. * Sets the feed language.
* <p> * <p>
* This method is a convenience method, it maps to the Dublin Core module language. * This method is a convenience method, it maps to the Dublin Core module
* language.
* <p> * <p>
*
* @param language the feed language to set, <b>null</b> if none. * @param language the feed language to set, <b>null</b> if none.
* *
*/ */
void setLanguage(String language); void setLanguage(String language);
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
@Override
public Module getModule(String uri); public Module getModule(String uri);
/** /**
* Returns the feed modules. * Returns the feed modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the feed modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the feed modules, an empty
* * list if none.
*
*/ */
@Override
List<Module> getModules(); List<Module> getModules();
/** /**
* Sets the feed modules. * Sets the feed modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the feed modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the feed modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
@Override
void setModules(List<Module> modules); void setModules(List<Module> modules);
/** /**
* Returns foreign markup found at channel level. * Returns foreign markup found at channel level.
* <p> * <p>
*
* @return Opaque object to discourage use * @return Opaque object to discourage use
* *
*/ */
public List<Element> getForeignMarkup(); public List<Element> getForeignMarkup();
/** /**
* Sets foreign markup found at channel level. * Sets foreign markup found at channel level.
* <p> * <p>
*
* @param foreignMarkup Opaque object to discourage use * @param foreignMarkup Opaque object to discourage use
* *
*/ */
public void setForeignMarkup(List<Element> foreignMarkup); public void setForeignMarkup(List<Element> foreignMarkup);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

File diff suppressed because it is too large Load diff

View file

@ -22,80 +22,91 @@ import com.sun.syndication.feed.CopyFrom;
/** /**
* Bean interface for images of SyndFeedImpl feeds. * Bean interface for images of SyndFeedImpl feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface SyndImage extends Cloneable,CopyFrom { public interface SyndImage extends Cloneable, CopyFrom {
/** /**
* Returns the image title. * Returns the image title.
* <p> * <p>
*
* @return the image title, <b>null</b> if none. * @return the image title, <b>null</b> if none.
* *
*/ */
String getTitle(); String getTitle();
/** /**
* Sets the image title. * Sets the image title.
* <p> * <p>
*
* @param title the image title to set, <b>null</b> if none. * @param title the image title to set, <b>null</b> if none.
* *
*/ */
void setTitle(String title); void setTitle(String title);
/** /**
* Returns the image URL. * Returns the image URL.
* <p> * <p>
*
* @return the image URL, <b>null</b> if none. * @return the image URL, <b>null</b> if none.
* *
*/ */
String getUrl(); String getUrl();
/** /**
* Sets the image URL. * Sets the image URL.
* <p> * <p>
*
* @param url the image URL to set, <b>null</b> if none. * @param url the image URL to set, <b>null</b> if none.
* *
*/ */
void setUrl(String url); void setUrl(String url);
/** /**
* Returns the image link. * Returns the image link.
* <p> * <p>
*
* @return the image link, <b>null</b> if none. * @return the image link, <b>null</b> if none.
* *
*/ */
String getLink(); String getLink();
/** /**
* Sets the image link. * Sets the image link.
* <p> * <p>
*
* @param link the image link to set, <b>null</b> if none. * @param link the image link to set, <b>null</b> if none.
* *
*/ */
void setLink(String link); void setLink(String link);
/** /**
* Returns the image description. * Returns the image description.
* <p> * <p>
*
* @return the image description, <b>null</b> if none. * @return the image description, <b>null</b> if none.
* *
*/ */
String getDescription(); String getDescription();
/** /**
* Sets the image description. * Sets the image description.
* <p> * <p>
*
* @param description the image description to set, <b>null</b> if none. * @param description the image description to set, <b>null</b> if none.
* *
*/ */
void setDescription(String description); void setDescription(String description);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

View file

@ -16,23 +16,24 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.io.Serializable;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Bean for images of SyndFeedImpl feeds. * Bean for images of SyndFeedImpl feeds.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyndImageImpl implements Serializable,SyndImage { public class SyndImageImpl implements Serializable, SyndImage {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _title; private String _title;
private String _url; private String _url;
private String _link; private String _link;
@ -41,32 +42,38 @@ public class SyndImageImpl implements Serializable,SyndImage {
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyndImageImpl() { public SyndImageImpl() {
_objBean = new ObjectBean(SyndImage.class,this); this._objBean = new ObjectBean(SyndImage.class, this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
public boolean equals(Object other) { @Override
return _objBean.equals(other); public boolean equals(final Object other) {
return this._objBean.equals(other);
} }
/** /**
@ -74,123 +81,145 @@ public class SyndImageImpl implements Serializable,SyndImage {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the image title. * Returns the image title.
* <p> * <p>
*
* @return the image title, <b>null</b> if none. * @return the image title, <b>null</b> if none.
* *
*/ */
@Override
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the image title. * Sets the image title.
* <p> * <p>
*
* @param title the image title to set, <b>null</b> if none. * @param title the image title to set, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { @Override
_title = title; public void setTitle(final String title) {
this._title = title;
} }
/** /**
* Returns the image URL. * Returns the image URL.
* <p> * <p>
*
* @return the image URL, <b>null</b> if none. * @return the image URL, <b>null</b> if none.
* *
*/ */
@Override
public String getUrl() { public String getUrl() {
return _url; return this._url;
} }
/** /**
* Sets the image URL. * Sets the image URL.
* <p> * <p>
*
* @param url the image URL to set, <b>null</b> if none. * @param url the image URL to set, <b>null</b> if none.
* *
*/ */
public void setUrl(String url) { @Override
_url = url; public void setUrl(final String url) {
this._url = url;
} }
/** /**
* Returns the image link. * Returns the image link.
* <p> * <p>
*
* @return the image link, <b>null</b> if none. * @return the image link, <b>null</b> if none.
* *
*/ */
@Override
public String getLink() { public String getLink() {
return _link; return this._link;
} }
/** /**
* Sets the image link. * Sets the image link.
* <p> * <p>
*
* @param link the image link to set, <b>null</b> if none. * @param link the image link to set, <b>null</b> if none.
* *
*/ */
public void setLink(String link) { @Override
_link = link; public void setLink(final String link) {
this._link = link;
} }
/** /**
* Returns the image description. * Returns the image description.
* <p> * <p>
*
* @return the image description, <b>null</b> if none. * @return the image description, <b>null</b> if none.
* *
*/ */
@Override
public String getDescription() { public String getDescription() {
return _description; return this._description;
} }
/** /**
* Sets the image description. * Sets the image description.
* <p> * <p>
*
* @param description the image description to set, <b>null</b> if none. * @param description the image description to set, <b>null</b> if none.
* *
*/ */
public void setDescription(String description) { @Override
_description = description; public void setDescription(final String description) {
this._description = description;
} }
@Override
public Class getInterface() { public Class getInterface() {
return SyndImage.class; return SyndImage.class;
} }
public void copyFrom(CopyFrom syndImage) { @Override
COPY_FROM_HELPER.copy(this,syndImage); public void copyFrom(final CopyFrom syndImage) {
COPY_FROM_HELPER.copy(this, syndImage);
} }
private static final CopyFromHelper COPY_FROM_HELPER; private static final CopyFromHelper COPY_FROM_HELPER;
static { static {
Map basePropInterfaceMap = new HashMap(); final Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("title",String.class); basePropInterfaceMap.put("title", String.class);
basePropInterfaceMap.put("url",String.class); basePropInterfaceMap.put("url", String.class);
basePropInterfaceMap.put("link",String.class); basePropInterfaceMap.put("link", String.class);
basePropInterfaceMap.put("description",String.class); basePropInterfaceMap.put("description", String.class);
Map basePropClassImplMap = Collections.EMPTY_MAP; final Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyndImage.class,basePropInterfaceMap,basePropClassImplMap); COPY_FROM_HELPER = new CopyFromHelper(SyndImage.class, basePropInterfaceMap, basePropClassImplMap);
} }
} }

View file

@ -19,24 +19,29 @@ package com.sun.syndication.feed.synd;
/** /**
* Represents a link or enclosure associated with entry. * Represents a link or enclosure associated with entry.
*
* @author Dave Johnson * @author Dave Johnson
*/ */
public interface SyndLink { public interface SyndLink {
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public abstract Object clone() throws CloneNotSupportedException; public abstract Object clone() throws CloneNotSupportedException;
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public abstract boolean equals(Object other); public abstract boolean equals(Object other);
@ -46,8 +51,9 @@ public interface SyndLink {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public abstract int hashCode(); public abstract int hashCode();
@ -55,8 +61,9 @@ public interface SyndLink {
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public abstract String toString(); public abstract String toString();
@ -64,70 +71,79 @@ public interface SyndLink {
/** /**
* Returns the link rel. * Returns the link rel.
* <p> * <p>
*
* @return the link rel, <b>null</b> if none. * @return the link rel, <b>null</b> if none.
* *
*/ */
public abstract String getRel(); public abstract String getRel();
/** /**
* Sets the link rel. * Sets the link rel.
* <p> * <p>
*
* @param rel the link rel,, <b>null</b> if none. * @param rel the link rel,, <b>null</b> if none.
* *
*/ */
public abstract void setRel(String rel); public abstract void setRel(String rel);
/** /**
* Returns the link type. * Returns the link type.
* <p> * <p>
*
* @return the link type, <b>null</b> if none. * @return the link type, <b>null</b> if none.
* *
*/ */
public abstract String getType(); public abstract String getType();
/** /**
* Sets the link type. * Sets the link type.
* <p> * <p>
*
* @param type the link type, <b>null</b> if none. * @param type the link type, <b>null</b> if none.
* *
*/ */
public abstract void setType(String type); public abstract void setType(String type);
/** /**
* Returns the link href. * Returns the link href.
* <p> * <p>
*
* @return the link href, <b>null</b> if none. * @return the link href, <b>null</b> if none.
* *
*/ */
public abstract String getHref(); public abstract String getHref();
/** /**
* Sets the link href. * Sets the link href.
* <p> * <p>
*
* @param href the link href, <b>null</b> if none. * @param href the link href, <b>null</b> if none.
* *
*/ */
public abstract void setHref(String href); public abstract void setHref(String href);
/** /**
* Returns the link title. * Returns the link title.
* <p> * <p>
*
* @return the link title, <b>null</b> if none. * @return the link title, <b>null</b> if none.
* *
*/ */
public abstract String getTitle(); public abstract String getTitle();
/** /**
* Sets the link title. * Sets the link title.
* <p> * <p>
*
* @param title the link title, <b>null</b> if none. * @param title the link title, <b>null</b> if none.
* *
*/ */
public abstract void setTitle(String title); public abstract void setTitle(String title);
/** /**
* Returns the hreflang * Returns the hreflang
* <p> * <p>
*
* @return Returns the hreflang. * @return Returns the hreflang.
*/ */
public abstract String getHreflang(); public abstract String getHreflang();
@ -135,6 +151,7 @@ public interface SyndLink {
/** /**
* Set the hreflang * Set the hreflang
* <p> * <p>
*
* @param hreflang The hreflang to set. * @param hreflang The hreflang to set.
*/ */
public abstract void setHreflang(String hreflang); public abstract void setHreflang(String hreflang);
@ -142,6 +159,7 @@ public interface SyndLink {
/** /**
* Returns the length * Returns the length
* <p> * <p>
*
* @return Returns the length. * @return Returns the length.
*/ */
public abstract long getLength(); public abstract long getLength();
@ -149,6 +167,7 @@ public interface SyndLink {
/** /**
* Set the length * Set the length
* <p> * <p>
*
* @param length The length to set. * @param length The length to set.
*/ */
public abstract void setLength(long length); public abstract void setLength(long length);

View file

@ -17,61 +17,66 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable; import java.io.Serializable;
import com.sun.syndication.feed.impl.ObjectBean;
/** /**
* Represents a link or an enclosure. * Represents a link or an enclosure.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
*/ */
public class SyndLinkImpl implements Cloneable,Serializable, SyndLink { public class SyndLinkImpl implements Cloneable, Serializable, SyndLink {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _href; private String _href;
private String _rel; private String _rel;
private String _type; private String _type;
private String _hreflang; private String _hreflang;
private String _title; private String _title;
private long _length; private long _length;
/** /**
* Default constructor. All properties are set to <b>null</b>. * Default constructor. All properties are set to <b>null</b>.
* <p> * <p>
* *
*/ */
public SyndLinkImpl() { public SyndLinkImpl() {
_objBean = new ObjectBean(this.getClass(),this); this._objBean = new ObjectBean(this.getClass(), this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof SyndLinkImpl)){ if (!(other instanceof SyndLinkImpl)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -79,139 +84,165 @@ public class SyndLinkImpl implements Cloneable,Serializable, SyndLink {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the link rel. * Returns the link rel.
* <p> * <p>
*
* @return the link rel, <b>null</b> if none. * @return the link rel, <b>null</b> if none.
* *
*/ */
@Override
public String getRel() { public String getRel() {
return _rel; return this._rel;
} }
/** /**
* Sets the link rel. * Sets the link rel.
* <p> * <p>
*
* @param rel the link rel,, <b>null</b> if none. * @param rel the link rel,, <b>null</b> if none.
* *
*/ */
public void setRel(String rel) { @Override
//TODO add check, ask P@ about the check public void setRel(final String rel) {
_rel = rel; // TODO add check, ask P@ about the check
this._rel = rel;
} }
/** /**
* Returns the link type. * Returns the link type.
* <p> * <p>
*
* @return the link type, <b>null</b> if none. * @return the link type, <b>null</b> if none.
* *
*/ */
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
/** /**
* Sets the link type. * Sets the link type.
* <p> * <p>
*
* @param type the link type, <b>null</b> if none. * @param type the link type, <b>null</b> if none.
* *
*/ */
public void setType(String type) { @Override
_type = type; public void setType(final String type) {
this._type = type;
} }
/** /**
* Returns the link href. * Returns the link href.
* <p> * <p>
*
* @return the link href, <b>null</b> if none. * @return the link href, <b>null</b> if none.
* *
*/ */
@Override
public String getHref() { public String getHref() {
return _href; return this._href;
} }
/** /**
* Sets the link href. * Sets the link href.
* <p> * <p>
*
* @param href the link href, <b>null</b> if none. * @param href the link href, <b>null</b> if none.
* *
*/ */
public void setHref(String href) { @Override
_href = href; public void setHref(final String href) {
this._href = href;
} }
/** /**
* Returns the link title. * Returns the link title.
* <p> * <p>
*
* @return the link title, <b>null</b> if none. * @return the link title, <b>null</b> if none.
* *
*/ */
@Override
public String getTitle() { public String getTitle() {
return _title; return this._title;
} }
/** /**
* Sets the link title. * Sets the link title.
* <p> * <p>
*
* @param title the link title, <b>null</b> if none. * @param title the link title, <b>null</b> if none.
* *
*/ */
public void setTitle(String title) { @Override
_title = title; public void setTitle(final String title) {
this._title = title;
} }
/** /**
* Returns the hreflang * Returns the hreflang
* <p> * <p>
*
* @return Returns the hreflang. * @return Returns the hreflang.
*/ */
@Override
public String getHreflang() { public String getHreflang() {
return _hreflang; return this._hreflang;
} }
/** /**
* Set the hreflang * Set the hreflang
* <p> * <p>
*
* @param hreflang The hreflang to set. * @param hreflang The hreflang to set.
*/ */
public void setHreflang(String hreflang) { @Override
_hreflang = hreflang; public void setHreflang(final String hreflang) {
this._hreflang = hreflang;
} }
/** /**
* Returns the length * Returns the length
* <p> * <p>
*
* @return Returns the length. * @return Returns the length.
*/ */
@Override
public long getLength() { public long getLength() {
return _length; return this._length;
} }
/** /**
* Set the length * Set the length
* <p> * <p>
*
* @param length The length to set. * @param length The length to set.
*/ */
public void setLength(long length) { @Override
_length = length; public void setLength(final long length) {
this._length = length;
} }
} }

View file

@ -20,51 +20,53 @@ package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.module.Extendable; import com.sun.syndication.feed.module.Extendable;
/** /**
* Bean interface for authors and contributors of SyndFeedImpl feeds and entries. * Bean interface for authors and contributors of SyndFeedImpl feeds and
* entries.
* <p> * <p>
*
* @author Dave Johnson * @author Dave Johnson
* *
*/ */
public interface SyndPerson extends Cloneable, Extendable public interface SyndPerson extends Cloneable, Extendable {
{
/** /**
* Returns name of person * Returns name of person
*/ */
public String getName(); public String getName();
/** /**
* Sets name of person. * Sets name of person.
*/ */
public void setName(String name); public void setName(String name);
/** /**
* Returns URI of person. * Returns URI of person.
*/ */
public String getUri(); public String getUri();
/** /**
* Sets URI of person. * Sets URI of person.
*/ */
public void setUri(String uri); public void setUri(String uri);
/** /**
* Returns email of person. * Returns email of person.
*/ */
public String getEmail(); public String getEmail();
/** /**
* Sets email of person. * Sets email of person.
*/ */
public void setEmail(String email); public void setEmail(String email);
/** /**
* Creates a deep clone of the object. * Creates a deep clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
public Object clone() throws CloneNotSupportedException; public Object clone() throws CloneNotSupportedException;

View file

@ -17,60 +17,65 @@
*/ */
package com.sun.syndication.feed.synd; package com.sun.syndication.feed.synd;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.sun.syndication.feed.impl.ObjectBean; import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils; import com.sun.syndication.feed.module.impl.ModuleUtils;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
/** /**
* Bean for authors and contributors of SyndFeedImpl feeds and entries. * Bean for authors and contributors of SyndFeedImpl feeds and entries.
* <p> * <p>
*
* @author Dave Johnson * @author Dave Johnson
* *
*/ */
public class SyndPersonImpl implements Serializable, SyndPerson { public class SyndPersonImpl implements Serializable, SyndPerson {
private ObjectBean _objBean; private final ObjectBean _objBean;
private String _name; private String _name;
private String _uri; private String _uri;
private String _email; private String _email;
private List<Module> _modules; private List<Module> _modules;
/** /**
* For implementations extending SyndContentImpl to be able to use the ObjectBean functionality * For implementations extending SyndContentImpl to be able to use the
* with extended interfaces. * ObjectBean functionality with extended interfaces.
*/ */
public SyndPersonImpl() { public SyndPersonImpl() {
_objBean = new ObjectBean(SyndPerson.class,this); this._objBean = new ObjectBean(SyndPerson.class, this);
} }
/** /**
* Creates a deep 'bean' clone of the object. * Creates a deep 'bean' clone of the object.
* <p> * <p>
*
* @return a clone of the object. * @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned. * @throws CloneNotSupportedException thrown if an element of the object
* * cannot be cloned.
*
*/ */
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return _objBean.clone(); return this._objBean.clone();
} }
/** /**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method. * Indicates whether some other object is "equal to" this one as defined by
* the Object equals() method.
* <p> * <p>
*
* @param other he reference object with which to compare. * @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object. * @return <b>true</b> if 'this' object is equal to the 'other' object.
* *
*/ */
@Override @Override
public boolean equals(Object other) { public boolean equals(final Object other) {
if(!(other instanceof SyndPersonImpl)){ if (!(other instanceof SyndPersonImpl)) {
return false; return false;
} }
return _objBean.equals(other); return this._objBean.equals(other);
} }
/** /**
@ -78,117 +83,136 @@ public class SyndPersonImpl implements Serializable, SyndPerson {
* <p> * <p>
* It follows the contract defined by the Object hashCode() method. * It follows the contract defined by the Object hashCode() method.
* <p> * <p>
*
* @return the hashcode of the bean object. * @return the hashcode of the bean object.
* *
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return _objBean.hashCode(); return this._objBean.hashCode();
} }
/** /**
* Returns the String representation for the object. * Returns the String representation for the object.
* <p> * <p>
*
* @return String representation for the object. * @return String representation for the object.
* *
*/ */
@Override @Override
public String toString() { public String toString() {
return _objBean.toString(); return this._objBean.toString();
} }
/** /**
* Returns the person name. * Returns the person name.
* <p> * <p>
*
* @return the person name, <b>null</b> if none. * @return the person name, <b>null</b> if none.
* *
*/ */
@Override
public String getName() { public String getName() {
return _name; return this._name;
} }
/** /**
* Sets the category name. * Sets the category name.
* <p> * <p>
*
* @param name the category name to set, <b>null</b> if none. * @param name the category name to set, <b>null</b> if none.
* *
*/ */
public void setName(String name) { @Override
_name = name; public void setName(final String name) {
this._name = name;
} }
/** /**
* Returns the person's e-mail address. * Returns the person's e-mail address.
* <p> * <p>
*
* @return the person's e-mail address, <b>null</b> if none. * @return the person's e-mail address, <b>null</b> if none.
* *
*/ */
@Override
public String getEmail() { public String getEmail() {
return _email; return this._email;
} }
/** /**
* Sets the person's e-mail address. * Sets the person's e-mail address.
* <p> * <p>
*
* @param email The person's e-mail address to set, <b>null</b> if none. * @param email The person's e-mail address to set, <b>null</b> if none.
* *
*/ */
public void setEmail(String email) { @Override
_email = email; public void setEmail(final String email) {
this._email = email;
} }
/** /**
* Returns the person's URI. * Returns the person's URI.
* <p> * <p>
*
* @return the person's URI, <b>null</b> if none. * @return the person's URI, <b>null</b> if none.
* *
*/ */
@Override
public String getUri() { public String getUri() {
return _uri; return this._uri;
} }
/** /**
* Sets the person's URI. * Sets the person's URI.
* <p> * <p>
*
* @param uri the peron's URI to set, <b>null</b> if none. * @param uri the peron's URI to set, <b>null</b> if none.
* *
*/ */
public void setUri(String uri) { @Override
_uri = uri; public void setUri(final String uri) {
this._uri = uri;
} }
/** /**
* Returns the person modules. * Returns the person modules.
* <p> * <p>
* @return a list of ModuleImpl elements with the person modules, *
* an empty list if none. * @return a list of ModuleImpl elements with the person modules, an empty
* list if none.
*/ */
public List<Module> getModules() @Override
{ public List<Module> getModules() {
if (_modules==null) { if (this._modules == null) {
_modules=new ArrayList<Module>(); this._modules = new ArrayList<Module>();
} }
return _modules; return this._modules;
} }
/** /**
* Sets the person modules. * Sets the person modules.
* <p> * <p>
* @param modules the list of ModuleImpl elements with the person modules to set, *
* an empty list or <b>null</b> if none. * @param modules the list of ModuleImpl elements with the person modules to
* * set, an empty list or <b>null</b> if none.
*
*/ */
public void setModules(List<Module> modules) { @Override
_modules = modules; public void setModules(final List<Module> modules) {
this._modules = modules;
} }
/** /**
* Returns the module identified by a given URI. * Returns the module identified by a given URI.
* <p> * <p>
*
* @param uri the URI of the ModuleImpl. * @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none. * @return The module with the given URI, <b>null</b> if none.
*/ */
public Module getModule(String uri) { @Override
return ModuleUtils.getModule(getModules(),uri); public Module getModule(final String uri) {
return ModuleUtils.getModule(getModules(), uri);
} }
} }

View file

@ -17,6 +17,10 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Content; import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry; import com.sun.syndication.feed.atom.Entry;
@ -24,52 +28,47 @@ import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link; import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Person; import com.sun.syndication.feed.atom.Person;
import com.sun.syndication.feed.module.impl.ModuleUtils; import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.Converter; import com.sun.syndication.feed.synd.Converter;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEnclosure; import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl; import com.sun.syndication.feed.synd.SyndEnclosureImpl;
import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntryImpl; import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndLink; import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl; import com.sun.syndication.feed.synd.SyndLinkImpl;
import com.sun.syndication.feed.synd.SyndPerson; import com.sun.syndication.feed.synd.SyndPerson;
import com.sun.syndication.feed.synd.SyndPersonImpl; import com.sun.syndication.feed.synd.SyndPersonImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Iterator;
import org.jdom2.Element;
/** /**
*/ */
public class ConverterForAtom03 implements Converter { public class ConverterForAtom03 implements Converter {
private String _type; private final String _type;
public ConverterForAtom03() { public ConverterForAtom03() {
this("atom_0.3"); this("atom_0.3");
} }
protected ConverterForAtom03(String type) { protected ConverterForAtom03(final String type) {
_type = type; this._type = type;
} }
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
public void copyInto(WireFeed feed,SyndFeed syndFeed) { @Override
Feed aFeed = (Feed) feed; public void copyInto(final WireFeed feed, final SyndFeed syndFeed) {
final Feed aFeed = (Feed) feed;
syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules())); syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules()));
if (((List<Element>)feed.getForeignMarkup()).size() > 0) { if (feed.getForeignMarkup().size() > 0) {
syndFeed.setForeignMarkup(feed.getForeignMarkup()); syndFeed.setForeignMarkup(feed.getForeignMarkup());
} }
syndFeed.setEncoding(aFeed.getEncoding()); syndFeed.setEncoding(aFeed.getEncoding());
syndFeed.setUri(aFeed.getId()); syndFeed.setUri(aFeed.getId());
@ -77,162 +76,154 @@ public class ConverterForAtom03 implements Converter {
syndFeed.setTitle(aFeed.getTitle()); syndFeed.setTitle(aFeed.getTitle());
// use first alternate links as THE link // use first alternate links as THE link
if (aFeed.getAlternateLinks() != null if (aFeed.getAlternateLinks() != null && aFeed.getAlternateLinks().size() > 0) {
&& aFeed.getAlternateLinks().size() > 0) { final Link theLink = aFeed.getAlternateLinks().get(0);
Link theLink = (Link)aFeed.getAlternateLinks().get(0);
syndFeed.setLink(theLink.getHrefResolved()); syndFeed.setLink(theLink.getHrefResolved());
} }
// lump alternate and other links together // lump alternate and other links together
List<SyndLink> syndLinks = new ArrayList<SyndLink>(); final List<SyndLink> syndLinks = new ArrayList<SyndLink>();
if (aFeed.getAlternateLinks() != null if (aFeed.getAlternateLinks() != null && aFeed.getAlternateLinks().size() > 0) {
&& aFeed.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks())); syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks()));
} }
if (aFeed.getOtherLinks() != null if (aFeed.getOtherLinks() != null && aFeed.getOtherLinks().size() > 0) {
&& aFeed.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks())); syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks()));
} }
syndFeed.setLinks(syndLinks); syndFeed.setLinks(syndLinks);
Content tagline = aFeed.getTagline(); final Content tagline = aFeed.getTagline();
if (tagline!=null) { if (tagline != null) {
syndFeed.setDescription(tagline.getValue()); syndFeed.setDescription(tagline.getValue());
} }
final List<Entry> aEntries = aFeed.getEntries();
List<Entry> aEntries = aFeed.getEntries(); if (aEntries != null) {
if (aEntries!=null) {
syndFeed.setEntries(createSyndEntries(aEntries, syndFeed.isPreservingWireFeed())); syndFeed.setEntries(createSyndEntries(aEntries, syndFeed.isPreservingWireFeed()));
} }
// Core Atom language/author/copyright/modified elements have precedence // Core Atom language/author/copyright/modified elements have precedence
// over DC equivalent info. // over DC equivalent info.
String language = aFeed.getLanguage(); final String language = aFeed.getLanguage();
if (language!=null) { if (language != null) {
syndFeed.setLanguage(language); syndFeed.setLanguage(language);
} }
List<Person> authors = aFeed.getAuthors(); final List<Person> authors = aFeed.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
syndFeed.setAuthors(createSyndPersons(authors)); syndFeed.setAuthors(createSyndPersons(authors));
} }
String copyright = aFeed.getCopyright(); final String copyright = aFeed.getCopyright();
if (copyright!=null) { if (copyright != null) {
syndFeed.setCopyright(copyright); syndFeed.setCopyright(copyright);
} }
Date date = aFeed.getModified(); final Date date = aFeed.getModified();
if (date!=null) { if (date != null) {
syndFeed.setPublishedDate(date); syndFeed.setPublishedDate(date);
} }
} }
protected List<SyndLink> createSyndLinks(List<Link> aLinks) { protected List<SyndLink> createSyndLinks(final List<Link> aLinks) {
ArrayList<SyndLink> sLinks = new ArrayList<SyndLink>(); final ArrayList<SyndLink> sLinks = new ArrayList<SyndLink>();
for (Iterator<Link> iter = aLinks.iterator(); iter.hasNext();) { for (final Link link2 : aLinks) {
Link link = (Link)iter.next(); final Link link = link2;
if (!link.getRel().equals("enclosure")) { if (!link.getRel().equals("enclosure")) {
SyndLink sLink = createSyndLink(link); final SyndLink sLink = createSyndLink(link);
sLinks.add(sLink); sLinks.add(sLink);
} }
} }
return sLinks; return sLinks;
} }
public SyndLink createSyndLink(Link link) { public SyndLink createSyndLink(final Link link) {
SyndLink syndLink = new SyndLinkImpl(); final SyndLink syndLink = new SyndLinkImpl();
syndLink.setRel( link.getRel()); syndLink.setRel(link.getRel());
syndLink.setType( link.getType()); syndLink.setType(link.getType());
syndLink.setHref( link.getHrefResolved()); syndLink.setHref(link.getHrefResolved());
syndLink.setTitle( link.getTitle()); syndLink.setTitle(link.getTitle());
return syndLink; return syndLink;
} }
protected List<SyndEntry> createSyndEntries(List<Entry> atomEntries, boolean preserveWireItems) { protected List<SyndEntry> createSyndEntries(final List<Entry> atomEntries, final boolean preserveWireItems) {
List<SyndEntry> syndEntries = new ArrayList<SyndEntry>(); final List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
for (int i=0;i<atomEntries.size();i++) { for (int i = 0; i < atomEntries.size(); i++) {
syndEntries.add(createSyndEntry((Entry) atomEntries.get(i), preserveWireItems)); syndEntries.add(createSyndEntry(atomEntries.get(i), preserveWireItems));
} }
return syndEntries; return syndEntries;
} }
protected SyndEntry createSyndEntry(Entry entry, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Entry entry, final boolean preserveWireItem) {
SyndEntryImpl syndEntry = new SyndEntryImpl(); final SyndEntryImpl syndEntry = new SyndEntryImpl();
if (preserveWireItem) { if (preserveWireItem) {
syndEntry.setWireEntry(entry); syndEntry.setWireEntry(entry);
} }
syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules())); syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules()));
if (((List<Element>)entry.getForeignMarkup()).size() > 0) { if (entry.getForeignMarkup().size() > 0) {
syndEntry.setForeignMarkup((List<Element>)entry.getForeignMarkup()); syndEntry.setForeignMarkup(entry.getForeignMarkup());
} }
syndEntry.setTitle(entry.getTitle()); syndEntry.setTitle(entry.getTitle());
// if there is exactly one alternate link, use that as THE link // if there is exactly one alternate link, use that as THE link
if (entry.getAlternateLinks() != null if (entry.getAlternateLinks() != null && entry.getAlternateLinks().size() == 1) {
&& entry.getAlternateLinks().size() == 1) { final Link theLink = entry.getAlternateLinks().get(0);
Link theLink = (Link)entry.getAlternateLinks().get(0);
syndEntry.setLink(theLink.getHrefResolved()); syndEntry.setLink(theLink.getHrefResolved());
} }
// Create synd enclosures from enclosure links // Create synd enclosures from enclosure links
List<SyndEnclosure> syndEnclosures = new ArrayList<SyndEnclosure>(); final List<SyndEnclosure> syndEnclosures = new ArrayList<SyndEnclosure>();
if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) { if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
List<Link> oLinks = entry.getOtherLinks(); final List<Link> oLinks = entry.getOtherLinks();
for (Iterator<Link> iter = oLinks.iterator(); iter.hasNext(); ) { for (final Link link : oLinks) {
Link thisLink = (Link)iter.next(); final Link thisLink = link;
if ("enclosure".equals(thisLink.getRel())) if ("enclosure".equals(thisLink.getRel())) {
syndEnclosures.add(createSyndEnclosure(entry, thisLink)); syndEnclosures.add(createSyndEnclosure(entry, thisLink));
}
} }
} }
syndEntry.setEnclosures(syndEnclosures); syndEntry.setEnclosures(syndEnclosures);
// lump alternate and other links together // lump alternate and other links together
List<SyndLink> syndLinks = new ArrayList<SyndLink>(); final List<SyndLink> syndLinks = new ArrayList<SyndLink>();
if (entry.getAlternateLinks() != null if (entry.getAlternateLinks() != null && entry.getAlternateLinks().size() > 0) {
&& entry.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getAlternateLinks())); syndLinks.addAll(createSyndLinks(entry.getAlternateLinks()));
} }
if (entry.getOtherLinks() != null if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
&& entry.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getOtherLinks())); syndLinks.addAll(createSyndLinks(entry.getOtherLinks()));
} }
syndEntry.setLinks(syndLinks); syndEntry.setLinks(syndLinks);
final String id = entry.getId();
String id = entry.getId(); if (id != null) {
if (id!=null) {
syndEntry.setUri(entry.getId()); syndEntry.setUri(entry.getId());
} } else {
else {
syndEntry.setUri(syndEntry.getLink()); syndEntry.setUri(syndEntry.getLink());
} }
Content content = entry.getSummary(); Content content = entry.getSummary();
if (content==null) { if (content == null) {
List<Content> contents = entry.getContents(); final List<Content> contents = entry.getContents();
if (contents!=null && contents.size()>0) { if (contents != null && contents.size() > 0) {
content = (Content) contents.get(0); content = contents.get(0);
} }
} }
if (content!=null) { if (content != null) {
SyndContent sContent = new SyndContentImpl(); final SyndContent sContent = new SyndContentImpl();
sContent.setType(content.getType()); sContent.setType(content.getType());
sContent.setValue(content.getValue()); sContent.setValue(content.getValue());
syndEntry.setDescription(sContent); syndEntry.setDescription(sContent);
} }
List<Content> contents = entry.getContents(); final List<Content> contents = entry.getContents();
if (contents.size()>0) { if (contents.size() > 0) {
List<SyndContent> sContents = new ArrayList<SyndContent>(); final List<SyndContent> sContents = new ArrayList<SyndContent>();
for (int i=0;i<contents.size();i++) { for (int i = 0; i < contents.size(); i++) {
content = (Content) contents.get(i); content = contents.get(i);
SyndContent sContent = new SyndContentImpl(); final SyndContent sContent = new SyndContentImpl();
sContent.setType(content.getType()); sContent.setType(content.getType());
sContent.setValue(content.getValue()); sContent.setValue(content.getValue());
sContent.setMode(content.getMode()); sContent.setMode(content.getMode());
@ -241,46 +232,47 @@ public class ConverterForAtom03 implements Converter {
syndEntry.setContents(sContents); syndEntry.setContents(sContents);
} }
List<Person> authors = entry.getAuthors(); final List<Person> authors = entry.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
syndEntry.setAuthors(createSyndPersons(authors)); syndEntry.setAuthors(createSyndPersons(authors));
SyndPerson person0 = (SyndPerson)syndEntry.getAuthors().get(0); final SyndPerson person0 = syndEntry.getAuthors().get(0);
syndEntry.setAuthor(person0.getName()); syndEntry.setAuthor(person0.getName());
} }
Date date = entry.getModified(); Date date = entry.getModified();
if (date==null) { if (date == null) {
date = entry.getIssued(); date = entry.getIssued();
if (date==null) { if (date == null) {
date = entry.getCreated(); date = entry.getCreated();
} }
} }
if (date!=null) { if (date != null) {
syndEntry.setPublishedDate(date); syndEntry.setPublishedDate(date);
} }
return syndEntry; return syndEntry;
} }
public SyndEnclosure createSyndEnclosure(Entry entry, Link link) { public SyndEnclosure createSyndEnclosure(final Entry entry, final Link link) {
SyndEnclosure syndEncl = new SyndEnclosureImpl(); final SyndEnclosure syndEncl = new SyndEnclosureImpl();
syndEncl.setUrl(link.getHrefResolved()); syndEncl.setUrl(link.getHrefResolved());
syndEncl.setType(link.getType()); syndEncl.setType(link.getType());
syndEncl.setLength(link.getLength()); syndEncl.setLength(link.getLength());
return syndEncl; return syndEncl;
} }
public WireFeed createRealFeed(SyndFeed syndFeed) { @Override
Feed aFeed = new Feed(getType()); public WireFeed createRealFeed(final SyndFeed syndFeed) {
final Feed aFeed = new Feed(getType());
aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules())); aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
aFeed.setEncoding(syndFeed.getEncoding()); aFeed.setEncoding(syndFeed.getEncoding());
aFeed.setId(syndFeed.getUri()); aFeed.setId(syndFeed.getUri());
SyndContent sTitle = syndFeed.getTitleEx(); final SyndContent sTitle = syndFeed.getTitleEx();
if (sTitle != null) { if (sTitle != null) {
Content title = new Content(); final Content title = new Content();
if (sTitle.getType() != null) { if (sTitle.getType() != null) {
title.setType(sTitle.getType()); title.setType(sTitle.getType());
} }
@ -294,16 +286,14 @@ public class ConverterForAtom03 implements Converter {
} }
// separate SyndEntry's links collection into alternate and other links // separate SyndEntry's links collection into alternate and other links
List<Link> alternateLinks = new ArrayList<Link>(); final List<Link> alternateLinks = new ArrayList<Link>();
List<Link> otherLinks = new ArrayList<Link>(); final List<Link> otherLinks = new ArrayList<Link>();
List<SyndLink> slinks = syndFeed.getLinks(); final List<SyndLink> slinks = syndFeed.getLinks();
if (slinks != null) { if (slinks != null) {
for (Iterator<SyndLink> iter=slinks.iterator(); iter.hasNext();) { for (final SyndLink syndLink2 : slinks) {
SyndLink syndLink = (SyndLink)iter.next(); final SyndLink syndLink = syndLink2;
Link link = createAtomLink(syndLink); final Link link = createAtomLink(syndLink);
if (link.getRel() == null || if (link.getRel() == null || "".equals(link.getRel().trim()) || "alternate".equals(link.getRel())) {
"".equals(link.getRel().trim()) ||
"alternate".equals(link.getRel())) {
alternateLinks.add(link); alternateLinks.add(link);
} else { } else {
otherLinks.add(link); otherLinks.add(link);
@ -312,26 +302,30 @@ public class ConverterForAtom03 implements Converter {
} }
// no alternate link? then use THE link if there is one // no alternate link? then use THE link if there is one
if (alternateLinks.isEmpty() && syndFeed.getLink() != null) { if (alternateLinks.isEmpty() && syndFeed.getLink() != null) {
Link link = new Link(); final Link link = new Link();
link.setRel("alternate"); link.setRel("alternate");
link.setHref(syndFeed.getLink()); link.setHref(syndFeed.getLink());
alternateLinks.add(link); alternateLinks.add(link);
} }
if (alternateLinks.size() > 0) aFeed.setAlternateLinks(alternateLinks); if (alternateLinks.size() > 0) {
if (otherLinks.size() > 0) aFeed.setOtherLinks(otherLinks); aFeed.setAlternateLinks(alternateLinks);
}
if (otherLinks.size() > 0) {
aFeed.setOtherLinks(otherLinks);
}
String sDesc = syndFeed.getDescription(); final String sDesc = syndFeed.getDescription();
if (sDesc!=null) { if (sDesc != null) {
Content tagline = new Content(); final Content tagline = new Content();
tagline.setValue(sDesc); tagline.setValue(sDesc);
aFeed.setTagline(tagline); aFeed.setTagline(tagline);
} }
aFeed.setLanguage(syndFeed.getLanguage()); aFeed.setLanguage(syndFeed.getLanguage());
List<SyndPerson> authors = syndFeed.getAuthors(); final List<SyndPerson> authors = syndFeed.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
aFeed.setAuthors(createAtomPersons(authors)); aFeed.setAuthors(createAtomPersons(authors));
} }
@ -339,19 +333,19 @@ public class ConverterForAtom03 implements Converter {
aFeed.setModified(syndFeed.getPublishedDate()); aFeed.setModified(syndFeed.getPublishedDate());
List<SyndEntry> sEntries = syndFeed.getEntries(); final List<SyndEntry> sEntries = syndFeed.getEntries();
if (sEntries!=null) { if (sEntries != null) {
aFeed.setEntries(createAtomEntries(sEntries)); aFeed.setEntries(createAtomEntries(sEntries));
} }
return aFeed; return aFeed;
} }
protected static List<Person> createAtomPersons(List<SyndPerson> sPersons) { protected static List<Person> createAtomPersons(final List<SyndPerson> sPersons) {
List<Person> persons = new ArrayList<Person>(); final List<Person> persons = new ArrayList<Person>();
for (Iterator<SyndPerson> iter = sPersons.iterator(); iter.hasNext(); ) { for (final SyndPerson syndPerson : sPersons) {
SyndPerson sPerson = (SyndPerson)iter.next(); final SyndPerson sPerson = syndPerson;
Person person = new Person(); final Person person = new Person();
person.setName(sPerson.getName()); person.setName(sPerson.getName());
person.setUri(sPerson.getUri()); person.setUri(sPerson.getUri());
person.setEmail(sPerson.getEmail()); person.setEmail(sPerson.getEmail());
@ -360,12 +354,12 @@ public class ConverterForAtom03 implements Converter {
} }
return persons; return persons;
} }
protected static List<SyndPerson> createSyndPersons(List<Person> aPersons) { protected static List<SyndPerson> createSyndPersons(final List<Person> aPersons) {
List<SyndPerson> persons = new ArrayList<SyndPerson>(); final List<SyndPerson> persons = new ArrayList<SyndPerson>();
for (Iterator<Person> iter = aPersons.iterator(); iter.hasNext(); ) { for (final Person person2 : aPersons) {
Person aPerson = (Person)iter.next(); final Person aPerson = person2;
SyndPerson person = new SyndPersonImpl(); final SyndPerson person = new SyndPersonImpl();
person.setName(aPerson.getName()); person.setName(aPerson.getName());
person.setUri(aPerson.getUri()); person.setUri(aPerson.getUri());
person.setEmail(aPerson.getEmail()); person.setEmail(aPerson.getEmail());
@ -374,24 +368,24 @@ public class ConverterForAtom03 implements Converter {
} }
return persons; return persons;
} }
protected List<Entry> createAtomEntries(List<SyndEntry> syndEntries) { protected List<Entry> createAtomEntries(final List<SyndEntry> syndEntries) {
List<Entry> atomEntries = new ArrayList<Entry>(); final List<Entry> atomEntries = new ArrayList<Entry>();
for (int i=0;i<syndEntries.size();i++) { for (int i = 0; i < syndEntries.size(); i++) {
atomEntries.add(createAtomEntry((SyndEntry)syndEntries.get(i))); atomEntries.add(createAtomEntry(syndEntries.get(i)));
} }
return atomEntries; return atomEntries;
} }
protected Entry createAtomEntry(SyndEntry sEntry) { protected Entry createAtomEntry(final SyndEntry sEntry) {
Entry aEntry = new Entry(); final Entry aEntry = new Entry();
aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules())); aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
aEntry.setId(sEntry.getUri()); aEntry.setId(sEntry.getUri());
SyndContent sTitle = sEntry.getTitleEx(); final SyndContent sTitle = sEntry.getTitleEx();
if (sTitle!=null) { if (sTitle != null) {
Content title = new Content(); final Content title = new Content();
if (sTitle.getType() != null) { if (sTitle.getType() != null) {
title.setType(sTitle.getType()); title.setType(sTitle.getType());
} }
@ -405,16 +399,14 @@ public class ConverterForAtom03 implements Converter {
} }
// separate SyndEntry's links collection into alternate and other links // separate SyndEntry's links collection into alternate and other links
List<Link> alternateLinks = new ArrayList<Link>(); final List<Link> alternateLinks = new ArrayList<Link>();
List<Link> otherLinks = new ArrayList<Link>(); final List<Link> otherLinks = new ArrayList<Link>();
List<SyndLink> slinks = sEntry.getLinks(); final List<SyndLink> slinks = sEntry.getLinks();
if (slinks != null) { if (slinks != null) {
for (Iterator<SyndLink> iter=slinks.iterator(); iter.hasNext();) { for (final SyndLink syndLink2 : slinks) {
SyndLink syndLink = (SyndLink)iter.next(); final SyndLink syndLink = syndLink2;
Link link = createAtomLink(syndLink); final Link link = createAtomLink(syndLink);
if (link.getRel() == null || if (link.getRel() == null || "".equals(link.getRel().trim()) || "alternate".equals(link.getRel())) {
"".equals(link.getRel().trim()) ||
"alternate".equals(link.getRel())) {
alternateLinks.add(link); alternateLinks.add(link);
} else { } else {
otherLinks.add(link); otherLinks.add(link);
@ -423,40 +415,43 @@ public class ConverterForAtom03 implements Converter {
} }
// no alternate link? then use THE link if there is one // no alternate link? then use THE link if there is one
if (alternateLinks.isEmpty() && sEntry.getLink() != null) { if (alternateLinks.isEmpty() && sEntry.getLink() != null) {
Link link = new Link(); final Link link = new Link();
link.setRel("alternate"); link.setRel("alternate");
link.setHref(sEntry.getLink()); link.setHref(sEntry.getLink());
alternateLinks.add(link); alternateLinks.add(link);
} }
List<SyndEnclosure> sEnclosures = sEntry.getEnclosures(); final List<SyndEnclosure> sEnclosures = sEntry.getEnclosures();
if (sEnclosures != null) { if (sEnclosures != null) {
for (Iterator<SyndEnclosure> iter=sEnclosures.iterator(); iter.hasNext();) { for (final SyndEnclosure syndEnclosure2 : sEnclosures) {
SyndEnclosure syndEnclosure = (SyndEnclosure) iter.next(); final SyndEnclosure syndEnclosure = syndEnclosure2;
Link link = createAtomEnclosure(syndEnclosure); final Link link = createAtomEnclosure(syndEnclosure);
otherLinks.add(link); otherLinks.add(link);
} }
} }
if (alternateLinks.size() > 0) aEntry.setAlternateLinks(alternateLinks); if (alternateLinks.size() > 0) {
if (otherLinks.size() > 0) aEntry.setOtherLinks(otherLinks); aEntry.setAlternateLinks(alternateLinks);
}
if (otherLinks.size() > 0) {
aEntry.setOtherLinks(otherLinks);
}
SyndContent sContent = sEntry.getDescription(); SyndContent sContent = sEntry.getDescription();
if (sContent!=null) { if (sContent != null) {
Content content = new Content(); final Content content = new Content();
content.setType(sContent.getType()); content.setType(sContent.getType());
content.setValue(sContent.getValue()); content.setValue(sContent.getValue());
content.setMode(Content.ESCAPED); content.setMode(Content.ESCAPED);
aEntry.setSummary(content); aEntry.setSummary(content);
} }
List<SyndContent> contents = sEntry.getContents(); final List<SyndContent> contents = sEntry.getContents();
if (contents.size()>0) { if (contents.size() > 0) {
List<Content> aContents = new ArrayList<Content>(); final List<Content> aContents = new ArrayList<Content>();
for (int i=0;i<contents.size();i++) { for (int i = 0; i < contents.size(); i++) {
sContent = (SyndContentImpl) contents.get(i); sContent = contents.get(i);
Content content = new Content(); final Content content = new Content();
content.setType(sContent.getType()); content.setType(sContent.getType());
content.setValue(sContent.getValue()); content.setValue(sContent.getValue());
content.setMode(sContent.getMode()); content.setMode(sContent.getMode());
@ -466,13 +461,13 @@ public class ConverterForAtom03 implements Converter {
aEntry.setContents(aContents); aEntry.setContents(aContents);
} }
List<SyndPerson> sAuthors = sEntry.getAuthors(); final List<SyndPerson> sAuthors = sEntry.getAuthors();
if (sAuthors!=null && sAuthors.size() > 0) { if (sAuthors != null && sAuthors.size() > 0) {
aEntry.setAuthors(createAtomPersons(sAuthors)); aEntry.setAuthors(createAtomPersons(sAuthors));
} else if (sEntry.getAuthor() != null) { } else if (sEntry.getAuthor() != null) {
Person person = new Person(); final Person person = new Person();
person.setName(sEntry.getAuthor()); person.setName(sEntry.getAuthor());
List<Person> authors = new ArrayList<Person>(); final List<Person> authors = new ArrayList<Person>();
authors.add(person); authors.add(person);
aEntry.setAuthors(authors); aEntry.setAuthors(authors);
} }
@ -483,22 +478,22 @@ public class ConverterForAtom03 implements Converter {
return aEntry; return aEntry;
} }
public Link createAtomLink(SyndLink syndLink) { public Link createAtomLink(final SyndLink syndLink) {
Link link = new Link(); final Link link = new Link();
link.setRel( syndLink.getRel()); link.setRel(syndLink.getRel());
link.setType( syndLink.getType()); link.setType(syndLink.getType());
link.setHref( syndLink.getHref()); link.setHref(syndLink.getHref());
link.setTitle( syndLink.getTitle()); link.setTitle(syndLink.getTitle());
return link; return link;
} }
public Link createAtomEnclosure(SyndEnclosure syndEnclosure) { public Link createAtomEnclosure(final SyndEnclosure syndEnclosure) {
Link link = new Link(); final Link link = new Link();
link.setRel( "enclosure"); link.setRel("enclosure");
link.setType( syndEnclosure.getType()); link.setType(syndEnclosure.getType());
link.setHref( syndEnclosure.getUrl()); link.setHref(syndEnclosure.getUrl());
link.setLength( syndEnclosure.getLength()); link.setLength(syndEnclosure.getLength());
return link; return link;
} }
} }

View file

@ -18,11 +18,8 @@ package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jdom2.Element;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Category; import com.sun.syndication.feed.atom.Category;
import com.sun.syndication.feed.atom.Content; import com.sun.syndication.feed.atom.Content;
@ -36,6 +33,8 @@ import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndCategoryImpl; import com.sun.syndication.feed.synd.SyndCategoryImpl;
import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl;
import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl; import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.feed.synd.SyndFeed;
@ -43,316 +42,306 @@ import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.feed.synd.SyndLink; import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl; import com.sun.syndication.feed.synd.SyndLinkImpl;
import com.sun.syndication.feed.synd.SyndPerson; import com.sun.syndication.feed.synd.SyndPerson;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl;
/** /**
*/ */
public class ConverterForAtom10 implements Converter { public class ConverterForAtom10 implements Converter {
private String _type; private final String _type;
public ConverterForAtom10() { public ConverterForAtom10() {
this("atom_1.0"); this("atom_1.0");
} }
protected ConverterForAtom10(String type) { protected ConverterForAtom10(final String type) {
_type = type; this._type = type;
} }
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
public void copyInto(WireFeed feed, SyndFeed syndFeed) { @Override
Feed aFeed = (Feed) feed; public void copyInto(final WireFeed feed, final SyndFeed syndFeed) {
final Feed aFeed = (Feed) feed;
syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules())); syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules()));
if (((List<Element>)feed.getForeignMarkup()).size() > 0) { if (feed.getForeignMarkup().size() > 0) {
syndFeed.setForeignMarkup((List<Element>)feed.getForeignMarkup()); syndFeed.setForeignMarkup(feed.getForeignMarkup());
} }
syndFeed.setEncoding(aFeed.getEncoding()); syndFeed.setEncoding(aFeed.getEncoding());
syndFeed.setUri(aFeed.getId()); syndFeed.setUri(aFeed.getId());
Content aTitle = aFeed.getTitleEx(); final Content aTitle = aFeed.getTitleEx();
if (aTitle != null) { if (aTitle != null) {
SyndContent c = new SyndContentImpl(); final SyndContent c = new SyndContentImpl();
c.setType(aTitle.getType()); c.setType(aTitle.getType());
c.setValue(aTitle.getValue()); c.setValue(aTitle.getValue());
syndFeed.setTitleEx(c); syndFeed.setTitleEx(c);
} }
Content aSubtitle = aFeed.getSubtitle(); final Content aSubtitle = aFeed.getSubtitle();
if (aSubtitle!=null) { if (aSubtitle != null) {
SyndContent c = new SyndContentImpl(); final SyndContent c = new SyndContentImpl();
c.setType(aSubtitle.getType()); c.setType(aSubtitle.getType());
c.setValue(aSubtitle.getValue()); c.setValue(aSubtitle.getValue());
syndFeed.setDescriptionEx(c); syndFeed.setDescriptionEx(c);
} }
// use first alternate links as THE link // use first alternate links as THE link
if (aFeed.getAlternateLinks() != null if (aFeed.getAlternateLinks() != null && aFeed.getAlternateLinks().size() > 0) {
&& aFeed.getAlternateLinks().size() > 0) { final Link theLink = aFeed.getAlternateLinks().get(0);
Link theLink = (Link)aFeed.getAlternateLinks().get(0);
syndFeed.setLink(theLink.getHrefResolved()); syndFeed.setLink(theLink.getHrefResolved());
} }
// lump alternate and other links together // lump alternate and other links together
List<SyndLink> syndLinks = new ArrayList<SyndLink>(); final List<SyndLink> syndLinks = new ArrayList<SyndLink>();
if (aFeed.getAlternateLinks() != null if (aFeed.getAlternateLinks() != null && aFeed.getAlternateLinks().size() > 0) {
&& aFeed.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks())); syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks()));
} }
if (aFeed.getOtherLinks() != null if (aFeed.getOtherLinks() != null && aFeed.getOtherLinks().size() > 0) {
&& aFeed.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks())); syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks()));
} }
syndFeed.setLinks(syndLinks); syndFeed.setLinks(syndLinks);
List<Entry> aEntries = aFeed.getEntries(); final List<Entry> aEntries = aFeed.getEntries();
if (aEntries!=null) { if (aEntries != null) {
syndFeed.setEntries(createSyndEntries(aFeed, aEntries, syndFeed.isPreservingWireFeed())); syndFeed.setEntries(createSyndEntries(aFeed, aEntries, syndFeed.isPreservingWireFeed()));
} }
// Core Atom language/author/copyright/modified elements have precedence // Core Atom language/author/copyright/modified elements have precedence
// over DC equivalent info. // over DC equivalent info.
List<Person> authors = aFeed.getAuthors(); final List<Person> authors = aFeed.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
syndFeed.setAuthors(ConverterForAtom03.createSyndPersons(authors)); syndFeed.setAuthors(ConverterForAtom03.createSyndPersons(authors));
} }
List<Person> contributors = aFeed.getContributors(); final List<Person> contributors = aFeed.getContributors();
if (contributors!=null && contributors.size() > 0) { if (contributors != null && contributors.size() > 0) {
syndFeed.setContributors(ConverterForAtom03.createSyndPersons(contributors)); syndFeed.setContributors(ConverterForAtom03.createSyndPersons(contributors));
} }
String rights = aFeed.getRights(); final String rights = aFeed.getRights();
if (rights!=null) { if (rights != null) {
syndFeed.setCopyright(rights); syndFeed.setCopyright(rights);
} }
Date date = aFeed.getUpdated(); final Date date = aFeed.getUpdated();
if (date!=null) { if (date != null) {
syndFeed.setPublishedDate(date); syndFeed.setPublishedDate(date);
} }
} }
protected List<SyndLink> createSyndLinks(List<Link> aLinks) { protected List<SyndLink> createSyndLinks(final List<Link> aLinks) {
ArrayList<SyndLink> sLinks = new ArrayList<SyndLink>(); final ArrayList<SyndLink> sLinks = new ArrayList<SyndLink>();
for (Iterator<Link> iter = aLinks.iterator(); iter.hasNext();) { for (final Link link2 : aLinks) {
Link link = (Link)iter.next(); final Link link = link2;
SyndLink sLink = createSyndLink(link); final SyndLink sLink = createSyndLink(link);
sLinks.add(sLink); sLinks.add(sLink);
} }
return sLinks; return sLinks;
} }
protected List<SyndEntry> createSyndEntries(Feed feed, List<Entry> atomEntries, boolean preserveWireItems) { protected List<SyndEntry> createSyndEntries(final Feed feed, final List<Entry> atomEntries, final boolean preserveWireItems) {
List<SyndEntry> syndEntries = new ArrayList<SyndEntry>(); final List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
for (int i=0;i<atomEntries.size();i++) { for (int i = 0; i < atomEntries.size(); i++) {
syndEntries.add(createSyndEntry(feed, (Entry) atomEntries.get(i), preserveWireItems)); syndEntries.add(createSyndEntry(feed, atomEntries.get(i), preserveWireItems));
} }
return syndEntries; return syndEntries;
} }
protected SyndEntry createSyndEntry(Feed feed, Entry entry, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Feed feed, final Entry entry, final boolean preserveWireItem) {
SyndEntryImpl syndEntry = new SyndEntryImpl(); final SyndEntryImpl syndEntry = new SyndEntryImpl();
if (preserveWireItem) { if (preserveWireItem) {
syndEntry.setWireEntry(entry); syndEntry.setWireEntry(entry);
} }
syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules())); syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules()));
if (((List<Element>)entry.getForeignMarkup()).size() > 0) { if (entry.getForeignMarkup().size() > 0) {
syndEntry.setForeignMarkup((List<Element>)entry.getForeignMarkup()); syndEntry.setForeignMarkup(entry.getForeignMarkup());
} }
Content eTitle = entry.getTitleEx(); final Content eTitle = entry.getTitleEx();
if (eTitle != null) { if (eTitle != null) {
syndEntry.setTitleEx(createSyndContent(eTitle)); syndEntry.setTitleEx(createSyndContent(eTitle));
} }
Content summary = entry.getSummary(); final Content summary = entry.getSummary();
if (summary!=null) { if (summary != null) {
syndEntry.setDescription(createSyndContent(summary)); syndEntry.setDescription(createSyndContent(summary));
} }
List<Content> contents = entry.getContents(); final List<Content> contents = entry.getContents();
if (contents != null && contents.size() > 0) { if (contents != null && contents.size() > 0) {
List<SyndContent> sContents = new ArrayList<SyndContent>(); final List<SyndContent> sContents = new ArrayList<SyndContent>();
for (Iterator<Content> iter=contents.iterator(); iter.hasNext();) { for (final Content content2 : contents) {
Content content = (Content)iter.next(); final Content content = content2;
sContents.add(createSyndContent(content)); sContents.add(createSyndContent(content));
} }
syndEntry.setContents(sContents); syndEntry.setContents(sContents);
} }
List<Person> authors = entry.getAuthors(); final List<Person> authors = entry.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
syndEntry.setAuthors(ConverterForAtom03.createSyndPersons(authors)); syndEntry.setAuthors(ConverterForAtom03.createSyndPersons(authors));
SyndPerson person0 = (SyndPerson)syndEntry.getAuthors().get(0); final SyndPerson person0 = syndEntry.getAuthors().get(0);
syndEntry.setAuthor(person0.getName()); syndEntry.setAuthor(person0.getName());
} }
List<Person> contributors = entry.getContributors(); final List<Person> contributors = entry.getContributors();
if (contributors!=null && contributors.size() > 0) { if (contributors != null && contributors.size() > 0) {
syndEntry.setContributors(ConverterForAtom03.createSyndPersons(contributors)); syndEntry.setContributors(ConverterForAtom03.createSyndPersons(contributors));
} }
Date date = entry.getPublished(); Date date = entry.getPublished();
if (date!=null) { if (date != null) {
syndEntry.setPublishedDate(date); syndEntry.setPublishedDate(date);
} }
date = entry.getUpdated(); date = entry.getUpdated();
if (date!=null) { if (date != null) {
syndEntry.setUpdatedDate(date); syndEntry.setUpdatedDate(date);
} }
List<Category> categories = entry.getCategories(); final List<Category> categories = entry.getCategories();
if (categories!=null) { if (categories != null) {
List<SyndCategory> syndCategories = new ArrayList<SyndCategory>(); final List<SyndCategory> syndCategories = new ArrayList<SyndCategory>();
for (Iterator<Category> iter=categories.iterator(); iter.hasNext();) { for (final Category category : categories) {
Category c = (Category)iter.next(); final Category c = category;
SyndCategory syndCategory = new SyndCategoryImpl(); final SyndCategory syndCategory = new SyndCategoryImpl();
syndCategory.setName(c.getTerm()); syndCategory.setName(c.getTerm());
syndCategory.setTaxonomyUri(c.getSchemeResolved()); syndCategory.setTaxonomyUri(c.getSchemeResolved());
// TODO: categories MAY have labels // TODO: categories MAY have labels
// syndCategory.setLabel(c.getLabel()); // syndCategory.setLabel(c.getLabel());
syndCategories.add(syndCategory); syndCategories.add(syndCategory);
} }
syndEntry.setCategories(syndCategories); syndEntry.setCategories(syndCategories);
} }
// use first alternate link as THE link // use first alternate link as THE link
if (entry.getAlternateLinks() != null if (entry.getAlternateLinks() != null && entry.getAlternateLinks().size() > 0) {
&& entry.getAlternateLinks().size() > 0) { final Link theLink = entry.getAlternateLinks().get(0);
Link theLink = (Link)entry.getAlternateLinks().get(0);
syndEntry.setLink(theLink.getHrefResolved()); syndEntry.setLink(theLink.getHrefResolved());
} }
// Create synd enclosures from enclosure links // Create synd enclosures from enclosure links
List<SyndEnclosure> syndEnclosures = new ArrayList<SyndEnclosure>(); final List<SyndEnclosure> syndEnclosures = new ArrayList<SyndEnclosure>();
if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) { if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
List<Link> oLinks = entry.getOtherLinks(); final List<Link> oLinks = entry.getOtherLinks();
for (Iterator<Link> iter = oLinks.iterator(); iter.hasNext(); ) { for (final Link link : oLinks) {
Link thisLink = (Link)iter.next(); final Link thisLink = link;
if ("enclosure".equals(thisLink.getRel())) if ("enclosure".equals(thisLink.getRel())) {
syndEnclosures.add( syndEnclosures.add(createSyndEnclosure(feed, entry, thisLink));
createSyndEnclosure(feed, entry, thisLink)); }
} }
} }
syndEntry.setEnclosures(syndEnclosures); syndEntry.setEnclosures(syndEnclosures);
// lump alternate and other links together // lump alternate and other links together
List<SyndLink> syndLinks = new ArrayList<SyndLink>(); final List<SyndLink> syndLinks = new ArrayList<SyndLink>();
if (entry.getAlternateLinks() != null if (entry.getAlternateLinks() != null && entry.getAlternateLinks().size() > 0) {
&& entry.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getAlternateLinks())); syndLinks.addAll(createSyndLinks(entry.getAlternateLinks()));
} }
if (entry.getOtherLinks() != null if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
&& entry.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getOtherLinks())); syndLinks.addAll(createSyndLinks(entry.getOtherLinks()));
} }
syndEntry.setLinks(syndLinks); syndEntry.setLinks(syndLinks);
String id = entry.getId(); final String id = entry.getId();
if (id!=null) { if (id != null) {
syndEntry.setUri(entry.getId()); syndEntry.setUri(entry.getId());
} } else {
else {
syndEntry.setUri(syndEntry.getLink()); syndEntry.setUri(syndEntry.getLink());
} }
// Convert source element Feed into SyndFeed and assign as SyndEntry // Convert source element Feed into SyndFeed and assign as SyndEntry
// source // source
Feed source = entry.getSource(); final Feed source = entry.getSource();
if (source != null) { if (source != null) {
SyndFeed syndSource = new SyndFeedImpl(source); final SyndFeed syndSource = new SyndFeedImpl(source);
syndEntry.setSource(syndSource); syndEntry.setSource(syndSource);
} }
return syndEntry; return syndEntry;
} }
public SyndEnclosure createSyndEnclosure(Feed feed, Entry entry, public SyndEnclosure createSyndEnclosure(final Feed feed, final Entry entry, final Link link) {
Link link) { final SyndEnclosure syndEncl = new SyndEnclosureImpl();
SyndEnclosure syndEncl = new SyndEnclosureImpl();
syndEncl.setUrl(link.getHrefResolved()); syndEncl.setUrl(link.getHrefResolved());
syndEncl.setType(link.getType()); syndEncl.setType(link.getType());
syndEncl.setLength(link.getLength()); syndEncl.setLength(link.getLength());
return syndEncl; return syndEncl;
} }
public Link createAtomEnclosure(SyndEnclosure syndEnclosure) {
Link link = new Link();
link.setRel( "enclosure");
link.setType( syndEnclosure.getType());
link.setHref( syndEnclosure.getUrl());
link.setLength( syndEnclosure.getLength());
return link;
}
public SyndLink createSyndLink(Link link) { public Link createAtomEnclosure(final SyndEnclosure syndEnclosure) {
SyndLink syndLink = new SyndLinkImpl(); final Link link = new Link();
syndLink.setRel( link.getRel()); link.setRel("enclosure");
syndLink.setType( link.getType()); link.setType(syndEnclosure.getType());
syndLink.setHref( link.getHrefResolved()); link.setHref(syndEnclosure.getUrl());
syndLink.setHreflang(link.getHreflang()); link.setLength(syndEnclosure.getLength());
syndLink.setLength( link.getLength());
syndLink.setTitle( link.getTitle());
return syndLink;
}
public Link createAtomLink(SyndLink syndLink) {
Link link = new Link();
link.setRel( syndLink.getRel());
link.setType( syndLink.getType());
link.setHref( syndLink.getHref());
link.setHreflang(syndLink.getHreflang());
link.setLength( syndLink.getLength());
link.setTitle( syndLink.getTitle());
return link; return link;
} }
public WireFeed createRealFeed(SyndFeed syndFeed) { public SyndLink createSyndLink(final Link link) {
Feed aFeed = new Feed(getType()); final SyndLink syndLink = new SyndLinkImpl();
syndLink.setRel(link.getRel());
syndLink.setType(link.getType());
syndLink.setHref(link.getHrefResolved());
syndLink.setHreflang(link.getHreflang());
syndLink.setLength(link.getLength());
syndLink.setTitle(link.getTitle());
return syndLink;
}
public Link createAtomLink(final SyndLink syndLink) {
final Link link = new Link();
link.setRel(syndLink.getRel());
link.setType(syndLink.getType());
link.setHref(syndLink.getHref());
link.setHreflang(syndLink.getHreflang());
link.setLength(syndLink.getLength());
link.setTitle(syndLink.getTitle());
return link;
}
@Override
public WireFeed createRealFeed(final SyndFeed syndFeed) {
final Feed aFeed = new Feed(getType());
aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules())); aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
aFeed.setEncoding(syndFeed.getEncoding()); aFeed.setEncoding(syndFeed.getEncoding());
aFeed.setId(syndFeed.getUri()); aFeed.setId(syndFeed.getUri());
SyndContent sTitle = syndFeed.getTitleEx(); final SyndContent sTitle = syndFeed.getTitleEx();
if (sTitle != null) { if (sTitle != null) {
Content title = new Content(); final Content title = new Content();
title.setType(sTitle.getType()); title.setType(sTitle.getType());
title.setValue(sTitle.getValue()); title.setValue(sTitle.getValue());
aFeed.setTitleEx(title); aFeed.setTitleEx(title);
} }
SyndContent sDesc = syndFeed.getDescriptionEx(); final SyndContent sDesc = syndFeed.getDescriptionEx();
if (sDesc != null) { if (sDesc != null) {
Content subtitle = new Content(); final Content subtitle = new Content();
subtitle.setType(sDesc.getType()); subtitle.setType(sDesc.getType());
subtitle.setValue(sDesc.getValue()); subtitle.setValue(sDesc.getValue());
aFeed.setSubtitle(subtitle); aFeed.setSubtitle(subtitle);
} }
// separate SyndEntry's links collection into alternate and other links // separate SyndEntry's links collection into alternate and other links
List<Link> alternateLinks = new ArrayList<Link>(); final List<Link> alternateLinks = new ArrayList<Link>();
List<Link> otherLinks = new ArrayList<Link>(); final List<Link> otherLinks = new ArrayList<Link>();
List<SyndLink> slinks = syndFeed.getLinks(); final List<SyndLink> slinks = syndFeed.getLinks();
if (slinks != null) { if (slinks != null) {
for (Iterator<SyndLink> iter=slinks.iterator(); iter.hasNext();) { for (final SyndLink syndLink2 : slinks) {
SyndLink syndLink = (SyndLink)iter.next(); final SyndLink syndLink = syndLink2;
Link link = createAtomLink(syndLink); final Link link = createAtomLink(syndLink);
if (link.getRel() == null || if (link.getRel() == null || "".equals(link.getRel().trim()) || "alternate".equals(link.getRel())) {
"".equals(link.getRel().trim()) ||
"alternate".equals(link.getRel())) {
alternateLinks.add(link); alternateLinks.add(link);
} else { } else {
otherLinks.add(link); otherLinks.add(link);
@ -361,35 +350,41 @@ public class ConverterForAtom10 implements Converter {
} }
// no alternate link? then use THE link if there is one // no alternate link? then use THE link if there is one
if (alternateLinks.isEmpty() && syndFeed.getLink() != null) { if (alternateLinks.isEmpty() && syndFeed.getLink() != null) {
Link link = new Link(); final Link link = new Link();
link.setRel("alternate"); link.setRel("alternate");
link.setHref(syndFeed.getLink()); link.setHref(syndFeed.getLink());
alternateLinks.add(link); alternateLinks.add(link);
} }
if (alternateLinks.size() > 0) aFeed.setAlternateLinks(alternateLinks); if (alternateLinks.size() > 0) {
if (otherLinks.size() > 0) aFeed.setOtherLinks(otherLinks); aFeed.setAlternateLinks(alternateLinks);
}
List<SyndCategory> sCats = syndFeed.getCategories(); if (otherLinks.size() > 0) {
List<Category> aCats = new ArrayList<Category>(); aFeed.setOtherLinks(otherLinks);
}
final List<SyndCategory> sCats = syndFeed.getCategories();
final List<Category> aCats = new ArrayList<Category>();
if (sCats != null) { if (sCats != null) {
for (Iterator<SyndCategory> iter=sCats.iterator(); iter.hasNext();) { for (final SyndCategory syndCategory : sCats) {
SyndCategory sCat = (SyndCategory)iter.next(); final SyndCategory sCat = syndCategory;
Category aCat = new Category(); final Category aCat = new Category();
aCat.setTerm(sCat.getName()); aCat.setTerm(sCat.getName());
// TODO: aCat.setLabel(sCat.getLabel()); // TODO: aCat.setLabel(sCat.getLabel());
aCat.setScheme(sCat.getTaxonomyUri()); aCat.setScheme(sCat.getTaxonomyUri());
aCats.add(aCat); aCats.add(aCat);
} }
} }
if (aCats.size() > 0) aFeed.setCategories(aCats); if (aCats.size() > 0) {
aFeed.setCategories(aCats);
}
List<SyndPerson> authors = syndFeed.getAuthors(); final List<SyndPerson> authors = syndFeed.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
aFeed.setAuthors(ConverterForAtom03.createAtomPersons(authors)); aFeed.setAuthors(ConverterForAtom03.createAtomPersons(authors));
} }
List<SyndPerson> contributors = syndFeed.getContributors(); final List<SyndPerson> contributors = syndFeed.getContributors();
if (contributors!=null && contributors.size() > 0) { if (contributors != null && contributors.size() > 0) {
aFeed.setContributors(ConverterForAtom03.createAtomPersons(contributors)); aFeed.setContributors(ConverterForAtom03.createAtomPersons(contributors));
} }
@ -397,89 +392,86 @@ public class ConverterForAtom10 implements Converter {
aFeed.setUpdated(syndFeed.getPublishedDate()); aFeed.setUpdated(syndFeed.getPublishedDate());
List<SyndEntry> sEntries = syndFeed.getEntries(); final List<SyndEntry> sEntries = syndFeed.getEntries();
if (sEntries!=null) { if (sEntries != null) {
aFeed.setEntries(createAtomEntries(sEntries)); aFeed.setEntries(createAtomEntries(sEntries));
} }
if (((List<Element>)syndFeed.getForeignMarkup()).size() > 0) { if (syndFeed.getForeignMarkup().size() > 0) {
aFeed.setForeignMarkup(syndFeed.getForeignMarkup()); aFeed.setForeignMarkup(syndFeed.getForeignMarkup());
} }
return aFeed; return aFeed;
} }
protected SyndContent createSyndContent(Content content) { protected SyndContent createSyndContent(final Content content) {
SyndContent sContent = new SyndContentImpl(); final SyndContent sContent = new SyndContentImpl();
sContent.setType(content.getType()); sContent.setType(content.getType());
sContent.setValue(content.getValue()); sContent.setValue(content.getValue());
return sContent; return sContent;
} }
protected List<Entry> createAtomEntries(List<SyndEntry> syndEntries) { protected List<Entry> createAtomEntries(final List<SyndEntry> syndEntries) {
List<Entry> atomEntries = new ArrayList<Entry>(); final List<Entry> atomEntries = new ArrayList<Entry>();
for (int i=0;i<syndEntries.size();i++) { for (int i = 0; i < syndEntries.size(); i++) {
atomEntries.add(createAtomEntry((SyndEntry)syndEntries.get(i))); atomEntries.add(createAtomEntry(syndEntries.get(i)));
} }
return atomEntries; return atomEntries;
} }
protected Content createAtomContent(SyndContent sContent) { protected Content createAtomContent(final SyndContent sContent) {
Content content = new Content(); final Content content = new Content();
content.setType(sContent.getType()); content.setType(sContent.getType());
content.setValue(sContent.getValue()); content.setValue(sContent.getValue());
return content; return content;
} }
protected List<Content> createAtomContents(List<SyndContent> syndContents) { protected List<Content> createAtomContents(final List<SyndContent> syndContents) {
List<Content> atomContents = new ArrayList<Content>(); final List<Content> atomContents = new ArrayList<Content>();
for (int i=0;i<syndContents.size();i++) { for (int i = 0; i < syndContents.size(); i++) {
atomContents.add(createAtomContent((SyndContent)syndContents.get(i))); atomContents.add(createAtomContent(syndContents.get(i)));
} }
return atomContents; return atomContents;
} }
protected Entry createAtomEntry(SyndEntry sEntry) { protected Entry createAtomEntry(final SyndEntry sEntry) {
Entry aEntry = new Entry(); final Entry aEntry = new Entry();
aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules())); aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
aEntry.setId(sEntry.getUri()); aEntry.setId(sEntry.getUri());
SyndContent sTitle = sEntry.getTitleEx(); final SyndContent sTitle = sEntry.getTitleEx();
if (sTitle!=null) { if (sTitle != null) {
Content title = new Content(); final Content title = new Content();
title.setType(sTitle.getType()); title.setType(sTitle.getType());
title.setValue(sTitle.getValue()); title.setValue(sTitle.getValue());
aEntry.setTitleEx(title); aEntry.setTitleEx(title);
} }
SyndContent sDescription = sEntry.getDescription(); final SyndContent sDescription = sEntry.getDescription();
if (sDescription!=null) { if (sDescription != null) {
Content summary = new Content(); final Content summary = new Content();
summary.setType(sDescription.getType()); summary.setType(sDescription.getType());
summary.setValue(sDescription.getValue()); summary.setValue(sDescription.getValue());
aEntry.setSummary(summary); aEntry.setSummary(summary);
} }
// separate SyndEntry's links collection into alternate and other links // separate SyndEntry's links collection into alternate and other links
List<Link> alternateLinks = new ArrayList<Link>(); final List<Link> alternateLinks = new ArrayList<Link>();
List<Link> otherLinks = new ArrayList<Link>(); final List<Link> otherLinks = new ArrayList<Link>();
List<SyndLink> slinks = sEntry.getLinks(); final List<SyndLink> slinks = sEntry.getLinks();
List<SyndEnclosure> enclosures = sEntry.getEnclosures(); final List<SyndEnclosure> enclosures = sEntry.getEnclosures();
boolean linkRelEnclosureExists = false; boolean linkRelEnclosureExists = false;
if (slinks != null) { if (slinks != null) {
for (Iterator<SyndLink> iter=slinks.iterator(); iter.hasNext();) { for (final SyndLink syndLink2 : slinks) {
SyndLink syndLink = (SyndLink)iter.next(); final SyndLink syndLink = syndLink2;
Link link = createAtomLink(syndLink); final Link link = createAtomLink(syndLink);
// Set this flag if there's a link of rel = enclosure so that // Set this flag if there's a link of rel = enclosure so that
// enclosures won't be duplicated when pulled from // enclosures won't be duplicated when pulled from
// SyndEntry.getEnclosures() // SyndEntry.getEnclosures()
if (syndLink.getRel() != null && if (syndLink.getRel() != null && "enclosure".equals(syndLink.getRel())) {
"enclosure".equals(syndLink.getRel())) {
linkRelEnclosureExists = true; linkRelEnclosureExists = true;
} }
if (link.getRel() == null || if (link.getRel() == null || "".equals(link.getRel().trim()) || "alternate".equals(syndLink.getRel())) {
"".equals(link.getRel().trim()) ||
"alternate".equals(syndLink.getRel())) {
alternateLinks.add(link); alternateLinks.add(link);
} else { } else {
otherLinks.add(link); otherLinks.add(link);
@ -488,7 +480,7 @@ public class ConverterForAtom10 implements Converter {
} }
// no alternate link? then use THE link if there is one // no alternate link? then use THE link if there is one
if (alternateLinks.isEmpty() && sEntry.getLink() != null) { if (alternateLinks.isEmpty() && sEntry.getLink() != null) {
Link link = new Link(); final Link link = new Link();
link.setRel("alternate"); link.setRel("alternate");
link.setHref(sEntry.getLink()); link.setHref(sEntry.getLink());
alternateLinks.add(link); alternateLinks.add(link);
@ -496,45 +488,51 @@ public class ConverterForAtom10 implements Converter {
// add SyndEnclosures as links with rel="enclosure" ONLY if // add SyndEnclosures as links with rel="enclosure" ONLY if
// there are no SyndEntry.getLinks() with rel="enclosure" // there are no SyndEntry.getLinks() with rel="enclosure"
if (enclosures != null && linkRelEnclosureExists == false) { if (enclosures != null && linkRelEnclosureExists == false) {
for (Iterator<SyndEnclosure> iter=enclosures.iterator(); iter.hasNext();) { for (final SyndEnclosure syndEnclosure : enclosures) {
SyndEnclosure syndEncl = (SyndEnclosure)iter.next(); final SyndEnclosure syndEncl = syndEnclosure;
Link link = createAtomEnclosure(syndEncl); final Link link = createAtomEnclosure(syndEncl);
otherLinks.add(link); otherLinks.add(link);
} }
} }
if (alternateLinks.size() > 0) aEntry.setAlternateLinks(alternateLinks); if (alternateLinks.size() > 0) {
if (otherLinks.size() > 0) aEntry.setOtherLinks(otherLinks); aEntry.setAlternateLinks(alternateLinks);
}
List<SyndCategory> sCats = sEntry.getCategories(); if (otherLinks.size() > 0) {
List<Category> aCats = new ArrayList<Category>(); aEntry.setOtherLinks(otherLinks);
}
final List<SyndCategory> sCats = sEntry.getCategories();
final List<Category> aCats = new ArrayList<Category>();
if (sCats != null) { if (sCats != null) {
for (Iterator<SyndCategory> iter=sCats.iterator(); iter.hasNext();) { for (final SyndCategory syndCategory : sCats) {
SyndCategory sCat = (SyndCategory)iter.next(); final SyndCategory sCat = syndCategory;
Category aCat = new Category(); final Category aCat = new Category();
aCat.setTerm(sCat.getName()); aCat.setTerm(sCat.getName());
// TODO: aCat.setLabel(sCat.getLabel()); // TODO: aCat.setLabel(sCat.getLabel());
aCat.setScheme(sCat.getTaxonomyUri()); aCat.setScheme(sCat.getTaxonomyUri());
aCats.add(aCat); aCats.add(aCat);
} }
} }
if (aCats.size() > 0) aEntry.setCategories(aCats); if (aCats.size() > 0) {
aEntry.setCategories(aCats);
List<SyndContent> syndContents = sEntry.getContents(); }
final List<SyndContent> syndContents = sEntry.getContents();
aEntry.setContents(createAtomContents(syndContents)); aEntry.setContents(createAtomContents(syndContents));
List authors = sEntry.getAuthors(); List authors = sEntry.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
aEntry.setAuthors(ConverterForAtom03.createAtomPersons(authors)); aEntry.setAuthors(ConverterForAtom03.createAtomPersons(authors));
} else if (sEntry.getAuthor() != null) { } else if (sEntry.getAuthor() != null) {
Person person = new Person(); final Person person = new Person();
person.setName(sEntry.getAuthor()); person.setName(sEntry.getAuthor());
authors = new ArrayList(); authors = new ArrayList();
authors.add(person); authors.add(person);
aEntry.setAuthors(authors); aEntry.setAuthors(authors);
} }
List<SyndPerson> contributors = sEntry.getContributors(); final List<SyndPerson> contributors = sEntry.getContributors();
if (contributors!=null && contributors.size() > 0) { if (contributors != null && contributors.size() > 0) {
aEntry.setContributors(ConverterForAtom03.createAtomPersons(contributors)); aEntry.setContributors(ConverterForAtom03.createAtomPersons(contributors));
} }
@ -544,19 +542,19 @@ public class ConverterForAtom10 implements Converter {
// And issue #42 "Atom 1.0 Date (Updated or Published) Not Set" // And issue #42 "Atom 1.0 Date (Updated or Published) Not Set"
// Atom requires an updated date, if it's missing use the published date // Atom requires an updated date, if it's missing use the published date
if (sEntry.getUpdatedDate() != null) { if (sEntry.getUpdatedDate() != null) {
aEntry.setUpdated(sEntry.getUpdatedDate()); aEntry.setUpdated(sEntry.getUpdatedDate());
} else { } else {
aEntry.setUpdated(sEntry.getPublishedDate()); aEntry.setUpdated(sEntry.getPublishedDate());
} }
if (((List<Element>)sEntry.getForeignMarkup()).size() > 0) { if (sEntry.getForeignMarkup().size() > 0) {
aEntry.setForeignMarkup((List<Element>)sEntry.getForeignMarkup()); aEntry.setForeignMarkup(sEntry.getForeignMarkup());
} }
SyndFeed sSource = sEntry.getSource(); final SyndFeed sSource = sEntry.getSource();
if (sSource != null) { if (sSource != null) {
Feed aSource = (Feed) sSource.createWireFeed(getType()); final Feed aSource = (Feed) sSource.createWireFeed(getType());
aEntry.setSource(aSource); aEntry.setSource(aSource);
} }
return aEntry; return aEntry;
} }

View file

@ -16,85 +16,90 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.List;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.impl.ModuleUtils; import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.rss.Channel; import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Image; import com.sun.syndication.feed.rss.Image;
import com.sun.syndication.feed.rss.Item; import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.*; import com.sun.syndication.feed.synd.Converter;
import com.sun.syndication.feed.synd.SyndEntry;
import java.util.ArrayList; import com.sun.syndication.feed.synd.SyndEntryImpl;
import java.util.List; import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndImage;
import org.jdom2.Element; import com.sun.syndication.feed.synd.SyndImageImpl;
/** /**
*/ */
public class ConverterForRSS090 implements Converter { public class ConverterForRSS090 implements Converter {
private String _type; private final String _type;
public ConverterForRSS090() { public ConverterForRSS090() {
this("rss_0.9"); this("rss_0.9");
} }
protected ConverterForRSS090(String type) { protected ConverterForRSS090(final String type) {
_type = type; this._type = type;
} }
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
public void copyInto(WireFeed feed,SyndFeed syndFeed) { @Override
public void copyInto(final WireFeed feed, final SyndFeed syndFeed) {
syndFeed.setModules(ModuleUtils.cloneModules(feed.getModules())); syndFeed.setModules(ModuleUtils.cloneModules(feed.getModules()));
if (((List<Element>)feed.getForeignMarkup()).size() > 0) { if (feed.getForeignMarkup().size() > 0) {
syndFeed.setForeignMarkup(feed.getForeignMarkup()); syndFeed.setForeignMarkup(feed.getForeignMarkup());
} }
syndFeed.setEncoding(feed.getEncoding()); syndFeed.setEncoding(feed.getEncoding());
Channel channel = (Channel) feed; final Channel channel = (Channel) feed;
syndFeed.setTitle(channel.getTitle()); syndFeed.setTitle(channel.getTitle());
syndFeed.setLink(channel.getLink()); syndFeed.setLink(channel.getLink());
syndFeed.setDescription(channel.getDescription()); syndFeed.setDescription(channel.getDescription());
Image image = channel.getImage(); final Image image = channel.getImage();
if (image!=null) { if (image != null) {
syndFeed.setImage(createSyndImage(image)); syndFeed.setImage(createSyndImage(image));
} }
List<Item> items = channel.getItems(); final List<Item> items = channel.getItems();
if (items!=null) { if (items != null) {
syndFeed.setEntries(createSyndEntries(items, syndFeed.isPreservingWireFeed())); syndFeed.setEntries(createSyndEntries(items, syndFeed.isPreservingWireFeed()));
} }
} }
protected SyndImage createSyndImage(Image rssImage) { protected SyndImage createSyndImage(final Image rssImage) {
SyndImage syndImage = new SyndImageImpl(); final SyndImage syndImage = new SyndImageImpl();
syndImage.setTitle(rssImage.getTitle()); syndImage.setTitle(rssImage.getTitle());
syndImage.setUrl(rssImage.getUrl()); syndImage.setUrl(rssImage.getUrl());
syndImage.setLink(rssImage.getLink()); syndImage.setLink(rssImage.getLink());
return syndImage; return syndImage;
} }
protected List<SyndEntry> createSyndEntries(List<Item> rssItems, boolean preserveWireItems) { protected List<SyndEntry> createSyndEntries(final List<Item> rssItems, final boolean preserveWireItems) {
List<SyndEntry> syndEntries = new ArrayList<SyndEntry>(); final List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
for (int i=0;i<rssItems.size();i++) { for (int i = 0; i < rssItems.size(); i++) {
syndEntries.add(createSyndEntry((Item) rssItems.get(i), preserveWireItems)); syndEntries.add(createSyndEntry(rssItems.get(i), preserveWireItems));
} }
return syndEntries; return syndEntries;
} }
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Item item, final boolean preserveWireItem) {
SyndEntryImpl syndEntry = new SyndEntryImpl(); final SyndEntryImpl syndEntry = new SyndEntryImpl();
if (preserveWireItem) { if (preserveWireItem) {
syndEntry.setWireEntry(item); syndEntry.setWireEntry(item);
} }
syndEntry.setModules(ModuleUtils.cloneModules(item.getModules())); syndEntry.setModules(ModuleUtils.cloneModules(item.getModules()));
if (((List<Element>)item.getForeignMarkup()).size() > 0) { if (item.getForeignMarkup().size() > 0) {
syndEntry.setForeignMarkup(item.getForeignMarkup()); syndEntry.setForeignMarkup(item.getForeignMarkup());
} }
syndEntry.setUri(item.getUri()); syndEntry.setUri(item.getUri());
syndEntry.setLink(item.getLink()); syndEntry.setLink(item.getLink());
syndEntry.setTitle(item.getTitle()); syndEntry.setTitle(item.getTitle());
@ -102,12 +107,13 @@ public class ConverterForRSS090 implements Converter {
return syndEntry; return syndEntry;
} }
public WireFeed createRealFeed(SyndFeed syndFeed) { @Override
return createRealFeed(getType(),syndFeed); public WireFeed createRealFeed(final SyndFeed syndFeed) {
return this.createRealFeed(getType(), syndFeed);
} }
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) { protected WireFeed createRealFeed(final String type, final SyndFeed syndFeed) {
Channel channel = new Channel(type); final Channel channel = new Channel(type);
channel.setModules(ModuleUtils.cloneModules(syndFeed.getModules())); channel.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
channel.setEncoding(syndFeed.getEncoding()); channel.setEncoding(syndFeed.getEncoding());
@ -115,59 +121,56 @@ public class ConverterForRSS090 implements Converter {
channel.setTitle(syndFeed.getTitle()); channel.setTitle(syndFeed.getTitle());
if (syndFeed.getLink() != null) { if (syndFeed.getLink() != null) {
channel.setLink(syndFeed.getLink()); channel.setLink(syndFeed.getLink());
} } else if (syndFeed.getLinks().size() > 0) {
else channel.setLink(syndFeed.getLinks().get(0).getHref());
if (syndFeed.getLinks().size() > 0) {
channel.setLink(((SyndLink)syndFeed.getLinks().get(0)).getHref());
} }
channel.setDescription(syndFeed.getDescription()); channel.setDescription(syndFeed.getDescription());
SyndImage sImage = syndFeed.getImage(); final SyndImage sImage = syndFeed.getImage();
if (sImage!=null) { if (sImage != null) {
channel.setImage(createRSSImage(sImage)); channel.setImage(createRSSImage(sImage));
} }
List<SyndEntry> sEntries = syndFeed.getEntries(); final List<SyndEntry> sEntries = syndFeed.getEntries();
if (sEntries!=null) { if (sEntries != null) {
channel.setItems(createRSSItems(sEntries)); channel.setItems(createRSSItems(sEntries));
} }
if (((List<Element>)syndFeed.getForeignMarkup()).size() > 0) { if (syndFeed.getForeignMarkup().size() > 0) {
channel.setForeignMarkup(syndFeed.getForeignMarkup()); channel.setForeignMarkup(syndFeed.getForeignMarkup());
} }
return channel; return channel;
} }
protected Image createRSSImage(SyndImage sImage) { protected Image createRSSImage(final SyndImage sImage) {
Image image = new Image(); final Image image = new Image();
image.setTitle(sImage.getTitle()); image.setTitle(sImage.getTitle());
image.setUrl(sImage.getUrl()); image.setUrl(sImage.getUrl());
image.setLink(sImage.getLink()); image.setLink(sImage.getLink());
return image; return image;
} }
protected List<Item> createRSSItems(List<SyndEntry> sEntries) { protected List<Item> createRSSItems(final List<SyndEntry> sEntries) {
List<Item> list = new ArrayList<Item>(); final List<Item> list = new ArrayList<Item>();
for (int i=0;i<sEntries.size();i++) { for (int i = 0; i < sEntries.size(); i++) {
list.add(createRSSItem((SyndEntry)sEntries.get(i))); list.add(createRSSItem(sEntries.get(i)));
} }
return list; return list;
} }
protected Item createRSSItem(SyndEntry sEntry) { protected Item createRSSItem(final SyndEntry sEntry) {
Item item = new Item(); final Item item = new Item();
item.setModules(ModuleUtils.cloneModules(sEntry.getModules())); item.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
item.setTitle(sEntry.getTitle()); item.setTitle(sEntry.getTitle());
item.setLink(sEntry.getLink()); item.setLink(sEntry.getLink());
if (((List<Element>)sEntry.getForeignMarkup()).size() > 0) { if (sEntry.getForeignMarkup().size() > 0) {
item.setForeignMarkup(sEntry.getForeignMarkup()); item.setForeignMarkup(sEntry.getForeignMarkup());
} }
String uri = sEntry.getUri(); final String uri = sEntry.getUri();
if (uri != null) { if (uri != null) {
item.setUri(uri); item.setUri(uri);
} }
return item; return item;
} }

View file

@ -16,8 +16,6 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
/** /**
*/ */
public class ConverterForRSS091Netscape extends ConverterForRSS091Userland { public class ConverterForRSS091Netscape extends ConverterForRSS091Userland {
@ -26,7 +24,7 @@ public class ConverterForRSS091Netscape extends ConverterForRSS091Userland {
this("rss_0.91N"); this("rss_0.91N");
} }
protected ConverterForRSS091Netscape(String type) { protected ConverterForRSS091Netscape(final String type) {
super(type); super(type);
} }

View file

@ -16,6 +16,12 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.DCModule; import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.rss.Channel; import com.sun.syndication.feed.rss.Channel;
@ -30,13 +36,6 @@ import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndImage; import com.sun.syndication.feed.synd.SyndImage;
import com.sun.syndication.feed.synd.SyndPerson; import com.sun.syndication.feed.synd.SyndPerson;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** /**
*/ */
public class ConverterForRSS091Userland extends ConverterForRSS090 { public class ConverterForRSS091Userland extends ConverterForRSS090 {
@ -44,32 +43,34 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
this("rss_0.91U"); this("rss_0.91U");
} }
protected ConverterForRSS091Userland(String type) { protected ConverterForRSS091Userland(final String type) {
super(type); super(type);
} }
@Override @Override
public void copyInto(WireFeed feed, SyndFeed syndFeed) { public void copyInto(final WireFeed feed, final SyndFeed syndFeed) {
Channel channel = (Channel) feed; final Channel channel = (Channel) feed;
super.copyInto(channel, syndFeed); super.copyInto(channel, syndFeed);
syndFeed.setLanguage(channel.getLanguage()); //c syndFeed.setLanguage(channel.getLanguage()); // c
syndFeed.setCopyright(channel.getCopyright()); //c syndFeed.setCopyright(channel.getCopyright()); // c
Date pubDate = channel.getPubDate(); final Date pubDate = channel.getPubDate();
if (pubDate != null) { if (pubDate != null) {
syndFeed.setPublishedDate(pubDate); //c syndFeed.setPublishedDate(pubDate); // c
} else if (channel.getLastBuildDate() != null) { } else if (channel.getLastBuildDate() != null) {
syndFeed.setPublishedDate(channel.getLastBuildDate()); //c syndFeed.setPublishedDate(channel.getLastBuildDate()); // c
} }
String author = channel.getManagingEditor(); final String author = channel.getManagingEditor();
if (author != null) { if (author != null) {
List<String> creators = ((DCModule) syndFeed.getModule(DCModule.URI)).getCreators(); final List<String> creators = ((DCModule) syndFeed.getModule(DCModule.URI)).getCreators();
if (!creators.contains(author)) { if (!creators.contains(author)) {
Set<String> s = new HashSet<String>(); // using a set to remove duplicates final Set<String> s = new HashSet<String>(); // using a set to
// remove
// duplicates
s.addAll(creators); // DC creators s.addAll(creators); // DC creators
s.add(author); // feed native author s.add(author); // feed native author
creators.clear(); creators.clear();
@ -78,8 +79,8 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
} }
} }
protected Description createItemDescription(SyndContent sContent) { protected Description createItemDescription(final SyndContent sContent) {
Description desc = new Description(); final Description desc = new Description();
desc.setValue(sContent.getValue()); desc.setValue(sContent.getValue());
desc.setType(sContent.getType()); desc.setType(sContent.getType());
@ -87,8 +88,8 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
} }
@Override @Override
protected Image createRSSImage(SyndImage sImage) { protected Image createRSSImage(final SyndImage sImage) {
Image image = super.createRSSImage(sImage); final Image image = super.createRSSImage(sImage);
image.setDescription(sImage.getDescription()); image.setDescription(sImage.getDescription());
return image; return image;
@ -98,20 +99,20 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
// synd.content -> rss.content // synd.content -> rss.content
// synd.description -> rss.description // synd.description -> rss.description
@Override @Override
protected Item createRSSItem(SyndEntry sEntry) { protected Item createRSSItem(final SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry); final Item item = super.createRSSItem(sEntry);
SyndContent sContent = sEntry.getDescription(); final SyndContent sContent = sEntry.getDescription();
if (sContent != null) { if (sContent != null) {
item.setDescription(createItemDescription(sContent)); item.setDescription(createItemDescription(sContent));
} }
List<SyndContent> contents = sEntry.getContents(); final List<SyndContent> contents = sEntry.getContents();
if ((contents != null) && (contents.size() > 0)) { if (contents != null && contents.size() > 0) {
SyndContent syndContent = (SyndContent) contents.get(0); final SyndContent syndContent = contents.get(0);
Content cont = new Content(); final Content cont = new Content();
cont.setValue(syndContent.getValue()); cont.setValue(syndContent.getValue());
cont.setType(syndContent.getType()); cont.setType(syndContent.getType());
item.setContent(cont); item.setContent(cont);
@ -121,16 +122,14 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
} }
@Override @Override
protected WireFeed createRealFeed(String type, SyndFeed syndFeed) { protected WireFeed createRealFeed(final String type, final SyndFeed syndFeed) {
Channel channel = (Channel) super.createRealFeed(type, syndFeed); final Channel channel = (Channel) super.createRealFeed(type, syndFeed);
channel.setLanguage(syndFeed.getLanguage()); //c channel.setLanguage(syndFeed.getLanguage()); // c
channel.setCopyright(syndFeed.getCopyright()); //c channel.setCopyright(syndFeed.getCopyright()); // c
channel.setPubDate(syndFeed.getPublishedDate()); //c channel.setPubDate(syndFeed.getPublishedDate()); // c
if ((syndFeed.getAuthors() != null) && (syndFeed.getAuthors() if (syndFeed.getAuthors() != null && syndFeed.getAuthors().size() > 0) {
.size() > 0)) { final SyndPerson author = syndFeed.getAuthors().get(0);
SyndPerson author = (SyndPerson) syndFeed.getAuthors()
.get(0);
channel.setManagingEditor(author.getName()); channel.setManagingEditor(author.getName());
} }
@ -141,25 +140,25 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
// rss.content -> synd.content // rss.content -> synd.content
// rss.description -> synd.description // rss.description -> synd.description
@Override @Override
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Item item, final boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem); final SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
Description desc = item.getDescription(); final Description desc = item.getDescription();
if (desc != null) { if (desc != null) {
SyndContent descContent = new SyndContentImpl(); final SyndContent descContent = new SyndContentImpl();
descContent.setType(desc.getType()); descContent.setType(desc.getType());
descContent.setValue(desc.getValue()); descContent.setValue(desc.getValue());
syndEntry.setDescription(descContent); syndEntry.setDescription(descContent);
} }
Content cont = item.getContent(); final Content cont = item.getContent();
if (cont != null) { if (cont != null) {
SyndContent content = new SyndContentImpl(); final SyndContent content = new SyndContentImpl();
content.setType(cont.getType()); content.setType(cont.getType());
content.setValue(cont.getValue()); content.setValue(cont.getValue());
List<SyndContent> syndContents = new ArrayList<SyndContent>(); final List<SyndContent> syndContents = new ArrayList<SyndContent>();
syndContents.add(content); syndContents.add(content);
syndEntry.setContents(syndContents); syndEntry.setContents(syndContents);
} }
@ -168,8 +167,8 @@ public class ConverterForRSS091Userland extends ConverterForRSS090 {
} }
@Override @Override
protected SyndImage createSyndImage(Image rssImage) { protected SyndImage createSyndImage(final Image rssImage) {
SyndImage syndImage = super.createSyndImage(rssImage); final SyndImage syndImage = super.createSyndImage(rssImage);
syndImage.setDescription(rssImage.getDescription()); syndImage.setDescription(rssImage.getDescription());
return syndImage; return syndImage;

View file

@ -38,32 +38,47 @@ public class ConverterForRSS092 extends ConverterForRSS091Userland {
this("rss_0.92"); this("rss_0.92");
} }
protected ConverterForRSS092(String type) { protected ConverterForRSS092(final String type) {
super(type); super(type);
} }
@Override @Override
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Item item, final boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem); final SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
List<Category> cats = item.getCategories(); final List<Category> cats = item.getCategories();
if (cats.size()>0) { if (cats.size() > 0) {
Set<SyndCategory> s = new LinkedHashSet<SyndCategory>(); // using a set to remove duplicates and use a LinkedHashSet to try to retain the document order final Set<SyndCategory> s = new LinkedHashSet<SyndCategory>(); // using
s.addAll(createSyndCategories(cats)); // feed native categories (as syndcat) // a
s.addAll(syndEntry.getCategories()); // DC subjects (as syndcat) // set to
syndEntry.setCategories(new ArrayList<SyndCategory>(s)); //c // remove
// duplicates
// and use
// a
// LinkedHashSet
// to try
// to
// retain
// the
// document
// order
s.addAll(createSyndCategories(cats)); // feed native categories
// (as
// syndcat)
s.addAll(syndEntry.getCategories()); // DC subjects (as syndcat)
syndEntry.setCategories(new ArrayList<SyndCategory>(s)); // c
} }
List<Enclosure> enclosures = item.getEnclosures(); final List<Enclosure> enclosures = item.getEnclosures();
if (enclosures.size()>0) { if (enclosures.size() > 0) {
syndEntry.setEnclosures(createSyndEnclosures(enclosures)); syndEntry.setEnclosures(createSyndEnclosures(enclosures));
} }
return syndEntry; return syndEntry;
} }
protected List<SyndCategory> createSyndCategories(List<Category> rssCats) { protected List<SyndCategory> createSyndCategories(final List<Category> rssCats) {
List<SyndCategory> syndCats = new ArrayList<SyndCategory>(); final List<SyndCategory> syndCats = new ArrayList<SyndCategory>();
for (int i=0;i<rssCats.size();i++) { for (int i = 0; i < rssCats.size(); i++) {
Category rssCat = (Category) rssCats.get(i); final Category rssCat = rssCats.get(i);
SyndCategory sCat = new SyndCategoryImpl(); final SyndCategory sCat = new SyndCategoryImpl();
sCat.setTaxonomyUri(rssCat.getDomain()); sCat.setTaxonomyUri(rssCat.getDomain());
sCat.setName(rssCat.getValue()); sCat.setName(rssCat.getValue());
syndCats.add(sCat); syndCats.add(sCat);
@ -71,11 +86,11 @@ public class ConverterForRSS092 extends ConverterForRSS091Userland {
return syndCats; return syndCats;
} }
protected List<SyndEnclosure> createSyndEnclosures(List<Enclosure> enclosures) { protected List<SyndEnclosure> createSyndEnclosures(final List<Enclosure> enclosures) {
List<SyndEnclosure> sEnclosures = new ArrayList<SyndEnclosure>(); final List<SyndEnclosure> sEnclosures = new ArrayList<SyndEnclosure>();
for (int i=0;i<enclosures.size();i++) { for (int i = 0; i < enclosures.size(); i++) {
Enclosure enc = (Enclosure) enclosures.get(i); final Enclosure enc = enclosures.get(i);
SyndEnclosure sEnc = new SyndEnclosureImpl(); final SyndEnclosure sEnc = new SyndEnclosureImpl();
sEnc.setUrl(enc.getUrl()); sEnc.setUrl(enc.getUrl());
sEnc.setType(enc.getType()); sEnc.setType(enc.getType());
sEnc.setLength(enc.getLength()); sEnc.setLength(enc.getLength());
@ -85,25 +100,25 @@ public class ConverterForRSS092 extends ConverterForRSS091Userland {
} }
@Override @Override
protected Item createRSSItem(SyndEntry sEntry) { protected Item createRSSItem(final SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry); final Item item = super.createRSSItem(sEntry);
List<SyndCategory> sCats = sEntry.getCategories(); //c final List<SyndCategory> sCats = sEntry.getCategories(); // c
if (sCats.size()>0) { if (sCats.size() > 0) {
item.setCategories(createRSSCategories(sCats)); item.setCategories(createRSSCategories(sCats));
} }
List<SyndEnclosure> sEnclosures = sEntry.getEnclosures(); final List<SyndEnclosure> sEnclosures = sEntry.getEnclosures();
if (sEnclosures.size()>0) { if (sEnclosures.size() > 0) {
item.setEnclosures(createEnclosures(sEnclosures)); item.setEnclosures(createEnclosures(sEnclosures));
} }
return item; return item;
} }
protected List<Category> createRSSCategories(List<SyndCategory> sCats) { protected List<Category> createRSSCategories(final List<SyndCategory> sCats) {
List<Category> cats = new ArrayList<Category>(); final List<Category> cats = new ArrayList<Category>();
for (int i=0;i<sCats.size();i++) { for (int i = 0; i < sCats.size(); i++) {
SyndCategory sCat = (SyndCategory) sCats.get(i); final SyndCategory sCat = sCats.get(i);
Category cat = new Category(); final Category cat = new Category();
cat.setDomain(sCat.getTaxonomyUri()); cat.setDomain(sCat.getTaxonomyUri());
cat.setValue(sCat.getName()); cat.setValue(sCat.getName());
cats.add(cat); cats.add(cat);
@ -111,11 +126,11 @@ public class ConverterForRSS092 extends ConverterForRSS091Userland {
return cats; return cats;
} }
protected List<Enclosure> createEnclosures(List<SyndEnclosure> sEnclosures) { protected List<Enclosure> createEnclosures(final List<SyndEnclosure> sEnclosures) {
List<Enclosure> enclosures = new ArrayList<Enclosure>(); final List<Enclosure> enclosures = new ArrayList<Enclosure>();
for (int i=0;i<sEnclosures.size();i++) { for (int i = 0; i < sEnclosures.size(); i++) {
SyndEnclosure sEnc = (SyndEnclosure) sEnclosures.get(i); final SyndEnclosure sEnc = sEnclosures.get(i);
Enclosure enc = new Enclosure(); final Enclosure enc = new Enclosure();
enc.setUrl(sEnc.getUrl()); enc.setUrl(sEnc.getUrl());
enc.setType(sEnc.getType()); enc.setType(sEnc.getType());
enc.setLength(sEnc.getLength()); enc.setLength(sEnc.getLength());

View file

@ -16,11 +16,11 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import java.util.Date;
import com.sun.syndication.feed.rss.Item; import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntry;
import java.util.Date;
/** /**
*/ */
public class ConverterForRSS093 extends ConverterForRSS092 { public class ConverterForRSS093 extends ConverterForRSS092 {
@ -29,24 +29,24 @@ public class ConverterForRSS093 extends ConverterForRSS092 {
this("rss_0.93"); this("rss_0.93");
} }
protected ConverterForRSS093(String type) { protected ConverterForRSS093(final String type) {
super(type); super(type);
} }
@Override @Override
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Item item, final boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem); final SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
Date pubDate = item.getPubDate(); final Date pubDate = item.getPubDate();
if (pubDate!=null) { if (pubDate != null) {
syndEntry.setPublishedDate(pubDate); //c syndEntry.setPublishedDate(pubDate); // c
} }
return syndEntry; return syndEntry;
} }
@Override @Override
protected Item createRSSItem(SyndEntry sEntry) { protected Item createRSSItem(final SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry); final Item item = super.createRSSItem(sEntry);
item.setPubDate(sEntry.getPublishedDate()); //c item.setPubDate(sEntry.getPublishedDate()); // c
return item; return item;
} }

View file

@ -16,6 +16,11 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.DCModule; import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.rss.Category; import com.sun.syndication.feed.rss.Category;
@ -29,11 +34,6 @@ import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl; import com.sun.syndication.feed.synd.SyndLinkImpl;
import com.sun.syndication.feed.synd.SyndPerson; import com.sun.syndication.feed.synd.SyndPerson;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** /**
*/ */
public class ConverterForRSS094 extends ConverterForRSS093 { public class ConverterForRSS094 extends ConverterForRSS093 {
@ -42,52 +42,58 @@ public class ConverterForRSS094 extends ConverterForRSS093 {
this("rss_0.94"); this("rss_0.94");
} }
protected ConverterForRSS094(String type) { protected ConverterForRSS094(final String type) {
super(type); super(type);
} }
@Override @Override
public void copyInto(WireFeed feed,SyndFeed syndFeed) { public void copyInto(final WireFeed feed, final SyndFeed syndFeed) {
Channel channel = (Channel) feed; final Channel channel = (Channel) feed;
super.copyInto(channel,syndFeed); super.copyInto(channel, syndFeed);
List<Category> cats = channel.getCategories(); //c final List<Category> cats = channel.getCategories(); // c
if (cats.size()>0) { if (cats.size() > 0) {
Set<SyndCategory> s = new HashSet<SyndCategory>(); // using a set to remove duplicates final Set<SyndCategory> s = new HashSet<SyndCategory>(); // using a
s.addAll(createSyndCategories(cats)); // feed native categories (as syndcat) // set to
s.addAll(syndFeed.getCategories()); // DC subjects (as syndcat) // remove
// duplicates
s.addAll(createSyndCategories(cats)); // feed native categories
// (as
// syndcat)
s.addAll(syndFeed.getCategories()); // DC subjects (as syndcat)
syndFeed.setCategories(new ArrayList<SyndCategory>(s)); syndFeed.setCategories(new ArrayList<SyndCategory>(s));
} }
} }
@Override @Override
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) { protected SyndEntry createSyndEntry(final Item item, final boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem); final SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
// adding native feed author to DC creators list // adding native feed author to DC creators list
String author = item.getAuthor(); final String author = item.getAuthor();
if (author!=null) { if (author != null) {
List<String> creators = ((DCModule)syndEntry.getModule(DCModule.URI)).getCreators(); final List<String> creators = ((DCModule) syndEntry.getModule(DCModule.URI)).getCreators();
if (!creators.contains(author)) { if (!creators.contains(author)) {
Set<String> s = new HashSet<String>(); // using a set to remove duplicates final Set<String> s = new HashSet<String>(); // using a set to
s.addAll(creators); // DC creators // remove
s.add(author); // feed native author // duplicates
s.addAll(creators); // DC creators
s.add(author); // feed native author
creators.clear(); creators.clear();
creators.addAll(s); creators.addAll(s);
} }
} }
Guid guid = item.getGuid(); final Guid guid = item.getGuid();
if (guid!=null) { if (guid != null) {
syndEntry.setUri(guid.getValue()); syndEntry.setUri(guid.getValue());
if (item.getLink()==null && guid.isPermaLink()) { if (item.getLink() == null && guid.isPermaLink()) {
syndEntry.setLink(guid.getValue()); syndEntry.setLink(guid.getValue());
} }
} } else {
else {
syndEntry.setUri(item.getLink()); syndEntry.setUri(item.getLink());
} }
if(item.getComments() != null){ if (item.getComments() != null) {
SyndLinkImpl comments = new SyndLinkImpl(); final SyndLinkImpl comments = new SyndLinkImpl();
comments.setRel("comments"); comments.setRel("comments");
comments.setHref(item.getComments()); comments.setHref(item.getComments());
comments.setType("text/html"); comments.setType("text/html");
@ -95,43 +101,41 @@ public class ConverterForRSS094 extends ConverterForRSS093 {
return syndEntry; return syndEntry;
} }
@Override @Override
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) { protected WireFeed createRealFeed(final String type, final SyndFeed syndFeed) {
Channel channel = (Channel) super.createRealFeed(type,syndFeed); final Channel channel = (Channel) super.createRealFeed(type, syndFeed);
List<SyndCategory> cats = syndFeed.getCategories(); //c final List<SyndCategory> cats = syndFeed.getCategories(); // c
if (cats.size()>0) { if (cats.size() > 0) {
channel.setCategories(createRSSCategories(cats)); channel.setCategories(createRSSCategories(cats));
} }
return channel; return channel;
} }
@Override @Override
protected Item createRSSItem(SyndEntry sEntry) { protected Item createRSSItem(final SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry); final Item item = super.createRSSItem(sEntry);
if (sEntry.getAuthors()!=null && sEntry.getAuthors().size() > 0) { if (sEntry.getAuthors() != null && sEntry.getAuthors().size() > 0) {
SyndPerson author = (SyndPerson)sEntry.getAuthors().get(0); final SyndPerson author = sEntry.getAuthors().get(0);
item.setAuthor(author.getEmail()); item.setAuthor(author.getEmail());
} }
Guid guid = null; Guid guid = null;
String uri = sEntry.getUri(); final String uri = sEntry.getUri();
if (uri!=null) { if (uri != null) {
guid = new Guid(); guid = new Guid();
guid.setPermaLink(false); guid.setPermaLink(false);
guid.setValue(uri); guid.setValue(uri);
} } else {
else { final String link = sEntry.getLink();
String link = sEntry.getLink(); if (link != null) {
if (link!=null) {
guid = new Guid(); guid = new Guid();
guid.setPermaLink(true); guid.setPermaLink(true);
guid.setValue(link); guid.setValue(link);
} }
} }
item.setGuid(guid); item.setGuid(guid);
SyndLink comments = sEntry.findRelatedLink("comments"); final SyndLink comments = sEntry.findRelatedLink("comments");
if(comments != null && (comments.getType() == null || comments.getType().endsWith("html"))){ if (comments != null && (comments.getType() == null || comments.getType().endsWith("html"))) {
item.setComments(comments.getHref()); item.setComments(comments.getHref());
} }
return item; return item;

View file

@ -16,6 +16,9 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.List;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.rss.Channel; import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Content; import com.sun.syndication.feed.rss.Content;
@ -25,8 +28,6 @@ import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.feed.synd.SyndFeed;
import java.util.ArrayList;
import java.util.List;
/** /**
*/ */
@ -36,97 +37,97 @@ public class ConverterForRSS10 extends ConverterForRSS090 {
this("rss_1.0"); this("rss_1.0");
} }
protected ConverterForRSS10(String type) { protected ConverterForRSS10(final String type) {
super(type); super(type);
} }
@Override @Override
public void copyInto(WireFeed feed,SyndFeed syndFeed) { public void copyInto(final WireFeed feed, final SyndFeed syndFeed) {
Channel channel = (Channel) feed; final Channel channel = (Channel) feed;
super.copyInto(channel,syndFeed); super.copyInto(channel, syndFeed);
if (channel.getUri() != null) { if (channel.getUri() != null) {
syndFeed.setUri(channel.getUri()); syndFeed.setUri(channel.getUri());
} else { } else {
// if URI is not set use the value for link // if URI is not set use the value for link
syndFeed.setUri(channel.getLink()); syndFeed.setUri(channel.getLink());
} }
} }
// for rss -> synd // for rss -> synd
// rss.content -> synd.content // rss.content -> synd.content
// rss.description -> synd.description // rss.description -> synd.description
@Override
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
Description desc = item.getDescription(); @Override
if (desc!=null) { protected SyndEntry createSyndEntry(final Item item, final boolean preserveWireItem) {
SyndContent descContent = new SyndContentImpl(); final SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
final Description desc = item.getDescription();
if (desc != null) {
final SyndContent descContent = new SyndContentImpl();
descContent.setType(desc.getType()); descContent.setType(desc.getType());
descContent.setValue(desc.getValue()); descContent.setValue(desc.getValue());
syndEntry.setDescription(descContent); syndEntry.setDescription(descContent);
} }
Content cont = item.getContent(); final Content cont = item.getContent();
if (cont!=null) { if (cont != null) {
SyndContent contContent = new SyndContentImpl(); final SyndContent contContent = new SyndContentImpl();
contContent.setType(cont.getType()); contContent.setType(cont.getType());
contContent.setValue(cont.getValue()); contContent.setValue(cont.getValue());
List<SyndContent> contents = new ArrayList<SyndContent>(); final List<SyndContent> contents = new ArrayList<SyndContent>();
contents.add(contContent); contents.add(contContent);
syndEntry.setContents(contents); syndEntry.setContents(contents);
} }
return syndEntry; return syndEntry;
} }
@Override @Override
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) { protected WireFeed createRealFeed(final String type, final SyndFeed syndFeed) {
Channel channel = (Channel) super.createRealFeed(type,syndFeed); final Channel channel = (Channel) super.createRealFeed(type, syndFeed);
if (syndFeed.getUri() != null) { if (syndFeed.getUri() != null) {
channel.setUri(syndFeed.getUri()); channel.setUri(syndFeed.getUri());
} else { } else {
// if URI is not set use the value for link // if URI is not set use the value for link
channel.setUri(syndFeed.getLink()); channel.setUri(syndFeed.getLink());
} }
return channel; return channel;
} }
// for synd -> rss // for synd -> rss
// synd.content -> rss.content // synd.content -> rss.content
// synd.description -> rss.description // synd.description -> rss.description
@Override
protected Item createRSSItem(SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry);
SyndContent desc = sEntry.getDescription(); @Override
if (desc!=null) { protected Item createRSSItem(final SyndEntry sEntry) {
final Item item = super.createRSSItem(sEntry);
final SyndContent desc = sEntry.getDescription();
if (desc != null) {
item.setDescription(createItemDescription(desc)); item.setDescription(createItemDescription(desc));
} }
List<SyndContent> contents = sEntry.getContents(); final List<SyndContent> contents = sEntry.getContents();
if (contents!=null && contents.size() > 0) { if (contents != null && contents.size() > 0) {
item.setContent(createItemContent((SyndContent)contents.get(0))); item.setContent(createItemContent(contents.get(0)));
} }
String uri = sEntry.getUri(); final String uri = sEntry.getUri();
if (uri != null) { if (uri != null) {
item.setUri(uri); item.setUri(uri);
} }
return item; return item;
} }
protected Description createItemDescription(SyndContent sContent) { protected Description createItemDescription(final SyndContent sContent) {
Description desc = new Description(); final Description desc = new Description();
desc.setValue(sContent.getValue()); desc.setValue(sContent.getValue());
desc.setType(sContent.getType()); desc.setType(sContent.getType());
return desc; return desc;
} }
protected Content createItemContent(SyndContent sContent) { protected Content createItemContent(final SyndContent sContent) {
Content cont = new Content(); final Content cont = new Content();
cont.setValue(sContent.getValue()); cont.setValue(sContent.getValue());
cont.setType(sContent.getType()); cont.setType(sContent.getType());
return cont; return cont;

View file

@ -16,9 +16,6 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
/** /**
*/ */
public class ConverterForRSS20 extends ConverterForRSS094 { public class ConverterForRSS20 extends ConverterForRSS094 {
@ -27,7 +24,7 @@ public class ConverterForRSS20 extends ConverterForRSS094 {
this("rss_2.0"); this("rss_2.0");
} }
protected ConverterForRSS20(String type) { protected ConverterForRSS20(final String type) {
super(type); super(type);
} }

View file

@ -16,23 +16,20 @@
*/ */
package com.sun.syndication.feed.synd.impl; package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.io.impl.PluginManager;
import com.sun.syndication.feed.synd.Converter;
import java.util.List; import java.util.List;
import com.sun.syndication.feed.synd.Converter;
import com.sun.syndication.io.impl.PluginManager;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA. User: tucu Date: May 21, 2004 Time: 5:26:04 PM To
* User: tucu * change this template use Options | File Templates.
* Date: May 21, 2004
* Time: 5:26:04 PM
* To change this template use Options | File Templates.
*/ */
public class Converters extends PluginManager { public class Converters extends PluginManager {
/** /**
* Converter.classes= [className] ... * Converter.classes= [className] ...
* *
*/ */
public static final String CONVERTERS_KEY = "Converter.classes"; public static final String CONVERTERS_KEY = "Converter.classes";
@ -40,12 +37,13 @@ public class Converters extends PluginManager {
super(CONVERTERS_KEY); super(CONVERTERS_KEY);
} }
public Converter getConverter(String feedType) { public Converter getConverter(final String feedType) {
return (Converter) getPlugin(feedType); return (Converter) getPlugin(feedType);
} }
protected String getKey(Object obj) { @Override
return ((Converter)obj).getType(); protected String getKey(final Object obj) {
return ((Converter) obj).getType();
} }
public List getSupportedFeedTypes() { public List getSupportedFeedTypes() {

View file

@ -3,6 +3,7 @@ package com.sun.syndication.feed.synd.impl;
/** /**
* Utility class for normalizing an URI as specified in RFC 2396bis. * Utility class for normalizing an URI as specified in RFC 2396bis.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
*/ */
public class URINormalizer { public class URINormalizer {
@ -10,13 +11,15 @@ public class URINormalizer {
/** /**
* Normalizes an URI as specified in RFC 2396bis. * Normalizes an URI as specified in RFC 2396bis.
* <p> * <p>
*
* @param uri to normalize. * @param uri to normalize.
* @return the normalized value of the given URI, or <b>null</b> if the given URI was <b>null</b>. * @return the normalized value of the given URI, or <b>null</b> if the
* given URI was <b>null</b>.
*/ */
public static String normalize(String uri) { public static String normalize(final String uri) {
String normalizedUri = null; String normalizedUri = null;
if (uri!=null) { if (uri != null) {
normalizedUri = uri; //TODO THIS HAS TO BE IMPLEMENTED normalizedUri = uri; // TODO THIS HAS TO BE IMPLEMENTED
} }
return normalizedUri; return normalizedUri;
} }

View file

@ -2,15 +2,15 @@ package com.sun.syndication.io;
/** /**
* Adds the ability to give a direct wire feed generator reference to plugin * Adds the ability to give a direct wire feed generator reference to plugin
* modules that need to call back to their wire feed to complete * modules that need to call back to their wire feed to complete generation of
* generation of their particular namespace. Examples of such parsers * their particular namespace. Examples of such parsers include the
* include the SSE091Generator. * SSE091Generator.
*/ */
public interface DelegatingModuleGenerator extends ModuleGenerator { public interface DelegatingModuleGenerator extends ModuleGenerator {
/** /**
* Provides a parent wirefeed reference to this ModuleParser, * Provides a parent wirefeed reference to this ModuleParser, or
* or "plugin-in". * "plugin-in".
* *
* @param feedGenerator the parent wirefeed generator for this plugin. * @param feedGenerator the parent wirefeed generator for this plugin.
*/ */
void setFeedGenerator(WireFeedGenerator feedGenerator); void setFeedGenerator(WireFeedGenerator feedGenerator);

View file

@ -1,16 +1,15 @@
package com.sun.syndication.io; package com.sun.syndication.io;
/** /**
* Adds the ability to give a direct wire feed reference to plugin * Adds the ability to give a direct wire feed reference to plugin modules that
* modules that need to call back to their wire feed to complete * need to call back to their wire feed to complete parsing of their particular
* parsing of their particular namespace. Examples of such parsers * namespace. Examples of such parsers include the SSE091Parser.
* include the SSE091Parser.
*/ */
public interface DelegatingModuleParser extends ModuleParser { public interface DelegatingModuleParser extends ModuleParser {
/** /**
* Provides a parent wirefeed reference to this ModuleParser, * Provides a parent wirefeed reference to this ModuleParser, or
* or "plugin-in". * "plugin-in".
* *
* @param feedParser the parent wirefeed parser for this plugin. * @param feedParser the parent wirefeed parser for this plugin.
*/ */
void setFeedParser(WireFeedParser feedParser); void setFeedParser(WireFeedParser feedParser);

View file

@ -17,33 +17,36 @@
package com.sun.syndication.io; package com.sun.syndication.io;
/** /**
* Exception thrown by WireFeedInput, WireFeedOutput, WireFeedParser and WireFeedGenerator instances if they * Exception thrown by WireFeedInput, WireFeedOutput, WireFeedParser and
* can not parse or generate a feed. * WireFeedGenerator instances if they can not parse or generate a feed.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class FeedException extends Exception { public class FeedException extends Exception {
/** /**
* Creates a FeedException with a message. * Creates a FeedException with a message.
* <p> * <p>
*
* @param msg exception message. * @param msg exception message.
* *
*/ */
public FeedException(String msg) { public FeedException(final String msg) {
super(msg); super(msg);
} }
/** /**
* Creates a FeedException with a message and a root cause exception. * Creates a FeedException with a message and a root cause exception.
* <p> * <p>
*
* @param msg exception message. * @param msg exception message.
* @param rootCause root cause exception. * @param rootCause root cause exception.
* *
*/ */
public FeedException(String msg,Throwable rootCause) { public FeedException(final String msg, final Throwable rootCause) {
super(msg,rootCause); super(msg, rootCause);
} }
} }

View file

@ -16,10 +16,11 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.module.Module; import java.util.Set;
import org.jdom2.Element; import org.jdom2.Element;
import java.util.Set; import com.sun.syndication.feed.module.Module;
/** /**
* Injects module metadata into a XML node (JDOM element). * Injects module metadata into a XML node (JDOM element).
@ -28,35 +29,41 @@ import java.util.Set;
* <p> * <p>
* TODO: explain how developers can plugin their own implementations. * TODO: explain how developers can plugin their own implementations.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface ModuleGenerator { public interface ModuleGenerator {
/** /**
* Returns the namespace URI this generator handles. * Returns the namespace URI this generator handles.
* <p> * <p>
*
* @return the namespace URI. * @return the namespace URI.
* *
*/ */
public String getNamespaceUri(); public String getNamespaceUri();
/** /**
* Returns a set with all the URIs (JDOM Namespace elements) this module generator uses. * Returns a set with all the URIs (JDOM Namespace elements) this module
* generator uses.
* <p/> * <p/>
* It is used by the the feed generators to add their namespace definition in * It is used by the the feed generators to add their namespace definition
* the root element of the generated document (forward-missing of Java 5.0 Generics). * in the root element of the generated document (forward-missing of Java
* 5.0 Generics).
* <p/> * <p/>
* *
* @return a set with all the URIs (JDOM Namespace elements) this module generator uses. * @return a set with all the URIs (JDOM Namespace elements) this module
* generator uses.
*/ */
public Set getNamespaces(); public Set getNamespaces();
/** /**
* Generates and injects module metadata into an XML node (JDOM element). * Generates and injects module metadata into an XML node (JDOM element).
* <p> * <p>
*
* @param module the module to inject into the XML node (JDOM element). * @param module the module to inject into the XML node (JDOM element).
* @param element the XML node into which module meta-data will be injected. * @param element the XML node into which module meta-data will be injected.
*/ */
public void generate(Module module,Element element); public void generate(Module module, Element element);
} }

View file

@ -16,9 +16,10 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.module.Module;
import org.jdom2.Element; import org.jdom2.Element;
import com.sun.syndication.feed.module.Module;
/** /**
* Parses module metadata from a XML node (JDOM element). * Parses module metadata from a XML node (JDOM element).
* <p> * <p>
@ -26,25 +27,30 @@ import org.jdom2.Element;
* <p> * <p>
* TODO: explain how developers can plugin their own implementations. * TODO: explain how developers can plugin their own implementations.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface ModuleParser { public interface ModuleParser {
/** /**
* Returns the namespace URI this parser handles. * Returns the namespace URI this parser handles.
* <p> * <p>
*
* @return the namespace URI. * @return the namespace URI.
* *
*/ */
public String getNamespaceUri(); public String getNamespaceUri();
/** /**
* Parses the XML node (JDOM element) extracting module information. * Parses the XML node (JDOM element) extracting module information.
* <p> * <p>
* @param element the XML node (JDOM element) to extract module information from. *
* @return a module instance, <b>null</b> if the element did not have module information. * @param element the XML node (JDOM element) to extract module information
* * from.
* @return a module instance, <b>null</b> if the element did not have module
* information.
*
*/ */
public Module parse(Element element); public Module parse(Element element);
} }

View file

@ -21,58 +21,61 @@ import org.jdom2.input.JDOMParseException;
/** /**
* Exception thrown by WireFeedInput instance if it can not parse a feed. * Exception thrown by WireFeedInput instance if it can not parse a feed.
* <p> * <p>
*
* @author Elaine Chien * @author Elaine Chien
* *
*/ */
public class ParsingFeedException extends FeedException { public class ParsingFeedException extends FeedException {
/** /**
* Creates a FeedException with a message. * Creates a FeedException with a message.
* <p> * <p>
*
* @param msg exception message. * @param msg exception message.
* *
*/ */
public ParsingFeedException(String msg) { public ParsingFeedException(final String msg) {
super(msg); super(msg);
} }
/** /**
* Creates a FeedException with a message and a root cause exception. * Creates a FeedException with a message and a root cause exception.
* <p> * <p>
*
* @param msg exception message. * @param msg exception message.
* @param rootCause root cause exception. * @param rootCause root cause exception.
* *
*/ */
public ParsingFeedException(String msg, Throwable rootCause) { public ParsingFeedException(final String msg, final Throwable rootCause) {
super(msg, rootCause); super(msg, rootCause);
} }
/**
* Returns the line number of the end of the text where the
* parse error occurred.
* <p>
* The first line in the document is line 1.</p>
*
* @return an integer representing the line number, or -1
* if the information is not available.
*/
public int getLineNumber() {
return (getCause() instanceof JDOMParseException)?
((JDOMParseException)getCause()).getLineNumber(): -1;
}
/** /**
* Returns the column number of the end of the text where the * Returns the line number of the end of the text where the parse error
* parse error occurred. * occurred.
* <p> * <p>
* The first column in a line is position 1.</p> * The first line in the document is line 1.
* * </p>
* @return an integer representing the column number, or -1 *
* if the information is not available. * @return an integer representing the line number, or -1 if the information
* is not available.
*/
public int getLineNumber() {
return getCause() instanceof JDOMParseException ? ((JDOMParseException) getCause()).getLineNumber() : -1;
}
/**
* Returns the column number of the end of the text where the parse error
* occurred.
* <p>
* The first column in a line is position 1.
* </p>
*
* @return an integer representing the column number, or -1 if the
* information is not available.
*/ */
public int getColumnNumber() { public int getColumnNumber() {
return (getCause() instanceof JDOMParseException)? return getCause() instanceof JDOMParseException ? ((JDOMParseException) getCause()).getColumnNumber() : -1;
((JDOMParseException)getCause()).getColumnNumber(): -1;
} }
} }

View file

@ -17,21 +17,24 @@ import org.xml.sax.XMLReader;
* *
*/ */
public class SAXBuilder extends org.jdom2.input.SAXBuilder { public class SAXBuilder extends org.jdom2.input.SAXBuilder {
public SAXBuilder(XMLReaderJDOMFactory factory) { public SAXBuilder(final XMLReaderJDOMFactory factory) {
super(factory); super(factory);
} }
/** /**
* *
* @deprecated use SAXBuilder(XMLReaderJDOMFactory) with either XMLReaders.DTDVALIDATING or XMLReaders.NONVALIDATING * @deprecated use SAXBuilder(XMLReaderJDOMFactory) with either
* @param _validate * XMLReaders.DTDVALIDATING or XMLReaders.NONVALIDATING
*/ * @param _validate
public SAXBuilder(boolean _validate) { */
super(_validate ? XMLReaders.DTDVALIDATING : XMLReaders.NONVALIDATING); @Deprecated
} public SAXBuilder(final boolean _validate) {
super(_validate ? XMLReaders.DTDVALIDATING : XMLReaders.NONVALIDATING);
}
@Override
public XMLReader createParser() throws JDOMException {
return super.createParser();
}
public XMLReader createParser() throws JDOMException {
return super.createParser();
}
} }

View file

@ -16,33 +16,35 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import org.jdom2.Document;
import org.xml.sax.InputSource;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import org.jdom2.Document;
import org.xml.sax.InputSource;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
/** /**
* Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C DOM Document or JDom DOcument) * Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C
* into an SyndFeedImpl. * DOM Document or JDom DOcument) into an SyndFeedImpl.
* <p> * <p>
* It delegates to a WireFeedInput to handle all feed types. * It delegates to a WireFeedInput to handle all feed types.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyndFeedInput { public class SyndFeedInput {
private WireFeedInput _feedInput; private final WireFeedInput _feedInput;
private boolean preserveWireFeed = false; private boolean preserveWireFeed = false;
/** /**
* Creates a SyndFeedInput instance with input validation turned off. * Creates a SyndFeedInput instance with input validation turned off.
* <p> * <p>
* *
*/ */
public SyndFeedInput() { public SyndFeedInput() {
this(false); this(false);
@ -51,131 +53,153 @@ public class SyndFeedInput {
/** /**
* Creates a SyndFeedInput instance. * Creates a SyndFeedInput instance.
* <p> * <p>
* @param validate indicates if the input should be validated. NOT IMPLEMENTED YET (validation does not happen) *
* * @param validate indicates if the input should be validated. NOT
* IMPLEMENTED YET (validation does not happen)
*
*/ */
public SyndFeedInput(boolean validate) { public SyndFeedInput(final boolean validate) {
_feedInput = new WireFeedInput(validate); this._feedInput = new WireFeedInput(validate);
} }
/** /**
* Enables XML healing in the WiredFeedInput instance. * Enables XML healing in the WiredFeedInput instance.
* <p> * <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog. * Healing trims leading chars from the stream (empty spaces and comments)
* until the XML prolog.
* <p> * <p>
* Healing resolves HTML entities (from literal to code number) in the reader. * Healing resolves HTML entities (from literal to code number) in the
* reader.
* <p> * <p>
* The healing is done only with the build(File) and build(Reader) signatures. * The healing is done only with the build(File) and build(Reader)
* signatures.
* <p> * <p>
* By default is TRUE. * By default is TRUE.
* <p> * <p>
*
* @param heals TRUE enables stream healing, FALSE disables it. * @param heals TRUE enables stream healing, FALSE disables it.
* *
*/ */
public void setXmlHealerOn(boolean heals) { public void setXmlHealerOn(final boolean heals) {
_feedInput.setXmlHealerOn(heals); this._feedInput.setXmlHealerOn(heals);
} }
/** /**
* Indicates if the WiredFeedInput instance will XML heal (if necessary) the character stream. * Indicates if the WiredFeedInput instance will XML heal (if necessary) the
* character stream.
* <p> * <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog. * Healing trims leading chars from the stream (empty spaces and comments)
* until the XML prolog.
* <p> * <p>
* Healing resolves HTML entities (from literal to code number) in the reader. * Healing resolves HTML entities (from literal to code number) in the
* reader.
* <p> * <p>
* The healing is done only with the build(File) and build(Reader) signatures. * The healing is done only with the build(File) and build(Reader)
* signatures.
* <p> * <p>
* By default is TRUE. * By default is TRUE.
* <p> * <p>
*
* @return TRUE if healing is enabled, FALSE if not. * @return TRUE if healing is enabled, FALSE if not.
* *
*/ */
public boolean getXmlHealerOn() { public boolean getXmlHealerOn() {
return _feedInput.getXmlHealerOn(); return this._feedInput.getXmlHealerOn();
} }
/** /**
* Builds SyndFeedImpl from a file. * Builds SyndFeedImpl from a file.
* <p> * <p>
*
* @param file file to read to create the SyndFeedImpl. * @param file file to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the file. * @return the SyndFeedImpl read from the file.
* @throws FileNotFoundException thrown if the file could not be found. * @throws FileNotFoundException thrown if the file could not be found.
* @throws IOException thrown if there is problem reading the file. * @throws IOException thrown if there is problem reading the file.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public SyndFeed build(File file) throws FileNotFoundException,IOException,IllegalArgumentException,FeedException { public SyndFeed build(final File file) throws FileNotFoundException, IOException, IllegalArgumentException, FeedException {
return new SyndFeedImpl(_feedInput.build(file), preserveWireFeed); return new SyndFeedImpl(this._feedInput.build(file), this.preserveWireFeed);
} }
/** /**
* Builds SyndFeedImpl from an Reader. * Builds SyndFeedImpl from an Reader.
* <p> * <p>
*
* @param reader Reader to read to create the SyndFeedImpl. * @param reader Reader to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the Reader. * @return the SyndFeedImpl read from the Reader.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public SyndFeed build(Reader reader) throws IllegalArgumentException,FeedException { public SyndFeed build(final Reader reader) throws IllegalArgumentException, FeedException {
return new SyndFeedImpl(_feedInput.build(reader), preserveWireFeed); return new SyndFeedImpl(this._feedInput.build(reader), this.preserveWireFeed);
} }
/** /**
* Builds SyndFeedImpl from an W3C SAX InputSource. * Builds SyndFeedImpl from an W3C SAX InputSource.
* <p> * <p>
*
* @param is W3C SAX InputSource to read to create the SyndFeedImpl. * @param is W3C SAX InputSource to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the W3C SAX InputSource. * @return the SyndFeedImpl read from the W3C SAX InputSource.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public SyndFeed build(InputSource is) throws IllegalArgumentException,FeedException { public SyndFeed build(final InputSource is) throws IllegalArgumentException, FeedException {
return new SyndFeedImpl(_feedInput.build(is), preserveWireFeed); return new SyndFeedImpl(this._feedInput.build(is), this.preserveWireFeed);
} }
/** /**
* Builds SyndFeedImpl from an W3C DOM document. * Builds SyndFeedImpl from an W3C DOM document.
* <p> * <p>
*
* @param document W3C DOM document to read to create the SyndFeedImpl. * @param document W3C DOM document to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the W3C DOM document. * @return the SyndFeedImpl read from the W3C DOM document.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public SyndFeed build(org.w3c.dom.Document document) throws IllegalArgumentException,FeedException { public SyndFeed build(final org.w3c.dom.Document document) throws IllegalArgumentException, FeedException {
return new SyndFeedImpl(_feedInput.build(document), preserveWireFeed); return new SyndFeedImpl(this._feedInput.build(document), this.preserveWireFeed);
} }
/** /**
* Builds SyndFeedImpl from an JDOM document. * Builds SyndFeedImpl from an JDOM document.
* <p> * <p>
*
* @param document JDOM document to read to create the SyndFeedImpl. * @param document JDOM document to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the JDOM document. * @return the SyndFeedImpl read from the JDOM document.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public SyndFeed build(Document document) throws IllegalArgumentException,FeedException { public SyndFeed build(final Document document) throws IllegalArgumentException, FeedException {
return new SyndFeedImpl(_feedInput.build(document), preserveWireFeed); return new SyndFeedImpl(this._feedInput.build(document), this.preserveWireFeed);
} }
/** /**
* *
* @return true if the WireFeed is made available in the SyndFeed. False by default. * @return true if the WireFeed is made available in the SyndFeed. False by
* default.
*/ */
public boolean isPreserveWireFeed() { public boolean isPreserveWireFeed() {
return preserveWireFeed; return this.preserveWireFeed;
} }
/** /**
* *
* @param preserveWireFeed set to true to make the WireFeed is made available in the SyndFeed. False by default. * @param preserveWireFeed set to true to make the WireFeed is made
*/ * available in the SyndFeed. False by default.
public void setPreserveWireFeed(boolean preserveWireFeed) { */
this.preserveWireFeed = preserveWireFeed; public void setPreserveWireFeed(final boolean preserveWireFeed) {
} this.preserveWireFeed = preserveWireFeed;
}
} }

View file

@ -16,141 +16,175 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.synd.SyndFeed;
import org.jdom2.Document;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import org.jdom2.Document;
import com.sun.syndication.feed.synd.SyndFeed;
/** /**
* Generates an XML document (String, File, OutputStream, Writer, W3C DOM document or JDOM document) * Generates an XML document (String, File, OutputStream, Writer, W3C DOM
* out of an SyndFeedImpl.. * document or JDOM document) out of an SyndFeedImpl..
* <p> * <p>
* It delegates to a WireFeedOutput to generate all feed types. * It delegates to a WireFeedOutput to generate all feed types.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class SyndFeedOutput { public class SyndFeedOutput {
private WireFeedOutput _feedOutput; private final WireFeedOutput _feedOutput;
/** /**
* Creates a SyndFeedOutput instance. * Creates a SyndFeedOutput instance.
* <p> * <p>
* *
*/ */
public SyndFeedOutput() { public SyndFeedOutput() {
_feedOutput = new WireFeedOutput(); this._feedOutput = new WireFeedOutput();
} }
/** /**
* Creates a String with the XML representation for the given SyndFeedImpl. * Creates a String with the XML representation for the given SyndFeedImpl.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as * encoding attribute. It is the responsibility of the developer to ensure
* the feed encoding property. * that if the String is written to a character stream the stream charset is
* the same as the feed encoding property.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* the SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @return a String with the XML representation for the given SyndFeedImpl. * @return a String with the XML representation for the given SyndFeedImpl.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws FeedException thrown if the XML representation for the feed could
* * not be created.
*
*/ */
public String outputString(SyndFeed feed) throws FeedException { public String outputString(final SyndFeed feed) throws FeedException {
return _feedOutput.outputString(feed.createWireFeed()); return this._feedOutput.outputString(feed.createWireFeed());
} }
/** /**
* Creates a String with the XML representation for the given SyndFeedImpl. * Creates a String with the XML representation for the given SyndFeedImpl.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as * encoding attribute. It is the responsibility of the developer to ensure
* the feed encoding property. * that if the String is written to a character stream the stream charset is
* the same as the feed encoding property.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* the SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @param prettyPrint pretty-print XML (true) oder collapsed * @param prettyPrint pretty-print XML (true) oder collapsed
* @return a String with the XML representation for the given SyndFeedImpl. * @return a String with the XML representation for the given SyndFeedImpl.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws FeedException thrown if the XML representation for the feed could
* * not be created.
*
*/ */
public String outputString(SyndFeed feed,boolean prettyPrint) throws FeedException { public String outputString(final SyndFeed feed, final boolean prettyPrint) throws FeedException {
return _feedOutput.outputString(feed.createWireFeed(),prettyPrint); return this._feedOutput.outputString(feed.createWireFeed(), prettyPrint);
} }
/** /**
* Creates a File containing with the XML representation for the given SyndFeedImpl. * Creates a File containing with the XML representation for the given
* SyndFeedImpl.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform * If the feed encoding is not NULL, it will be used in the XML prolog
* default charset encoding is used to write the feed to the file. It is the responsibility * encoding attribute. The platform default charset encoding is used to
* of the developer to ensure the feed encoding is set to the platform charset encoding. * write the feed to the file. It is the responsibility of the developer to
* ensure the feed encoding is set to the platform charset encoding.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* @param file the file where to write the XML representation for the given SyndFeedImpl. * the SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @param file the file where to write the XML representation for the given
* SyndFeedImpl.
* @throws IOException thrown if there was some problem writing to the File. * @throws IOException thrown if there was some problem writing to the File.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws FeedException thrown if the XML representation for the feed could
* * not be created.
*
*/ */
public void output(SyndFeed feed,File file) throws IOException, FeedException { public void output(final SyndFeed feed, final File file) throws IOException, FeedException {
_feedOutput.output(feed.createWireFeed(),file); this._feedOutput.output(feed.createWireFeed(), file);
} }
/** /**
* Creates a File containing with the XML representation for the given SyndFeedImpl. * Creates a File containing with the XML representation for the given
* SyndFeedImpl.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform * If the feed encoding is not NULL, it will be used in the XML prolog
* default charset encoding is used to write the feed to the file. It is the responsibility * encoding attribute. The platform default charset encoding is used to
* of the developer to ensure the feed encoding is set to the platform charset encoding. * write the feed to the file. It is the responsibility of the developer to
* ensure the feed encoding is set to the platform charset encoding.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* the SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @param prettyPrint pretty-print XML (true) oder collapsed * @param prettyPrint pretty-print XML (true) oder collapsed
* @param file the file where to write the XML representation for the given SyndFeedImpl. * @param file the file where to write the XML representation for the given
* SyndFeedImpl.
* @throws IOException thrown if there was some problem writing to the File. * @throws IOException thrown if there was some problem writing to the File.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws FeedException thrown if the XML representation for the feed could
* * not be created.
*
*/ */
public void output(SyndFeed feed,File file,boolean prettyPrint) throws IOException, FeedException { public void output(final SyndFeed feed, final File file, final boolean prettyPrint) throws IOException, FeedException {
_feedOutput.output(feed.createWireFeed(),file,prettyPrint); this._feedOutput.output(feed.createWireFeed(), file, prettyPrint);
} }
/** /**
* Writes to an Writer the XML representation for the given SyndFeedImpl. * Writes to an Writer the XML representation for the given SyndFeedImpl.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as * encoding attribute. It is the responsibility of the developer to ensure
* the feed encoding property. * that if the String is written to a character stream the stream charset is
* the same as the feed encoding property.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* @param writer Writer to write the XML representation for the given SyndFeedImpl. * the SyndFeedImpl must match the type given to the FeedOuptut
* @throws IOException thrown if there was some problem writing to the Writer. * constructor.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @param writer Writer to write the XML representation for the given
* * SyndFeedImpl.
* @throws IOException thrown if there was some problem writing to the
* Writer.
* @throws FeedException thrown if the XML representation for the feed could
* not be created.
*
*/ */
public void output(SyndFeed feed,Writer writer) throws IOException, FeedException { public void output(final SyndFeed feed, final Writer writer) throws IOException, FeedException {
_feedOutput.output(feed.createWireFeed(),writer); this._feedOutput.output(feed.createWireFeed(), writer);
} }
/** /**
* Writes to an Writer the XML representation for the given SyndFeedImpl. * Writes to an Writer the XML representation for the given SyndFeedImpl.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as * encoding attribute. It is the responsibility of the developer to ensure
* the feed encoding property. * that if the String is written to a character stream the stream charset is
* the same as the feed encoding property.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* the SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @param prettyPrint pretty-print XML (true) oder collapsed * @param prettyPrint pretty-print XML (true) oder collapsed
* @param writer Writer to write the XML representation for the given SyndFeedImpl. * @param writer Writer to write the XML representation for the given
* @throws IOException thrown if there was some problem writing to the Writer. * SyndFeedImpl.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws IOException thrown if there was some problem writing to the
* * Writer.
* @throws FeedException thrown if the XML representation for the feed could
* not be created.
*
*/ */
public void output(SyndFeed feed,Writer writer,boolean prettyPrint) throws IOException, FeedException { public void output(final SyndFeed feed, final Writer writer, final boolean prettyPrint) throws IOException, FeedException {
_feedOutput.output(feed.createWireFeed(),writer,prettyPrint); this._feedOutput.output(feed.createWireFeed(), writer, prettyPrint);
} }
/** /**
@ -158,14 +192,17 @@ public class SyndFeedOutput {
* <p> * <p>
* This method does not use the feed encoding property. * This method does not use the feed encoding property.
* <p> * <p>
* @param feed Abstract feed to create W3C DOM document from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create W3C DOM document from. The type of
* the SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @return the W3C DOM document for the given SyndFeedImpl. * @return the W3C DOM document for the given SyndFeedImpl.
* @throws FeedException thrown if the W3C DOM document for the feed could not be created. * @throws FeedException thrown if the W3C DOM document for the feed could
* * not be created.
*
*/ */
public org.w3c.dom.Document outputW3CDom(SyndFeed feed) throws FeedException { public org.w3c.dom.Document outputW3CDom(final SyndFeed feed) throws FeedException {
return _feedOutput.outputW3CDom(feed.createWireFeed()); return this._feedOutput.outputW3CDom(feed.createWireFeed());
} }
/** /**
@ -173,14 +210,17 @@ public class SyndFeedOutput {
* <p> * <p>
* This method does not use the feed encoding property. * This method does not use the feed encoding property.
* <p> * <p>
* @param feed Abstract feed to create JDOM document from. The type of the SyndFeedImpl must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create JDOM document from. The type of the
* SyndFeedImpl must match the type given to the FeedOuptut
* constructor.
* @return the JDOM document for the given SyndFeedImpl. * @return the JDOM document for the given SyndFeedImpl.
* @throws FeedException thrown if the JDOM document for the feed could not be created. * @throws FeedException thrown if the JDOM document for the feed could not
* * be created.
*
*/ */
public Document outputJDom(SyndFeed feed) throws FeedException { public Document outputJDom(final SyndFeed feed) throws FeedException {
return _feedOutput.outputJDom(feed.createWireFeed()); return this._feedOutput.outputJDom(feed.createWireFeed());
} }
} }

View file

@ -16,10 +16,10 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.FeedException;
import org.jdom2.Document; import org.jdom2.Document;
import com.sun.syndication.feed.WireFeed;
/** /**
* Generates an XML document (JDOM) out of a feed for a specific real feed type. * Generates an XML document (JDOM) out of a feed for a specific real feed type.
* <p> * <p>
@ -27,31 +27,34 @@ import org.jdom2.Document;
* <p> * <p>
* TODO: explain how developers can plugin their own implementations. * TODO: explain how developers can plugin their own implementations.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface WireFeedGenerator { public interface WireFeedGenerator {
/** /**
* Returns the type of feed the generator creates. * Returns the type of feed the generator creates.
* <p> * <p>
*
* @see WireFeed for details on the format of this string. * @see WireFeed for details on the format of this string.
* <p> * <p>
* @return the type of feed the generator creates. * @return the type of feed the generator creates.
* *
*/ */
public String getType(); public String getType();
/** /**
* Creates an XML document (JDOM) for the given feed bean. * Creates an XML document (JDOM) for the given feed bean.
* <p> * <p>
*
* @param feed the feed bean to generate the XML document from. * @param feed the feed bean to generate the XML document from.
* @return the generated XML document (JDOM). * @return the generated XML document (JDOM).
* @throws IllegalArgumentException thrown if the type of the given feed bean does not * @throws IllegalArgumentException thrown if the type of the given feed
* match with the type of the WireFeedGenerator. * bean does not match with the type of the WireFeedGenerator.
* @throws FeedException thrown if the XML Document could not be created. * @throws FeedException thrown if the XML Document could not be created.
* *
*/ */
public Document generate(WireFeed feed) throws IllegalArgumentException,FeedException; public Document generate(WireFeed feed) throws IllegalArgumentException, FeedException;
} }

View file

@ -30,6 +30,7 @@ import org.jdom2.Document;
import org.jdom2.JDOMException; import org.jdom2.JDOMException;
import org.jdom2.input.DOMBuilder; import org.jdom2.input.DOMBuilder;
import org.jdom2.input.JDOMParseException; import org.jdom2.input.JDOMParseException;
import org.jdom2.input.sax.XMLReaders;
import org.xml.sax.EntityResolver; import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotRecognizedException;
@ -39,28 +40,28 @@ import org.xml.sax.XMLReader;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.impl.FeedParsers; import com.sun.syndication.io.impl.FeedParsers;
import com.sun.syndication.io.impl.XmlFixerReader; import com.sun.syndication.io.impl.XmlFixerReader;
import org.jdom2.input.sax.XMLReaders;
/** /**
* Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C DOM Document or JDom DOcument) * Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C
* into an WireFeed (RSS/Atom). * DOM Document or JDom DOcument) into an WireFeed (RSS/Atom).
* <p> * <p>
* It accepts all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and * It accepts all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and
* Atom 0.3 feeds. Parsers are plugable (they must implement the WireFeedParser interface). * Atom 0.3 feeds. Parsers are plugable (they must implement the WireFeedParser
* interface).
* <p> * <p>
* The WireFeedInput useds liberal parsers. * The WireFeedInput useds liberal parsers.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class WireFeedInput { public class WireFeedInput {
private static Map clMap = new WeakHashMap(); private static Map clMap = new WeakHashMap();
private static FeedParsers getFeedParsers() { private static FeedParsers getFeedParsers() {
synchronized(WireFeedInput.class) { synchronized (WireFeedInput.class) {
FeedParsers parsers = (FeedParsers) FeedParsers parsers = (FeedParsers) clMap.get(Thread.currentThread().getContextClassLoader());
clMap.get(Thread.currentThread().getContextClassLoader());
if (parsers == null) { if (parsers == null) {
parsers = new FeedParsers(); parsers = new FeedParsers();
clMap.put(Thread.currentThread().getContextClassLoader(), parsers); clMap.put(Thread.currentThread().getContextClassLoader(), parsers);
@ -73,23 +74,27 @@ public class WireFeedInput {
private static final EntityResolver RESOLVER = new EmptyEntityResolver(); private static final EntityResolver RESOLVER = new EmptyEntityResolver();
private static class EmptyEntityResolver implements EntityResolver { private static class EmptyEntityResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) { @Override
if(systemId != null && systemId.endsWith(".dtd")) return EMPTY_INPUTSOURCE; public InputSource resolveEntity(final String publicId, final String systemId) {
if (systemId != null && systemId.endsWith(".dtd")) {
return EMPTY_INPUTSOURCE;
}
return null; return null;
} }
} }
private boolean _validate; private final boolean _validate;
private boolean _xmlHealerOn; private boolean _xmlHealerOn;
/** /**
* Returns the list of supported input feed types. * Returns the list of supported input feed types.
* <p> * <p>
*
* @see WireFeed for details on the format of these strings. * @see WireFeed for details on the format of these strings.
* <p> * <p>
* @return a list of String elements with the supported input feed types. * @return a list of String elements with the supported input feed types.
* *
*/ */
public static List getSupportedFeedTypes() { public static List getSupportedFeedTypes() {
return getFeedParsers().getSupportedFeedTypes(); return getFeedParsers().getSupportedFeedTypes();
@ -98,79 +103,93 @@ public class WireFeedInput {
/** /**
* Creates a WireFeedInput instance with input validation turned off. * Creates a WireFeedInput instance with input validation turned off.
* <p> * <p>
* *
*/ */
public WireFeedInput() { public WireFeedInput() {
this (false); this(false);
} }
/** /**
* Creates a WireFeedInput instance. * Creates a WireFeedInput instance.
* <p> * <p>
* @param validate indicates if the input should be validated. NOT IMPLEMENTED YET (validation does not happen) *
* * @param validate indicates if the input should be validated. NOT
* IMPLEMENTED YET (validation does not happen)
*
*/ */
public WireFeedInput(boolean validate) { public WireFeedInput(final boolean validate) {
_validate = false; // TODO FIX THIS THINGY this._validate = false; // TODO FIX THIS THINGY
_xmlHealerOn = true; this._xmlHealerOn = true;
} }
/** /**
* Enables XML healing in the WiredFeedInput instance. * Enables XML healing in the WiredFeedInput instance.
* <p> * <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog. * Healing trims leading chars from the stream (empty spaces and comments)
* until the XML prolog.
* <p> * <p>
* Healing resolves HTML entities (from literal to code number) in the reader. * Healing resolves HTML entities (from literal to code number) in the
* reader.
* <p> * <p>
* The healing is done only with the build(File) and build(Reader) signatures. * The healing is done only with the build(File) and build(Reader)
* signatures.
* <p> * <p>
* By default is TRUE. * By default is TRUE.
* <p> * <p>
*
* @param heals TRUE enables stream healing, FALSE disables it. * @param heals TRUE enables stream healing, FALSE disables it.
* *
*/ */
public void setXmlHealerOn(boolean heals) { public void setXmlHealerOn(final boolean heals) {
_xmlHealerOn = heals; this._xmlHealerOn = heals;
} }
/** /**
* Indicates if the WiredFeedInput instance will XML heal (if necessary) the character stream. * Indicates if the WiredFeedInput instance will XML heal (if necessary) the
* character stream.
* <p> * <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog. * Healing trims leading chars from the stream (empty spaces and comments)
* until the XML prolog.
* <p> * <p>
* Healing resolves HTML entities (from literal to code number) in the reader. * Healing resolves HTML entities (from literal to code number) in the
* reader.
* <p> * <p>
* The healing is done only with the build(File) and build(Reader) signatures. * The healing is done only with the build(File) and build(Reader)
* signatures.
* <p> * <p>
* By default is TRUE. * By default is TRUE.
* <p> * <p>
*
* @return TRUE if healing is enabled, FALSE if not. * @return TRUE if healing is enabled, FALSE if not.
* *
*/ */
public boolean getXmlHealerOn() { public boolean getXmlHealerOn() {
return _xmlHealerOn; return this._xmlHealerOn;
} }
/** /**
* Builds an WireFeed (RSS or Atom) from a file. * Builds an WireFeed (RSS or Atom) from a file.
* <p> * <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom2.Document)'. * NOTE: This method delages to the 'AsbtractFeed
* WireFeedInput#build(org.jdom2.Document)'.
* <p> * <p>
*
* @param file file to read to create the WireFeed. * @param file file to read to create the WireFeed.
* @return the WireFeed read from the file. * @return the WireFeed read from the file.
* @throws FileNotFoundException thrown if the file could not be found. * @throws FileNotFoundException thrown if the file could not be found.
* @throws IOException thrown if there is problem reading the file. * @throws IOException thrown if there is problem reading the file.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public WireFeed build(File file) throws FileNotFoundException,IOException,IllegalArgumentException,FeedException { public WireFeed build(final File file) throws FileNotFoundException, IOException, IllegalArgumentException, FeedException {
WireFeed feed; WireFeed feed;
Reader reader = new FileReader(file); Reader reader = new FileReader(file);
if (_xmlHealerOn) { if (this._xmlHealerOn) {
reader = new XmlFixerReader(reader); reader = new XmlFixerReader(reader);
} }
feed = build(reader); feed = this.build(reader);
reader.close(); reader.close();
return feed; return feed;
} }
@ -178,84 +197,85 @@ public class WireFeedInput {
/** /**
* Builds an WireFeed (RSS or Atom) from an Reader. * Builds an WireFeed (RSS or Atom) from an Reader.
* <p> * <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom2.Document)'. * NOTE: This method delages to the 'AsbtractFeed
* WireFeedInput#build(org.jdom2.Document)'.
* <p> * <p>
*
* @param reader Reader to read to create the WireFeed. * @param reader Reader to read to create the WireFeed.
* @return the WireFeed read from the Reader. * @return the WireFeed read from the Reader.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public WireFeed build(Reader reader) throws IllegalArgumentException,FeedException { public WireFeed build(Reader reader) throws IllegalArgumentException, FeedException {
SAXBuilder saxBuilder = createSAXBuilder(); final SAXBuilder saxBuilder = createSAXBuilder();
try { try {
if (_xmlHealerOn) { if (this._xmlHealerOn) {
reader = new XmlFixerReader(reader); reader = new XmlFixerReader(reader);
} }
Document document = saxBuilder.build(reader); final Document document = saxBuilder.build(reader);
return build(document); return this.build(document);
} } catch (final JDOMParseException ex) {
catch (JDOMParseException ex) {
throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex); throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
} } catch (final IllegalArgumentException ex) {
catch (IllegalArgumentException ex) {
throw ex; throw ex;
} } catch (final Exception ex) {
catch (Exception ex) { throw new ParsingFeedException("Invalid XML", ex);
throw new ParsingFeedException("Invalid XML",ex);
} }
} }
/** /**
* Builds an WireFeed (RSS or Atom) from an W3C SAX InputSource. * Builds an WireFeed (RSS or Atom) from an W3C SAX InputSource.
* <p> * <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom2.Document)'. * NOTE: This method delages to the 'AsbtractFeed
* WireFeedInput#build(org.jdom2.Document)'.
* <p> * <p>
*
* @param is W3C SAX InputSource to read to create the WireFeed. * @param is W3C SAX InputSource to read to create the WireFeed.
* @return the WireFeed read from the W3C SAX InputSource. * @return the WireFeed read from the W3C SAX InputSource.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public WireFeed build(InputSource is) throws IllegalArgumentException,FeedException { public WireFeed build(final InputSource is) throws IllegalArgumentException, FeedException {
SAXBuilder saxBuilder = createSAXBuilder(); final SAXBuilder saxBuilder = createSAXBuilder();
try { try {
Document document = saxBuilder.build(is); final Document document = saxBuilder.build(is);
return build(document); return this.build(document);
} } catch (final JDOMParseException ex) {
catch (JDOMParseException ex) {
throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex); throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
} } catch (final IllegalArgumentException ex) {
catch (IllegalArgumentException ex) {
throw ex; throw ex;
} } catch (final Exception ex) {
catch (Exception ex) { throw new ParsingFeedException("Invalid XML", ex);
throw new ParsingFeedException("Invalid XML",ex);
} }
} }
/** /**
* Builds an WireFeed (RSS or Atom) from an W3C DOM document. * Builds an WireFeed (RSS or Atom) from an W3C DOM document.
* <p> * <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom2.Document)'. * NOTE: This method delages to the 'AsbtractFeed
* WireFeedInput#build(org.jdom2.Document)'.
* <p> * <p>
*
* @param document W3C DOM document to read to create the WireFeed. * @param document W3C DOM document to read to create the WireFeed.
* @return the WireFeed read from the W3C DOM document. * @return the WireFeed read from the W3C DOM document.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public WireFeed build(org.w3c.dom.Document document) throws IllegalArgumentException,FeedException { public WireFeed build(final org.w3c.dom.Document document) throws IllegalArgumentException, FeedException {
DOMBuilder domBuilder = new DOMBuilder(); final DOMBuilder domBuilder = new DOMBuilder();
try { try {
Document jdomDoc = domBuilder.build(document); final Document jdomDoc = domBuilder.build(document);
return build(jdomDoc); return this.build(jdomDoc);
} } catch (final IllegalArgumentException ex) {
catch (IllegalArgumentException ex) {
throw ex; throw ex;
} } catch (final Exception ex) {
catch (Exception ex) { throw new ParsingFeedException("Invalid XML", ex);
throw new ParsingFeedException("Invalid XML",ex);
} }
} }
@ -264,18 +284,20 @@ public class WireFeedInput {
* <p> * <p>
* NOTE: All other build methods delegate to this method. * NOTE: All other build methods delegate to this method.
* <p> * <p>
*
* @param document JDOM document to read to create the WireFeed. * @param document JDOM document to read to create the WireFeed.
* @return the WireFeed read from the JDOM document. * @return the WireFeed read from the JDOM document.
* @throws IllegalArgumentException thrown if feed type could not be understood by any of the underlying parsers. * @throws IllegalArgumentException thrown if feed type could not be
* understood by any of the underlying parsers.
* @throws FeedException if the feed could not be parsed * @throws FeedException if the feed could not be parsed
* *
*/ */
public WireFeed build(Document document) throws IllegalArgumentException,FeedException { public WireFeed build(final Document document) throws IllegalArgumentException, FeedException {
WireFeedParser parser = getFeedParsers().getParserFor(document); final WireFeedParser parser = getFeedParsers().getParserFor(document);
if (parser==null) { if (parser == null) {
throw new IllegalArgumentException("Invalid document"); throw new IllegalArgumentException("Invalid document");
} }
return parser.parse(document, _validate); return parser.parse(document, this._validate);
} }
/** /**
@ -284,52 +306,57 @@ public class WireFeedInput {
* @return a new org.jdom2.input.SAXBuilder object * @return a new org.jdom2.input.SAXBuilder object
*/ */
protected SAXBuilder createSAXBuilder() { protected SAXBuilder createSAXBuilder() {
SAXBuilder saxBuilder = new SAXBuilder(_validate ? XMLReaders.DTDVALIDATING : XMLReaders.NONVALIDATING); final SAXBuilder saxBuilder = new SAXBuilder(this._validate ? XMLReaders.DTDVALIDATING : XMLReaders.NONVALIDATING);
saxBuilder.setEntityResolver(RESOLVER); saxBuilder.setEntityResolver(RESOLVER);
// //
// This code is needed to fix the security problem outlined in http://www.securityfocus.com/archive/1/297714 // This code is needed to fix the security problem outlined in
// http://www.securityfocus.com/archive/1/297714
// //
// Unfortunately there isn't an easy way to check if an XML parser supports a particular feature, so // Unfortunately there isn't an easy way to check if an XML parser
// we need to set it and catch the exception if it fails. We also need to subclass the JDom SAXBuilder // supports a particular feature, so
// class in order to get access to the underlying SAX parser - otherwise the features don't get set until // we need to set it and catch the exception if it fails. We also need
// we are already building the document, by which time it's too late to fix the problem. // to subclass the JDom SAXBuilder
// class in order to get access to the underlying SAX parser - otherwise
// the features don't get set until
// we are already building the document, by which time it's too late to
// fix the problem.
// //
// Crimson is one parser which is known not to support these features. // Crimson is one parser which is known not to support these features.
try { try {
XMLReader parser = saxBuilder.createParser(); final XMLReader parser = saxBuilder.createParser();
try { try {
parser.setFeature("http://xml.org/sax/features/external-general-entities", false); parser.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxBuilder.setFeature("http://xml.org/sax/features/external-general-entities", false); saxBuilder.setFeature("http://xml.org/sax/features/external-general-entities", false);
} catch (SAXNotRecognizedException e) { } catch (final SAXNotRecognizedException e) {
// ignore // ignore
} catch (SAXNotSupportedException e) { } catch (final SAXNotSupportedException e) {
// ignore // ignore
} }
try {
parser.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
saxBuilder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
} catch (SAXNotRecognizedException e) {
// ignore
} catch (SAXNotSupportedException e) {
// ignore
}
try { try {
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); parser.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
saxBuilder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); saxBuilder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
} catch (SAXNotRecognizedException e) { } catch (final SAXNotRecognizedException e) {
// ignore // ignore
} catch (SAXNotSupportedException e) { } catch (final SAXNotSupportedException e) {
// ignore // ignore
} }
} catch (JDOMException e) {
throw new IllegalStateException("JDOM could not create a SAX parser");
}
saxBuilder.setExpandEntities(false); try {
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
saxBuilder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (final SAXNotRecognizedException e) {
// ignore
} catch (final SAXNotSupportedException e) {
// ignore
}
} catch (final JDOMException e) {
throw new IllegalStateException("JDOM could not create a SAX parser");
}
saxBuilder.setExpandEntities(false);
return saxBuilder; return saxBuilder;
} }
} }

View file

@ -16,39 +16,41 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.WireFeed; import java.io.File;
import com.sun.syndication.io.impl.FeedGenerators; import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.JDOMException; import org.jdom2.JDOMException;
import org.jdom2.output.DOMOutputter; import org.jdom2.output.DOMOutputter;
import org.jdom2.output.Format; import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter; import org.jdom2.output.XMLOutputter;
import java.io.IOException; import com.sun.syndication.feed.WireFeed;
import java.io.Writer; import com.sun.syndication.io.impl.FeedGenerators;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
/** /**
* Generates an XML document (String, File, OutputStream, Writer, W3C DOM document or JDOM document) * Generates an XML document (String, File, OutputStream, Writer, W3C DOM
* out of an WireFeed (RSS/Atom). * document or JDOM document) out of an WireFeed (RSS/Atom).
* <p> * <p>
* It generates all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and * It generates all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0)
* Atom 0.3 feeds. Generators are plugable (they must implement the ModuleParser interface). * and Atom 0.3 feeds. Generators are plugable (they must implement the
* ModuleParser interface).
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class WireFeedOutput { public class WireFeedOutput {
private static Map clMap = new WeakHashMap(); private static Map clMap = new WeakHashMap();
private static FeedGenerators getFeedGenerators() { private static FeedGenerators getFeedGenerators() {
synchronized(WireFeedOutput.class) { synchronized (WireFeedOutput.class) {
FeedGenerators generators = (FeedGenerators) FeedGenerators generators = (FeedGenerators) clMap.get(Thread.currentThread().getContextClassLoader());
clMap.get(Thread.currentThread().getContextClassLoader());
if (generators == null) { if (generators == null) {
generators = new FeedGenerators(); generators = new FeedGenerators();
clMap.put(Thread.currentThread().getContextClassLoader(), generators); clMap.put(Thread.currentThread().getContextClassLoader(), generators);
@ -60,10 +62,11 @@ public class WireFeedOutput {
/** /**
* Returns the list of supported output feed types. * Returns the list of supported output feed types.
* <p> * <p>
*
* @see WireFeed for details on the format of these strings. * @see WireFeed for details on the format of these strings.
* <p> * <p>
* @return a list of String elements with the supported output feed types. * @return a list of String elements with the supported output feed types.
* *
*/ */
public static List getSupportedFeedTypes() { public static List getSupportedFeedTypes() {
return getFeedGenerators().getSupportedFeedTypes(); return getFeedGenerators().getSupportedFeedTypes();
@ -72,7 +75,7 @@ public class WireFeedOutput {
/** /**
* Creates a FeedOuput instance. * Creates a FeedOuput instance.
* <p> * <p>
* *
*/ */
public WireFeedOutput() { public WireFeedOutput() {
} }
@ -80,142 +83,186 @@ public class WireFeedOutput {
/** /**
* Creates a String with the XML representation for the given WireFeed. * Creates a String with the XML representation for the given WireFeed.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as * encoding attribute. It is the responsibility of the developer to ensure
* the feed encoding property. * that if the String is written to a character stream the stream charset is
* the same as the feed encoding property.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* the WireFeed must match the type given to the FeedOuptut
* constructor.
* @return a String with the XML representation for the given WireFeed. * @return a String with the XML representation for the given WireFeed.
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * @throws IllegalArgumentException thrown if the feed type of the
* @throws FeedException thrown if the XML representation for the feed could not be created. * WireFeedOutput and WireFeed don't match.
* * @throws FeedException thrown if the XML representation for the feed could
* not be created.
*
*/ */
public String outputString(WireFeed feed) throws IllegalArgumentException,FeedException { public String outputString(final WireFeed feed) throws IllegalArgumentException, FeedException {
return outputString(feed, true); return this.outputString(feed, true);
} }
/** /**
* Creates a String with the XML representation for the given WireFeed. * Creates a String with the XML representation for the given WireFeed.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as * encoding attribute. It is the responsibility of the developer to ensure
* the feed encoding property. * that if the String is written to a character stream the stream charset is
* the same as the feed encoding property.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* the WireFeed must match the type given to the FeedOuptut
* constructor.
* @param prettyPrint pretty-print XML (true) oder collapsed * @param prettyPrint pretty-print XML (true) oder collapsed
* @return a String with the XML representation for the given WireFeed. * @return a String with the XML representation for the given WireFeed.
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * @throws IllegalArgumentException thrown if the feed type of the
* @throws FeedException thrown if the XML representation for the feed could not be created. * WireFeedOutput and WireFeed don't match.
* * @throws FeedException thrown if the XML representation for the feed could
* not be created.
*
*/ */
public String outputString(WireFeed feed, boolean prettyPrint) throws IllegalArgumentException,FeedException { public String outputString(final WireFeed feed, final boolean prettyPrint) throws IllegalArgumentException, FeedException {
Document doc = outputJDom(feed); final Document doc = outputJDom(feed);
String encoding = feed.getEncoding(); final String encoding = feed.getEncoding();
Format format = prettyPrint ? Format.getPrettyFormat() : Format.getCompactFormat(); final Format format = prettyPrint ? Format.getPrettyFormat() : Format.getCompactFormat();
if (encoding!=null) { if (encoding != null) {
format.setEncoding(encoding); format.setEncoding(encoding);
} }
XMLOutputter outputter = new XMLOutputter(format); final XMLOutputter outputter = new XMLOutputter(format);
return outputter.outputString(doc); return outputter.outputString(doc);
} }
/** /**
* Creates a File containing with the XML representation for the given WireFeed. * Creates a File containing with the XML representation for the given
* WireFeed.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform * If the feed encoding is not NULL, it will be used in the XML prolog
* default charset encoding is used to write the feed to the file. It is the responsibility * encoding attribute. The platform default charset encoding is used to
* of the developer to ensure the feed encoding is set to the platform charset encoding. * write the feed to the file. It is the responsibility of the developer to
* ensure the feed encoding is set to the platform charset encoding.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* @param file the file where to write the XML representation for the given WireFeed. * the WireFeed must match the type given to the FeedOuptut
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * constructor.
* @param file the file where to write the XML representation for the given
* WireFeed.
* @throws IllegalArgumentException thrown if the feed type of the
* WireFeedOutput and WireFeed don't match.
* @throws IOException thrown if there was some problem writing to the File. * @throws IOException thrown if there was some problem writing to the File.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws FeedException thrown if the XML representation for the feed could
* * not be created.
*
*/ */
public void output(WireFeed feed,File file) throws IllegalArgumentException,IOException,FeedException { public void output(final WireFeed feed, final File file) throws IllegalArgumentException, IOException, FeedException {
output(feed,file,true); this.output(feed, file, true);
} }
/** /**
* Creates a File containing with the XML representation for the given WireFeed. * Creates a File containing with the XML representation for the given
* WireFeed.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform * If the feed encoding is not NULL, it will be used in the XML prolog
* default charset encoding is used to write the feed to the file. It is the responsibility * encoding attribute. The platform default charset encoding is used to
* of the developer to ensure the feed encoding is set to the platform charset encoding. * write the feed to the file. It is the responsibility of the developer to
* ensure the feed encoding is set to the platform charset encoding.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* @param file the file where to write the XML representation for the given WireFeed. * the WireFeed must match the type given to the FeedOuptut
* constructor.
* @param file the file where to write the XML representation for the given
* WireFeed.
* @param prettyPrint pretty-print XML (true) oder collapsed * @param prettyPrint pretty-print XML (true) oder collapsed
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * @throws IllegalArgumentException thrown if the feed type of the
* WireFeedOutput and WireFeed don't match.
* @throws IOException thrown if there was some problem writing to the File. * @throws IOException thrown if there was some problem writing to the File.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws FeedException thrown if the XML representation for the feed could
* * not be created.
*
*/ */
public void output(WireFeed feed,File file,boolean prettyPrint) throws IllegalArgumentException,IOException,FeedException { public void output(final WireFeed feed, final File file, final boolean prettyPrint) throws IllegalArgumentException, IOException, FeedException {
Writer writer = new FileWriter(file); final Writer writer = new FileWriter(file);
output(feed,writer,prettyPrint); this.output(feed, writer, prettyPrint);
writer.close(); writer.close();
} }
/** /**
* Writes to an Writer the XML representation for the given WireFeed. * Writes to an Writer the XML representation for the given WireFeed.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure the Writer instance is using the same charset encoding. * encoding attribute. It is the responsibility of the developer to ensure
* the Writer instance is using the same charset encoding.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* @param writer Writer to write the XML representation for the given WireFeed. * the WireFeed must match the type given to the FeedOuptut
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * constructor.
* @throws IOException thrown if there was some problem writing to the Writer. * @param writer Writer to write the XML representation for the given
* @throws FeedException thrown if the XML representation for the feed could not be created. * WireFeed.
* * @throws IllegalArgumentException thrown if the feed type of the
* WireFeedOutput and WireFeed don't match.
* @throws IOException thrown if there was some problem writing to the
* Writer.
* @throws FeedException thrown if the XML representation for the feed could
* not be created.
*
*/ */
public void output(WireFeed feed,Writer writer) throws IllegalArgumentException,IOException, FeedException { public void output(final WireFeed feed, final Writer writer) throws IllegalArgumentException, IOException, FeedException {
output(feed,writer,true); this.output(feed, writer, true);
} }
/** /**
* Writes to an Writer the XML representation for the given WireFeed. * Writes to an Writer the XML representation for the given WireFeed.
* <p> * <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility * If the feed encoding is not NULL, it will be used in the XML prolog
* of the developer to ensure the Writer instance is using the same charset encoding. * encoding attribute. It is the responsibility of the developer to ensure
* the Writer instance is using the same charset encoding.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create XML representation from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create XML representation from. The type of
* @param writer Writer to write the XML representation for the given WireFeed. * the WireFeed must match the type given to the FeedOuptut
* constructor.
* @param writer Writer to write the XML representation for the given
* WireFeed.
* @param prettyPrint pretty-print XML (true) oder collapsed * @param prettyPrint pretty-print XML (true) oder collapsed
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * @throws IllegalArgumentException thrown if the feed type of the
* @throws IOException thrown if there was some problem writing to the Writer. * WireFeedOutput and WireFeed don't match.
* @throws FeedException thrown if the XML representation for the feed could not be created. * @throws IOException thrown if there was some problem writing to the
* * Writer.
* @throws FeedException thrown if the XML representation for the feed could
* not be created.
*
*/ */
public void output(WireFeed feed,Writer writer,boolean prettyPrint) throws IllegalArgumentException,IOException, FeedException { public void output(final WireFeed feed, final Writer writer, final boolean prettyPrint) throws IllegalArgumentException, IOException, FeedException {
Document doc = outputJDom(feed); final Document doc = outputJDom(feed);
String encoding = feed.getEncoding(); final String encoding = feed.getEncoding();
Format format = prettyPrint ? Format.getPrettyFormat() : Format.getCompactFormat(); final Format format = prettyPrint ? Format.getPrettyFormat() : Format.getCompactFormat();
if (encoding!=null) { if (encoding != null) {
format.setEncoding(encoding); format.setEncoding(encoding);
} }
XMLOutputter outputter = new XMLOutputter(format); final XMLOutputter outputter = new XMLOutputter(format);
outputter.output(doc,writer); outputter.output(doc, writer);
} }
/** /**
@ -223,23 +270,27 @@ public class WireFeedOutput {
* <p> * <p>
* This method does not use the feed encoding property. * This method does not use the feed encoding property.
* <p> * <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'. * NOTE: This method delages to the 'Document
* WireFeedOutput#outputJDom(WireFeed)'.
* <p> * <p>
* @param feed Abstract feed to create W3C DOM document from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create W3C DOM document from. The type of
* the WireFeed must match the type given to the FeedOuptut
* constructor.
* @return the W3C DOM document for the given WireFeed. * @return the W3C DOM document for the given WireFeed.
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * @throws IllegalArgumentException thrown if the feed type of the
* @throws FeedException thrown if the W3C DOM document for the feed could not be created. * WireFeedOutput and WireFeed don't match.
* * @throws FeedException thrown if the W3C DOM document for the feed could
* not be created.
*
*/ */
public org.w3c.dom.Document outputW3CDom(WireFeed feed) throws IllegalArgumentException,FeedException { public org.w3c.dom.Document outputW3CDom(final WireFeed feed) throws IllegalArgumentException, FeedException {
Document doc = outputJDom(feed); final Document doc = outputJDom(feed);
DOMOutputter outputter = new DOMOutputter(); final DOMOutputter outputter = new DOMOutputter();
try { try {
return outputter.output(doc); return outputter.output(doc);
} } catch (final JDOMException jdomEx) {
catch (JDOMException jdomEx) { throw new FeedException("Could not create DOM", jdomEx);
throw new FeedException("Could not create DOM",jdomEx);
} }
} }
@ -250,23 +301,26 @@ public class WireFeedOutput {
* <p> * <p>
* NOTE: All other output methods delegate to this method. * NOTE: All other output methods delegate to this method.
* <p> * <p>
* @param feed Abstract feed to create JDOM document from. The type of the WireFeed must match *
* the type given to the FeedOuptut constructor. * @param feed Abstract feed to create JDOM document from. The type of the
* WireFeed must match the type given to the FeedOuptut
* constructor.
* @return the JDOM document for the given WireFeed. * @return the JDOM document for the given WireFeed.
* @throws IllegalArgumentException thrown if the feed type of the WireFeedOutput and WireFeed don't match. * @throws IllegalArgumentException thrown if the feed type of the
* @throws FeedException thrown if the JDOM document for the feed could not be created. * WireFeedOutput and WireFeed don't match.
* * @throws FeedException thrown if the JDOM document for the feed could not
* be created.
*
*/ */
public Document outputJDom(WireFeed feed) throws IllegalArgumentException,FeedException { public Document outputJDom(final WireFeed feed) throws IllegalArgumentException, FeedException {
String type = feed.getFeedType(); final String type = feed.getFeedType();
WireFeedGenerator generator = getFeedGenerators().getGenerator(type); final WireFeedGenerator generator = getFeedGenerators().getGenerator(type);
if (generator==null) { if (generator == null) {
throw new IllegalArgumentException("Invalid feed type ["+type+"]"); throw new IllegalArgumentException("Invalid feed type [" + type + "]");
} }
if (!generator.getType().equals(type)) { if (!generator.getType().equals(type)) {
throw new IllegalArgumentException("WireFeedOutput type["+type+"] and WireFeed type ["+ throw new IllegalArgumentException("WireFeedOutput type[" + type + "] and WireFeed type [" + type + "] don't match");
type+"] don't match");
} }
return generator.generate(feed); return generator.generate(feed);
} }

View file

@ -16,10 +16,10 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.FeedException;
import org.jdom2.Document; import org.jdom2.Document;
import com.sun.syndication.feed.WireFeed;
/** /**
* Parses an XML document (JDOM) into a feed bean. * Parses an XML document (JDOM) into a feed bean.
* <p> * <p>
@ -27,43 +27,52 @@ import org.jdom2.Document;
* <p> * <p>
* TODO: explain how developers can plugin their own implementations. * TODO: explain how developers can plugin their own implementations.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public interface WireFeedParser { public interface WireFeedParser {
/** /**
* Returns the type of feed the parser handles. * Returns the type of feed the parser handles.
* <p> * <p>
*
* @see WireFeed for details on the format of this string. * @see WireFeed for details on the format of this string.
* <p> * <p>
* @return the type of feed the parser handles. * @return the type of feed the parser handles.
* *
*/ */
public String getType(); public String getType();
/** /**
* Inspects an XML Document (JDOM) to check if it can parse it. * Inspects an XML Document (JDOM) to check if it can parse it.
* <p> * <p>
* It checks if the given document if the type of feeds the parser understands. * It checks if the given document if the type of feeds the parser
* understands.
* <p> * <p>
* @param document XML Document (JDOM) to check if it can be parsed by this parser. *
* @return <b>true</b> if the parser know how to parser this feed, <b>false</b> otherwise. * @param document XML Document (JDOM) to check if it can be parsed by this
* * parser.
* @return <b>true</b> if the parser know how to parser this feed,
* <b>false</b> otherwise.
*
*/ */
public boolean isMyType(Document document); public boolean isMyType(Document document);
/** /**
* Parses an XML document (JDOM Document) into a feed bean. * Parses an XML document (JDOM Document) into a feed bean.
* <p> * <p>
*
* @param document XML document (JDOM) to parse. * @param document XML document (JDOM) to parse.
* @param validate indicates if the feed should be strictly validated (NOT YET IMPLEMENTED). * @param validate indicates if the feed should be strictly validated (NOT
* YET IMPLEMENTED).
* @return the resulting feed bean. * @return the resulting feed bean.
* @throws IllegalArgumentException thrown if the parser cannot handle the given feed type. * @throws IllegalArgumentException thrown if the parser cannot handle the
* @throws FeedException thrown if a feed bean cannot be created out of the XML document (JDOM). * given feed type.
* * @throws FeedException thrown if a feed bean cannot be created out of the
* XML document (JDOM).
*
*/ */
public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException; public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException, FeedException;
} }

View file

@ -16,37 +16,47 @@
*/ */
package com.sun.syndication.io; package com.sun.syndication.io;
import java.io.*; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* Character stream that handles (or at least attemtps to) all the necessary Voodo to figure out * Character stream that handles (or at least attemtps to) all the necessary
* the charset encoding of the XML document within the stream. * Voodo to figure out the charset encoding of the XML document within the
* stream.
* <p> * <p>
* IMPORTANT: This class is not related in any way to the org.xml.sax.XMLReader. This one IS a * IMPORTANT: This class is not related in any way to the org.xml.sax.XMLReader.
* character stream. * This one IS a character stream.
* <p> * <p>
* All this has to be done without consuming characters from the stream, if not the XML parser * All this has to be done without consuming characters from the stream, if not
* will not recognized the document as a valid XML. This is not 100% true, but it's close enough * the XML parser will not recognized the document as a valid XML. This is not
* (UTF-8 BOM is not handled by all parsers right now, XmlReader handles it and things work in all * 100% true, but it's close enough (UTF-8 BOM is not handled by all parsers
* parsers). * right now, XmlReader handles it and things work in all parsers).
* <p> * <p>
* The XmlReader class handles the charset encoding of XML documents in Files, raw streams and * The XmlReader class handles the charset encoding of XML documents in Files,
* HTTP streams by offering a wide set of constructors. * raw streams and HTTP streams by offering a wide set of constructors.
* <P> * <P>
* By default the charset encoding detection is lenient, the constructor with the lenient flag * By default the charset encoding detection is lenient, the constructor with
* can be used for an script (following HTTP MIME and XML specifications). * the lenient flag can be used for an script (following HTTP MIME and XML
* All this is nicely explained by Mark Pilgrim in his blog, * specifications). All this is nicely explained by Mark Pilgrim in his blog, <a
* <a href="http://diveintomark.org/archives/2004/02/13/xml-media-types"> * href="http://diveintomark.org/archives/2004/02/13/xml-media-types">
* Determining the character encoding of a feed</a>. * Determining the character encoding of a feed</a>.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class XmlReader extends Reader { public class XmlReader extends Reader {
private static final int BUFFER_SIZE = 4096; private static final int BUFFER_SIZE = 4096;
@ -61,20 +71,20 @@ public class XmlReader extends Reader {
private Reader _reader; private Reader _reader;
private String _encoding; private String _encoding;
private String _defaultEncoding; private final String _defaultEncoding;
/** /**
* Sets the default encoding to use if none is set in HTTP content-type, * Sets the default encoding to use if none is set in HTTP content-type, XML
* XML prolog and the rules based on content-type are not adequate. * prolog and the rules based on content-type are not adequate.
* <p/> * <p/>
* If it is set to NULL the content-type based rules are used. * If it is set to NULL the content-type based rules are used.
* <p/> * <p/>
* By default it is NULL. * By default it is NULL.
* <p/> * <p/>
* *
* @param encoding charset encoding to default to. * @param encoding charset encoding to default to.
*/ */
public static void setDefaultEncoding(String encoding) { public static void setDefaultEncoding(final String encoding) {
_staticDefaultEncoding = encoding; _staticDefaultEncoding = encoding;
} }
@ -84,7 +94,7 @@ public class XmlReader extends Reader {
* <p/> * <p/>
* If it is NULL the content-type based rules are used. * If it is NULL the content-type based rules are used.
* <p/> * <p/>
* *
* @return the default encoding to use. * @return the default encoding to use.
*/ */
public static String getDefaultEncoding() { public static String getDefaultEncoding() {
@ -94,17 +104,18 @@ public class XmlReader extends Reader {
/** /**
* Creates a Reader for a File. * Creates a Reader for a File.
* <p> * <p>
* It looks for the UTF-8 BOM first, if none sniffs the XML prolog charset, if this is also * It looks for the UTF-8 BOM first, if none sniffs the XML prolog charset,
* missing defaults to UTF-8. * if this is also missing defaults to UTF-8.
* <p> * <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter * It does a lenient charset encoding detection, check the constructor with
* for details. * the lenient parameter for details.
* <p> * <p>
*
* @param file File to create a Reader from. * @param file File to create a Reader from.
* @throws IOException thrown if there is a problem reading the file. * @throws IOException thrown if there is a problem reading the file.
* *
*/ */
public XmlReader(File file) throws IOException { public XmlReader(final File file) throws IOException {
this(new FileInputStream(file)); this(new FileInputStream(file));
} }
@ -113,26 +124,29 @@ public class XmlReader extends Reader {
* <p> * <p>
* It follows the same logic used for files. * It follows the same logic used for files.
* <p> * <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter * It does a lenient charset encoding detection, check the constructor with
* for details. * the lenient parameter for details.
* <p> * <p>
*
* @param is InputStream to create a Reader from. * @param is InputStream to create a Reader from.
* @throws IOException thrown if there is a problem reading the stream. * @throws IOException thrown if there is a problem reading the stream.
* *
*/ */
public XmlReader(InputStream is) throws IOException { public XmlReader(final InputStream is) throws IOException {
this(is,true); this(is, true);
} }
/** /**
* Creates a Reader for a raw InputStream and uses the provided default encoding if none is determined. * Creates a Reader for a raw InputStream and uses the provided default
* encoding if none is determined.
* <p> * <p>
* It follows the same logic used for files. * It follows the same logic used for files.
* <p> * <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts * If lenient detection is indicated and the detection above fails as per
* the following: * specifications it then attempts the following:
* <p> * <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again. * If the content type was 'text/html' it replaces it with 'text/xml' and
* tries the detection again.
* <p> * <p>
* Else if the XML prolog had a charset encoding that encoding is used. * Else if the XML prolog had a charset encoding that encoding is used.
* <p> * <p>
@ -142,25 +156,25 @@ public class XmlReader extends Reader {
* <p> * <p>
* If lenient detection is indicated an XmlReaderException is never thrown. * If lenient detection is indicated an XmlReaderException is never thrown.
* <p> * <p>
*
* @param is InputStream to create a Reader from. * @param is InputStream to create a Reader from.
* @param lenient indicates if the charset encoding detection should be relaxed. * @param lenient indicates if the charset encoding detection should be
* relaxed.
* @param defaultEncoding default encoding to use if one cannot be detected. * @param defaultEncoding default encoding to use if one cannot be detected.
* @throws IOException thrown if there is a problem reading the stream. * @throws IOException thrown if there is a problem reading the stream.
* @throws XmlReaderException thrown if the charset encoding could not be determined according to the specs. * @throws XmlReaderException thrown if the charset encoding could not be
* * determined according to the specs.
*
*/ */
public XmlReader(InputStream is, boolean lenient, String defaultEncoding) public XmlReader(final InputStream is, final boolean lenient, final String defaultEncoding) throws IOException, XmlReaderException {
throws IOException, XmlReaderException { this._defaultEncoding = defaultEncoding == null ? _staticDefaultEncoding : defaultEncoding;
_defaultEncoding = (defaultEncoding == null) ? _staticDefaultEncoding : defaultEncoding;
try { try {
doRawStream(is,lenient); doRawStream(is, lenient);
} } catch (final XmlReaderException ex) {
catch (XmlReaderException ex) {
if (!lenient) { if (!lenient) {
throw ex; throw ex;
} } else {
else { doLenientDetection(null, ex);
doLenientDetection(null,ex);
} }
} }
} }
@ -170,10 +184,11 @@ public class XmlReader extends Reader {
* <p> * <p>
* It follows the same logic used for files. * It follows the same logic used for files.
* <p> * <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts * If lenient detection is indicated and the detection above fails as per
* the following: * specifications it then attempts the following:
* <p> * <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again. * If the content type was 'text/html' it replaces it with 'text/xml' and
* tries the detection again.
* <p> * <p>
* Else if the XML prolog had a charset encoding that encoding is used. * Else if the XML prolog had a charset encoding that encoding is used.
* <p> * <p>
@ -183,33 +198,39 @@ public class XmlReader extends Reader {
* <p> * <p>
* If lenient detection is indicated an XmlReaderException is never thrown. * If lenient detection is indicated an XmlReaderException is never thrown.
* <p> * <p>
*
* @param is InputStream to create a Reader from. * @param is InputStream to create a Reader from.
* @param lenient indicates if the charset encoding detection should be relaxed. * @param lenient indicates if the charset encoding detection should be
* relaxed.
* @throws IOException thrown if there is a problem reading the stream. * @throws IOException thrown if there is a problem reading the stream.
* @throws XmlReaderException thrown if the charset encoding could not be determined according to the specs. * @throws XmlReaderException thrown if the charset encoding could not be
* * determined according to the specs.
*
*/ */
public XmlReader(InputStream is,boolean lenient) throws IOException, XmlReaderException { public XmlReader(final InputStream is, final boolean lenient) throws IOException, XmlReaderException {
this(is, lenient, null); this(is, lenient, null);
} }
/** /**
* Creates a Reader using the InputStream of a URL. * Creates a Reader using the InputStream of a URL.
* <p> * <p>
* If the URL is not of type HTTP and there is not 'content-type' header in the fetched * If the URL is not of type HTTP and there is not 'content-type' header in
* data it uses the same logic used for Files. * the fetched data it uses the same logic used for Files.
* <p> * <p>
* If the URL is a HTTP Url or there is a 'content-type' header in the fetched * If the URL is a HTTP Url or there is a 'content-type' header in the
* data it uses the same logic used for an InputStream with content-type. * fetched data it uses the same logic used for an InputStream with
* content-type.
* <p> * <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter * It does a lenient charset encoding detection, check the constructor with
* for details. * the lenient parameter for details.
* <p> * <p>
*
* @param url URL to create a Reader from. * @param url URL to create a Reader from.
* @throws IOException thrown if there is a problem reading the stream of the URL. * @throws IOException thrown if there is a problem reading the stream of
* * the URL.
*
*/ */
public XmlReader(URL url) throws IOException { public XmlReader(final URL url) throws IOException {
this(url.openConnection()); this(url.openConnection());
} }
@ -217,78 +238,83 @@ public class XmlReader extends Reader {
* Creates a Reader using the InputStream of a URLConnection. * Creates a Reader using the InputStream of a URLConnection.
* <p> * <p>
* If the URLConnection is not of type HttpURLConnection and there is not * If the URLConnection is not of type HttpURLConnection and there is not
* 'content-type' header in the fetched data it uses the same logic used for files. * 'content-type' header in the fetched data it uses the same logic used for
* files.
* <p> * <p>
* If the URLConnection is a HTTP Url or there is a 'content-type' header in the fetched * If the URLConnection is a HTTP Url or there is a 'content-type' header in
* data it uses the same logic used for an InputStream with content-type. * the fetched data it uses the same logic used for an InputStream with
* content-type.
* <p> * <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter * It does a lenient charset encoding detection, check the constructor with
* for details. * the lenient parameter for details.
* <p> * <p>
*
* @param conn URLConnection to create a Reader from. * @param conn URLConnection to create a Reader from.
* @throws IOException thrown if there is a problem reading the stream of the URLConnection. * @throws IOException thrown if there is a problem reading the stream of
* * the URLConnection.
*
*/ */
public XmlReader(URLConnection conn) throws IOException { public XmlReader(final URLConnection conn) throws IOException {
_defaultEncoding = _staticDefaultEncoding; this._defaultEncoding = _staticDefaultEncoding;
boolean lenient = true; final boolean lenient = true;
if (conn instanceof HttpURLConnection) { if (conn instanceof HttpURLConnection) {
try { try {
doHttpStream(conn.getInputStream(),conn.getContentType(),lenient); doHttpStream(conn.getInputStream(), conn.getContentType(), lenient);
} catch (final XmlReaderException ex) {
doLenientDetection(conn.getContentType(), ex);
} }
catch (XmlReaderException ex) { } else if (conn.getContentType() != null) {
doLenientDetection(conn.getContentType(),ex);
}
}
else
if (conn.getContentType()!=null) {
try { try {
doHttpStream(conn.getInputStream(),conn.getContentType(),lenient); doHttpStream(conn.getInputStream(), conn.getContentType(), lenient);
} catch (final XmlReaderException ex) {
doLenientDetection(conn.getContentType(), ex);
} }
catch (XmlReaderException ex) { } else {
doLenientDetection(conn.getContentType(),ex);
}
}
else {
try { try {
doRawStream(conn.getInputStream(),lenient); doRawStream(conn.getInputStream(), lenient);
} } catch (final XmlReaderException ex) {
catch (XmlReaderException ex) { doLenientDetection(null, ex);
doLenientDetection(null,ex);
} }
} }
} }
/** /**
* Creates a Reader using an InputStream and the associated content-type header. * Creates a Reader using an InputStream and the associated content-type
* header.
* <p> * <p>
* First it checks if the stream has BOM. If there is not BOM checks the content-type encoding. * First it checks if the stream has BOM. If there is not BOM checks the
* If there is not content-type encoding checks the XML prolog encoding. If there is not XML * content-type encoding. If there is not content-type encoding checks the
* prolog encoding uses the default encoding mandated by the content-type MIME type. * XML prolog encoding. If there is not XML prolog encoding uses the default
* encoding mandated by the content-type MIME type.
* <p> * <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter * It does a lenient charset encoding detection, check the constructor with
* for details. * the lenient parameter for details.
* <p> * <p>
*
* @param is InputStream to create the reader from. * @param is InputStream to create the reader from.
* @param httpContentType content-type header to use for the resolution of the charset encoding. * @param httpContentType content-type header to use for the resolution of
* the charset encoding.
* @throws IOException thrown if there is a problem reading the file. * @throws IOException thrown if there is a problem reading the file.
* *
*/ */
public XmlReader(InputStream is,String httpContentType) throws IOException { public XmlReader(final InputStream is, final String httpContentType) throws IOException {
this(is,httpContentType,true); this(is, httpContentType, true);
} }
/** /**
* Creates a Reader using an InputStream and the associated content-type header. * Creates a Reader using an InputStream and the associated content-type
* header.
* <p> * <p>
* First it checks if the stream has BOM. If there is not BOM checks the content-type encoding. * First it checks if the stream has BOM. If there is not BOM checks the
* If there is not content-type encoding checks the XML prolog encoding. If there is not XML * content-type encoding. If there is not content-type encoding checks the
* prolog encoding uses the default encoding mandated by the content-type MIME type. * XML prolog encoding. If there is not XML prolog encoding uses the default
* encoding mandated by the content-type MIME type.
* <p> * <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts * If lenient detection is indicated and the detection above fails as per
* the following: * specifications it then attempts the following:
* <p> * <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again. * If the content type was 'text/html' it replaces it with 'text/xml' and
* tries the detection again.
* <p> * <p>
* Else if the XML prolog had a charset encoding that encoding is used. * Else if the XML prolog had a charset encoding that encoding is used.
* <p> * <p>
@ -298,41 +324,46 @@ public class XmlReader extends Reader {
* <p> * <p>
* If lenient detection is indicated and XmlReaderException is never thrown. * If lenient detection is indicated and XmlReaderException is never thrown.
* <p> * <p>
*
* @param is InputStream to create the reader from. * @param is InputStream to create the reader from.
* @param httpContentType content-type header to use for the resolution of the charset encoding. * @param httpContentType content-type header to use for the resolution of
* @param lenient indicates if the charset encoding detection should be relaxed. * the charset encoding.
* @param lenient indicates if the charset encoding detection should be
* relaxed.
* @param defaultEncoding default encoding to use if one cannot be detected. * @param defaultEncoding default encoding to use if one cannot be detected.
* @throws IOException thrown if there is a problem reading the file. * @throws IOException thrown if there is a problem reading the file.
* @throws XmlReaderException thrown if the charset encoding could not be determined according to the specs. * @throws XmlReaderException thrown if the charset encoding could not be
* * determined according to the specs.
*
*/ */
public XmlReader(InputStream is,String httpContentType,boolean lenient, String defaultEncoding) public XmlReader(final InputStream is, final String httpContentType, final boolean lenient, final String defaultEncoding) throws IOException,
throws IOException, XmlReaderException { XmlReaderException {
_defaultEncoding = (defaultEncoding == null) ? _staticDefaultEncoding : defaultEncoding; this._defaultEncoding = defaultEncoding == null ? _staticDefaultEncoding : defaultEncoding;
try { try {
doHttpStream(is,httpContentType,lenient); doHttpStream(is, httpContentType, lenient);
} } catch (final XmlReaderException ex) {
catch (XmlReaderException ex) {
if (!lenient) { if (!lenient) {
throw ex; throw ex;
} } else {
else { doLenientDetection(httpContentType, ex);
doLenientDetection(httpContentType,ex);
} }
} }
} }
/** /**
* Creates a Reader using an InputStream and the associated content-type header. * Creates a Reader using an InputStream and the associated content-type
* header.
* <p> * <p>
* First it checks if the stream has BOM. If there is not BOM checks the content-type encoding. * First it checks if the stream has BOM. If there is not BOM checks the
* If there is not content-type encoding checks the XML prolog encoding. If there is not XML * content-type encoding. If there is not content-type encoding checks the
* prolog encoding uses the default encoding mandated by the content-type MIME type. * XML prolog encoding. If there is not XML prolog encoding uses the default
* encoding mandated by the content-type MIME type.
* <p> * <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts * If lenient detection is indicated and the detection above fails as per
* the following: * specifications it then attempts the following:
* <p> * <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again. * If the content type was 'text/html' it replaces it with 'text/xml' and
* tries the detection again.
* <p> * <p>
* Else if the XML prolog had a charset encoding that encoding is used. * Else if the XML prolog had a charset encoding that encoding is used.
* <p> * <p>
@ -342,210 +373,194 @@ public class XmlReader extends Reader {
* <p> * <p>
* If lenient detection is indicated and XmlReaderException is never thrown. * If lenient detection is indicated and XmlReaderException is never thrown.
* <p> * <p>
*
* @param is InputStream to create the reader from. * @param is InputStream to create the reader from.
* @param httpContentType content-type header to use for the resolution of the charset encoding. * @param httpContentType content-type header to use for the resolution of
* @param lenient indicates if the charset encoding detection should be relaxed. * the charset encoding.
* @param lenient indicates if the charset encoding detection should be
* relaxed.
* @throws IOException thrown if there is a problem reading the file. * @throws IOException thrown if there is a problem reading the file.
* @throws XmlReaderException thrown if the charset encoding could not be determined according to the specs. * @throws XmlReaderException thrown if the charset encoding could not be
* * determined according to the specs.
*
*/ */
public XmlReader(InputStream is, String httpContentType, boolean lenient) public XmlReader(final InputStream is, final String httpContentType, final boolean lenient) throws IOException, XmlReaderException {
throws IOException, XmlReaderException {
this(is, httpContentType, lenient, null); this(is, httpContentType, lenient, null);
} }
private void doLenientDetection(String httpContentType,XmlReaderException ex) throws IOException { private void doLenientDetection(String httpContentType, XmlReaderException ex) throws IOException {
if (httpContentType!=null) { if (httpContentType != null) {
if (httpContentType.startsWith("text/html")) { if (httpContentType.startsWith("text/html")) {
httpContentType = httpContentType.substring("text/html".length()); httpContentType = httpContentType.substring("text/html".length());
httpContentType = "text/xml" + httpContentType; httpContentType = "text/xml" + httpContentType;
try { try {
doHttpStream(ex.getInputStream(),httpContentType,true); doHttpStream(ex.getInputStream(), httpContentType, true);
ex = null; ex = null;
} } catch (final XmlReaderException ex2) {
catch (XmlReaderException ex2) {
ex = ex2; ex = ex2;
} }
} }
} }
if (ex!=null) { if (ex != null) {
String encoding = ex.getXmlEncoding(); String encoding = ex.getXmlEncoding();
if (encoding==null) { if (encoding == null) {
encoding = ex.getContentTypeEncoding(); encoding = ex.getContentTypeEncoding();
} }
if (encoding==null) { if (encoding == null) {
encoding = (_defaultEncoding == null) ? UTF_8 : _defaultEncoding; encoding = this._defaultEncoding == null ? UTF_8 : this._defaultEncoding;
} }
prepareReader(ex.getInputStream(),encoding); prepareReader(ex.getInputStream(), encoding);
} }
} }
/** /**
* Returns the charset encoding of the XmlReader. * Returns the charset encoding of the XmlReader.
* <p> * <p>
*
* @return charset encoding. * @return charset encoding.
* *
*/ */
public String getEncoding() { public String getEncoding() {
return _encoding; return this._encoding;
} }
public int read(char[] buf,int offset,int len) throws IOException { @Override
return _reader.read(buf,offset,len); public int read(final char[] buf, final int offset, final int len) throws IOException {
return this._reader.read(buf, offset, len);
} }
/** /**
* Closes the XmlReader stream. * Closes the XmlReader stream.
* <p> * <p>
*
* @throws IOException thrown if there was a problem closing the stream. * @throws IOException thrown if there was a problem closing the stream.
* *
*/ */
@Override
public void close() throws IOException { public void close() throws IOException {
_reader.close(); this._reader.close();
} }
private void doRawStream(InputStream is,boolean lenient) throws IOException { private void doRawStream(final InputStream is, final boolean lenient) throws IOException {
BufferedInputStream pis = new BufferedInputStream(is, BUFFER_SIZE); final BufferedInputStream pis = new BufferedInputStream(is, BUFFER_SIZE);
String bomEnc = getBOMEncoding(pis); final String bomEnc = getBOMEncoding(pis);
String xmlGuessEnc = getXMLGuessEncoding(pis); final String xmlGuessEnc = getXMLGuessEncoding(pis);
String xmlEnc = getXmlProlog(pis,xmlGuessEnc); final String xmlEnc = getXmlProlog(pis, xmlGuessEnc);
String encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, pis); final String encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, pis);
prepareReader(pis,encoding); prepareReader(pis, encoding);
} }
private void doHttpStream(InputStream is,String httpContentType,boolean lenient) throws IOException { private void doHttpStream(final InputStream is, final String httpContentType, final boolean lenient) throws IOException {
BufferedInputStream pis = new BufferedInputStream(is, BUFFER_SIZE); final BufferedInputStream pis = new BufferedInputStream(is, BUFFER_SIZE);
String cTMime = getContentTypeMime(httpContentType); final String cTMime = getContentTypeMime(httpContentType);
String cTEnc = getContentTypeEncoding(httpContentType); final String cTEnc = getContentTypeEncoding(httpContentType);
String bomEnc = getBOMEncoding(pis); final String bomEnc = getBOMEncoding(pis);
String xmlGuessEnc = getXMLGuessEncoding(pis); final String xmlGuessEnc = getXMLGuessEncoding(pis);
String xmlEnc = getXmlProlog(pis,xmlGuessEnc); final String xmlEnc = getXmlProlog(pis, xmlGuessEnc);
String encoding = calculateHttpEncoding(cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc, pis,lenient); final String encoding = calculateHttpEncoding(cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc, pis, lenient);
prepareReader(pis,encoding); prepareReader(pis, encoding);
} }
private void prepareReader(InputStream is,String encoding) throws IOException { private void prepareReader(final InputStream is, final String encoding) throws IOException {
_reader = new InputStreamReader(is,encoding); this._reader = new InputStreamReader(is, encoding);
_encoding = encoding; this._encoding = encoding;
} }
// InputStream is passed for XmlReaderException creation only // InputStream is passed for XmlReaderException creation only
private String calculateRawEncoding(String bomEnc, String xmlGuessEnc, String xmlEnc, InputStream is) throws IOException { private String calculateRawEncoding(final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final InputStream is) throws IOException {
String encoding; String encoding;
if (bomEnc==null) { if (bomEnc == null) {
if (xmlGuessEnc==null || xmlEnc==null) { if (xmlGuessEnc == null || xmlEnc == null) {
encoding = (_defaultEncoding == null) ? UTF_8 : _defaultEncoding; encoding = this._defaultEncoding == null ? UTF_8 : this._defaultEncoding;
} } else if (xmlEnc.equals(UTF_16) && (xmlGuessEnc.equals(UTF_16BE) || xmlGuessEnc.equals(UTF_16LE))) {
else
if (xmlEnc.equals(UTF_16) && (xmlGuessEnc.equals(UTF_16BE) || xmlGuessEnc.equals(UTF_16LE))) {
encoding = xmlGuessEnc; encoding = xmlGuessEnc;
} } else {
else {
encoding = xmlEnc; encoding = xmlEnc;
} }
} } else if (bomEnc.equals(UTF_8)) {
else if (xmlGuessEnc != null && !xmlGuessEnc.equals(UTF_8)) {
if (bomEnc.equals(UTF_8)) { throw new XmlReaderException(RAW_EX_1.format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }), bomEnc, xmlGuessEnc, xmlEnc, is);
if (xmlGuessEnc!=null && !xmlGuessEnc.equals(UTF_8)) {
throw new XmlReaderException(RAW_EX_1.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}),
bomEnc,xmlGuessEnc,xmlEnc,is);
} }
if (xmlEnc!=null && !xmlEnc.equals(UTF_8)) { if (xmlEnc != null && !xmlEnc.equals(UTF_8)) {
throw new XmlReaderException(RAW_EX_1.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}), throw new XmlReaderException(RAW_EX_1.format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }), bomEnc, xmlGuessEnc, xmlEnc, is);
bomEnc,xmlGuessEnc,xmlEnc,is);
} }
encoding = UTF_8; encoding = UTF_8;
} } else if (bomEnc.equals(UTF_16BE) || bomEnc.equals(UTF_16LE)) {
else if (xmlGuessEnc != null && !xmlGuessEnc.equals(bomEnc)) {
if (bomEnc.equals(UTF_16BE) || bomEnc.equals(UTF_16LE)) { throw new IOException(RAW_EX_1.format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }));
if (xmlGuessEnc!=null && !xmlGuessEnc.equals(bomEnc)) {
throw new IOException(RAW_EX_1.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}));
} }
if (xmlEnc!=null && !xmlEnc.equals(UTF_16) && !xmlEnc.equals(bomEnc)) { if (xmlEnc != null && !xmlEnc.equals(UTF_16) && !xmlEnc.equals(bomEnc)) {
throw new XmlReaderException(RAW_EX_1.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}), throw new XmlReaderException(RAW_EX_1.format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }), bomEnc, xmlGuessEnc, xmlEnc, is);
bomEnc,xmlGuessEnc,xmlEnc,is);
} }
encoding =bomEnc; encoding = bomEnc;
} } else {
else { throw new XmlReaderException(RAW_EX_2.format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }), bomEnc, xmlGuessEnc, xmlEnc, is);
throw new XmlReaderException(RAW_EX_2.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}),
bomEnc,xmlGuessEnc,xmlEnc,is);
} }
return encoding; return encoding;
} }
// InputStream is passed for XmlReaderException creation only // InputStream is passed for XmlReaderException creation only
private String calculateHttpEncoding(String cTMime, String cTEnc, String bomEnc, String xmlGuessEnc, String xmlEnc, InputStream is,boolean lenient) throws IOException { private String calculateHttpEncoding(final String cTMime, final String cTEnc, final String bomEnc, final String xmlGuessEnc, final String xmlEnc,
final InputStream is, final boolean lenient) throws IOException {
String encoding; String encoding;
if (lenient & xmlEnc!=null) { if (lenient & xmlEnc != null) {
encoding = xmlEnc; encoding = xmlEnc;
} } else {
else { final boolean appXml = isAppXml(cTMime);
boolean appXml = isAppXml(cTMime); final boolean textXml = isTextXml(cTMime);
boolean textXml = isTextXml(cTMime);
if (appXml || textXml) { if (appXml || textXml) {
if (cTEnc==null) { if (cTEnc == null) {
if (appXml) { if (appXml) {
encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, is); encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, is);
} else {
encoding = this._defaultEncoding == null ? US_ASCII : this._defaultEncoding;
} }
else { } else if (bomEnc != null && (cTEnc.equals(UTF_16BE) || cTEnc.equals(UTF_16LE))) {
encoding = (_defaultEncoding == null) ? US_ASCII : _defaultEncoding; throw new XmlReaderException(HTTP_EX_1.format(new Object[] { cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc }), cTMime, cTEnc, bomEnc,
} xmlGuessEnc, xmlEnc, is);
} } else if (cTEnc.equals(UTF_16)) {
else if (bomEnc != null && bomEnc.startsWith(UTF_16)) {
if (bomEnc!=null && (cTEnc.equals(UTF_16BE) || cTEnc.equals(UTF_16LE))) {
throw new XmlReaderException(HTTP_EX_1.format(new Object[]{cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc}),
cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc,is);
}
else
if (cTEnc.equals(UTF_16)) {
if (bomEnc!=null && bomEnc.startsWith(UTF_16)) {
encoding = bomEnc; encoding = bomEnc;
} else {
throw new XmlReaderException(HTTP_EX_2.format(new Object[] { cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc }), cTMime, cTEnc, bomEnc,
xmlGuessEnc, xmlEnc, is);
} }
else { } else {
throw new XmlReaderException(HTTP_EX_2.format(new Object[]{cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc}),
cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc,is);
}
}
else {
encoding = cTEnc; encoding = cTEnc;
} }
} } else {
else { throw new XmlReaderException(HTTP_EX_3.format(new Object[] { cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc }), cTMime, cTEnc, bomEnc, xmlGuessEnc,
throw new XmlReaderException(HTTP_EX_3.format(new Object[]{cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc}), xmlEnc, is);
cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc,is);
} }
} }
return encoding; return encoding;
} }
// returns MIME type or NULL if httpContentType is NULL // returns MIME type or NULL if httpContentType is NULL
private static String getContentTypeMime(String httpContentType) { private static String getContentTypeMime(final String httpContentType) {
String mime = null; String mime = null;
if (httpContentType!=null) { if (httpContentType != null) {
int i = httpContentType.indexOf(";"); final int i = httpContentType.indexOf(";");
mime = ((i==-1) ? httpContentType : httpContentType.substring(0,i)).trim(); mime = (i == -1 ? httpContentType : httpContentType.substring(0, i)).trim();
} }
return mime; return mime;
} }
private static final Pattern CHARSET_PATTERN = Pattern.compile("charset=([.[^; ]]*)"); private static final Pattern CHARSET_PATTERN = Pattern.compile("charset=([.[^; ]]*)");
// returns charset parameter value, NULL if not present, NULL if httpContentType is NULL // returns charset parameter value, NULL if not present, NULL if
private static String getContentTypeEncoding(String httpContentType) { // httpContentType is NULL
private static String getContentTypeEncoding(final String httpContentType) {
String encoding = null; String encoding = null;
if (httpContentType!=null) { if (httpContentType != null) {
int i = httpContentType.indexOf(";"); final int i = httpContentType.indexOf(";");
if (i>-1) { if (i > -1) {
String postMime = httpContentType.substring(i+1); final String postMime = httpContentType.substring(i + 1);
Matcher m = CHARSET_PATTERN.matcher(postMime); final Matcher m = CHARSET_PATTERN.matcher(postMime);
encoding = (m.find()) ? m.group(1) : null; encoding = m.find() ? m.group(1) : null;
encoding = (encoding!=null) ? encoding.toUpperCase() : null; encoding = encoding != null ? encoding.toUpperCase() : null;
} }
if (encoding != null && if (encoding != null && (encoding.startsWith("\"") && encoding.endsWith("\"") || encoding.startsWith("'") && encoding.endsWith("'"))) {
((encoding.startsWith("\"") && encoding.endsWith("\"")) ||
(encoding.startsWith("'") && encoding.endsWith("'"))
)) {
encoding = encoding.substring(1, encoding.length() - 1); encoding = encoding.substring(1, encoding.length() - 1);
} }
} }
@ -554,9 +569,9 @@ public class XmlReader extends Reader {
// returns the BOM in the stream, NULL if not present, // returns the BOM in the stream, NULL if not present,
// if there was BOM the in the stream it is consumed // if there was BOM the in the stream it is consumed
private static String getBOMEncoding(BufferedInputStream is) throws IOException { private static String getBOMEncoding(final BufferedInputStream is) throws IOException {
String encoding = null; String encoding = null;
int[] bytes = new int[3]; final int[] bytes = new int[3];
is.mark(3); is.mark(3);
bytes[0] = is.read(); bytes[0] = is.read();
bytes[1] = is.read(); bytes[1] = is.read();
@ -567,28 +582,24 @@ public class XmlReader extends Reader {
is.reset(); is.reset();
is.read(); is.read();
is.read(); is.read();
} } else if (bytes[0] == 0xFF && bytes[1] == 0xFE) {
else
if (bytes[0] == 0xFF && bytes[1] == 0xFE) {
encoding = UTF_16LE; encoding = UTF_16LE;
is.reset(); is.reset();
is.read(); is.read();
is.read(); is.read();
} } else if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
else
if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
encoding = UTF_8; encoding = UTF_8;
} } else {
else {
is.reset(); is.reset();
} }
return encoding; return encoding;
} }
// returns the best guess for the encoding by looking the first bytes of the stream, '<?' // returns the best guess for the encoding by looking the first bytes of the
private static String getXMLGuessEncoding(BufferedInputStream is) throws IOException { // stream, '<?'
private static String getXMLGuessEncoding(final BufferedInputStream is) throws IOException {
String encoding = null; String encoding = null;
int[] bytes = new int[4]; final int[] bytes = new int[4];
is.mark(4); is.mark(4);
bytes[0] = is.read(); bytes[0] = is.read();
bytes[1] = is.read(); bytes[1] = is.read();
@ -597,62 +608,55 @@ public class XmlReader extends Reader {
is.reset(); is.reset();
if (bytes[0] == 0x00 && bytes[1] == 0x3C && bytes[2] == 0x00 && bytes[3] == 0x3F) { if (bytes[0] == 0x00 && bytes[1] == 0x3C && bytes[2] == 0x00 && bytes[3] == 0x3F) {
encoding = UTF_16BE; encoding = UTF_16BE;
} } else if (bytes[0] == 0x3C && bytes[1] == 0x00 && bytes[2] == 0x3F && bytes[3] == 0x00) {
else encoding = UTF_16LE;
if (bytes[0] == 0x3C && bytes[1] == 0x00 && bytes[2] == 0x3F && bytes[3] == 0x00) { } else if (bytes[0] == 0x3C && bytes[1] == 0x3F && bytes[2] == 0x78 && bytes[3] == 0x6D) {
encoding = UTF_16LE;
}
else
if (bytes[0] == 0x3C && bytes[1] == 0x3F && bytes[2] == 0x78 && bytes[3] == 0x6D) {
encoding = UTF_8; encoding = UTF_8;
} }
return encoding; return encoding;
} }
private static final Pattern ENCODING_PATTERN = Pattern.compile("<\\?xml.*encoding[\\s]*=[\\s]*((?:\".[^\"]*\")|(?:'.[^']*'))", Pattern.MULTILINE);
private static final Pattern ENCODING_PATTERN = // returns the encoding declared in the <?xml encoding=...?>, NULL if none
Pattern.compile("<\\?xml.*encoding[\\s]*=[\\s]*((?:\".[^\"]*\")|(?:'.[^']*'))", Pattern.MULTILINE); private static String getXmlProlog(final BufferedInputStream is, final String guessedEnc) throws IOException {
// returns the encoding declared in the <?xml encoding=...?>, NULL if none
private static String getXmlProlog(BufferedInputStream is,String guessedEnc) throws IOException {
String encoding = null; String encoding = null;
if (guessedEnc!=null) { if (guessedEnc != null) {
byte[] bytes = new byte[BUFFER_SIZE]; final byte[] bytes = new byte[BUFFER_SIZE];
is.mark(BUFFER_SIZE); is.mark(BUFFER_SIZE);
int offset = 0; int offset = 0;
int max = BUFFER_SIZE; int max = BUFFER_SIZE;
int c = is.read(bytes,offset,max); int c = is.read(bytes, offset, max);
int firstGT = -1; int firstGT = -1;
while (c!=-1 && firstGT==-1 && offset< BUFFER_SIZE) { while (c != -1 && firstGT == -1 && offset < BUFFER_SIZE) {
offset += c; offset += c;
max -= c; max -= c;
c = is.read(bytes,offset,max); c = is.read(bytes, offset, max);
firstGT = new String(bytes, 0, offset).indexOf(">"); firstGT = new String(bytes, 0, offset).indexOf(">");
} }
if (firstGT == -1) { if (firstGT == -1) {
if (c == -1) { if (c == -1) {
throw new IOException("Unexpected end of XML stream"); throw new IOException("Unexpected end of XML stream");
} } else {
else {
throw new IOException("XML prolog or ROOT element not found on first " + offset + " bytes"); throw new IOException("XML prolog or ROOT element not found on first " + offset + " bytes");
} }
} }
int bytesRead = offset; final int bytesRead = offset;
if (bytesRead>0) { if (bytesRead > 0) {
is.reset(); is.reset();
Reader reader = new InputStreamReader(new ByteArrayInputStream(bytes,0,firstGT + 1), guessedEnc); final Reader reader = new InputStreamReader(new ByteArrayInputStream(bytes, 0, firstGT + 1), guessedEnc);
BufferedReader bReader = new BufferedReader(reader); final BufferedReader bReader = new BufferedReader(reader);
StringBuffer prolog = new StringBuffer(); final StringBuffer prolog = new StringBuffer();
String line = bReader.readLine(); String line = bReader.readLine();
while (line != null) { while (line != null) {
prolog.append(line); prolog.append(line);
line = bReader.readLine(); line = bReader.readLine();
} }
Matcher m = ENCODING_PATTERN.matcher(prolog); final Matcher m = ENCODING_PATTERN.matcher(prolog);
if (m.find()) { if (m.find()) {
encoding = m.group(1).toUpperCase(); encoding = m.group(1).toUpperCase();
encoding = encoding.substring(1,encoding.length()-1); encoding = encoding.substring(1, encoding.length() - 1);
} }
} }
} }
@ -660,27 +664,20 @@ public class XmlReader extends Reader {
} }
// indicates if the MIME type belongs to the APPLICATION XML family // indicates if the MIME type belongs to the APPLICATION XML family
private static boolean isAppXml(String mime) { private static boolean isAppXml(final String mime) {
return mime!=null && return mime != null
(mime.equals("application/xml") || && (mime.equals("application/xml") || mime.equals("application/xml-dtd") || mime.equals("application/xml-external-parsed-entity") || mime
mime.equals("application/xml-dtd") || .startsWith("application/") && mime.endsWith("+xml"));
mime.equals("application/xml-external-parsed-entity") ||
(mime.startsWith("application/") && mime.endsWith("+xml")));
} }
// indicates if the MIME type belongs to the TEXT XML family // indicates if the MIME type belongs to the TEXT XML family
private static boolean isTextXml(String mime) { private static boolean isTextXml(final String mime) {
return mime!=null && return mime != null && (mime.equals("text/xml") || mime.equals("text/xml-external-parsed-entity") || mime.startsWith("text/") && mime.endsWith("+xml"));
(mime.equals("text/xml") ||
mime.equals("text/xml-external-parsed-entity") ||
(mime.startsWith("text/") && mime.endsWith("+xml")));
} }
private static final MessageFormat RAW_EX_1 = new MessageFormat( private static final MessageFormat RAW_EX_1 = new MessageFormat("Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] encoding mismatch");
"Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] encoding mismatch");
private static final MessageFormat RAW_EX_2 = new MessageFormat( private static final MessageFormat RAW_EX_2 = new MessageFormat("Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] unknown BOM");
"Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] unknown BOM");
private static final MessageFormat HTTP_EX_1 = new MessageFormat( private static final MessageFormat HTTP_EX_1 = new MessageFormat(
"Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be NULL"); "Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be NULL");

View file

@ -1,49 +1,55 @@
package com.sun.syndication.io; package com.sun.syndication.io;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
/** /**
* The XmlReaderException is thrown by the XmlReader constructors if the charset encoding * The XmlReaderException is thrown by the XmlReader constructors if the charset
* can not be determined according to the XML 1.0 specification and RFC 3023. * encoding can not be determined according to the XML 1.0 specification and RFC
* 3023.
* <p> * <p>
* The exception returns the unconsumed InputStream to allow the application to do an * The exception returns the unconsumed InputStream to allow the application to
* alternate processing with the stream. Note that the original InputStream given to the * do an alternate processing with the stream. Note that the original
* XmlReader cannot be used as that one has been already read. * InputStream given to the XmlReader cannot be used as that one has been
* already read.
* <p> * <p>
* *
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class XmlReaderException extends IOException { public class XmlReaderException extends IOException {
private String _bomEncoding; private final String _bomEncoding;
private String _xmlGuessEncoding; private final String _xmlGuessEncoding;
private String _xmlEncoding; private final String _xmlEncoding;
private String _contentTypeMime; private final String _contentTypeMime;
private String _contentTypeEncoding; private final String _contentTypeEncoding;
private InputStream _is; private final InputStream _is;
/** /**
* Creates an exception instance if the charset encoding could not be determined. * Creates an exception instance if the charset encoding could not be
* determined.
* <p> * <p>
* Instances of this exception are thrown by the XmlReader. * Instances of this exception are thrown by the XmlReader.
* <p> * <p>
*
* @param msg message describing the reason for the exception. * @param msg message describing the reason for the exception.
* @param bomEnc BOM encoding. * @param bomEnc BOM encoding.
* @param xmlGuessEnc XML guess encoding. * @param xmlGuessEnc XML guess encoding.
* @param xmlEnc XML prolog encoding. * @param xmlEnc XML prolog encoding.
* @param is the unconsumed InputStream. * @param is the unconsumed InputStream.
* *
*/ */
public XmlReaderException(String msg,String bomEnc,String xmlGuessEnc,String xmlEnc,InputStream is) { public XmlReaderException(final String msg, final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final InputStream is) {
this(msg,null,null,bomEnc,xmlGuessEnc,xmlEnc,is); this(msg, null, null, bomEnc, xmlGuessEnc, xmlEnc, is);
} }
/** /**
* Creates an exception instance if the charset encoding could not be determined. * Creates an exception instance if the charset encoding could not be
* determined.
* <p> * <p>
* Instances of this exception are thrown by the XmlReader. * Instances of this exception are thrown by the XmlReader.
* <p> * <p>
*
* @param msg message describing the reason for the exception. * @param msg message describing the reason for the exception.
* @param ctMime MIME type in the content-type. * @param ctMime MIME type in the content-type.
* @param ctEnc encoding in the content-type. * @param ctEnc encoding in the content-type.
@ -51,79 +57,88 @@ public class XmlReaderException extends IOException {
* @param xmlGuessEnc XML guess encoding. * @param xmlGuessEnc XML guess encoding.
* @param xmlEnc XML prolog encoding. * @param xmlEnc XML prolog encoding.
* @param is the unconsumed InputStream. * @param is the unconsumed InputStream.
* *
*/ */
public XmlReaderException(String msg,String ctMime,String ctEnc, public XmlReaderException(final String msg, final String ctMime, final String ctEnc, final String bomEnc, final String xmlGuessEnc, final String xmlEnc,
String bomEnc,String xmlGuessEnc,String xmlEnc,InputStream is) { final InputStream is) {
super(msg); super(msg);
_contentTypeMime = ctMime; this._contentTypeMime = ctMime;
_contentTypeEncoding = ctEnc; this._contentTypeEncoding = ctEnc;
_bomEncoding = bomEnc; this._bomEncoding = bomEnc;
_xmlGuessEncoding = xmlGuessEnc; this._xmlGuessEncoding = xmlGuessEnc;
_xmlEncoding = xmlEnc; this._xmlEncoding = xmlEnc;
_is = is; this._is = is;
} }
/** /**
* Returns the BOM encoding found in the InputStream. * Returns the BOM encoding found in the InputStream.
* <p> * <p>
*
* @return the BOM encoding, null if none. * @return the BOM encoding, null if none.
* *
*/ */
public String getBomEncoding() { public String getBomEncoding() {
return _bomEncoding; return this._bomEncoding;
} }
/** /**
* Returns the encoding guess based on the first bytes of the InputStream. * Returns the encoding guess based on the first bytes of the InputStream.
* <p> * <p>
*
* @return the encoding guess, null if it couldn't be guessed. * @return the encoding guess, null if it couldn't be guessed.
* *
*/ */
public String getXmlGuessEncoding() { public String getXmlGuessEncoding() {
return _xmlGuessEncoding; return this._xmlGuessEncoding;
} }
/** /**
* Returns the encoding found in the XML prolog of the InputStream. * Returns the encoding found in the XML prolog of the InputStream.
* <p> * <p>
*
* @return the encoding of the XML prolog, null if none. * @return the encoding of the XML prolog, null if none.
* *
*/ */
public String getXmlEncoding() { public String getXmlEncoding() {
return _xmlEncoding; return this._xmlEncoding;
} }
/** /**
* Returns the MIME type in the content-type used to attempt determining the encoding. * Returns the MIME type in the content-type used to attempt determining the
* encoding.
* <p> * <p>
* @return the MIME type in the content-type, null if there was not content-type or the encoding detection *
* did not involve HTTP. * @return the MIME type in the content-type, null if there was not
* * content-type or the encoding detection did not involve HTTP.
*
*/ */
public String getContentTypeMime() { public String getContentTypeMime() {
return _contentTypeMime; return this._contentTypeMime;
} }
/** /**
* Returns the encoding in the content-type used to attempt determining the encoding. * Returns the encoding in the content-type used to attempt determining the
* encoding.
* <p> * <p>
* @return the encoding in the content-type, null if there was not content-type, no encoding in it *
* or the encoding detection did not involve HTTP. * @return the encoding in the content-type, null if there was not
* * content-type, no encoding in it or the encoding detection did not
* involve HTTP.
*
*/ */
public String getContentTypeEncoding() { public String getContentTypeEncoding() {
return _contentTypeEncoding; return this._contentTypeEncoding;
} }
/** /**
* Returns the unconsumed InputStream to allow the application to do an alternate * Returns the unconsumed InputStream to allow the application to do an
* encoding detection on the InputStream. * alternate encoding detection on the InputStream.
* <p> * <p>
*
* @return the unconsumed InputStream. * @return the unconsumed InputStream.
* *
*/ */
public InputStream getInputStream() { public InputStream getInputStream() {
return _is; return this._is;
} }
} }

View file

@ -16,130 +16,137 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.WireFeed; import java.io.StringReader;
import com.sun.syndication.feed.atom.*; import java.util.List;
import com.sun.syndication.io.FeedException;
import org.jdom2.Attribute; import org.jdom2.Attribute;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
import java.io.StringReader; import com.sun.syndication.feed.WireFeed;
import java.util.List; import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Generator;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Person;
import com.sun.syndication.io.FeedException;
/** /**
* Feed Generator for Atom * Feed Generator for Atom
* <p/> * <p/>
* *
* @author Elaine Chien * @author Elaine Chien
* *
*/ */
public class Atom03Generator extends BaseWireFeedGenerator { public class Atom03Generator extends BaseWireFeedGenerator {
private static final String ATOM_03_URI = "http://purl.org/atom/ns#"; private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_03_URI); private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_03_URI);
private String _version; private final String _version;
public Atom03Generator() { public Atom03Generator() {
this("atom_0.3","0.3"); this("atom_0.3", "0.3");
} }
protected Atom03Generator(String type,String version) { protected Atom03Generator(final String type, final String version) {
super(type); super(type);
_version = version; this._version = version;
} }
protected String getVersion() { protected String getVersion() {
return _version; return this._version;
} }
protected Namespace getFeedNamespace() { protected Namespace getFeedNamespace() {
return ATOM_NS; return ATOM_NS;
} }
public Document generate(WireFeed wFeed) throws FeedException { @Override
Feed feed = (Feed) wFeed; public Document generate(final WireFeed wFeed) throws FeedException {
Element root = createRootElement(feed); final Feed feed = (Feed) wFeed;
populateFeed(feed,root); final Element root = createRootElement(feed);
purgeUnusedNamespaceDeclarations(root); populateFeed(feed, root);
purgeUnusedNamespaceDeclarations(root);
return createDocument(root); return createDocument(root);
} }
protected Document createDocument(Element root) { protected Document createDocument(final Element root) {
return new Document(root); return new Document(root);
} }
protected Element createRootElement(Feed feed) { protected Element createRootElement(final Feed feed) {
Element root = new Element("feed",getFeedNamespace()); final Element root = new Element("feed", getFeedNamespace());
root.addNamespaceDeclaration(getFeedNamespace()); root.addNamespaceDeclaration(getFeedNamespace());
Attribute version = new Attribute("version", getVersion()); final Attribute version = new Attribute("version", getVersion());
root.setAttribute(version); root.setAttribute(version);
generateModuleNamespaceDefs(root); generateModuleNamespaceDefs(root);
return root; return root;
} }
protected void populateFeed(Feed feed,Element parent) throws FeedException { protected void populateFeed(final Feed feed, final Element parent) throws FeedException {
addFeed(feed,parent); addFeed(feed, parent);
addEntries(feed,parent); addEntries(feed, parent);
} }
protected void addFeed(Feed feed, Element parent) throws FeedException { protected void addFeed(final Feed feed, final Element parent) throws FeedException {
Element eFeed = parent; final Element eFeed = parent;
populateFeedHeader(feed,eFeed); populateFeedHeader(feed, eFeed);
checkFeedHeaderConstraints(eFeed); checkFeedHeaderConstraints(eFeed);
generateFeedModules(feed.getModules(),eFeed); generateFeedModules(feed.getModules(), eFeed);
generateForeignMarkup(eFeed, (List<Element>)feed.getForeignMarkup()); generateForeignMarkup(eFeed, feed.getForeignMarkup());
} }
protected void addEntries(Feed feed,Element parent) throws FeedException { protected void addEntries(final Feed feed, final Element parent) throws FeedException {
List<Entry> items = feed.getEntries(); final List<Entry> items = feed.getEntries();
for (int i=0;i<items.size();i++) { for (int i = 0; i < items.size(); i++) {
addEntry((Entry)items.get(i),parent); addEntry(items.get(i), parent);
} }
checkEntriesConstraints(parent); checkEntriesConstraints(parent);
} }
protected void addEntry(Entry entry,Element parent) throws FeedException { protected void addEntry(final Entry entry, final Element parent) throws FeedException {
Element eEntry = new Element("entry", getFeedNamespace()); final Element eEntry = new Element("entry", getFeedNamespace());
populateEntry(entry,eEntry); populateEntry(entry, eEntry);
checkEntryConstraints(eEntry); checkEntryConstraints(eEntry);
generateItemModules(entry.getModules(),eEntry); generateItemModules(entry.getModules(), eEntry);
parent.addContent(eEntry); parent.addContent(eEntry);
} }
protected void populateFeedHeader(Feed feed, Element eFeed) throws FeedException { protected void populateFeedHeader(final Feed feed, final Element eFeed) throws FeedException {
if (feed.getTitleEx() != null) { if (feed.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace()); final Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, feed.getTitleEx()); fillContentElement(titleElement, feed.getTitleEx());
eFeed.addContent(titleElement); eFeed.addContent(titleElement);
} }
List<Link> links = feed.getAlternateLinks(); List<Link> links = feed.getAlternateLinks();
for (int i = 0; i < links.size(); i++) { for (int i = 0; i < links.size(); i++) {
eFeed.addContent(generateLinkElement((Link)links.get(i))); eFeed.addContent(generateLinkElement(links.get(i)));
} }
links = feed.getOtherLinks(); links = feed.getOtherLinks();
for (int i = 0; i < links.size(); i++) { for (int i = 0; i < links.size(); i++) {
eFeed.addContent(generateLinkElement((Link)links.get(i))); eFeed.addContent(generateLinkElement(links.get(i)));
} }
if (feed.getAuthors()!=null && feed.getAuthors().size() > 0) { if (feed.getAuthors() != null && feed.getAuthors().size() > 0) {
Element authorElement = new Element("author", getFeedNamespace()); final Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)feed.getAuthors().get(0)); fillPersonElement(authorElement, feed.getAuthors().get(0));
eFeed.addContent(authorElement); eFeed.addContent(authorElement);
} }
List<Person> contributors = feed.getContributors(); final List<Person> contributors = feed.getContributors();
for (int i = 0; i < contributors.size(); i++) { for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace()); final Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i)); fillPersonElement(contributorElement, contributors.get(i));
eFeed.addContent(contributorElement); eFeed.addContent(contributorElement);
} }
if (feed.getTagline() != null) { if (feed.getTagline() != null) {
Element taglineElement = new Element("tagline", getFeedNamespace()); final Element taglineElement = new Element("tagline", getFeedNamespace());
fillContentElement(taglineElement, feed.getTagline()); fillContentElement(taglineElement, feed.getTagline());
eFeed.addContent(taglineElement); eFeed.addContent(taglineElement);
} }
@ -157,44 +164,44 @@ public class Atom03Generator extends BaseWireFeedGenerator {
} }
if (feed.getInfo() != null) { if (feed.getInfo() != null) {
Element infoElement = new Element("info", getFeedNamespace()); final Element infoElement = new Element("info", getFeedNamespace());
fillContentElement(infoElement, feed.getInfo()); fillContentElement(infoElement, feed.getInfo());
eFeed.addContent(infoElement); eFeed.addContent(infoElement);
} }
if (feed.getModified() != null) { if (feed.getModified() != null) {
Element modifiedElement = new Element("modified", getFeedNamespace()); final Element modifiedElement = new Element("modified", getFeedNamespace());
modifiedElement.addContent(DateParser.formatW3CDateTime(feed.getModified())); modifiedElement.addContent(DateParser.formatW3CDateTime(feed.getModified()));
eFeed.addContent(modifiedElement); eFeed.addContent(modifiedElement);
} }
} }
protected void populateEntry(Entry entry, Element eEntry) throws FeedException { protected void populateEntry(final Entry entry, final Element eEntry) throws FeedException {
if (entry.getTitleEx() != null) { if (entry.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace()); final Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, entry.getTitleEx()); fillContentElement(titleElement, entry.getTitleEx());
eEntry.addContent(titleElement); eEntry.addContent(titleElement);
} }
List<Link> links = entry.getAlternateLinks(); List<Link> links = entry.getAlternateLinks();
for (int i = 0; i < links.size(); i++) { for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i))); eEntry.addContent(generateLinkElement(links.get(i)));
} }
links = entry.getOtherLinks(); links = entry.getOtherLinks();
for (int i = 0; i < links.size(); i++) { for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i))); eEntry.addContent(generateLinkElement(links.get(i)));
} }
if (entry.getAuthors()!=null && entry.getAuthors().size() > 0) { if (entry.getAuthors() != null && entry.getAuthors().size() > 0) {
Element authorElement = new Element("author", getFeedNamespace()); final Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)entry.getAuthors().get(0)); fillPersonElement(authorElement, entry.getAuthors().get(0));
eEntry.addContent(authorElement); eEntry.addContent(authorElement);
} }
List<Person> contributors = entry.getContributors(); final List<Person> contributors = entry.getContributors();
for (int i = 0; i < contributors.size(); i++) { for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace()); final Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i)); fillPersonElement(contributorElement, contributors.get(i));
eEntry.addContent(contributorElement); eEntry.addContent(contributorElement);
} }
if (entry.getId() != null) { if (entry.getId() != null) {
@ -202,71 +209,69 @@ public class Atom03Generator extends BaseWireFeedGenerator {
} }
if (entry.getModified() != null) { if (entry.getModified() != null) {
Element modifiedElement = new Element("modified", getFeedNamespace()); final Element modifiedElement = new Element("modified", getFeedNamespace());
modifiedElement.addContent(DateParser.formatW3CDateTime(entry.getModified())); modifiedElement.addContent(DateParser.formatW3CDateTime(entry.getModified()));
eEntry.addContent(modifiedElement); eEntry.addContent(modifiedElement);
} }
if (entry.getIssued() != null) { if (entry.getIssued() != null) {
Element issuedElement = new Element("issued", getFeedNamespace()); final Element issuedElement = new Element("issued", getFeedNamespace());
issuedElement.addContent(DateParser.formatW3CDateTime(entry.getIssued())); issuedElement.addContent(DateParser.formatW3CDateTime(entry.getIssued()));
eEntry.addContent(issuedElement); eEntry.addContent(issuedElement);
} }
if (entry.getCreated() != null) { if (entry.getCreated() != null) {
Element createdElement = new Element("created", getFeedNamespace()); final Element createdElement = new Element("created", getFeedNamespace());
createdElement.addContent(DateParser.formatW3CDateTime(entry.getCreated())); createdElement.addContent(DateParser.formatW3CDateTime(entry.getCreated()));
eEntry.addContent(createdElement); eEntry.addContent(createdElement);
} }
if (entry.getSummary() != null) { if (entry.getSummary() != null) {
Element summaryElement = new Element("summary", getFeedNamespace()); final Element summaryElement = new Element("summary", getFeedNamespace());
fillContentElement(summaryElement, entry.getSummary()); fillContentElement(summaryElement, entry.getSummary());
eEntry.addContent(summaryElement); eEntry.addContent(summaryElement);
} }
List<Content> contents = entry.getContents(); final List<Content> contents = entry.getContents();
for (int i = 0; i < contents.size(); i++) { for (int i = 0; i < contents.size(); i++) {
Element contentElement = new Element("content", getFeedNamespace()); final Element contentElement = new Element("content", getFeedNamespace());
fillContentElement(contentElement, (Content)contents.get(i)); fillContentElement(contentElement, contents.get(i));
eEntry.addContent(contentElement); eEntry.addContent(contentElement);
} }
generateForeignMarkup(eEntry, (List<Element>)entry.getForeignMarkup()); generateForeignMarkup(eEntry, entry.getForeignMarkup());
} }
protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException { protected void checkFeedHeaderConstraints(final Element eFeed) throws FeedException {
} }
protected void checkEntriesConstraints(Element parent) throws FeedException { protected void checkEntriesConstraints(final Element parent) throws FeedException {
} }
protected void checkEntryConstraints(Element eEntry) throws FeedException { protected void checkEntryConstraints(final Element eEntry) throws FeedException {
} }
protected Element generateLinkElement(final Link link) {
protected Element generateLinkElement(Link link) { final Element linkElement = new Element("link", getFeedNamespace());
Element linkElement = new Element("link", getFeedNamespace());
if (link.getRel() != null) { if (link.getRel() != null) {
Attribute relAttribute = new Attribute("rel", link.getRel().toString()); final Attribute relAttribute = new Attribute("rel", link.getRel().toString());
linkElement.setAttribute(relAttribute); linkElement.setAttribute(relAttribute);
} }
if (link.getType() != null) { if (link.getType() != null) {
Attribute typeAttribute = new Attribute("type", link.getType()); final Attribute typeAttribute = new Attribute("type", link.getType());
linkElement.setAttribute(typeAttribute); linkElement.setAttribute(typeAttribute);
} }
if (link.getHref() != null) { if (link.getHref() != null) {
Attribute hrefAttribute = new Attribute("href", link.getHref()); final Attribute hrefAttribute = new Attribute("href", link.getHref());
linkElement.setAttribute(hrefAttribute); linkElement.setAttribute(hrefAttribute);
} }
return linkElement; return linkElement;
} }
protected void fillPersonElement(final Element element, final Person person) {
protected void fillPersonElement(Element element, Person person) {
if (person.getName() != null) { if (person.getName() != null) {
element.addContent(generateSimpleElement("name", person.getName())); element.addContent(generateSimpleElement("name", person.getName()));
} }
@ -279,11 +284,11 @@ public class Atom03Generator extends BaseWireFeedGenerator {
} }
} }
protected Element generateTagLineElement(Content tagline) { protected Element generateTagLineElement(final Content tagline) {
Element taglineElement = new Element("tagline", getFeedNamespace()); final Element taglineElement = new Element("tagline", getFeedNamespace());
if (tagline.getType() != null) { if (tagline.getType() != null) {
Attribute typeAttribute = new Attribute("type", tagline.getType()); final Attribute typeAttribute = new Attribute("type", tagline.getType());
taglineElement.setAttribute(typeAttribute); taglineElement.setAttribute(typeAttribute);
} }
@ -293,17 +298,16 @@ public class Atom03Generator extends BaseWireFeedGenerator {
return taglineElement; return taglineElement;
} }
protected void fillContentElement(Element contentElement, Content content) protected void fillContentElement(final Element contentElement, final Content content) throws FeedException {
throws FeedException {
if (content.getType() != null) { if (content.getType() != null) {
Attribute typeAttribute = new Attribute("type", content.getType()); final Attribute typeAttribute = new Attribute("type", content.getType());
contentElement.setAttribute(typeAttribute); contentElement.setAttribute(typeAttribute);
} }
String mode = content.getMode(); final String mode = content.getMode();
if (mode != null) { if (mode != null) {
Attribute modeAttribute = new Attribute("mode", content.getMode().toString()); final Attribute modeAttribute = new Attribute("mode", content.getMode().toString());
contentElement.setAttribute(modeAttribute); contentElement.setAttribute(modeAttribute);
} }
@ -315,36 +319,35 @@ public class Atom03Generator extends BaseWireFeedGenerator {
contentElement.addContent(Base64.encode(content.getValue())); contentElement.addContent(Base64.encode(content.getValue()));
} else if (mode.equals(Content.XML)) { } else if (mode.equals(Content.XML)) {
StringBuffer tmpDocString = new StringBuffer("<tmpdoc>"); final StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
tmpDocString.append(content.getValue()); tmpDocString.append(content.getValue());
tmpDocString.append("</tmpdoc>"); tmpDocString.append("</tmpdoc>");
StringReader tmpDocReader = new StringReader(tmpDocString.toString()); final StringReader tmpDocReader = new StringReader(tmpDocString.toString());
Document tmpDoc; Document tmpDoc;
try { try {
SAXBuilder saxBuilder = new SAXBuilder(); final SAXBuilder saxBuilder = new SAXBuilder();
tmpDoc = saxBuilder.build(tmpDocReader); tmpDoc = saxBuilder.build(tmpDocReader);
} } catch (final Exception ex) {
catch (Exception ex) { throw new FeedException("Invalid XML", ex);
throw new FeedException("Invalid XML",ex);
} }
List<org.jdom2.Content> children = tmpDoc.getRootElement().removeContent(); final List<org.jdom2.Content> children = tmpDoc.getRootElement().removeContent();
contentElement.addContent(children); contentElement.addContent(children);
} }
} }
} }
protected Element generateGeneratorElement(Generator generator) { protected Element generateGeneratorElement(final Generator generator) {
Element generatorElement = new Element("generator", getFeedNamespace()); final Element generatorElement = new Element("generator", getFeedNamespace());
if (generator.getUrl() != null) { if (generator.getUrl() != null) {
Attribute urlAttribute = new Attribute("url", generator.getUrl()); final Attribute urlAttribute = new Attribute("url", generator.getUrl());
generatorElement.setAttribute(urlAttribute); generatorElement.setAttribute(urlAttribute);
} }
if (generator.getVersion() != null) { if (generator.getVersion() != null) {
Attribute versionAttribute = new Attribute("version", generator.getVersion()); final Attribute versionAttribute = new Attribute("version", generator.getVersion());
generatorElement.setAttribute(versionAttribute); generatorElement.setAttribute(versionAttribute);
} }
@ -356,8 +359,8 @@ public class Atom03Generator extends BaseWireFeedGenerator {
} }
protected Element generateSimpleElement(String name, String value) { protected Element generateSimpleElement(final String name, final String value) {
Element element = new Element(name, getFeedNamespace()); final Element element = new Element(name, getFeedNamespace());
element.addContent(value); element.addContent(value);
return element; return element;
} }

View file

@ -16,15 +16,22 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.WireFeed; import java.util.ArrayList;
import com.sun.syndication.feed.atom.*; import java.util.Iterator;
import com.sun.syndication.io.FeedException; import java.util.List;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import org.jdom2.output.XMLOutputter; import org.jdom2.output.XMLOutputter;
import java.util.*; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Generator;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Person;
import com.sun.syndication.io.FeedException;
/** /**
*/ */
@ -36,7 +43,7 @@ public class Atom03Parser extends BaseWireFeedParser {
this("atom_0.3", ATOM_03_NS); this("atom_0.3", ATOM_03_NS);
} }
protected Atom03Parser(String type, Namespace ns) { protected Atom03Parser(final String type, final Namespace ns) {
super(type, ns); super(type, ns);
} }
@ -44,186 +51,187 @@ public class Atom03Parser extends BaseWireFeedParser {
return ATOM_03_NS; return ATOM_03_NS;
} }
public boolean isMyType(Document document) { @Override
Element rssRoot = document.getRootElement(); public boolean isMyType(final Document document) {
Namespace defaultNS = rssRoot.getNamespace(); final Element rssRoot = document.getRootElement();
return (defaultNS!=null) && defaultNS.equals(getAtomNamespace()); final Namespace defaultNS = rssRoot.getNamespace();
return defaultNS != null && defaultNS.equals(getAtomNamespace());
} }
public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException { @Override
public WireFeed parse(final Document document, final boolean validate) throws IllegalArgumentException, FeedException {
if (validate) { if (validate) {
validateFeed(document); validateFeed(document);
} }
Element rssRoot = document.getRootElement(); final Element rssRoot = document.getRootElement();
return parseFeed(rssRoot); return parseFeed(rssRoot);
} }
protected void validateFeed(Document document) throws FeedException { protected void validateFeed(final Document document) throws FeedException {
// TBD // TBD
// here we have to validate the Feed against a schema or whatever // here we have to validate the Feed against a schema or whatever
// not sure how to do it // not sure how to do it
// one posibility would be to produce an ouput and attempt to parse it again // one posibility would be to produce an ouput and attempt to parse it
// again
// with validation turned on. // with validation turned on.
// otherwise will have to check the document elements by hand. // otherwise will have to check the document elements by hand.
} }
protected WireFeed parseFeed(Element eFeed) { protected WireFeed parseFeed(final Element eFeed) {
com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType()); final com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
Element e = eFeed.getChild("title",getAtomNamespace()); Element e = eFeed.getChild("title", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setTitleEx(parseContent(e)); feed.setTitleEx(parseContent(e));
} }
List<Element> eList = eFeed.getChildren("link",getAtomNamespace()); List<Element> eList = eFeed.getChildren("link", getAtomNamespace());
feed.setAlternateLinks(parseAlternateLinks(eList)); feed.setAlternateLinks(parseAlternateLinks(eList));
feed.setOtherLinks(parseOtherLinks(eList)); feed.setOtherLinks(parseOtherLinks(eList));
e = eFeed.getChild("author",getAtomNamespace()); e = eFeed.getChild("author", getAtomNamespace());
if (e!=null) { if (e != null) {
List<Person> authors = new ArrayList<Person>(); final List<Person> authors = new ArrayList<Person>();
authors.add(parsePerson(e)); authors.add(parsePerson(e));
feed.setAuthors(authors); feed.setAuthors(authors);
} }
eList = eFeed.getChildren("contributor",getAtomNamespace()); eList = eFeed.getChildren("contributor", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
feed.setContributors(parsePersons(eList)); feed.setContributors(parsePersons(eList));
} }
e = eFeed.getChild("tagline",getAtomNamespace()); e = eFeed.getChild("tagline", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setTagline(parseContent(e)); feed.setTagline(parseContent(e));
} }
e = eFeed.getChild("id",getAtomNamespace()); e = eFeed.getChild("id", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setId(e.getText()); feed.setId(e.getText());
} }
e = eFeed.getChild("generator",getAtomNamespace()); e = eFeed.getChild("generator", getAtomNamespace());
if (e!=null) { if (e != null) {
Generator gen = new Generator(); final Generator gen = new Generator();
gen.setValue(e.getText()); gen.setValue(e.getText());
String att = getAttributeValue(e, "url"); String att = getAttributeValue(e, "url");
if (att!=null) { if (att != null) {
gen.setUrl(att); gen.setUrl(att);
} }
att = getAttributeValue(e, "version"); att = getAttributeValue(e, "version");
if (att!=null) { if (att != null) {
gen.setVersion(att); gen.setVersion(att);
} }
feed.setGenerator(gen); feed.setGenerator(gen);
} }
e = eFeed.getChild("copyright",getAtomNamespace()); e = eFeed.getChild("copyright", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setCopyright(e.getText()); feed.setCopyright(e.getText());
} }
e = eFeed.getChild("info",getAtomNamespace()); e = eFeed.getChild("info", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setInfo(parseContent(e)); feed.setInfo(parseContent(e));
} }
e = eFeed.getChild("modified",getAtomNamespace()); e = eFeed.getChild("modified", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setModified(DateParser.parseDate(e.getText())); feed.setModified(DateParser.parseDate(e.getText()));
} }
feed.setModules(parseFeedModules(eFeed)); feed.setModules(parseFeedModules(eFeed));
eList = eFeed.getChildren("entry",getAtomNamespace()); eList = eFeed.getChildren("entry", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
feed.setEntries(parseEntries(eList)); feed.setEntries(parseEntries(eList));
} }
List<Element> foreignMarkup = final List<Element> foreignMarkup = extractForeignMarkup(eFeed, feed, getAtomNamespace());
extractForeignMarkup(eFeed, feed, getAtomNamespace());
if (foreignMarkup.size() > 0) { if (foreignMarkup.size() > 0) {
feed.setForeignMarkup(foreignMarkup); feed.setForeignMarkup(foreignMarkup);
} }
return feed; return feed;
} }
private Link parseLink(Element eLink) { private Link parseLink(final Element eLink) {
Link link = new Link(); final Link link = new Link();
String att = getAttributeValue(eLink, "rel"); String att = getAttributeValue(eLink, "rel");
if (att!=null) { if (att != null) {
link.setRel(att); link.setRel(att);
} }
att = getAttributeValue(eLink, "type"); att = getAttributeValue(eLink, "type");
if (att!=null) { if (att != null) {
link.setType(att); link.setType(att);
} }
att = getAttributeValue(eLink, "href"); att = getAttributeValue(eLink, "href");
if (att!=null) { if (att != null) {
link.setHref(att); link.setHref(att);
} }
return link; return link;
} }
// List(Elements) -> List(Link) // List(Elements) -> List(Link)
private List<Link> parseLinks(List<Element> eLinks,boolean alternate) { private List<Link> parseLinks(final List<Element> eLinks, final boolean alternate) {
List<Link> links = new ArrayList<Link>(); final List<Link> links = new ArrayList<Link>();
for (int i=0;i<eLinks.size();i++) { for (int i = 0; i < eLinks.size(); i++) {
Element eLink = (Element) eLinks.get(i); final Element eLink = eLinks.get(i);
String rel = getAttributeValue(eLink, "rel"); final String rel = getAttributeValue(eLink, "rel");
if (alternate) { if (alternate) {
if ("alternate".equals(rel)) { if ("alternate".equals(rel)) {
links.add(parseLink(eLink)); links.add(parseLink(eLink));
} }
} } else {
else { if (!"alternate".equals(rel)) {
if (!("alternate".equals(rel))) {
links.add(parseLink(eLink)); links.add(parseLink(eLink));
} }
} }
} }
return (links.size()>0) ? links : null; return links.size() > 0 ? links : null;
} }
// List(Elements) -> List(Link) // List(Elements) -> List(Link)
private List<Link> parseAlternateLinks(List<Element> eLinks) { private List<Link> parseAlternateLinks(final List<Element> eLinks) {
return parseLinks(eLinks,true); return parseLinks(eLinks, true);
} }
// List(Elements) -> List(Link) // List(Elements) -> List(Link)
private List<Link> parseOtherLinks(List<Element> eLinks) { private List<Link> parseOtherLinks(final List<Element> eLinks) {
return parseLinks(eLinks,false); return parseLinks(eLinks, false);
} }
private Person parsePerson(Element ePerson) { private Person parsePerson(final Element ePerson) {
Person person = new Person(); final Person person = new Person();
Element e = ePerson.getChild("name",getAtomNamespace()); Element e = ePerson.getChild("name", getAtomNamespace());
if (e!=null) { if (e != null) {
person.setName(e.getText()); person.setName(e.getText());
} }
e = ePerson.getChild("url",getAtomNamespace()); e = ePerson.getChild("url", getAtomNamespace());
if (e!=null) { if (e != null) {
person.setUrl(e.getText()); person.setUrl(e.getText());
} }
e = ePerson.getChild("email",getAtomNamespace()); e = ePerson.getChild("email", getAtomNamespace());
if (e!=null) { if (e != null) {
person.setEmail(e.getText()); person.setEmail(e.getText());
} }
return person; return person;
} }
// List(Elements) -> List(Persons) // List(Elements) -> List(Persons)
private List<Person> parsePersons(List<Element> ePersons) { private List<Person> parsePersons(final List<Element> ePersons) {
List<Person> persons = new ArrayList<Person>(); final List<Person> persons = new ArrayList<Person>();
for (int i=0;i<ePersons.size();i++) { for (int i = 0; i < ePersons.size(); i++) {
persons.add(parsePerson((Element)ePersons.get(i))); persons.add(parsePerson(ePersons.get(i)));
} }
return (persons.size()>0) ? persons : null; return persons.size() > 0 ? persons : null;
} }
private Content parseContent(Element e) { private Content parseContent(final Element e) {
String value = null; String value = null;
String type = getAttributeValue(e, "type"); String type = getAttributeValue(e, "type");
type = (type!=null) ? type : "text/plain"; type = type != null ? type : "text/plain";
String mode = getAttributeValue(e, "mode"); String mode = getAttributeValue(e, "mode");
if (mode == null) { if (mode == null) {
mode = Content.XML; // default to xml content mode = Content.XML; // default to xml content
@ -231,29 +239,25 @@ public class Atom03Parser extends BaseWireFeedParser {
if (mode.equals(Content.ESCAPED)) { if (mode.equals(Content.ESCAPED)) {
// do nothing XML Parser took care of this // do nothing XML Parser took care of this
value = e.getText(); value = e.getText();
} } else if (mode.equals(Content.BASE64)) {
else value = Base64.decode(e.getText());
if (mode.equals(Content.BASE64)) { } else if (mode.equals(Content.XML)) {
value = Base64.decode(e.getText()); final XMLOutputter outputter = new XMLOutputter();
} final List<org.jdom2.Content> eContent = e.getContent();
else final Iterator<org.jdom2.Content> i = eContent.iterator();
if (mode.equals(Content.XML)) {
XMLOutputter outputter = new XMLOutputter();
List<org.jdom2.Content> eContent = e.getContent();
Iterator<org.jdom2.Content> i = eContent.iterator();
while (i.hasNext()) { while (i.hasNext()) {
org.jdom2.Content c = (org.jdom2.Content) i.next(); final org.jdom2.Content c = i.next();
if (c instanceof Element) { if (c instanceof Element) {
Element eC = (Element) c; final Element eC = (Element) c;
if (eC.getNamespace().equals(getAtomNamespace())) { if (eC.getNamespace().equals(getAtomNamespace())) {
((Element)c).setNamespace(Namespace.NO_NAMESPACE); ((Element) c).setNamespace(Namespace.NO_NAMESPACE);
} }
} }
} }
value = outputter.outputString(eContent); value = outputter.outputString(eContent);
} }
Content content = new Content(); final Content content = new Content();
content.setType(type); content.setType(type);
content.setMode(mode); content.setMode(mode);
content.setValue(value); content.setValue(value);
@ -261,81 +265,79 @@ public class Atom03Parser extends BaseWireFeedParser {
} }
// List(Elements) -> List(Entries) // List(Elements) -> List(Entries)
private List<Entry> parseEntries(List<Element> eEntries) { private List<Entry> parseEntries(final List<Element> eEntries) {
List<Entry> entries = new ArrayList<Entry>(); final List<Entry> entries = new ArrayList<Entry>();
for (int i=0;i<eEntries.size();i++) { for (int i = 0; i < eEntries.size(); i++) {
entries.add(parseEntry((Element)eEntries.get(i))); entries.add(parseEntry(eEntries.get(i)));
} }
return (entries.size()>0) ? entries : null; return entries.size() > 0 ? entries : null;
} }
private Entry parseEntry(Element eEntry) { private Entry parseEntry(final Element eEntry) {
Entry entry = new Entry(); final Entry entry = new Entry();
Element e = eEntry.getChild("title",getAtomNamespace()); Element e = eEntry.getChild("title", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setTitleEx(parseContent(e)); entry.setTitleEx(parseContent(e));
} }
List<Element> eList = eEntry.getChildren("link",getAtomNamespace()); List<Element> eList = eEntry.getChildren("link", getAtomNamespace());
entry.setAlternateLinks(parseAlternateLinks(eList)); entry.setAlternateLinks(parseAlternateLinks(eList));
entry.setOtherLinks(parseOtherLinks(eList)); entry.setOtherLinks(parseOtherLinks(eList));
e = eEntry.getChild("author",getAtomNamespace()); e = eEntry.getChild("author", getAtomNamespace());
if (e!=null) { if (e != null) {
List<Person> authors = new ArrayList<Person>(); final List<Person> authors = new ArrayList<Person>();
authors.add(parsePerson(e)); authors.add(parsePerson(e));
entry.setAuthors(authors); entry.setAuthors(authors);
} }
eList = eEntry.getChildren("contributor",getAtomNamespace()); eList = eEntry.getChildren("contributor", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
entry.setContributors(parsePersons(eList)); entry.setContributors(parsePersons(eList));
} }
e = eEntry.getChild("id",getAtomNamespace()); e = eEntry.getChild("id", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setId(e.getText()); entry.setId(e.getText());
} }
e = eEntry.getChild("modified",getAtomNamespace()); e = eEntry.getChild("modified", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setModified(DateParser.parseDate(e.getText())); entry.setModified(DateParser.parseDate(e.getText()));
} }
e = eEntry.getChild("issued",getAtomNamespace()); e = eEntry.getChild("issued", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setIssued(DateParser.parseDate(e.getText())); entry.setIssued(DateParser.parseDate(e.getText()));
} }
e = eEntry.getChild("created",getAtomNamespace()); e = eEntry.getChild("created", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setCreated(DateParser.parseDate(e.getText())); entry.setCreated(DateParser.parseDate(e.getText()));
} }
e = eEntry.getChild("summary",getAtomNamespace()); e = eEntry.getChild("summary", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setSummary(parseContent(e)); entry.setSummary(parseContent(e));
} }
eList = eEntry.getChildren("content",getAtomNamespace()); eList = eEntry.getChildren("content", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
List<Content> content = new ArrayList<Content>(); final List<Content> content = new ArrayList<Content>();
for (int i=0;i<eList.size();i++) { for (int i = 0; i < eList.size(); i++) {
content.add(parseContent((Element)eList.get(i))); content.add(parseContent(eList.get(i)));
} }
entry.setContents(content); entry.setContents(content);
} }
entry.setModules(parseItemModules(eEntry)); entry.setModules(parseItemModules(eEntry));
List<Element> foreignMarkup = final List<Element> foreignMarkup = extractForeignMarkup(eEntry, entry, getAtomNamespace());
extractForeignMarkup(eEntry, entry, getAtomNamespace());
if (foreignMarkup.size() > 0) { if (foreignMarkup.size() > 0) {
entry.setForeignMarkup(foreignMarkup); entry.setForeignMarkup(foreignMarkup);
} }
return entry; return entry;
} }
} }

View file

@ -16,8 +16,10 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.Iterator; import java.io.Writer;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jdom2.Attribute; import org.jdom2.Attribute;
@ -25,6 +27,7 @@ import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Category; import com.sun.syndication.feed.atom.Category;
@ -36,60 +39,57 @@ import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Person; import com.sun.syndication.feed.atom.Person;
import com.sun.syndication.io.FeedException; import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.WireFeedOutput; import com.sun.syndication.io.WireFeedOutput;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import org.jdom2.output.XMLOutputter;
/** /**
* Feed Generator for Atom * Feed Generator for Atom
* <p/> * <p/>
* *
* @author Elaine Chien * @author Elaine Chien
* @author Dave Johnson (updated for Atom 1.0) * @author Dave Johnson (updated for Atom 1.0)
* *
*/ */
public class Atom10Generator extends BaseWireFeedGenerator { public class Atom10Generator extends BaseWireFeedGenerator {
private static final String ATOM_10_URI = "http://www.w3.org/2005/Atom"; private static final String ATOM_10_URI = "http://www.w3.org/2005/Atom";
private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_10_URI); private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_10_URI);
private String _version; private final String _version;
public Atom10Generator() { public Atom10Generator() {
this("atom_1.0","1.0"); this("atom_1.0", "1.0");
} }
protected Atom10Generator(String type,String version) { protected Atom10Generator(final String type, final String version) {
super(type); super(type);
_version = version; this._version = version;
} }
protected String getVersion() { protected String getVersion() {
return _version; return this._version;
} }
protected Namespace getFeedNamespace() { protected Namespace getFeedNamespace() {
return ATOM_NS; return ATOM_NS;
} }
public Document generate(WireFeed wFeed) throws FeedException { @Override
Feed feed = (Feed) wFeed; public Document generate(final WireFeed wFeed) throws FeedException {
Element root = createRootElement(feed); final Feed feed = (Feed) wFeed;
populateFeed(feed,root); final Element root = createRootElement(feed);
populateFeed(feed, root);
purgeUnusedNamespaceDeclarations(root); purgeUnusedNamespaceDeclarations(root);
return createDocument(root); return createDocument(root);
} }
protected Document createDocument(Element root) { protected Document createDocument(final Element root) {
return new Document(root); return new Document(root);
} }
protected Element createRootElement(Feed feed) { protected Element createRootElement(final Feed feed) {
Element root = new Element("feed",getFeedNamespace()); final Element root = new Element("feed", getFeedNamespace());
root.addNamespaceDeclaration(getFeedNamespace()); root.addNamespaceDeclaration(getFeedNamespace());
//Attribute version = new Attribute("version", getVersion()); // Attribute version = new Attribute("version", getVersion());
//root.setAttribute(version); // root.setAttribute(version);
if (feed.getXmlBase() != null) { if (feed.getXmlBase() != null) {
root.setAttribute("base", feed.getXmlBase(), Namespace.XML_NAMESPACE); root.setAttribute("base", feed.getXmlBase(), Namespace.XML_NAMESPACE);
} }
@ -97,82 +97,88 @@ public class Atom10Generator extends BaseWireFeedGenerator {
return root; return root;
} }
protected void populateFeed(Feed feed,Element parent) throws FeedException { protected void populateFeed(final Feed feed, final Element parent) throws FeedException {
addFeed(feed,parent); addFeed(feed, parent);
addEntries(feed,parent); addEntries(feed, parent);
} }
protected void addFeed(Feed feed,Element parent) throws FeedException { protected void addFeed(final Feed feed, final Element parent) throws FeedException {
Element eFeed = parent; final Element eFeed = parent;
populateFeedHeader(feed,eFeed); populateFeedHeader(feed, eFeed);
generateForeignMarkup(eFeed, (List<Element>)feed.getForeignMarkup()); generateForeignMarkup(eFeed, feed.getForeignMarkup());
checkFeedHeaderConstraints(eFeed); checkFeedHeaderConstraints(eFeed);
generateFeedModules(feed.getModules(),eFeed); generateFeedModules(feed.getModules(), eFeed);
} }
protected void addEntries(Feed feed,Element parent) throws FeedException { protected void addEntries(final Feed feed, final Element parent) throws FeedException {
List<Entry> items = feed.getEntries(); final List<Entry> items = feed.getEntries();
for (int i=0;i<items.size();i++) { for (int i = 0; i < items.size(); i++) {
addEntry((Entry)items.get(i),parent); addEntry(items.get(i), parent);
} }
checkEntriesConstraints(parent); checkEntriesConstraints(parent);
} }
protected void addEntry(Entry entry,Element parent) throws FeedException { protected void addEntry(final Entry entry, final Element parent) throws FeedException {
Element eEntry = new Element("entry", getFeedNamespace()); final Element eEntry = new Element("entry", getFeedNamespace());
if (entry.getXmlBase() != null) { if (entry.getXmlBase() != null) {
eEntry.setAttribute("base", entry.getXmlBase(), Namespace.XML_NAMESPACE); eEntry.setAttribute("base", entry.getXmlBase(), Namespace.XML_NAMESPACE);
} }
populateEntry(entry,eEntry); populateEntry(entry, eEntry);
generateForeignMarkup(eEntry, (List<Element>)entry.getForeignMarkup()); generateForeignMarkup(eEntry, entry.getForeignMarkup());
checkEntryConstraints(eEntry); checkEntryConstraints(eEntry);
generateItemModules(entry.getModules(),eEntry); generateItemModules(entry.getModules(), eEntry);
parent.addContent(eEntry); parent.addContent(eEntry);
} }
protected void populateFeedHeader(Feed feed,Element eFeed) throws FeedException { protected void populateFeedHeader(final Feed feed, final Element eFeed) throws FeedException {
if (feed.getTitleEx() != null) { if (feed.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace()); final Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, feed.getTitleEx()); fillContentElement(titleElement, feed.getTitleEx());
eFeed.addContent(titleElement); eFeed.addContent(titleElement);
} }
List<Link> links = feed.getAlternateLinks(); List<Link> links = feed.getAlternateLinks();
if (links != null) for (int i = 0; i < links.size(); i++) { if (links != null) {
eFeed.addContent(generateLinkElement((Link)links.get(i))); for (int i = 0; i < links.size(); i++) {
eFeed.addContent(generateLinkElement(links.get(i)));
}
} }
links = feed.getOtherLinks(); links = feed.getOtherLinks();
if (links != null) for (int j = 0; j < links.size(); j++) { if (links != null) {
eFeed.addContent(generateLinkElement((Link)links.get(j))); for (int j = 0; j < links.size(); j++) {
eFeed.addContent(generateLinkElement(links.get(j)));
}
} }
List<Category> cats = feed.getCategories(); final List<Category> cats = feed.getCategories();
if (cats != null) for (Iterator<Category> iter=cats.iterator(); iter.hasNext();) { if (cats != null) {
eFeed.addContent(generateCategoryElement((Category)iter.next())); for (final Category category : cats) {
eFeed.addContent(generateCategoryElement(category));
}
} }
List<Person> authors = feed.getAuthors(); final List<Person> authors = feed.getAuthors();
if (authors != null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
for (int i = 0; i < authors.size(); i++) { for (int i = 0; i < authors.size(); i++) {
Element authorElement = new Element("author", getFeedNamespace()); final Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)feed.getAuthors().get(i)); fillPersonElement(authorElement, feed.getAuthors().get(i));
eFeed.addContent(authorElement); eFeed.addContent(authorElement);
} }
} }
List<Person> contributors = feed.getContributors(); final List<Person> contributors = feed.getContributors();
if (contributors != null && contributors.size() > 0) { if (contributors != null && contributors.size() > 0) {
for (int i = 0; i < contributors.size(); i++) { for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace()); final Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i)); fillPersonElement(contributorElement, contributors.get(i));
eFeed.addContent(contributorElement); eFeed.addContent(contributorElement);
} }
} }
if (feed.getSubtitle() != null) { if (feed.getSubtitle() != null) {
Element subtitleElement = new Element("subtitle", getFeedNamespace()); final Element subtitleElement = new Element("subtitle", getFeedNamespace());
fillContentElement(subtitleElement, feed.getSubtitle()); fillContentElement(subtitleElement, feed.getSubtitle());
eFeed.addContent(subtitleElement); eFeed.addContent(subtitleElement);
} }
if (feed.getId() != null) { if (feed.getId() != null) {
@ -188,60 +194,60 @@ public class Atom10Generator extends BaseWireFeedGenerator {
} }
if (feed.getIcon() != null) { if (feed.getIcon() != null) {
eFeed.addContent(generateSimpleElement("icon", feed.getIcon())); eFeed.addContent(generateSimpleElement("icon", feed.getIcon()));
} }
if (feed.getLogo() != null) { if (feed.getLogo() != null) {
eFeed.addContent(generateSimpleElement("logo", feed.getLogo())); eFeed.addContent(generateSimpleElement("logo", feed.getLogo()));
} }
if (feed.getUpdated() != null) { if (feed.getUpdated() != null) {
Element updatedElement = new Element("updated", getFeedNamespace()); final Element updatedElement = new Element("updated", getFeedNamespace());
updatedElement.addContent(DateParser.formatW3CDateTime(feed.getUpdated())); updatedElement.addContent(DateParser.formatW3CDateTime(feed.getUpdated()));
eFeed.addContent(updatedElement); eFeed.addContent(updatedElement);
} }
} }
protected void populateEntry(Entry entry, Element eEntry) throws FeedException { protected void populateEntry(final Entry entry, final Element eEntry) throws FeedException {
if (entry.getTitleEx() != null) { if (entry.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace()); final Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, entry.getTitleEx()); fillContentElement(titleElement, entry.getTitleEx());
eEntry.addContent(titleElement); eEntry.addContent(titleElement);
} }
List<Link> links = entry.getAlternateLinks(); List<Link> links = entry.getAlternateLinks();
if (links != null) { if (links != null) {
for (int i = 0; i < links.size(); i++) { for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i))); eEntry.addContent(generateLinkElement(links.get(i)));
} }
} }
links = entry.getOtherLinks(); links = entry.getOtherLinks();
if (links != null) { if (links != null) {
for (int i = 0; i < links.size(); i++) { for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i))); eEntry.addContent(generateLinkElement(links.get(i)));
} }
} }
List<Category> cats = entry.getCategories(); final List<Category> cats = entry.getCategories();
if (cats != null) { if (cats != null) {
for (int i = 0; i < cats.size(); i++) { for (int i = 0; i < cats.size(); i++) {
eEntry.addContent(generateCategoryElement((Category)cats.get(i))); eEntry.addContent(generateCategoryElement(cats.get(i)));
}
}
List<Person> authors = entry.getAuthors();
if (authors != null && authors.size() > 0) {
for (int i = 0; i < authors.size(); i++) {
Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)entry.getAuthors().get(i));
eEntry.addContent(authorElement);
} }
} }
List<Person> contributors = entry.getContributors(); final List<Person> authors = entry.getAuthors();
if (authors != null && authors.size() > 0) {
for (int i = 0; i < authors.size(); i++) {
final Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, entry.getAuthors().get(i));
eEntry.addContent(authorElement);
}
}
final List<Person> contributors = entry.getContributors();
if (contributors != null && contributors.size() > 0) { if (contributors != null && contributors.size() > 0) {
for (int i = 0; i < contributors.size(); i++) { for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace()); final Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i)); fillPersonElement(contributorElement, contributors.get(i));
eEntry.addContent(contributorElement); eEntry.addContent(contributorElement);
} }
} }
@ -250,102 +256,100 @@ public class Atom10Generator extends BaseWireFeedGenerator {
} }
if (entry.getUpdated() != null) { if (entry.getUpdated() != null) {
Element updatedElement = new Element("updated", getFeedNamespace()); final Element updatedElement = new Element("updated", getFeedNamespace());
updatedElement.addContent(DateParser.formatW3CDateTime(entry.getUpdated())); updatedElement.addContent(DateParser.formatW3CDateTime(entry.getUpdated()));
eEntry.addContent(updatedElement); eEntry.addContent(updatedElement);
} }
if (entry.getPublished() != null) { if (entry.getPublished() != null) {
Element publishedElement = new Element("published", getFeedNamespace()); final Element publishedElement = new Element("published", getFeedNamespace());
publishedElement.addContent(DateParser.formatW3CDateTime(entry.getPublished())); publishedElement.addContent(DateParser.formatW3CDateTime(entry.getPublished()));
eEntry.addContent(publishedElement); eEntry.addContent(publishedElement);
} }
if (entry.getContents() != null && entry.getContents().size() > 0) { if (entry.getContents() != null && entry.getContents().size() > 0) {
Element contentElement = new Element("content", getFeedNamespace()); final Element contentElement = new Element("content", getFeedNamespace());
Content content = (Content)entry.getContents().get(0); final Content content = entry.getContents().get(0);
fillContentElement(contentElement, content); fillContentElement(contentElement, content);
eEntry.addContent(contentElement); eEntry.addContent(contentElement);
} }
if (entry.getSummary() != null) { if (entry.getSummary() != null) {
Element summaryElement = new Element("summary", getFeedNamespace()); final Element summaryElement = new Element("summary", getFeedNamespace());
fillContentElement(summaryElement, entry.getSummary()); fillContentElement(summaryElement, entry.getSummary());
eEntry.addContent(summaryElement); eEntry.addContent(summaryElement);
} }
if (entry.getSource() != null) { if (entry.getSource() != null) {
Element sourceElement = new Element("source", getFeedNamespace()); final Element sourceElement = new Element("source", getFeedNamespace());
populateFeedHeader(entry.getSource(), sourceElement); populateFeedHeader(entry.getSource(), sourceElement);
eEntry.addContent(sourceElement); eEntry.addContent(sourceElement);
} }
} }
protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException { protected void checkFeedHeaderConstraints(final Element eFeed) throws FeedException {
} }
protected void checkEntriesConstraints(Element parent) throws FeedException { protected void checkEntriesConstraints(final Element parent) throws FeedException {
} }
protected void checkEntryConstraints(Element eEntry) throws FeedException { protected void checkEntryConstraints(final Element eEntry) throws FeedException {
} }
protected Element generateCategoryElement(final Category cat) {
protected Element generateCategoryElement(Category cat) { final Element catElement = new Element("category", getFeedNamespace());
Element catElement = new Element("category", getFeedNamespace());
if (cat.getTerm() != null) { if (cat.getTerm() != null) {
Attribute termAttribute = new Attribute("term", cat.getTerm()); final Attribute termAttribute = new Attribute("term", cat.getTerm());
catElement.setAttribute(termAttribute); catElement.setAttribute(termAttribute);
} }
if (cat.getLabel() != null) { if (cat.getLabel() != null) {
Attribute labelAttribute = new Attribute("label", cat.getLabel()); final Attribute labelAttribute = new Attribute("label", cat.getLabel());
catElement.setAttribute(labelAttribute); catElement.setAttribute(labelAttribute);
} }
if (cat.getScheme() != null) { if (cat.getScheme() != null) {
Attribute schemeAttribute = new Attribute("scheme", cat.getScheme()); final Attribute schemeAttribute = new Attribute("scheme", cat.getScheme());
catElement.setAttribute(schemeAttribute); catElement.setAttribute(schemeAttribute);
} }
return catElement; return catElement;
} }
protected Element generateLinkElement(Link link) { protected Element generateLinkElement(final Link link) {
Element linkElement = new Element("link", getFeedNamespace()); final Element linkElement = new Element("link", getFeedNamespace());
if (link.getRel() != null) { if (link.getRel() != null) {
Attribute relAttribute = new Attribute("rel", link.getRel()); final Attribute relAttribute = new Attribute("rel", link.getRel());
linkElement.setAttribute(relAttribute); linkElement.setAttribute(relAttribute);
} }
if (link.getType() != null) { if (link.getType() != null) {
Attribute typeAttribute = new Attribute("type", link.getType()); final Attribute typeAttribute = new Attribute("type", link.getType());
linkElement.setAttribute(typeAttribute); linkElement.setAttribute(typeAttribute);
} }
if (link.getHref() != null) { if (link.getHref() != null) {
Attribute hrefAttribute = new Attribute("href", link.getHref()); final Attribute hrefAttribute = new Attribute("href", link.getHref());
linkElement.setAttribute(hrefAttribute); linkElement.setAttribute(hrefAttribute);
} }
if (link.getHreflang() != null) { if (link.getHreflang() != null) {
Attribute hreflangAttribute = new Attribute("hreflang", link.getHreflang()); final Attribute hreflangAttribute = new Attribute("hreflang", link.getHreflang());
linkElement.setAttribute(hreflangAttribute); linkElement.setAttribute(hreflangAttribute);
} }
if (link.getTitle() != null) { if (link.getTitle() != null) {
Attribute title = new Attribute("title", link.getTitle()); final Attribute title = new Attribute("title", link.getTitle());
linkElement.setAttribute(title); linkElement.setAttribute(title);
} }
if (link.getLength() != 0) { if (link.getLength() != 0) {
Attribute lenght = new Attribute("length", Long.toString(link.getLength())); final Attribute lenght = new Attribute("length", Long.toString(link.getLength()));
linkElement.setAttribute(lenght); linkElement.setAttribute(lenght);
} }
return linkElement; return linkElement;
} }
protected void fillPersonElement(final Element element, final Person person) {
protected void fillPersonElement(Element element, Person person) {
if (person.getName() != null) { if (person.getName() != null) {
element.addContent(generateSimpleElement("name", person.getName())); element.addContent(generateSimpleElement("name", person.getName()));
} }
@ -359,11 +363,11 @@ public class Atom10Generator extends BaseWireFeedGenerator {
generatePersonModules(person.getModules(), element); generatePersonModules(person.getModules(), element);
} }
protected Element generateTagLineElement(Content tagline) { protected Element generateTagLineElement(final Content tagline) {
Element taglineElement = new Element("subtitle", getFeedNamespace()); final Element taglineElement = new Element("subtitle", getFeedNamespace());
if (tagline.getType() != null) { if (tagline.getType() != null) {
Attribute typeAttribute = new Attribute("type", tagline.getType()); final Attribute typeAttribute = new Attribute("type", tagline.getType());
taglineElement.setAttribute(typeAttribute); taglineElement.setAttribute(typeAttribute);
} }
@ -373,45 +377,46 @@ public class Atom10Generator extends BaseWireFeedGenerator {
return taglineElement; return taglineElement;
} }
protected void fillContentElement(Element contentElement, Content content) protected void fillContentElement(final Element contentElement, final Content content) throws FeedException {
throws FeedException {
String type = content.getType(); final String type = content.getType();
String atomType = type; String atomType = type;
if (type != null) { if (type != null) {
// Fix for issue #39 "Atom 1.0 Text Types Not Set Correctly" // Fix for issue #39 "Atom 1.0 Text Types Not Set Correctly"
// we're not sure who set this value, so ensure Atom types are used // we're not sure who set this value, so ensure Atom types are used
if ("text/plain".equals(type)) atomType = Content.TEXT; if ("text/plain".equals(type)) {
else if ("text/html".equals(type)) atomType = Content.HTML; atomType = Content.TEXT;
else if ("application/xhtml+xml".equals(type)) atomType = Content.XHTML; } else if ("text/html".equals(type)) {
atomType = Content.HTML;
Attribute typeAttribute = new Attribute("type", atomType); } else if ("application/xhtml+xml".equals(type)) {
atomType = Content.XHTML;
}
final Attribute typeAttribute = new Attribute("type", atomType);
contentElement.setAttribute(typeAttribute); contentElement.setAttribute(typeAttribute);
} }
String href = content.getSrc(); final String href = content.getSrc();
if (href != null) { if (href != null) {
Attribute srcAttribute = new Attribute("src", href); final Attribute srcAttribute = new Attribute("src", href);
contentElement.setAttribute(srcAttribute); contentElement.setAttribute(srcAttribute);
} }
if (content.getValue() != null) { if (content.getValue() != null) {
if (atomType != null && (atomType.equals(Content.XHTML) || (atomType.indexOf("/xml")) != -1 || if (atomType != null && (atomType.equals(Content.XHTML) || atomType.indexOf("/xml") != -1 || atomType.indexOf("+xml") != -1)) {
(atomType.indexOf("+xml")) != -1)) {
StringBuffer tmpDocString = new StringBuffer("<tmpdoc>"); final StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
tmpDocString.append(content.getValue()); tmpDocString.append(content.getValue());
tmpDocString.append("</tmpdoc>"); tmpDocString.append("</tmpdoc>");
StringReader tmpDocReader = new StringReader(tmpDocString.toString()); final StringReader tmpDocReader = new StringReader(tmpDocString.toString());
Document tmpDoc; Document tmpDoc;
try { try {
SAXBuilder saxBuilder = new SAXBuilder(); final SAXBuilder saxBuilder = new SAXBuilder();
tmpDoc = saxBuilder.build(tmpDocReader); tmpDoc = saxBuilder.build(tmpDocReader);
} catch (final Exception ex) {
throw new FeedException("Invalid XML", ex);
} }
catch (Exception ex) { final List<org.jdom2.Content> children = tmpDoc.getRootElement().removeContent();
throw new FeedException("Invalid XML",ex);
}
List<org.jdom2.Content> children = tmpDoc.getRootElement().removeContent();
contentElement.addContent(children); contentElement.addContent(children);
} else { } else {
// must be type html, text or some other non-XML format // must be type html, text or some other non-XML format
// JDOM will escape property for XML // JDOM will escape property for XML
contentElement.addContent(content.getValue()); contentElement.addContent(content.getValue());
@ -419,16 +424,16 @@ public class Atom10Generator extends BaseWireFeedGenerator {
} }
} }
protected Element generateGeneratorElement(Generator generator) { protected Element generateGeneratorElement(final Generator generator) {
Element generatorElement = new Element("generator", getFeedNamespace()); final Element generatorElement = new Element("generator", getFeedNamespace());
if (generator.getUrl() != null) { if (generator.getUrl() != null) {
Attribute urlAttribute = new Attribute("uri", generator.getUrl()); final Attribute urlAttribute = new Attribute("uri", generator.getUrl());
generatorElement.setAttribute(urlAttribute); generatorElement.setAttribute(urlAttribute);
} }
if (generator.getVersion() != null) { if (generator.getVersion() != null) {
Attribute versionAttribute = new Attribute("version", generator.getVersion()); final Attribute versionAttribute = new Attribute("version", generator.getVersion());
generatorElement.setAttribute(versionAttribute); generatorElement.setAttribute(versionAttribute);
} }
@ -440,33 +445,32 @@ public class Atom10Generator extends BaseWireFeedGenerator {
} }
protected Element generateSimpleElement(String name, String value) { protected Element generateSimpleElement(final String name, final String value) {
Element element = new Element(name, getFeedNamespace()); final Element element = new Element(name, getFeedNamespace());
element.addContent(value); element.addContent(value);
return element; return element;
} }
/** /**
* Utility method to serialize an entry to writer. * Utility method to serialize an entry to writer.
*/ */
public static void serializeEntry(Entry entry, Writer writer) public static void serializeEntry(final Entry entry, final Writer writer) throws IllegalArgumentException, FeedException, IOException {
throws IllegalArgumentException, FeedException, IOException {
// Build a feed containing only the entry // Build a feed containing only the entry
List<Entry> entries = new ArrayList<Entry>(); final List<Entry> entries = new ArrayList<Entry>();
entries.add(entry); entries.add(entry);
Feed feed1 = new Feed(); final Feed feed1 = new Feed();
feed1.setFeedType("atom_1.0"); feed1.setFeedType("atom_1.0");
feed1.setEntries(entries); feed1.setEntries(entries);
// Get Rome to output feed as a JDOM document // Get Rome to output feed as a JDOM document
WireFeedOutput wireFeedOutput = new WireFeedOutput(); final WireFeedOutput wireFeedOutput = new WireFeedOutput();
Document feedDoc = wireFeedOutput.outputJDom(feed1); final Document feedDoc = wireFeedOutput.outputJDom(feed1);
// Grab entry element from feed and get JDOM to serialize it // Grab entry element from feed and get JDOM to serialize it
Element entryElement= (Element)feedDoc.getRootElement().getChildren().get(0); final Element entryElement = feedDoc.getRootElement().getChildren().get(0);
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
outputter.output(entryElement, writer); outputter.output(entryElement, writer);
} }

View file

@ -16,14 +16,22 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
import org.jdom2.Document; import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import org.jdom2.output.XMLOutputter; import org.jdom2.Parent;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Category; import com.sun.syndication.feed.atom.Category;
@ -36,17 +44,10 @@ import com.sun.syndication.feed.atom.Person;
import com.sun.syndication.io.FeedException; import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.WireFeedInput; import com.sun.syndication.io.WireFeedInput;
import com.sun.syndication.io.WireFeedOutput; import com.sun.syndication.io.WireFeedOutput;
import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;
import java.util.regex.Pattern;
import org.jdom2.Attribute;
import org.jdom2.JDOMException;
import org.jdom2.Parent;
import org.jdom2.input.SAXBuilder;
/** /**
* Parser for Atom 1.0 * Parser for Atom 1.0
*
* @author Dave Johnson * @author Dave Johnson
*/ */
public class Atom10Parser extends BaseWireFeedParser { public class Atom10Parser extends BaseWireFeedParser {
@ -55,7 +56,7 @@ public class Atom10Parser extends BaseWireFeedParser {
private static boolean resolveURIs = false; private static boolean resolveURIs = false;
public static void setResolveURIs(boolean resolveURIs) { public static void setResolveURIs(final boolean resolveURIs) {
Atom10Parser.resolveURIs = resolveURIs; Atom10Parser.resolveURIs = resolveURIs;
} }
@ -66,268 +67,266 @@ public class Atom10Parser extends BaseWireFeedParser {
public Atom10Parser() { public Atom10Parser() {
this("atom_1.0"); this("atom_1.0");
} }
protected Atom10Parser(String type) { protected Atom10Parser(final String type) {
super(type, ATOM_10_NS); super(type, ATOM_10_NS);
} }
protected Namespace getAtomNamespace() { protected Namespace getAtomNamespace() {
return ATOM_10_NS; return ATOM_10_NS;
} }
public boolean isMyType(Document document) { @Override
Element rssRoot = document.getRootElement(); public boolean isMyType(final Document document) {
Namespace defaultNS = rssRoot.getNamespace(); final Element rssRoot = document.getRootElement();
return (defaultNS!=null) && defaultNS.equals(getAtomNamespace()); final Namespace defaultNS = rssRoot.getNamespace();
return defaultNS != null && defaultNS.equals(getAtomNamespace());
} }
public WireFeed parse(Document document, boolean validate) @Override
throws IllegalArgumentException,FeedException { public WireFeed parse(final Document document, final boolean validate) throws IllegalArgumentException, FeedException {
if (validate) { if (validate) {
validateFeed(document); validateFeed(document);
} }
Element rssRoot = document.getRootElement(); final Element rssRoot = document.getRootElement();
return parseFeed(rssRoot); return parseFeed(rssRoot);
} }
protected void validateFeed(Document document) throws FeedException { protected void validateFeed(final Document document) throws FeedException {
// TBD // TBD
// here we have to validate the Feed against a schema or whatever // here we have to validate the Feed against a schema or whatever
// not sure how to do it // not sure how to do it
// one posibility would be to produce an ouput and attempt to parse it again // one posibility would be to produce an ouput and attempt to parse it
// again
// with validation turned on. // with validation turned on.
// otherwise will have to check the document elements by hand. // otherwise will have to check the document elements by hand.
} }
protected WireFeed parseFeed(Element eFeed) throws FeedException { protected WireFeed parseFeed(final Element eFeed) throws FeedException {
String baseURI = null; String baseURI = null;
try { try {
baseURI = findBaseURI(eFeed); baseURI = findBaseURI(eFeed);
} catch (Exception e) { } catch (final Exception e) {
throw new FeedException("ERROR while finding base URI of feed", e); throw new FeedException("ERROR while finding base URI of feed", e);
} }
Feed feed = parseFeedMetadata(baseURI, eFeed);
String xmlBase = eFeed.getAttributeValue("base", Namespace.XML_NAMESPACE); final Feed feed = parseFeedMetadata(baseURI, eFeed);
final String xmlBase = eFeed.getAttributeValue("base", Namespace.XML_NAMESPACE);
if (xmlBase != null) { if (xmlBase != null) {
feed.setXmlBase(xmlBase); feed.setXmlBase(xmlBase);
} }
feed.setModules(parseFeedModules(eFeed)); feed.setModules(parseFeedModules(eFeed));
List<Element> eList = eFeed.getChildren("entry",getAtomNamespace()); final List<Element> eList = eFeed.getChildren("entry", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
feed.setEntries(parseEntries(feed, baseURI, eList)); feed.setEntries(parseEntries(feed, baseURI, eList));
} }
List<Element> foreignMarkup = final List<Element> foreignMarkup = extractForeignMarkup(eFeed, feed, getAtomNamespace());
extractForeignMarkup(eFeed, feed, getAtomNamespace());
if (foreignMarkup.size() > 0) { if (foreignMarkup.size() > 0) {
feed.setForeignMarkup(foreignMarkup); feed.setForeignMarkup(foreignMarkup);
} }
return feed; return feed;
} }
private Feed parseFeedMetadata(String baseURI, Element eFeed) { private Feed parseFeedMetadata(final String baseURI, final Element eFeed) {
com.sun.syndication.feed.atom.Feed feed = final com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
new com.sun.syndication.feed.atom.Feed(getType());
Element e = eFeed.getChild("title",getAtomNamespace()); Element e = eFeed.getChild("title", getAtomNamespace());
if (e!=null) { if (e != null) {
Content c = new Content(); final Content c = new Content();
c.setValue(parseTextConstructToString(e)); c.setValue(parseTextConstructToString(e));
c.setType(getAttributeValue(e, "type")); c.setType(getAttributeValue(e, "type"));
feed.setTitleEx(c); feed.setTitleEx(c);
} }
List<Element> eList = eFeed.getChildren("link",getAtomNamespace()); List<Element> eList = eFeed.getChildren("link", getAtomNamespace());
feed.setAlternateLinks(parseAlternateLinks(feed, null, baseURI, eList)); feed.setAlternateLinks(parseAlternateLinks(feed, null, baseURI, eList));
feed.setOtherLinks(parseOtherLinks(feed, null, baseURI, eList)); feed.setOtherLinks(parseOtherLinks(feed, null, baseURI, eList));
List<Element> cList = eFeed.getChildren("category",getAtomNamespace()); final List<Element> cList = eFeed.getChildren("category", getAtomNamespace());
feed.setCategories(parseCategories(baseURI, cList)); feed.setCategories(parseCategories(baseURI, cList));
eList = eFeed.getChildren("author", getAtomNamespace()); eList = eFeed.getChildren("author", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
feed.setAuthors(parsePersons(baseURI, eList)); feed.setAuthors(parsePersons(baseURI, eList));
} }
eList = eFeed.getChildren("contributor",getAtomNamespace()); eList = eFeed.getChildren("contributor", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
feed.setContributors(parsePersons(baseURI, eList)); feed.setContributors(parsePersons(baseURI, eList));
} }
e = eFeed.getChild("subtitle",getAtomNamespace()); e = eFeed.getChild("subtitle", getAtomNamespace());
if (e!=null) { if (e != null) {
Content subtitle = new Content(); final Content subtitle = new Content();
subtitle.setValue(parseTextConstructToString(e)); subtitle.setValue(parseTextConstructToString(e));
subtitle.setType(getAttributeValue(e, "type")); subtitle.setType(getAttributeValue(e, "type"));
feed.setSubtitle(subtitle); feed.setSubtitle(subtitle);
} }
e = eFeed.getChild("id",getAtomNamespace()); e = eFeed.getChild("id", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setId(e.getText()); feed.setId(e.getText());
} }
e = eFeed.getChild("generator",getAtomNamespace()); e = eFeed.getChild("generator", getAtomNamespace());
if (e!=null) { if (e != null) {
Generator gen = new Generator(); final Generator gen = new Generator();
gen.setValue(e.getText()); gen.setValue(e.getText());
String att = getAttributeValue(e, "uri"); String att = getAttributeValue(e, "uri");
if (att!=null) { if (att != null) {
gen.setUrl(att); gen.setUrl(att);
} }
att = getAttributeValue(e, "version"); att = getAttributeValue(e, "version");
if (att!=null) { if (att != null) {
gen.setVersion(att); gen.setVersion(att);
} }
feed.setGenerator(gen); feed.setGenerator(gen);
} }
e = eFeed.getChild("rights",getAtomNamespace()); e = eFeed.getChild("rights", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setRights(parseTextConstructToString(e)); feed.setRights(parseTextConstructToString(e));
} }
e = eFeed.getChild("icon",getAtomNamespace()); e = eFeed.getChild("icon", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setIcon(e.getText()); feed.setIcon(e.getText());
} }
e = eFeed.getChild("logo",getAtomNamespace()); e = eFeed.getChild("logo", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setLogo(e.getText()); feed.setLogo(e.getText());
} }
e = eFeed.getChild("updated",getAtomNamespace()); e = eFeed.getChild("updated", getAtomNamespace());
if (e!=null) { if (e != null) {
feed.setUpdated(DateParser.parseDate(e.getText())); feed.setUpdated(DateParser.parseDate(e.getText()));
} }
return feed; return feed;
} }
private Link parseLink(Feed feed , Entry entry, String baseURI, Element eLink) { private Link parseLink(final Feed feed, final Entry entry, final String baseURI, final Element eLink) {
Link link = new Link(); final Link link = new Link();
String att = getAttributeValue(eLink, "rel"); String att = getAttributeValue(eLink, "rel");
if (att!=null) { if (att != null) {
link.setRel(att); link.setRel(att);
} }
att = getAttributeValue(eLink, "type"); att = getAttributeValue(eLink, "type");
if (att!=null) { if (att != null) {
link.setType(att); link.setType(att);
} }
att = getAttributeValue(eLink, "href"); att = getAttributeValue(eLink, "href");
if (att!=null) { if (att != null) {
link.setHref(att); link.setHref(att);
if (isRelativeURI(att)) { if (isRelativeURI(att)) {
link.setHrefResolved(resolveURI(baseURI, eLink, att)); link.setHrefResolved(resolveURI(baseURI, eLink, att));
} }
} }
att = getAttributeValue(eLink, "title"); att = getAttributeValue(eLink, "title");
if (att!=null) { if (att != null) {
link.setTitle(att); link.setTitle(att);
} }
att = getAttributeValue(eLink, "hreflang"); att = getAttributeValue(eLink, "hreflang");
if (att!=null) { if (att != null) {
link.setHreflang(att); link.setHreflang(att);
} }
att = getAttributeValue(eLink, "length"); att = getAttributeValue(eLink, "length");
if (att!=null) { if (att != null) {
Long val = NumberParser.parseLong(att); final Long val = NumberParser.parseLong(att);
if (val != null) { if (val != null) {
link.setLength(val.longValue()); link.setLength(val.longValue());
} }
} }
return link; return link;
} }
// List(Elements) -> List(Link) // List(Elements) -> List(Link)
private List<Link> parseAlternateLinks(Feed feed, Entry entry, String baseURI, List<Element> eLinks) { private List<Link> parseAlternateLinks(final Feed feed, final Entry entry, final String baseURI, final List<Element> eLinks) {
List<Link> links = new ArrayList<Link>(); final List<Link> links = new ArrayList<Link>();
for (int i=0;i<eLinks.size();i++) { for (int i = 0; i < eLinks.size(); i++) {
Element eLink = (Element) eLinks.get(i); final Element eLink = eLinks.get(i);
Link link = parseLink(feed, entry, baseURI, eLink); final Link link = parseLink(feed, entry, baseURI, eLink);
if (link.getRel() == null if (link.getRel() == null || "".equals(link.getRel().trim()) || "alternate".equals(link.getRel())) {
|| "".equals(link.getRel().trim())
|| "alternate".equals(link.getRel())) {
links.add(link); links.add(link);
} }
} }
return (links.size()>0) ? links : null; return links.size() > 0 ? links : null;
} }
private List<Link> parseOtherLinks(Feed feed, Entry entry, String baseURI, List<Element> eLinks) { private List<Link> parseOtherLinks(final Feed feed, final Entry entry, final String baseURI, final List<Element> eLinks) {
List<Link> links = new ArrayList<Link>(); final List<Link> links = new ArrayList<Link>();
for (int i=0;i<eLinks.size();i++) { for (int i = 0; i < eLinks.size(); i++) {
Element eLink = (Element) eLinks.get(i); final Element eLink = eLinks.get(i);
Link link = parseLink(feed, entry, baseURI, eLink); final Link link = parseLink(feed, entry, baseURI, eLink);
if (!"alternate".equals(link.getRel())) { if (!"alternate".equals(link.getRel())) {
links.add(link); links.add(link);
} }
} }
return (links.size()>0) ? links : null; return links.size() > 0 ? links : null;
} }
private Person parsePerson(String baseURI, Element ePerson) { private Person parsePerson(final String baseURI, final Element ePerson) {
Person person = new Person(); final Person person = new Person();
Element e = ePerson.getChild("name",getAtomNamespace()); Element e = ePerson.getChild("name", getAtomNamespace());
if (e!=null) { if (e != null) {
person.setName(e.getText()); person.setName(e.getText());
} }
e = ePerson.getChild("uri",getAtomNamespace()); e = ePerson.getChild("uri", getAtomNamespace());
if (e!=null) { if (e != null) {
person.setUri(e.getText()); person.setUri(e.getText());
if (isRelativeURI(e.getText())) { if (isRelativeURI(e.getText())) {
person.setUriResolved(resolveURI(baseURI, ePerson, e.getText())); person.setUriResolved(resolveURI(baseURI, ePerson, e.getText()));
} }
} }
e = ePerson.getChild("email",getAtomNamespace()); e = ePerson.getChild("email", getAtomNamespace());
if (e!=null) { if (e != null) {
person.setEmail(e.getText()); person.setEmail(e.getText());
} }
person.setModules(parsePersonModules(ePerson)); person.setModules(parsePersonModules(ePerson));
return person; return person;
} }
// List(Elements) -> List(Persons) // List(Elements) -> List(Persons)
private List<Person> parsePersons(String baseURI, List<Element> ePersons) { private List<Person> parsePersons(final String baseURI, final List<Element> ePersons) {
List<Person> persons = new ArrayList<Person>(); final List<Person> persons = new ArrayList<Person>();
for (int i=0;i<ePersons.size();i++) { for (int i = 0; i < ePersons.size(); i++) {
persons.add(parsePerson(baseURI, (Element)ePersons.get(i))); persons.add(parsePerson(baseURI, ePersons.get(i)));
} }
return (persons.size()>0) ? persons : null; return persons.size() > 0 ? persons : null;
} }
private Content parseContent(Element e) { private Content parseContent(final Element e) {
String value = parseTextConstructToString(e); final String value = parseTextConstructToString(e);
String src = getAttributeValue(e, "src"); final String src = getAttributeValue(e, "src");
String type = getAttributeValue(e, "type"); final String type = getAttributeValue(e, "type");
Content content = new Content(); final Content content = new Content();
content.setSrc(src); content.setSrc(src);
content.setType(type); content.setType(type);
content.setValue(value); content.setValue(value);
return content; return content;
} }
private String parseTextConstructToString(Element e) { private String parseTextConstructToString(final Element e) {
String value = null; String value = null;
String type = getAttributeValue(e, "type"); String type = getAttributeValue(e, "type");
type = (type!=null) ? type : Content.TEXT; type = type != null ? type : Content.TEXT;
if (type.equals(Content.XHTML) || (type.indexOf("/xml")) != -1 || (type.indexOf("+xml")) != -1) { if (type.equals(Content.XHTML) || type.indexOf("/xml") != -1 || type.indexOf("+xml") != -1) {
// XHTML content needs special handling // XHTML content needs special handling
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
List<org.jdom2.Content> eContent = e.getContent(); final List<org.jdom2.Content> eContent = e.getContent();
Iterator<org.jdom2.Content> i = eContent.iterator(); final Iterator<org.jdom2.Content> i = eContent.iterator();
while (i.hasNext()) { while (i.hasNext()) {
org.jdom2.Content c = (org.jdom2.Content) i.next(); final org.jdom2.Content c = i.next();
if (c instanceof Element) { if (c instanceof Element) {
Element eC = (Element) c; final Element eC = (Element) c;
if (eC.getNamespace().equals(getAtomNamespace())) { if (eC.getNamespace().equals(getAtomNamespace())) {
((Element)c).setNamespace(Namespace.NO_NAMESPACE); ((Element) c).setNamespace(Namespace.NO_NAMESPACE);
} }
} }
} }
@ -338,237 +337,244 @@ public class Atom10Parser extends BaseWireFeedParser {
} }
return value; return value;
} }
// List(Elements) -> List(Entries) // List(Elements) -> List(Entries)
protected List<Entry> parseEntries(Feed feed, String baseURI, List<Element> eEntries) { protected List<Entry> parseEntries(final Feed feed, final String baseURI, final List<Element> eEntries) {
List<Entry> entries = new ArrayList<Entry>(); final List<Entry> entries = new ArrayList<Entry>();
for (int i=0;i<eEntries.size();i++) { for (int i = 0; i < eEntries.size(); i++) {
entries.add(parseEntry(feed, (Element)eEntries.get(i), baseURI)); entries.add(this.parseEntry(feed, eEntries.get(i), baseURI));
} }
return (entries.size()>0) ? entries : null; return entries.size() > 0 ? entries : null;
} }
protected Entry parseEntry(Feed feed, Element eEntry, String baseURI) { protected Entry parseEntry(final Feed feed, final Element eEntry, final String baseURI) {
Entry entry = new Entry(); final Entry entry = new Entry();
String xmlBase = eEntry.getAttributeValue("base", Namespace.XML_NAMESPACE); final String xmlBase = eEntry.getAttributeValue("base", Namespace.XML_NAMESPACE);
if (xmlBase != null) { if (xmlBase != null) {
entry.setXmlBase(xmlBase); entry.setXmlBase(xmlBase);
} }
Element e = eEntry.getChild("title",getAtomNamespace()); Element e = eEntry.getChild("title", getAtomNamespace());
if (e!=null) { if (e != null) {
Content c = new Content(); final Content c = new Content();
c.setValue(parseTextConstructToString(e)); c.setValue(parseTextConstructToString(e));
c.setType(getAttributeValue(e, "type")); c.setType(getAttributeValue(e, "type"));
entry.setTitleEx(c); entry.setTitleEx(c);
} }
List<Element> eList = eEntry.getChildren("link",getAtomNamespace()); List<Element> eList = eEntry.getChildren("link", getAtomNamespace());
entry.setAlternateLinks(parseAlternateLinks(feed, entry, baseURI, eList)); entry.setAlternateLinks(parseAlternateLinks(feed, entry, baseURI, eList));
entry.setOtherLinks(parseOtherLinks(feed, entry, baseURI, eList)); entry.setOtherLinks(parseOtherLinks(feed, entry, baseURI, eList));
eList = eEntry.getChildren("author", getAtomNamespace()); eList = eEntry.getChildren("author", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
entry.setAuthors(parsePersons(baseURI, eList)); entry.setAuthors(parsePersons(baseURI, eList));
} }
eList = eEntry.getChildren("contributor",getAtomNamespace()); eList = eEntry.getChildren("contributor", getAtomNamespace());
if (eList.size()>0) { if (eList.size() > 0) {
entry.setContributors(parsePersons(baseURI, eList)); entry.setContributors(parsePersons(baseURI, eList));
} }
e = eEntry.getChild("id",getAtomNamespace()); e = eEntry.getChild("id", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setId(e.getText()); entry.setId(e.getText());
} }
e = eEntry.getChild("updated",getAtomNamespace()); e = eEntry.getChild("updated", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setUpdated(DateParser.parseDate(e.getText())); entry.setUpdated(DateParser.parseDate(e.getText()));
} }
e = eEntry.getChild("published",getAtomNamespace()); e = eEntry.getChild("published", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setPublished(DateParser.parseDate(e.getText())); entry.setPublished(DateParser.parseDate(e.getText()));
} }
e = eEntry.getChild("summary",getAtomNamespace()); e = eEntry.getChild("summary", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setSummary(parseContent(e)); entry.setSummary(parseContent(e));
} }
e = eEntry.getChild("content",getAtomNamespace()); e = eEntry.getChild("content", getAtomNamespace());
if (e!=null) { if (e != null) {
List<Content> contents = new ArrayList<Content>(); final List<Content> contents = new ArrayList<Content>();
contents.add(parseContent(e)); contents.add(parseContent(e));
entry.setContents(contents); entry.setContents(contents);
} }
e = eEntry.getChild("rights",getAtomNamespace()); e = eEntry.getChild("rights", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setRights(e.getText()); entry.setRights(e.getText());
} }
List<Element> cList = eEntry.getChildren("category",getAtomNamespace()); final List<Element> cList = eEntry.getChildren("category", getAtomNamespace());
entry.setCategories(parseCategories(baseURI, cList)); entry.setCategories(parseCategories(baseURI, cList));
// TODO: SHOULD handle Atom entry source element // TODO: SHOULD handle Atom entry source element
e = eEntry.getChild("source", getAtomNamespace()); e = eEntry.getChild("source", getAtomNamespace());
if (e!=null) { if (e != null) {
entry.setSource(parseFeedMetadata(baseURI, e)); entry.setSource(parseFeedMetadata(baseURI, e));
} }
entry.setModules(parseItemModules(eEntry)); entry.setModules(parseItemModules(eEntry));
List<Element> foreignMarkup = final List<Element> foreignMarkup = extractForeignMarkup(eEntry, entry, getAtomNamespace());
extractForeignMarkup(eEntry, entry, getAtomNamespace());
if (foreignMarkup.size() > 0) { if (foreignMarkup.size() > 0) {
entry.setForeignMarkup(foreignMarkup); entry.setForeignMarkup(foreignMarkup);
} }
return entry; return entry;
} }
private List<Category> parseCategories(String baseURI, List<Element> eCategories) { private List<Category> parseCategories(final String baseURI, final List<Element> eCategories) {
List<Category> cats = new ArrayList<Category>(); final List<Category> cats = new ArrayList<Category>();
for (int i=0;i<eCategories.size();i++) { for (int i = 0; i < eCategories.size(); i++) {
Element eCategory = (Element) eCategories.get(i); final Element eCategory = eCategories.get(i);
cats.add(parseCategory(baseURI, eCategory)); cats.add(parseCategory(baseURI, eCategory));
} }
return (cats.size()>0) ? cats : null; return cats.size() > 0 ? cats : null;
} }
private Category parseCategory(String baseURI, Element eCategory) { private Category parseCategory(final String baseURI, final Element eCategory) {
Category category = new Category(); final Category category = new Category();
String att = getAttributeValue(eCategory, "term"); String att = getAttributeValue(eCategory, "term");
if (att!=null) { if (att != null) {
category.setTerm(att); category.setTerm(att);
} }
att = getAttributeValue(eCategory, "scheme"); att = getAttributeValue(eCategory, "scheme");
if (att!=null) { if (att != null) {
category.setScheme(att); category.setScheme(att);
if (isRelativeURI(att)) { if (isRelativeURI(att)) {
category.setSchemeResolved(resolveURI(baseURI, eCategory, att)); category.setSchemeResolved(resolveURI(baseURI, eCategory, att));
} }
} }
att = getAttributeValue(eCategory, "label"); att = getAttributeValue(eCategory, "label");
if (att!=null) { if (att != null) {
category.setLabel(att); category.setLabel(att);
} }
return category; return category;
} }
// Once following relative URI methods are made public in the ROME // Once following relative URI methods are made public in the ROME
// Atom10Parser, then use them instead and delete these. // Atom10Parser, then use them instead and delete these.
// Fix for issue #34 "valid IRI href attributes are stripped for atom:link" // Fix for issue #34 "valid IRI href attributes are stripped for atom:link"
// URI's that didn't start with http were being treated as relative URIs. // URI's that didn't start with http were being treated as relative URIs.
// So now consider an absolute URI to be any alpha-numeric string followed // So now consider an absolute URI to be any alpha-numeric string followed
// by a colon, followed by anything -- specified by this regex: // by a colon, followed by anything -- specified by this regex:
static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$"); static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$");
public static boolean isAbsoluteURI(String uri) { public static boolean isAbsoluteURI(final String uri) {
return absoluteURIPattern.matcher(uri).find(); return absoluteURIPattern.matcher(uri).find();
} }
/** Returns true if URI is relative. */ /** Returns true if URI is relative. */
public static boolean isRelativeURI(String uri) { public static boolean isRelativeURI(final String uri) {
return !isAbsoluteURI(uri); return !isAbsoluteURI(uri);
} }
/** /**
* Resolve URI via base URL and parent element. * Resolve URI via base URL and parent element. Resolve URI based
* Resolve URI based considering xml:base and baseURI. * considering xml:base and baseURI.
*
* @param baseURI Base URI used to fetch the XML document * @param baseURI Base URI used to fetch the XML document
* @param parent Parent element from which to consider xml:base * @param parent Parent element from which to consider xml:base
* @param url URL to be resolved * @param url URL to be resolved
*/ */
public static String resolveURI(String baseURI, Parent parent, String url) { public static String resolveURI(final String baseURI, final Parent parent, String url) {
if (!resolveURIs) { if (!resolveURIs) {
return url; return url;
} }
if (isRelativeURI(url)) { if (isRelativeURI(url)) {
url = (!".".equals(url) && !"./".equals(url)) ? url : ""; url = !".".equals(url) && !"./".equals(url) ? url : "";
if (url.startsWith("/") && baseURI != null) { if (url.startsWith("/") && baseURI != null) {
String base = null; String base = null;
int slashslash = baseURI.indexOf("//"); final int slashslash = baseURI.indexOf("//");
int nextslash = baseURI.indexOf("/", slashslash + 2); final int nextslash = baseURI.indexOf("/", slashslash + 2);
if (nextslash != -1) base = baseURI.substring(0, nextslash); if (nextslash != -1) {
return formURI(base, url); base = baseURI.substring(0, nextslash);
} }
return formURI(base, url);
}
// Relative URI with parent // Relative URI with parent
if (parent != null && parent instanceof Element) { if (parent != null && parent instanceof Element) {
// Do we have an xml:base? // Do we have an xml:base?
String xmlbase = ((Element)parent).getAttributeValue( String xmlbase = ((Element) parent).getAttributeValue("base", Namespace.XML_NAMESPACE);
"base", Namespace.XML_NAMESPACE);
if (xmlbase != null && xmlbase.trim().length() > 0) { if (xmlbase != null && xmlbase.trim().length() > 0) {
if (isAbsoluteURI(xmlbase)) { if (isAbsoluteURI(xmlbase)) {
// Absolute xml:base, so form URI right now // Absolute xml:base, so form URI right now
if (url.startsWith("/")) { if (url.startsWith("/")) {
// Host relative URI // Host relative URI
int slashslash = xmlbase.indexOf("//"); final int slashslash = xmlbase.indexOf("//");
int nextslash = xmlbase.indexOf("/", slashslash + 2); final int nextslash = xmlbase.indexOf("/", slashslash + 2);
if (nextslash != -1) xmlbase = xmlbase.substring(0, nextslash); if (nextslash != -1) {
return formURI(xmlbase, url); xmlbase = xmlbase.substring(0, nextslash);
}
return formURI(xmlbase, url);
} }
if (!xmlbase.endsWith("/")) { if (!xmlbase.endsWith("/")) {
// Base URI is filename, strip it off // Base URI is filename, strip it off
xmlbase = xmlbase.substring(0, xmlbase.lastIndexOf("/")); xmlbase = xmlbase.substring(0, xmlbase.lastIndexOf("/"));
} }
return formURI(xmlbase, url); return formURI(xmlbase, url);
} else { } else {
// Relative xml:base, so walk up tree // Relative xml:base, so walk up tree
return resolveURI(baseURI, parent.getParent(), return resolveURI(baseURI, parent.getParent(), stripTrailingSlash(xmlbase) + "/" + stripStartingSlash(url));
stripTrailingSlash(xmlbase) + "/"+ stripStartingSlash(url));
} }
} }
// No xml:base so walk up tree // No xml:base so walk up tree
return resolveURI(baseURI, parent.getParent(), url); return resolveURI(baseURI, parent.getParent(), url);
// Relative URI with no parent (i.e. top of tree), so form URI right now // Relative URI with no parent (i.e. top of tree), so form URI
// right now
} else if (parent == null || parent instanceof Document) { } else if (parent == null || parent instanceof Document) {
return formURI(baseURI, url); return formURI(baseURI, url);
} }
} }
return url; return url;
} }
/** /**
* Find base URI of feed considering relative URIs. * Find base URI of feed considering relative URIs.
*
* @param root Root element of feed. * @param root Root element of feed.
*/ */
private String findBaseURI(Element root) throws MalformedURLException { private String findBaseURI(final Element root) throws MalformedURLException {
String ret = null; String ret = null;
if (findAtomLink(root, "self") != null) { if (findAtomLink(root, "self") != null) {
ret = findAtomLink(root, "self"); ret = findAtomLink(root, "self");
if (".".equals(ret) || "./".equals(ret)) ret = ""; if (".".equals(ret) || "./".equals(ret)) {
if (ret.indexOf("/") != -1) ret = ret.substring(0, ret.lastIndexOf("/")); ret = "";
}
if (ret.indexOf("/") != -1) {
ret = ret.substring(0, ret.lastIndexOf("/"));
}
ret = resolveURI(null, root, ret); ret = resolveURI(null, root, ret);
} }
return ret; return ret;
} }
/** /**
* Return URL string of Atom link element under parent element. * Return URL string of Atom link element under parent element. Link with no
* Link with no rel attribute is considered to be rel="alternate" * rel attribute is considered to be rel="alternate"
*
* @param parent Consider only children of this parent element * @param parent Consider only children of this parent element
* @param rel Consider only links with this relationship * @param rel Consider only links with this relationship
*/ */
private String findAtomLink(Element parent, String rel) { private String findAtomLink(final Element parent, final String rel) {
String ret = null; String ret = null;
List<Element> linksList = parent.getChildren("link", ATOM_10_NS); final List<Element> linksList = parent.getChildren("link", ATOM_10_NS);
if (linksList != null) { if (linksList != null) {
for (Iterator<Element> links = linksList.iterator(); links.hasNext(); ) { for (final Element element : linksList) {
Element link = (Element)links.next(); final Element link = element;
Attribute relAtt = getAttribute(link, "rel"); final Attribute relAtt = getAttribute(link, "rel");
Attribute hrefAtt = getAttribute(link, "href"); final Attribute hrefAtt = getAttribute(link, "href");
if ( (relAtt == null && "alternate".equals(rel)) if (relAtt == null && "alternate".equals(rel) || relAtt != null && relAtt.getValue().equals(rel)) {
|| (relAtt != null && relAtt.getValue().equals(rel))) {
ret = hrefAtt.getValue(); ret = hrefAtt.getValue();
break; break;
} }
@ -576,34 +582,36 @@ public class Atom10Parser extends BaseWireFeedParser {
} }
return ret; return ret;
} }
/** /**
* Form URI by combining base with append portion and giving * Form URI by combining base with append portion and giving special
* special consideration to append portions that begin with ".." * consideration to append portions that begin with ".."
* @param base Base of URI, may end with trailing slash *
* @param base Base of URI, may end with trailing slash
* @param append String to append, may begin with slash or ".." * @param append String to append, may begin with slash or ".."
*/ */
private static String formURI(String base, String append) { private static String formURI(String base, String append) {
base = stripTrailingSlash(base); base = stripTrailingSlash(base);
append = stripStartingSlash(append); append = stripStartingSlash(append);
if (append.startsWith("..")) { if (append.startsWith("..")) {
String ret = null; final String ret = null;
String[] parts = append.split("/"); final String[] parts = append.split("/");
for (int i=0; i<parts.length; i++) { for (final String part : parts) {
if ("..".equals(parts[i])) { if ("..".equals(part)) {
int last = base.lastIndexOf("/"); final int last = base.lastIndexOf("/");
if (last != -1) { if (last != -1) {
base = base.substring(0, last); base = base.substring(0, last);
append = append.substring(3, append.length()); append = append.substring(3, append.length());
} else {
break;
} }
else break;
} }
} }
} }
return base + "/" + append; return base + "/" + append;
} }
/** /**
* Strip starting slash from beginning of string. * Strip starting slash from beginning of string.
*/ */
private static String stripStartingSlash(String s) { private static String stripStartingSlash(String s) {
@ -612,8 +620,8 @@ public class Atom10Parser extends BaseWireFeedParser {
} }
return s; return s;
} }
/** /**
* Strip trailing slash from end of string. * Strip trailing slash from end of string.
*/ */
private static String stripTrailingSlash(String s) { private static String stripTrailingSlash(String s) {
@ -621,35 +629,32 @@ public class Atom10Parser extends BaseWireFeedParser {
s = s.substring(0, s.length() - 1); s = s.substring(0, s.length() - 1);
} }
return s; return s;
} }
/** /**
* Parse entry from reader. * Parse entry from reader.
*/ */
public static Entry parseEntry(Reader rd, String baseURI) public static Entry parseEntry(final Reader rd, final String baseURI) throws JDOMException, IOException, IllegalArgumentException, FeedException {
throws JDOMException, IOException, IllegalArgumentException, FeedException {
// Parse entry into JDOM tree // Parse entry into JDOM tree
SAXBuilder builder = new SAXBuilder(); final SAXBuilder builder = new SAXBuilder();
Document entryDoc = builder.build(rd); final Document entryDoc = builder.build(rd);
Element fetchedEntryElement = entryDoc.getRootElement(); final Element fetchedEntryElement = entryDoc.getRootElement();
fetchedEntryElement.detach(); fetchedEntryElement.detach();
// Put entry into a JDOM document with 'feed' root so that Rome can handle it // Put entry into a JDOM document with 'feed' root so that Rome can
Feed feed = new Feed(); // handle it
final Feed feed = new Feed();
feed.setFeedType("atom_1.0"); feed.setFeedType("atom_1.0");
WireFeedOutput wireFeedOutput = new WireFeedOutput(); final WireFeedOutput wireFeedOutput = new WireFeedOutput();
Document feedDoc = wireFeedOutput.outputJDom(feed); final Document feedDoc = wireFeedOutput.outputJDom(feed);
feedDoc.getRootElement().addContent(fetchedEntryElement); feedDoc.getRootElement().addContent(fetchedEntryElement);
if (baseURI != null) { if (baseURI != null) {
feedDoc.getRootElement().setAttribute("base", baseURI, Namespace.XML_NAMESPACE); feedDoc.getRootElement().setAttribute("base", baseURI, Namespace.XML_NAMESPACE);
} }
WireFeedInput input = new WireFeedInput(); final WireFeedInput input = new WireFeedInput();
Feed parsedFeed = (Feed)input.build(feedDoc); final Feed parsedFeed = (Feed) input.build(feedDoc);
return (Entry)parsedFeed.getEntries().get(0); return parsedFeed.getEntries().get(0);
} }
} }

View file

@ -20,20 +20,23 @@ package com.sun.syndication.io.impl;
/** /**
* Encodes/decodes byte arrays and Strings into/from a base 64 String. * Encodes/decodes byte arrays and Strings into/from a base 64 String.
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class Base64 { public class Base64 {
/** /**
* Encodes a String into a base 64 String. The resulting encoding is chunked at 76 bytes. * Encodes a String into a base 64 String. The resulting encoding is chunked
* at 76 bytes.
* <p> * <p>
*
* @param s String to encode. * @param s String to encode.
* @return encoded string. * @return encoded string.
* *
*/ */
public static String encode(String s) { public static String encode(String s) {
byte[] sBytes = s.getBytes(); byte[] sBytes = s.getBytes();
sBytes = encode(sBytes); sBytes = encode(sBytes);
s = new String(sBytes); s = new String(sBytes);
return s; return s;
@ -42,10 +45,12 @@ public class Base64 {
/** /**
* Decodes a base 64 String into a String. * Decodes a base 64 String into a String.
* <p> * <p>
*
* @param s String to decode. * @param s String to decode.
* @return encoded string. * @return encoded string.
* @throws java.lang.IllegalArgumentException thrown if the given byte array was not valid com.sun.syndication.io.impl.Base64 encoding. * @throws java.lang.IllegalArgumentException thrown if the given byte array
* * was not valid com.sun.syndication.io.impl.Base64 encoding.
*
*/ */
public static String decode(String s) throws IllegalArgumentException { public static String decode(String s) throws IllegalArgumentException {
s = s.replaceAll("\n", ""); s = s.replaceAll("\n", "");
@ -56,9 +61,7 @@ public class Base64 {
return s; return s;
} }
private static final byte[] ALPHASET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".getBytes();
private static final byte[] ALPHASET =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".getBytes();
private static final int I6O2 = 255 - 3; private static final int I6O2 = 255 - 3;
private static final int O6I2 = 3; private static final int O6I2 = 3;
@ -70,50 +73,49 @@ public class Base64 {
/** /**
* Encodes a byte array into a base 64 byte array. * Encodes a byte array into a base 64 byte array.
* <p> * <p>
*
* @param dData byte array to encode. * @param dData byte array to encode.
* @return encoded byte array. * @return encoded byte array.
* *
*/ */
public static byte[] encode(byte[] dData) { public static byte[] encode(final byte[] dData) {
if (dData==null) { if (dData == null) {
throw new IllegalArgumentException("Cannot encode null"); throw new IllegalArgumentException("Cannot encode null");
} }
byte[] eData = new byte[((dData.length+2)/3)*4]; final byte[] eData = new byte[(dData.length + 2) / 3 * 4];
int eIndex = 0; int eIndex = 0;
for (int i = 0; i<dData.length; i += 3) { for (int i = 0; i < dData.length; i += 3) {
int d1; int d1;
int d2=0; int d2 = 0;
int d3=0; int d3 = 0;
int e1; int e1;
int e2; int e2;
int e3; int e3;
int e4; int e4;
int pad=0; int pad = 0;
d1 = dData[i]; d1 = dData[i];
if ((i+1)<dData.length) { if (i + 1 < dData.length) {
d2 = dData[i+1]; d2 = dData[i + 1];
if ((i+2)<dData.length) { if (i + 2 < dData.length) {
d3 = dData[i+2]; d3 = dData[i + 2];
} else {
pad = 1;
} }
else { } else {
pad =1; pad = 2;
}
}
else {
pad =2;
} }
e1 = ALPHASET[(d1&I6O2)>>2]; e1 = ALPHASET[(d1 & I6O2) >> 2];
e2 = ALPHASET[(d1&O6I2)<<4 | (d2&I4O4)>>4]; e2 = ALPHASET[(d1 & O6I2) << 4 | (d2 & I4O4) >> 4];
e3 = ALPHASET[(d2&O4I4)<<2 | (d3&I2O6)>>6]; e3 = ALPHASET[(d2 & O4I4) << 2 | (d3 & I2O6) >> 6];
e4 = ALPHASET[(d3&O2I6)]; e4 = ALPHASET[d3 & O2I6];
eData[eIndex++] = (byte)e1; eData[eIndex++] = (byte) e1;
eData[eIndex++] = (byte)e2; eData[eIndex++] = (byte) e2;
eData[eIndex++] = (pad<2) ?(byte)e3 : (byte)'='; eData[eIndex++] = pad < 2 ? (byte) e3 : (byte) '=';
eData[eIndex++] = (pad<1) ?(byte)e4 : (byte)'='; eData[eIndex++] = pad < 1 ? (byte) e4 : (byte) '=';
} }
return eData; return eData;
@ -122,10 +124,10 @@ public class Base64 {
private final static int[] CODES = new int[256]; private final static int[] CODES = new int[256];
static { static {
for (int i=0;i<CODES.length;i++) { for (int i = 0; i < CODES.length; i++) {
CODES[i] = 64; CODES[i] = 64;
} }
for (int i=0;i<ALPHASET.length;i++) { for (int i = 0; i < ALPHASET.length; i++) {
CODES[ALPHASET[i]] = i; CODES[ALPHASET[i]] = i;
} }
} }
@ -133,25 +135,27 @@ public class Base64 {
/** /**
* Dencodes a com.sun.syndication.io.impl.Base64 byte array. * Dencodes a com.sun.syndication.io.impl.Base64 byte array.
* <p> * <p>
*
* @param eData byte array to decode. * @param eData byte array to decode.
* @return decoded byte array. * @return decoded byte array.
* @throws java.lang.IllegalArgumentException thrown if the given byte array was not valid com.sun.syndication.io.impl.Base64 encoding. * @throws java.lang.IllegalArgumentException thrown if the given byte array
* * was not valid com.sun.syndication.io.impl.Base64 encoding.
*
*/ */
public static byte[] decode(byte[] eData) { public static byte[] decode(final byte[] eData) {
if (eData==null) { if (eData == null) {
throw new IllegalArgumentException("Cannot decode null"); throw new IllegalArgumentException("Cannot decode null");
} }
byte[] cleanEData = (byte[]) eData.clone(); final byte[] cleanEData = eData.clone();
int cleanELength = 0; int cleanELength = 0;
for (int i=0;i<eData.length;i++) { for (final byte element : eData) {
if (eData[i]<256 && CODES[eData[i]]<64) { if (element < 256 && CODES[element] < 64) {
cleanEData[cleanELength++] = eData[i]; cleanEData[cleanELength++] = element;
} }
} }
int dLength = (cleanELength/4)*3; int dLength = cleanELength / 4 * 3;
switch (cleanELength%4) { switch (cleanELength % 4) {
case 3: case 3:
dLength += 2; dLength += 2;
break; break;
@ -160,42 +164,39 @@ public class Base64 {
break; break;
} }
byte[] dData = new byte[dLength]; final byte[] dData = new byte[dLength];
int dIndex = 0; int dIndex = 0;
for (int i = 0; i < eData.length; i += 4) { for (int i = 0; i < eData.length; i += 4) {
if ((i + 3) > eData.length) { if (i + 3 > eData.length) {
throw new IllegalArgumentException("byte array is not a valid com.sun.syndication.io.impl.Base64 encoding"); throw new IllegalArgumentException("byte array is not a valid com.sun.syndication.io.impl.Base64 encoding");
} }
int e1 = CODES[cleanEData[i]]; final int e1 = CODES[cleanEData[i]];
int e2 = CODES[cleanEData[i+1]]; final int e2 = CODES[cleanEData[i + 1]];
int e3 = CODES[cleanEData[i+2]]; final int e3 = CODES[cleanEData[i + 2]];
int e4 = CODES[cleanEData[i+3]]; final int e4 = CODES[cleanEData[i + 3]];
dData[dIndex++] = (byte) ((e1<<2)|(e2>>4)); dData[dIndex++] = (byte) (e1 << 2 | e2 >> 4);
if (dIndex<dData.length) { if (dIndex < dData.length) {
dData[dIndex++] = (byte) ((e2<<4) | (e3>>2)); dData[dIndex++] = (byte) (e2 << 4 | e3 >> 2);
} }
if (dIndex<dData.length) { if (dIndex < dData.length) {
dData[dIndex++] = (byte) ((e3<<6) | (e4)); dData[dIndex++] = (byte) (e3 << 6 | e4);
} }
} }
return dData; return dData;
} }
public static void main(String[] args) throws Exception { public static void main(final String[] args) throws Exception {
String s = final String s = "\nPGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+V2UncmUgcHJvcG9zaW5nIDxhIGhy\n"
"\nPGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+V2UncmUgcHJvcG9zaW5nIDxhIGhy\n"+ + "ZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9jb3Jwb3JhdGUvc29mdHdhcmVfcHJpbmNpcGxlcy5odG1sIj5z\n"
"ZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9jb3Jwb3JhdGUvc29mdHdhcmVfcHJpbmNpcGxlcy5odG1sIj5z\n"+ + "b21lIGd1aWRlbGluZXMgPC9hPnRvIGhlbHAgY3VyYiB0aGUgcHJvYmxlbSBvZiBJbnRlcm5ldCBzb2Z0d2Fy\n"
"b21lIGd1aWRlbGluZXMgPC9hPnRvIGhlbHAgY3VyYiB0aGUgcHJvYmxlbSBvZiBJbnRlcm5ldCBzb2Z0d2Fy\n"+ + "ZSB0aGF0IGluc3RhbGxzIGl0c2VsZiB3aXRob3V0IHRlbGxpbmcgeW91LCBvciBiZWhhdmVzIGJhZGx5IG9u\n"
"ZSB0aGF0IGluc3RhbGxzIGl0c2VsZiB3aXRob3V0IHRlbGxpbmcgeW91LCBvciBiZWhhdmVzIGJhZGx5IG9u\n"+ + "Y2UgaXQgZ2V0cyBvbiB5b3VyIGNvbXB1dGVyLiBXZSd2ZSBiZWVuIGhlYXJpbmcgYSBsb3Qgb2YgY29tcGxh\n"
"Y2UgaXQgZ2V0cyBvbiB5b3VyIGNvbXB1dGVyLiBXZSd2ZSBiZWVuIGhlYXJpbmcgYSBsb3Qgb2YgY29tcGxh\n"+ + "aW50cyBhYm91dCB0aGlzIGxhdGVseSBhbmQgaXQgc2VlbXMgdG8gYmUgZ2V0dGluZyB3b3JzZS4gV2UgdGhp\n"
"aW50cyBhYm91dCB0aGlzIGxhdGVseSBhbmQgaXQgc2VlbXMgdG8gYmUgZ2V0dGluZyB3b3JzZS4gV2UgdGhp\n"+ + "bmsgaXQncyBpbXBvcnRhbnQgdGhhdCB5b3UgcmV0YWluIGNvbnRyb2wgb2YgeW91ciBjb21wdXRlciBhbmQg\n"
"bmsgaXQncyBpbXBvcnRhbnQgdGhhdCB5b3UgcmV0YWluIGNvbnRyb2wgb2YgeW91ciBjb21wdXRlciBhbmQg\n"+ + "dGhhdCB0aGVyZSBiZSBzb21lIGNsZWFyIHN0YW5kYXJkcyBpbiBvdXIgaW5kdXN0cnkuIExldCB1cyBrbm93\n"
"dGhhdCB0aGVyZSBiZSBzb21lIGNsZWFyIHN0YW5kYXJkcyBpbiBvdXIgaW5kdXN0cnkuIExldCB1cyBrbm93\n"+ + "IGlmIHlvdSB0aGluayB0aGVzZSBndWlkZWxpbmVzIGFyZSB1c2VmdWwgb3IgaWYgeW91IGhhdmUgc3VnZ2Vz\n"
"IGlmIHlvdSB0aGluayB0aGVzZSBndWlkZWxpbmVzIGFyZSB1c2VmdWwgb3IgaWYgeW91IGhhdmUgc3VnZ2Vz\n"+ + "dGlvbnMgdG8gaW1wcm92ZSB0aGVtLgo8YnIgLz4KPGJyIC8+Sm9uYXRoYW4gUm9zZW5iZXJnCjxiciAvPgo8\n" + "L2Rpdj4K\n";
"dGlvbnMgdG8gaW1wcm92ZSB0aGVtLgo8YnIgLz4KPGJyIC8+Sm9uYXRoYW4gUm9zZW5iZXJnCjxiciAvPgo8\n"+
"L2Rpdj4K\n";
System.out.println(decode(s)); System.out.println(decode(s));
} }
} }

View file

@ -1,22 +1,23 @@
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.io.WireFeedGenerator;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.Parent;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.Parent;
import com.sun.syndication.io.WireFeedGenerator;
/** /**
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
*/ */
public abstract class BaseWireFeedGenerator implements WireFeedGenerator { public abstract class BaseWireFeedGenerator implements WireFeedGenerator {
/** /**
* [TYPE].feed.ModuleParser.classes= [className] ... * [TYPE].feed.ModuleParser.classes= [className] ...
*/ */
private static final String FEED_MODULE_GENERATORS_POSFIX_KEY = ".feed.ModuleGenerator.classes"; private static final String FEED_MODULE_GENERATORS_POSFIX_KEY = ".feed.ModuleGenerator.classes";
@ -30,63 +31,63 @@ public abstract class BaseWireFeedGenerator implements WireFeedGenerator {
*/ */
private static final String PERSON_MODULE_GENERATORS_POSFIX_KEY = ".person.ModuleGenerator.classes"; private static final String PERSON_MODULE_GENERATORS_POSFIX_KEY = ".person.ModuleGenerator.classes";
private final String _type;
private final ModuleGenerators _feedModuleGenerators;
private final ModuleGenerators _itemModuleGenerators;
private final ModuleGenerators _personModuleGenerators;
private final Namespace[] _allModuleNamespaces;
private String _type; protected BaseWireFeedGenerator(final String type) {
private ModuleGenerators _feedModuleGenerators; this._type = type;
private ModuleGenerators _itemModuleGenerators; this._feedModuleGenerators = new ModuleGenerators(type + FEED_MODULE_GENERATORS_POSFIX_KEY, this);
private ModuleGenerators _personModuleGenerators; this._itemModuleGenerators = new ModuleGenerators(type + ITEM_MODULE_GENERATORS_POSFIX_KEY, this);
private Namespace[] _allModuleNamespaces; this._personModuleGenerators = new ModuleGenerators(type + PERSON_MODULE_GENERATORS_POSFIX_KEY, this);
final Set allModuleNamespaces = new HashSet();
protected BaseWireFeedGenerator(String type) { Iterator i = this._feedModuleGenerators.getAllNamespaces().iterator();
_type = type;
_feedModuleGenerators = new ModuleGenerators(type + FEED_MODULE_GENERATORS_POSFIX_KEY, this);
_itemModuleGenerators = new ModuleGenerators(type + ITEM_MODULE_GENERATORS_POSFIX_KEY, this);
_personModuleGenerators = new ModuleGenerators(type + PERSON_MODULE_GENERATORS_POSFIX_KEY, this);
Set allModuleNamespaces = new HashSet();
Iterator i = _feedModuleGenerators.getAllNamespaces().iterator();
while (i.hasNext()) { while (i.hasNext()) {
allModuleNamespaces.add(i.next()); allModuleNamespaces.add(i.next());
} }
i = _itemModuleGenerators.getAllNamespaces().iterator(); i = this._itemModuleGenerators.getAllNamespaces().iterator();
while (i.hasNext()) { while (i.hasNext()) {
allModuleNamespaces.add(i.next()); allModuleNamespaces.add(i.next());
} }
i = _personModuleGenerators.getAllNamespaces().iterator(); i = this._personModuleGenerators.getAllNamespaces().iterator();
while (i.hasNext()) { while (i.hasNext()) {
allModuleNamespaces.add(i.next()); allModuleNamespaces.add(i.next());
} }
_allModuleNamespaces = new Namespace[allModuleNamespaces.size()]; this._allModuleNamespaces = new Namespace[allModuleNamespaces.size()];
allModuleNamespaces.toArray(_allModuleNamespaces); allModuleNamespaces.toArray(this._allModuleNamespaces);
} }
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
protected void generateModuleNamespaceDefs(Element root) { protected void generateModuleNamespaceDefs(final Element root) {
for (int i = 0; i < _allModuleNamespaces.length; i++) { for (final Namespace _allModuleNamespace : this._allModuleNamespaces) {
root.addNamespaceDeclaration(_allModuleNamespaces[i]); root.addNamespaceDeclaration(_allModuleNamespace);
} }
} }
protected void generateFeedModules(List modules, Element feed) { protected void generateFeedModules(final List modules, final Element feed) {
_feedModuleGenerators.generateModules(modules, feed); this._feedModuleGenerators.generateModules(modules, feed);
} }
public void generateItemModules(List modules, Element item) { public void generateItemModules(final List modules, final Element item) {
_itemModuleGenerators.generateModules(modules, item); this._itemModuleGenerators.generateModules(modules, item);
} }
public void generatePersonModules(List modules, Element person) { public void generatePersonModules(final List modules, final Element person) {
_personModuleGenerators.generateModules(modules, person); this._personModuleGenerators.generateModules(modules, person);
} }
protected void generateForeignMarkup(Element e, List foreignMarkup) { protected void generateForeignMarkup(final Element e, final List foreignMarkup) {
if (foreignMarkup != null) { if (foreignMarkup != null) {
Iterator elems = (Iterator) foreignMarkup.iterator(); final Iterator elems = foreignMarkup.iterator();
while (elems.hasNext()) { while (elems.hasNext()) {
Element elem = (Element) elems.next(); final Element elem = (Element) elems.next();
Parent parent = elem.getParent(); final Parent parent = elem.getParent();
if (parent != null) { if (parent != null) {
parent.removeContent(elem); parent.removeContent(elem);
} }
@ -96,40 +97,45 @@ public abstract class BaseWireFeedGenerator implements WireFeedGenerator {
} }
/** /**
* Purging unused declarations is less optimal, performance-wise, than never adding them in the first place. So, we * Purging unused declarations is less optimal, performance-wise, than never
* should still ask the ROME guys to fix their code (not adding dozens of unnecessary module declarations). Having * adding them in the first place. So, we should still ask the ROME guys to
* said that: purging them here, before XML generation, is more efficient than parsing and re-molding the XML after * fix their code (not adding dozens of unnecessary module declarations).
* ROME generates it. * Having said that: purging them here, before XML generation, is more
* efficient than parsing and re-molding the XML after ROME generates it.
* <p/> * <p/>
* Note that the calling app could still add declarations/modules to the Feed tree after this. Which is fine. But * Note that the calling app could still add declarations/modules to the
* those modules are then responsible for crawling to the root of the tree, at generate() time, to make sure their * Feed tree after this. Which is fine. But those modules are then
* namespace declarations are present. * responsible for crawling to the root of the tree, at generate() time, to
* make sure their namespace declarations are present.
*/ */
protected static void purgeUnusedNamespaceDeclarations(Element root) { protected static void purgeUnusedNamespaceDeclarations(final Element root) {
java.util.Set usedPrefixes = new java.util.HashSet(); final java.util.Set usedPrefixes = new java.util.HashSet();
collectUsedPrefixes(root, usedPrefixes); collectUsedPrefixes(root, usedPrefixes);
List list = root.getAdditionalNamespaces(); final List list = root.getAdditionalNamespaces();
List additionalNamespaces = new java.util.ArrayList(); final List additionalNamespaces = new java.util.ArrayList();
additionalNamespaces.addAll(list); // the duplication will prevent a ConcurrentModificationException below additionalNamespaces.addAll(list); // the duplication will prevent a
// ConcurrentModificationException
// below
for (int i = 0; i < additionalNamespaces.size(); i++) { for (int i = 0; i < additionalNamespaces.size(); i++) {
Namespace ns = (Namespace) additionalNamespaces.get(i); final Namespace ns = (Namespace) additionalNamespaces.get(i);
String prefix = ns.getPrefix(); final String prefix = ns.getPrefix();
if (prefix != null && prefix.length() > 0 && !usedPrefixes.contains(prefix)) { if (prefix != null && prefix.length() > 0 && !usedPrefixes.contains(prefix)) {
root.removeNamespaceDeclaration(ns); root.removeNamespaceDeclaration(ns);
} }
} }
} }
private static void collectUsedPrefixes(Element el, java.util.Set collector) { private static void collectUsedPrefixes(final Element el, final java.util.Set collector) {
String prefix = el.getNamespacePrefix(); final String prefix = el.getNamespacePrefix();
if (prefix != null && prefix.length() > 0 && !collector.contains(prefix)) { if (prefix != null && prefix.length() > 0 && !collector.contains(prefix)) {
collector.add(prefix); collector.add(prefix);
} }
List kids = el.getChildren(); final List kids = el.getChildren();
for (int i = 0; i < kids.size(); i++) { for (int i = 0; i < kids.size(); i++) {
collectUsedPrefixes((Element) kids.get(i), collector); // recursion - worth it collectUsedPrefixes((Element) kids.get(i), collector); // recursion
// - worth it
} }
} }

View file

@ -1,115 +1,116 @@
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jdom2.Attribute;
import org.jdom2.Element;
import org.jdom2.Namespace;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Extendable; import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.WireFeedParser; import com.sun.syndication.io.WireFeedParser;
import java.util.ArrayList;
import java.util.Iterator;
import org.jdom2.Element;
import java.util.List;
import org.jdom2.Namespace;
import org.jdom2.Attribute;
/** /**
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
*/ */
public abstract class BaseWireFeedParser implements WireFeedParser { public abstract class BaseWireFeedParser implements WireFeedParser {
/** /**
* [TYPE].feed.ModuleParser.classes= [className] ... * [TYPE].feed.ModuleParser.classes= [className] ...
* *
*/ */
private static final String FEED_MODULE_PARSERS_POSFIX_KEY = ".feed.ModuleParser.classes"; private static final String FEED_MODULE_PARSERS_POSFIX_KEY = ".feed.ModuleParser.classes";
/** /**
* [TYPE].item.ModuleParser.classes= [className] ... * [TYPE].item.ModuleParser.classes= [className] ...
* *
*/ */
private static final String ITEM_MODULE_PARSERS_POSFIX_KEY = ".item.ModuleParser.classes"; private static final String ITEM_MODULE_PARSERS_POSFIX_KEY = ".item.ModuleParser.classes";
/** /**
* [TYPE].person.ModuleParser.classes= [className] ... * [TYPE].person.ModuleParser.classes= [className] ...
* *
*/ */
private static final String PERSON_MODULE_PARSERS_POSFIX_KEY = ".person.ModuleParser.classes"; private static final String PERSON_MODULE_PARSERS_POSFIX_KEY = ".person.ModuleParser.classes";
private final String _type;
private final ModuleParsers _feedModuleParsers;
private final ModuleParsers _itemModuleParsers;
private final ModuleParsers _personModuleParsers;
private final Namespace _namespace;
private String _type; protected BaseWireFeedParser(final String type, final Namespace namespace) {
private ModuleParsers _feedModuleParsers; this._type = type;
private ModuleParsers _itemModuleParsers; this._namespace = namespace;
private ModuleParsers _personModuleParsers; this._feedModuleParsers = new ModuleParsers(type + FEED_MODULE_PARSERS_POSFIX_KEY, this);
private Namespace _namespace; this._itemModuleParsers = new ModuleParsers(type + ITEM_MODULE_PARSERS_POSFIX_KEY, this);
this._personModuleParsers = new ModuleParsers(type + PERSON_MODULE_PARSERS_POSFIX_KEY, this);
protected BaseWireFeedParser(String type, Namespace namespace) {
_type = type;
_namespace = namespace;
_feedModuleParsers = new ModuleParsers(type+FEED_MODULE_PARSERS_POSFIX_KEY, this);
_itemModuleParsers = new ModuleParsers(type+ITEM_MODULE_PARSERS_POSFIX_KEY, this);
_personModuleParsers = new ModuleParsers(type+PERSON_MODULE_PARSERS_POSFIX_KEY, this);
} }
/** /**
* Returns the type of feed the parser handles. * Returns the type of feed the parser handles.
* <p> * <p>
*
* @see WireFeed for details on the format of this string. * @see WireFeed for details on the format of this string.
* <p> * <p>
* @return the type of feed the parser handles. * @return the type of feed the parser handles.
* *
*/ */
@Override
public String getType() { public String getType() {
return _type; return this._type;
} }
protected List<Module> parseFeedModules(Element feedElement) { protected List<Module> parseFeedModules(final Element feedElement) {
return _feedModuleParsers.parseModules(feedElement); return this._feedModuleParsers.parseModules(feedElement);
} }
protected List<Module> parseItemModules(Element itemElement) { protected List<Module> parseItemModules(final Element itemElement) {
return _itemModuleParsers.parseModules(itemElement); return this._itemModuleParsers.parseModules(itemElement);
} }
protected List<Module> parsePersonModules(Element itemElement) { protected List<Module> parsePersonModules(final Element itemElement) {
return _personModuleParsers.parseModules(itemElement); return this._personModuleParsers.parseModules(itemElement);
} }
protected List<Element> extractForeignMarkup(Element e, Extendable ext, Namespace basens) { protected List<Element> extractForeignMarkup(final Element e, final Extendable ext, final Namespace basens) {
ArrayList<Element> foreignMarkup = new ArrayList<Element>(); final ArrayList<Element> foreignMarkup = new ArrayList<Element>();
Iterator<Element> children = e.getChildren().iterator(); final Iterator<Element> children = e.getChildren().iterator();
while (children.hasNext()) { while (children.hasNext()) {
Element elem = (Element)children.next(); final Element elem = children.next();
if ( if (
// if elemet not in the RSS namespace // if elemet not in the RSS namespace
!basens.equals(elem.getNamespace()) !basens.equals(elem.getNamespace())
// and elem was not handled by a module // and elem was not handled by a module
&& null == ext.getModule(elem.getNamespaceURI())) { && null == ext.getModule(elem.getNamespaceURI())) {
// save it as foreign markup, // save it as foreign markup,
// but we can't detach it while we're iterating // but we can't detach it while we're iterating
foreignMarkup.add(elem.clone()); foreignMarkup.add(elem.clone());
} }
} }
// Now we can detach the foreign markup elements // Now we can detach the foreign markup elements
Iterator<Element> fm = foreignMarkup.iterator(); final Iterator<Element> fm = foreignMarkup.iterator();
while (fm.hasNext()) { while (fm.hasNext()) {
Element elem = (Element)fm.next(); final Element elem = fm.next();
elem.detach(); elem.detach();
} }
return foreignMarkup; return foreignMarkup;
} }
protected Attribute getAttribute(Element e, String attributeName) { protected Attribute getAttribute(final Element e, final String attributeName) {
Attribute attribute = e.getAttribute(attributeName); Attribute attribute = e.getAttribute(attributeName);
if (attribute == null) { if (attribute == null) {
attribute = e.getAttribute(attributeName, _namespace); attribute = e.getAttribute(attributeName, this._namespace);
} }
return attribute; return attribute;
} }
protected String getAttributeValue(Element e, String attributeName) { protected String getAttributeValue(final Element e, final String attributeName) {
Attribute attr = getAttribute(e, attributeName); final Attribute attr = getAttribute(e, attributeName);
return (attr != null) ? attr.getValue() : null; return attr != null ? attr.getValue() : null;
} }
} }

View file

@ -16,54 +16,54 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.Module; import java.util.ArrayList;
import com.sun.syndication.feed.module.DCModule; import java.util.Collections;
import com.sun.syndication.feed.module.DCSubject; import java.util.Date;
import com.sun.syndication.io.ModuleGenerator; import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jdom2.Attribute; import org.jdom2.Attribute;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import java.util.ArrayList; import com.sun.syndication.feed.module.DCModule;
import java.util.Date; import com.sun.syndication.feed.module.DCSubject;
import java.util.Iterator; import com.sun.syndication.feed.module.Module;
import java.util.List; import com.sun.syndication.io.ModuleGenerator;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
/** /**
* Feed Generator for DublinCore Module. * Feed Generator for DublinCore Module.
* <p/> * <p/>
* *
* @author Elaine Chien * @author Elaine Chien
* *
*/ */
public class DCModuleGenerator implements ModuleGenerator { public class DCModuleGenerator implements ModuleGenerator {
private static final String DC_URI = "http://purl.org/dc/elements/1.1/"; private static final String DC_URI = "http://purl.org/dc/elements/1.1/";
private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/"; private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/";
private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
private static final Namespace DC_NS = Namespace.getNamespace("dc", DC_URI); private static final Namespace DC_NS = Namespace.getNamespace("dc", DC_URI);
private static final Namespace TAXO_NS = Namespace.getNamespace("taxo", TAXO_URI); private static final Namespace TAXO_NS = Namespace.getNamespace("taxo", TAXO_URI);
private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI); private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI);
private static final Set<Namespace> NAMESPACES; private static final Set<Namespace> NAMESPACES;
static { static {
Set<Namespace> nss = new HashSet<Namespace>(); final Set<Namespace> nss = new HashSet<Namespace>();
nss.add(DC_NS); nss.add(DC_NS);
nss.add(TAXO_NS); nss.add(TAXO_NS);
nss.add(RDF_NS); nss.add(RDF_NS);
NAMESPACES = Collections.unmodifiableSet(nss); NAMESPACES = Collections.unmodifiableSet(nss);
} }
@Override
public final String getNamespaceUri() { public final String getNamespaceUri() {
return DC_URI; return DC_URI;
} }
private final Namespace getDCNamespace() { private final Namespace getDCNamespace() {
return DC_NS; return DC_NS;
} }
@ -81,12 +81,13 @@ public class DCModuleGenerator implements ModuleGenerator {
* generator uses. * generator uses.
* <p/> * <p/>
* It is used by the the feed generators to add their namespace definition * It is used by the the feed generators to add their namespace definition
* in the root element of the generated document (forward-missing of * in the root element of the generated document (forward-missing of Java
* Java 5.0 Generics). * 5.0 Generics).
* <p/> * <p/>
* *
* @return a set with all the URIs this module generator uses. * @return a set with all the URIs this module generator uses.
*/ */
@Override
public final Set<Namespace> getNamespaces() { public final Set<Namespace> getNamespaces() {
return NAMESPACES; return NAMESPACES;
} }
@ -94,11 +95,13 @@ public class DCModuleGenerator implements ModuleGenerator {
/** /**
* Populate an element tree with elements for a module. * Populate an element tree with elements for a module.
* <p> * <p>
*
* @param module the module to populate from. * @param module the module to populate from.
* @param element the root element to attach child elements to. * @param element the root element to attach child elements to.
*/ */
public final void generate(Module module, Element element) { @Override
DCModule dcModule = (DCModule) module; public final void generate(final Module module, final Element element) {
final DCModule dcModule = (DCModule) module;
if (dcModule.getTitle() != null) { if (dcModule.getTitle() != null) {
element.addContent(generateSimpleElementList("title", dcModule.getTitles())); element.addContent(generateSimpleElementList("title", dcModule.getTitles()));
@ -106,9 +109,9 @@ public class DCModuleGenerator implements ModuleGenerator {
if (dcModule.getCreator() != null) { if (dcModule.getCreator() != null) {
element.addContent(generateSimpleElementList("creator", dcModule.getCreators())); element.addContent(generateSimpleElementList("creator", dcModule.getCreators()));
} }
List<DCSubject> subjects = dcModule.getSubjects(); final List<DCSubject> subjects = dcModule.getSubjects();
for (int i = 0; i < subjects.size(); i++) { for (int i = 0; i < subjects.size(); i++) {
element.addContent(generateSubjectElement((DCSubject) subjects.get(i))); element.addContent(generateSubjectElement(subjects.get(i)));
} }
if (dcModule.getDescription() != null) { if (dcModule.getDescription() != null) {
element.addContent(generateSimpleElementList("description", dcModule.getDescriptions())); element.addContent(generateSimpleElementList("description", dcModule.getDescriptions()));
@ -120,9 +123,8 @@ public class DCModuleGenerator implements ModuleGenerator {
element.addContent(generateSimpleElementList("contributor", dcModule.getContributors())); element.addContent(generateSimpleElementList("contributor", dcModule.getContributors()));
} }
if (dcModule.getDate() != null) { if (dcModule.getDate() != null) {
for (Iterator<Date> i = dcModule.getDates().iterator(); i.hasNext();) { for (final Date date : dcModule.getDates()) {
element.addContent(generateSimpleElement("date", element.addContent(generateSimpleElement("date", DateParser.formatW3CDateTime(date)));
DateParser.formatW3CDateTime((Date) i.next())));
} }
} }
if (dcModule.getType() != null) { if (dcModule.getType() != null) {
@ -154,21 +156,22 @@ public class DCModuleGenerator implements ModuleGenerator {
/** /**
* Utility method to generate an element for a subject. * Utility method to generate an element for a subject.
* <p> * <p>
*
* @param subject the subject to generate an element for. * @param subject the subject to generate an element for.
* @return the element for the subject. * @return the element for the subject.
*/ */
protected final Element generateSubjectElement(DCSubject subject) { protected final Element generateSubjectElement(final DCSubject subject) {
Element subjectElement = new Element("subject", getDCNamespace()); final Element subjectElement = new Element("subject", getDCNamespace());
if (subject.getTaxonomyUri() != null) { if (subject.getTaxonomyUri() != null) {
Element descriptionElement = new Element("Description", getRDFNamespace()); final Element descriptionElement = new Element("Description", getRDFNamespace());
Element topicElement = new Element("topic", getTaxonomyNamespace()); final Element topicElement = new Element("topic", getTaxonomyNamespace());
Attribute resourceAttribute = new Attribute("resource", subject.getTaxonomyUri(), getRDFNamespace()); final Attribute resourceAttribute = new Attribute("resource", subject.getTaxonomyUri(), getRDFNamespace());
topicElement.setAttribute(resourceAttribute); topicElement.setAttribute(resourceAttribute);
descriptionElement.addContent(topicElement); descriptionElement.addContent(topicElement);
if (subject.getValue() != null) { if (subject.getValue() != null) {
Element valueElement = new Element("value", getRDFNamespace()); final Element valueElement = new Element("value", getRDFNamespace());
valueElement.addContent(subject.getValue()); valueElement.addContent(subject.getValue());
descriptionElement.addContent(valueElement); descriptionElement.addContent(valueElement);
} }
@ -179,16 +182,16 @@ public class DCModuleGenerator implements ModuleGenerator {
return subjectElement; return subjectElement;
} }
/** /**
* Utility method to generate a single element containing a string. * Utility method to generate a single element containing a string.
* <p> * <p>
*
* @param name the name of the elment to generate. * @param name the name of the elment to generate.
* @param value the value of the text in the element. * @param value the value of the text in the element.
* @return the element generated. * @return the element generated.
*/ */
protected final Element generateSimpleElement(String name, String value) { protected final Element generateSimpleElement(final String name, final String value) {
Element element = new Element(name, getDCNamespace()); final Element element = new Element(name, getDCNamespace());
element.addContent(value); element.addContent(value);
return element; return element;
@ -197,14 +200,15 @@ public class DCModuleGenerator implements ModuleGenerator {
/** /**
* Utility method to generate a list of simple elements. * Utility method to generate a list of simple elements.
* <p> * <p>
*
* @param name the name of the element list to generate. * @param name the name of the element list to generate.
* @param value the list of values for the elements. * @param value the list of values for the elements.
* @return a list of Elements created. * @return a list of Elements created.
*/ */
protected final List<Element> generateSimpleElementList(String name, List<String> value) { protected final List<Element> generateSimpleElementList(final String name, final List<String> value) {
List<Element> elements = new ArrayList<Element>(); final List<Element> elements = new ArrayList<Element>();
for (Iterator<String> i = value.iterator(); i.hasNext();) { for (final String string : value) {
elements.add(generateSimpleElement(name, (String) i.next())); elements.add(generateSimpleElement(name, string));
} }
return elements; return elements;

View file

@ -16,20 +16,20 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.DCModuleImpl; import java.util.ArrayList;
import com.sun.syndication.feed.module.DCSubjectImpl; import java.util.Date;
import com.sun.syndication.feed.module.Module; import java.util.List;
import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.module.DCSubject;
import com.sun.syndication.io.ModuleParser;
import org.jdom2.Attribute; import org.jdom2.Attribute;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import java.util.ArrayList; import com.sun.syndication.feed.module.DCModule;
import java.util.Date; import com.sun.syndication.feed.module.DCModuleImpl;
import java.util.Iterator; import com.sun.syndication.feed.module.DCSubject;
import java.util.List; import com.sun.syndication.feed.module.DCSubjectImpl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleParser;
/** /**
* Parser for the Dublin Core module. * Parser for the Dublin Core module.
@ -43,6 +43,7 @@ public class DCModuleParser implements ModuleParser {
private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI); private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
private static final Namespace TAXO_NS = Namespace.getNamespace(TAXO_URI); private static final Namespace TAXO_NS = Namespace.getNamespace(TAXO_URI);
@Override
public final String getNamespaceUri() { public final String getNamespaceUri() {
return DCModule.URI; return DCModule.URI;
} }
@ -62,12 +63,14 @@ public class DCModuleParser implements ModuleParser {
/** /**
* Parse an element tree and return the module found in it. * Parse an element tree and return the module found in it.
* <p> * <p>
*
* @param dcRoot the root element containing the module elements. * @param dcRoot the root element containing the module elements.
* @return the module parsed from the element tree, <i>null</i> if none. * @return the module parsed from the element tree, <i>null</i> if none.
*/ */
public Module parse(Element dcRoot) { @Override
public Module parse(final Element dcRoot) {
boolean foundSomething = false; boolean foundSomething = false;
DCModule dcm = new DCModuleImpl(); final DCModule dcm = new DCModuleImpl();
List<Element> eList = dcRoot.getChildren("title", getDCNamespace()); List<Element> eList = dcRoot.getChildren("title", getDCNamespace());
if (eList.size() > 0) { if (eList.size() > 0) {
@ -145,21 +148,22 @@ public class DCModuleParser implements ModuleParser {
dcm.setRightsList(parseElementList(eList)); dcm.setRightsList(parseElementList(eList));
} }
return (foundSomething) ? dcm : null; return foundSomething ? dcm : null;
} }
/** /**
* Utility method to parse a taxonomy from an element. * Utility method to parse a taxonomy from an element.
* <p> * <p>
*
* @param desc the taxonomy description element. * @param desc the taxonomy description element.
* @return the string contained in the resource of the element. * @return the string contained in the resource of the element.
*/ */
protected final String getTaxonomy(Element desc) { protected final String getTaxonomy(final Element desc) {
String d = null; String d = null;
Element taxo = desc.getChild("topic", getTaxonomyNamespace()); final Element taxo = desc.getChild("topic", getTaxonomyNamespace());
if (taxo!=null) { if (taxo != null) {
Attribute a = taxo.getAttribute("resource", getRDFNamespace()); final Attribute a = taxo.getAttribute("resource", getRDFNamespace());
if (a!=null) { if (a != null) {
d = a.getValue(); d = a.getValue();
} }
} }
@ -169,26 +173,27 @@ public class DCModuleParser implements ModuleParser {
/** /**
* Utility method to parse a list of subjects out of a list of elements. * Utility method to parse a list of subjects out of a list of elements.
* <p> * <p>
*
* @param eList the element list to parse. * @param eList the element list to parse.
* @return a list of subjects parsed from the elements. * @return a list of subjects parsed from the elements.
*/ */
protected final List<DCSubject> parseSubjects(List<Element> eList) { protected final List<DCSubject> parseSubjects(final List<Element> eList) {
List<DCSubject> subjects = new ArrayList<DCSubject>(); final List<DCSubject> subjects = new ArrayList<DCSubject>();
for (Iterator<Element> i = eList.iterator(); i.hasNext();) { for (final Element element : eList) {
Element eSubject = (Element) i.next(); final Element eSubject = element;
Element eDesc = eSubject.getChild("Description", getRDFNamespace()); final Element eDesc = eSubject.getChild("Description", getRDFNamespace());
if (eDesc != null) { if (eDesc != null) {
String taxonomy = getTaxonomy(eDesc); final String taxonomy = getTaxonomy(eDesc);
List<Element> eValues = eDesc.getChildren("value", getRDFNamespace()); final List<Element> eValues = eDesc.getChildren("value", getRDFNamespace());
for (Iterator<Element> v = eValues.iterator(); v.hasNext();) { for (final Element element2 : eValues) {
Element eValue = (Element) v.next(); final Element eValue = element2;
DCSubject subject = new DCSubjectImpl(); final DCSubject subject = new DCSubjectImpl();
subject.setTaxonomyUri(taxonomy); subject.setTaxonomyUri(taxonomy);
subject.setValue(eValue.getText()); subject.setValue(eValue.getText());
subjects.add(subject); subjects.add(subject);
} }
} else { } else {
DCSubject subject = new DCSubjectImpl(); final DCSubject subject = new DCSubjectImpl();
subject.setValue(eSubject.getText()); subject.setValue(eSubject.getText());
subjects.add(subject); subjects.add(subject);
} }
@ -200,13 +205,14 @@ public class DCModuleParser implements ModuleParser {
/** /**
* Utility method to parse a list of strings out of a list of elements. * Utility method to parse a list of strings out of a list of elements.
* <p> * <p>
*
* @param eList the list of elements to parse. * @param eList the list of elements to parse.
* @return the list of strings * @return the list of strings
*/ */
protected final List<String> parseElementList(List<Element> eList) { protected final List<String> parseElementList(final List<Element> eList) {
List<String> values= new ArrayList<String>(); final List<String> values = new ArrayList<String>();
for (Iterator<Element> i = eList.iterator(); i.hasNext();) { for (final Element element : eList) {
Element e = (Element) i.next(); final Element e = element;
values.add(e.getText()); values.add(e.getText());
} }
@ -216,13 +222,14 @@ public class DCModuleParser implements ModuleParser {
/** /**
* Utility method to parse a list of dates out of a list of elements. * Utility method to parse a list of dates out of a list of elements.
* <p> * <p>
*
* @param eList the list of elements to parse. * @param eList the list of elements to parse.
* @return the list of dates. * @return the list of dates.
*/ */
protected final List<Date> parseElementListDate(List<Element> eList) { protected final List<Date> parseElementListDate(final List<Element> eList) {
List<Date> values = new ArrayList<Date>(); final List<Date> values = new ArrayList<Date>();
for (Iterator<Element> i = eList.iterator(); i.hasNext();) { for (final Element element : eList) {
Element e = (Element) i.next(); final Element e = element;
values.add(DateParser.parseDate(e.getText())); values.add(DateParser.parseDate(e.getText()));
} }

View file

@ -17,96 +17,73 @@
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParsePosition; import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone;
/** /**
* A helper class that parses Dates out of Strings with date time in RFC822 and W3CDateTime * A helper class that parses Dates out of Strings with date time in RFC822 and
* formats plus the variants Atom (0.3) and RSS (0.9, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) * W3CDateTime formats plus the variants Atom (0.3) and RSS (0.9, 0.91, 0.92,
* specificators added to those formats. * 0.93, 0.94, 1.0 and 2.0) specificators added to those formats.
* <p/> * <p/>
* It uses the JDK java.text.SimpleDateFormat class attemtping the parse using a mask for * It uses the JDK java.text.SimpleDateFormat class attemtping the parse using a
* each one of the possible formats. * mask for each one of the possible formats.
* <p/> * <p/>
* *
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class DateParser { public class DateParser {
private static String[] ADDITIONAL_MASKS; private static String[] ADDITIONAL_MASKS;
static { static {
ADDITIONAL_MASKS = PropertiesLoader.getPropertiesLoader().getTokenizedProperty("datetime.extra.masks","|"); ADDITIONAL_MASKS = PropertiesLoader.getPropertiesLoader().getTokenizedProperty("datetime.extra.masks", "|");
} }
// order is like this because the SimpleDateFormat.parse does not fail with exception // order is like this because the SimpleDateFormat.parse does not fail with
// if it can parse a valid date out of a substring of the full string given the mask // exception
// so we have to check the most complete format first, then it fails with exception // if it can parse a valid date out of a substring of the full string given
private static final String[] RFC822_MASKS = { // the mask
"EEE, dd MMM yy HH:mm:ss z", // so we have to check the most complete format first, then it fails with
"EEE, dd MMM yy HH:mm z", // exception
"dd MMM yy HH:mm:ss z", private static final String[] RFC822_MASKS = { "EEE, dd MMM yy HH:mm:ss z", "EEE, dd MMM yy HH:mm z", "dd MMM yy HH:mm:ss z", "dd MMM yy HH:mm z" };
"dd MMM yy HH:mm z"
};
// order is like this because the SimpleDateFormat.parse does not fail with
// exception
// if it can parse a valid date out of a substring of the full string given
// the mask
// so we have to check the most complete format first, then it fails with
// exception
private static final String[] W3CDATETIME_MASKS = { "yyyy-MM-dd'T'HH:mm:ss.SSSz", "yyyy-MM-dd't'HH:mm:ss.SSSz", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd't'HH:mm:ss.SSS'z'", "yyyy-MM-dd'T'HH:mm:ssz", "yyyy-MM-dd't'HH:mm:ssz", "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd't'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd't'HH:mm:ss'z'", "yyyy-MM-dd'T'HH:mmz", // together
// with
// logic
// in
// the
// parseW3CDateTime
// they
"yyyy-MM'T'HH:mmz", // handle W3C dates without time forcing them to
// be GMT
"yyyy'T'HH:mmz", "yyyy-MM-dd't'HH:mmz", "yyyy-MM-dd'T'HH:mm'Z'", "yyyy-MM-dd't'HH:mm'z'", "yyyy-MM-dd", "yyyy-MM", "yyyy" };
/**
// order is like this because the SimpleDateFormat.parse does not fail with exception * The masks used to validate and parse the input to this Atom date. These
// if it can parse a valid date out of a substring of the full string given the mask * are a lot more forgiving than what the Atom spec allows. The forms that
// so we have to check the most complete format first, then it fails with exception * are invalid according to the spec are indicated.
private static final String[] W3CDATETIME_MASKS = { */
"yyyy-MM-dd'T'HH:mm:ss.SSSz", private static final String[] masks = { "yyyy-MM-dd'T'HH:mm:ss.SSSz", "yyyy-MM-dd't'HH:mm:ss.SSSz", // invalid
"yyyy-MM-dd't'HH:mm:ss.SSSz", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd't'HH:mm:ss.SSS'z'", // invalid
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ssz", "yyyy-MM-dd't'HH:mm:ssz", // invalid
"yyyy-MM-dd't'HH:mm:ss.SSS'z'", "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd't'HH:mm:ss'z'", // invalid
"yyyy-MM-dd'T'HH:mm:ssz", "yyyy-MM-dd'T'HH:mmz", // invalid
"yyyy-MM-dd't'HH:mm:ssz", "yyyy-MM-dd't'HH:mmz", // invalid
"yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm'Z'", // invalid
"yyyy-MM-dd't'HH:mm:ssZ", "yyyy-MM-dd't'HH:mm'z'", // invalid
"yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd", "yyyy-MM", "yyyy" };
"yyyy-MM-dd't'HH:mm:ss'z'",
"yyyy-MM-dd'T'HH:mmz", // together with logic in the parseW3CDateTime they
"yyyy-MM'T'HH:mmz", // handle W3C dates without time forcing them to be GMT
"yyyy'T'HH:mmz",
"yyyy-MM-dd't'HH:mmz",
"yyyy-MM-dd'T'HH:mm'Z'",
"yyyy-MM-dd't'HH:mm'z'",
"yyyy-MM-dd",
"yyyy-MM",
"yyyy"
};
/**
* The masks used to validate and parse the input to this Atom date.
* These are a lot more forgiving than what the Atom spec allows.
* The forms that are invalid according to the spec are indicated.
*/
private static final String[] masks = {
"yyyy-MM-dd'T'HH:mm:ss.SSSz",
"yyyy-MM-dd't'HH:mm:ss.SSSz", // invalid
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd't'HH:mm:ss.SSS'z'", // invalid
"yyyy-MM-dd'T'HH:mm:ssz",
"yyyy-MM-dd't'HH:mm:ssz", // invalid
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd't'HH:mm:ss'z'", // invalid
"yyyy-MM-dd'T'HH:mmz", // invalid
"yyyy-MM-dd't'HH:mmz", // invalid
"yyyy-MM-dd'T'HH:mm'Z'", // invalid
"yyyy-MM-dd't'HH:mm'z'", // invalid
"yyyy-MM-dd",
"yyyy-MM",
"yyyy"
};
/** /**
* Private constructor to avoid DateParser instances creation. * Private constructor to avoid DateParser instances creation.
@ -119,31 +96,31 @@ public class DateParser {
* <p/> * <p/>
* It uses the masks in order until one of them succedes or all fail. * It uses the masks in order until one of them succedes or all fail.
* <p/> * <p/>
* *
* @param masks array of masks to use for parsing the string * @param masks array of masks to use for parsing the string
* @param sDate string to parse for a date. * @param sDate string to parse for a date.
* @return the Date represented by the given string using one of the given masks. * @return the Date represented by the given string using one of the given
* It returns <b>null</b> if it was not possible to parse the the string with any of the masks. * masks. It returns <b>null</b> if it was not possible to parse the
* * the string with any of the masks.
*
*/ */
private static Date parseUsingMask(String[] masks,String sDate) { private static Date parseUsingMask(final String[] masks, String sDate) {
sDate = (sDate!=null) ? sDate.trim() : null; sDate = sDate != null ? sDate.trim() : null;
ParsePosition pp = null; ParsePosition pp = null;
Date d = null; Date d = null;
for (int i=0;d==null && i<masks.length;i++) { for (int i = 0; d == null && i < masks.length; i++) {
DateFormat df = new SimpleDateFormat(masks[i],Locale.US); final DateFormat df = new SimpleDateFormat(masks[i], Locale.US);
//df.setLenient(false); // df.setLenient(false);
df.setLenient(true); df.setLenient(true);
try { try {
pp = new ParsePosition(0); pp = new ParsePosition(0);
d = df.parse(sDate,pp); d = df.parse(sDate, pp);
if (pp.getIndex()!=sDate.length()) { if (pp.getIndex() != sDate.length()) {
d = null; d = null;
} }
//System.out.println("pp["+pp.getIndex()+"] s["+sDate+" m["+masks[i]+"] d["+d+"]"); // System.out.println("pp["+pp.getIndex()+"] s["+sDate+" m["+masks[i]+"] d["+d+"]");
} } catch (final Exception ex1) {
catch (Exception ex1) { // System.out.println("s: "+sDate+" m: "+masks[i]+" d: "+null);
//System.out.println("s: "+sDate+" m: "+masks[i]+" d: "+null);
} }
} }
return d; return d;
@ -154,97 +131,103 @@ public class DateParser {
* <p/> * <p/>
* It parsers the following formats: * It parsers the following formats:
* <ul> * <ul>
* <li>"EEE, dd MMM yyyy HH:mm:ss z"</li> * <li>"EEE, dd MMM yyyy HH:mm:ss z"</li>
* <li>"EEE, dd MMM yyyy HH:mm z"</li> * <li>"EEE, dd MMM yyyy HH:mm z"</li>
* <li>"EEE, dd MMM yy HH:mm:ss z"</li> * <li>"EEE, dd MMM yy HH:mm:ss z"</li>
* <li>"EEE, dd MMM yy HH:mm z"</li> * <li>"EEE, dd MMM yy HH:mm z"</li>
* <li>"dd MMM yyyy HH:mm:ss z"</li> * <li>"dd MMM yyyy HH:mm:ss z"</li>
* <li>"dd MMM yyyy HH:mm z"</li> * <li>"dd MMM yyyy HH:mm z"</li>
* <li>"dd MMM yy HH:mm:ss z"</li> * <li>"dd MMM yy HH:mm:ss z"</li>
* <li>"dd MMM yy HH:mm z"</li> * <li>"dd MMM yy HH:mm z"</li>
* </ul> * </ul>
* <p/> * <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element. * Refer to the java.text.SimpleDateFormat javadocs for details on the
* format of each element.
* <p/> * <p/>
*
* @param sDate string to parse for a date. * @param sDate string to parse for a date.
* @return the Date represented by the given RFC822 string. * @return the Date represented by the given RFC822 string. It returns
* It returns <b>null</b> if it was not possible to parse the given string into a Date. * <b>null</b> if it was not possible to parse the given string into
* * a Date.
*
*/ */
public static Date parseRFC822(String sDate) { public static Date parseRFC822(String sDate) {
int utIndex = sDate.indexOf(" UT"); final int utIndex = sDate.indexOf(" UT");
if (utIndex>-1) { if (utIndex > -1) {
String pre = sDate.substring(0,utIndex); final String pre = sDate.substring(0, utIndex);
String post = sDate.substring(utIndex+3); final String post = sDate.substring(utIndex + 3);
sDate = pre + " GMT" + post; sDate = pre + " GMT" + post;
} }
return parseUsingMask(RFC822_MASKS,sDate); return parseUsingMask(RFC822_MASKS, sDate);
} }
/** /**
* Parses a Date out of a String with a date in W3C date-time format. * Parses a Date out of a String with a date in W3C date-time format.
* <p/> * <p/>
* It parsers the following formats: * It parsers the following formats:
* <ul> * <ul>
* <li>"yyyy-MM-dd'T'HH:mm:ssz"</li> * <li>"yyyy-MM-dd'T'HH:mm:ssz"</li>
* <li>"yyyy-MM-dd'T'HH:mmz"</li> * <li>"yyyy-MM-dd'T'HH:mmz"</li>
* <li>"yyyy-MM-dd"</li> * <li>"yyyy-MM-dd"</li>
* <li>"yyyy-MM"</li> * <li>"yyyy-MM"</li>
* <li>"yyyy"</li> * <li>"yyyy"</li>
* </ul> * </ul>
* <p/> * <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element. * Refer to the java.text.SimpleDateFormat javadocs for details on the
* format of each element.
* <p/> * <p/>
*
* @param sDate string to parse for a date. * @param sDate string to parse for a date.
* @return the Date represented by the given W3C date-time string. * @return the Date represented by the given W3C date-time string. It
* It returns <b>null</b> if it was not possible to parse the given string into a Date. * returns <b>null</b> if it was not possible to parse the given
* * string into a Date.
*
*/ */
public static Date parseW3CDateTime(String sDate) { public static Date parseW3CDateTime(String sDate) {
// if sDate has time on it, it injects 'GTM' before de TZ displacement to // if sDate has time on it, it injects 'GTM' before de TZ displacement
// to
// allow the SimpleDateFormat parser to parse it properly // allow the SimpleDateFormat parser to parse it properly
int tIndex = sDate.indexOf("T"); final int tIndex = sDate.indexOf("T");
if (tIndex>-1) { if (tIndex > -1) {
if (sDate.endsWith("Z")) { if (sDate.endsWith("Z")) {
sDate = sDate.substring(0,sDate.length()-1)+"+00:00"; sDate = sDate.substring(0, sDate.length() - 1) + "+00:00";
} }
int tzdIndex = sDate.indexOf("+",tIndex); int tzdIndex = sDate.indexOf("+", tIndex);
if (tzdIndex==-1) { if (tzdIndex == -1) {
tzdIndex = sDate.indexOf("-",tIndex); tzdIndex = sDate.indexOf("-", tIndex);
} }
if (tzdIndex>-1) { if (tzdIndex > -1) {
String pre = sDate.substring(0,tzdIndex); String pre = sDate.substring(0, tzdIndex);
int secFraction = pre.indexOf(","); final int secFraction = pre.indexOf(",");
if (secFraction>-1) { if (secFraction > -1) {
pre = pre.substring(0,secFraction); pre = pre.substring(0, secFraction);
} }
String post = sDate.substring(tzdIndex); final String post = sDate.substring(tzdIndex);
sDate = pre + "GMT" + post; sDate = pre + "GMT" + post;
} }
} } else {
else {
sDate += "T00:00GMT"; sDate += "T00:00GMT";
} }
return parseUsingMask(W3CDATETIME_MASKS,sDate); return parseUsingMask(W3CDATETIME_MASKS, sDate);
} }
/** /**
* Parses a Date out of a String with a date in W3C date-time format or * Parses a Date out of a String with a date in W3C date-time format or in a
* in a RFC822 format. * RFC822 format.
* <p> * <p>
*
* @param sDate string to parse for a date. * @param sDate string to parse for a date.
* @return the Date represented by the given W3C date-time string. * @return the Date represented by the given W3C date-time string. It
* It returns <b>null</b> if it was not possible to parse the given string into a Date. * returns <b>null</b> if it was not possible to parse the given
* * string into a Date.
*
* */ * */
public static Date parseDate(String sDate) { public static Date parseDate(final String sDate) {
Date d = parseW3CDateTime(sDate); Date d = parseW3CDateTime(sDate);
if (d==null) { if (d == null) {
d = parseRFC822(sDate); d = parseRFC822(sDate);
if (d==null && ADDITIONAL_MASKS.length>0) { if (d == null && ADDITIONAL_MASKS.length > 0) {
d = parseUsingMask(ADDITIONAL_MASKS,sDate); d = parseUsingMask(ADDITIONAL_MASKS, sDate);
} }
} }
return d; return d;
@ -253,15 +236,17 @@ public class DateParser {
/** /**
* create a RFC822 representation of a date. * create a RFC822 representation of a date.
* <p/> * <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element. * Refer to the java.text.SimpleDateFormat javadocs for details on the
* format of each element.
* <p/> * <p/>
*
* @param date Date to parse * @param date Date to parse
* @return the RFC822 represented by the given Date * @return the RFC822 represented by the given Date It returns <b>null</b>
* It returns <b>null</b> if it was not possible to parse the date. * if it was not possible to parse the date.
* *
*/ */
public static String formatRFC822(Date date) { public static String formatRFC822(final Date date) {
SimpleDateFormat dateFormater = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'",Locale.US); final SimpleDateFormat dateFormater = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
dateFormater.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormater.format(date); return dateFormater.format(date);
} }
@ -269,15 +254,17 @@ public class DateParser {
/** /**
* create a W3C Date Time representation of a date. * create a W3C Date Time representation of a date.
* <p/> * <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element. * Refer to the java.text.SimpleDateFormat javadocs for details on the
* format of each element.
* <p/> * <p/>
*
* @param date Date to parse * @param date Date to parse
* @return the W3C Date Time represented by the given Date * @return the W3C Date Time represented by the given Date It returns
* It returns <b>null</b> if it was not possible to parse the date. * <b>null</b> if it was not possible to parse the date.
* *
*/ */
public static String formatW3CDateTime(Date date) { public static String formatW3CDateTime(final Date date) {
SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.US); final SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
dateFormater.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormater.format(date); return dateFormater.format(date);
} }

View file

@ -16,43 +16,45 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.io.WireFeedGenerator;
import java.util.List; import java.util.List;
import com.sun.syndication.io.WireFeedGenerator;
/** /**
* Generates an XML document (JDOM Document) out of a Feed. * Generates an XML document (JDOM Document) out of a Feed.
* <p> * <p>
* It can generate all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and * It can generate all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and
* Atom 0.3 feed. * 2.0) and Atom 0.3 feed.
* <p> * <p>
* WireFeedGenerator instances are thread safe. * WireFeedGenerator instances are thread safe.
* <p> * <p>
* Generators for a specific type must extend this class and register in the generator list. * Generators for a specific type must extend this class and register in the
* (Right now registration is hardcoded in the WireFeedGenerator constructor). * generator list. (Right now registration is hardcoded in the WireFeedGenerator
* constructor).
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class FeedGenerators extends PluginManager { public class FeedGenerators extends PluginManager {
/** /**
* WireFeedGenerator.classes= [className] ... * WireFeedGenerator.classes= [className] ...
* *
*/ */
public static final String FEED_GENERATORS_KEY = "WireFeedGenerator.classes"; public static final String FEED_GENERATORS_KEY = "WireFeedGenerator.classes";
public FeedGenerators() { public FeedGenerators() {
super(FEED_GENERATORS_KEY); super(FEED_GENERATORS_KEY);
} }
public WireFeedGenerator getGenerator(String feedType) { public WireFeedGenerator getGenerator(final String feedType) {
return (WireFeedGenerator) getPlugin(feedType); return (WireFeedGenerator) getPlugin(feedType);
} }
protected String getKey(Object obj) { @Override
return ((WireFeedGenerator)obj).getType(); protected String getKey(final Object obj) {
return ((WireFeedGenerator) obj).getType();
} }
public List getSupportedFeedTypes() { public List getSupportedFeedTypes() {

View file

@ -16,10 +16,12 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.io.WireFeedParser;
import org.jdom2.Document;
import java.util.List; import java.util.List;
import org.jdom2.Document;
import com.sun.syndication.io.WireFeedParser;
/** /**
* Parses an XML document (JDOM Document) into a Feed. * Parses an XML document (JDOM Document) into a Feed.
* <p> * <p>
@ -30,24 +32,26 @@ import java.util.List;
* <p> * <p>
* WireFeedParser instances are thread safe. * WireFeedParser instances are thread safe.
* <p> * <p>
* Parsers for a specific type must extend this class and register in the parser list. * Parsers for a specific type must extend this class and register in the parser
* (Right now registration is hardcoded in the WireFeedParser constructor). * list. (Right now registration is hardcoded in the WireFeedParser
* constructor).
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class FeedParsers extends PluginManager { public class FeedParsers extends PluginManager {
/** /**
* WireFeedParser.classes= [className] ... * WireFeedParser.classes= [className] ...
* *
*/ */
public static final String FEED_PARSERS_KEY = "WireFeedParser.classes"; public static final String FEED_PARSERS_KEY = "WireFeedParser.classes";
/** /**
* Creates a parser instance. * Creates a parser instance.
* <p> * <p>
* *
*/ */
public FeedParsers() { public FeedParsers() {
super(FEED_PARSERS_KEY); super(FEED_PARSERS_KEY);
@ -60,14 +64,16 @@ public class FeedParsers extends PluginManager {
/** /**
* Finds the real parser type for the given document feed. * Finds the real parser type for the given document feed.
* <p> * <p>
*
* @param document document feed to find the parser for. * @param document document feed to find the parser for.
* @return the parser for the given document or <b>null</b> if there is no parser for that document. * @return the parser for the given document or <b>null</b> if there is no
* * parser for that document.
*
*/ */
public WireFeedParser getParserFor(Document document) { public WireFeedParser getParserFor(final Document document) {
List parsers = getPlugins(); final List parsers = getPlugins();
WireFeedParser parser = null; WireFeedParser parser = null;
for (int i=0;parser==null && i<parsers.size();i++) { for (int i = 0; parser == null && i < parsers.size(); i++) {
parser = (WireFeedParser) parsers.get(i); parser = (WireFeedParser) parsers.get(i);
if (!parser.isMyType(document)) { if (!parser.isMyType(document)) {
parser = null; parser = null;
@ -76,8 +82,9 @@ public class FeedParsers extends PluginManager {
return parser; return parser;
} }
protected String getKey(Object obj) { @Override
return ((WireFeedParser)obj).getType(); protected String getKey(final Object obj) {
return ((WireFeedParser) obj).getType();
} }
} }

View file

@ -16,42 +16,44 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleGenerator;
import org.jdom2.Element;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.jdom2.Element;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleGenerator;
/** /**
*/ */
public class ModuleGenerators extends PluginManager { public class ModuleGenerators extends PluginManager {
private Set _allNamespaces; private Set _allNamespaces;
public ModuleGenerators(String propertyKey, BaseWireFeedGenerator parentGenerator) { public ModuleGenerators(final String propertyKey, final BaseWireFeedGenerator parentGenerator) {
super(propertyKey, null, parentGenerator); super(propertyKey, null, parentGenerator);
} }
public ModuleGenerator getGenerator(String uri) { public ModuleGenerator getGenerator(final String uri) {
return (ModuleGenerator) getPlugin(uri); return (ModuleGenerator) getPlugin(uri);
} }
protected String getKey(Object obj) { @Override
return ((ModuleGenerator)obj).getNamespaceUri(); protected String getKey(final Object obj) {
return ((ModuleGenerator) obj).getNamespaceUri();
} }
public List getModuleNamespaces() { public List getModuleNamespaces() {
return getKeys(); return getKeys();
} }
public void generateModules(List modules, Element element) { public void generateModules(final List modules, final Element element) {
Map generators = getPluginMap(); final Map generators = getPluginMap();
for (int i = 0; i < modules.size(); i++) { for (int i = 0; i < modules.size(); i++) {
Module module = (Module) modules.get(i); final Module module = (Module) modules.get(i);
String namespaceUri = module.getUri(); final String namespaceUri = module.getUri();
ModuleGenerator generator = (ModuleGenerator)generators.get(namespaceUri); final ModuleGenerator generator = (ModuleGenerator) generators.get(namespaceUri);
if (generator != null) { if (generator != null) {
generator.generate(module, element); generator.generate(module, element);
} }
@ -59,14 +61,14 @@ public class ModuleGenerators extends PluginManager {
} }
public Set getAllNamespaces() { public Set getAllNamespaces() {
if (_allNamespaces==null) { if (this._allNamespaces == null) {
_allNamespaces = new HashSet(); this._allNamespaces = new HashSet();
List mUris = getModuleNamespaces(); final List mUris = getModuleNamespaces();
for (int i=0;i<mUris.size();i++) { for (int i = 0; i < mUris.size(); i++) {
ModuleGenerator mGen = getGenerator((String)mUris.get(i)); final ModuleGenerator mGen = getGenerator((String) mUris.get(i));
_allNamespaces.addAll(mGen.getNamespaces()); this._allNamespaces.addAll(mGen.getNamespaces());
} }
} }
return _allNamespaces; return this._allNamespaces;
} }
} }

View file

@ -16,39 +16,41 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.Module; import java.util.ArrayList;
import com.sun.syndication.io.ModuleParser; import java.util.List;
import com.sun.syndication.io.WireFeedParser;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import java.util.ArrayList; import com.sun.syndication.feed.module.Module;
import java.util.List; import com.sun.syndication.io.ModuleParser;
import com.sun.syndication.io.WireFeedParser;
/** /**
*/ */
public class ModuleParsers extends PluginManager { public class ModuleParsers extends PluginManager {
public ModuleParsers(String propertyKey, WireFeedParser parentParser) { public ModuleParsers(final String propertyKey, final WireFeedParser parentParser) {
super(propertyKey, parentParser, null); super(propertyKey, parentParser, null);
} }
public String getKey(Object obj) { @Override
return ((ModuleParser)obj).getNamespaceUri(); public String getKey(final Object obj) {
return ((ModuleParser) obj).getNamespaceUri();
} }
public List getModuleNamespaces() { public List getModuleNamespaces() {
return getKeys(); return getKeys();
} }
public List<Module> parseModules(Element root) { public List<Module> parseModules(final Element root) {
List<ModuleParser> parsers = getPlugins(); final List<ModuleParser> parsers = getPlugins();
List<Module> modules = null; List<Module> modules = null;
for (int i=0;i<parsers.size();i++) { for (int i = 0; i < parsers.size(); i++) {
ModuleParser parser = (ModuleParser) parsers.get(i); final ModuleParser parser = parsers.get(i);
String namespaceUri = parser.getNamespaceUri(); final String namespaceUri = parser.getNamespaceUri();
Namespace namespace = Namespace.getNamespace(namespaceUri); final Namespace namespace = Namespace.getNamespace(namespaceUri);
if (hasElementsFrom(root, namespace)) { if (hasElementsFrom(root, namespace)) {
Module module = parser.parse(root); final Module module = parser.parse(root);
if (module != null) { if (module != null) {
if (modules == null) { if (modules == null) {
modules = new ArrayList<Module>(); modules = new ArrayList<Module>();
@ -60,14 +62,14 @@ public class ModuleParsers extends PluginManager {
return modules; return modules;
} }
private boolean hasElementsFrom(Element root, Namespace namespace) { private boolean hasElementsFrom(final Element root, final Namespace namespace) {
boolean hasElements = false; boolean hasElements = false;
// boolean hasElements = namespace.equals(root.getNamespace()); // boolean hasElements = namespace.equals(root.getNamespace());
if (!hasElements) { if (!hasElements) {
List<Element> children = root.getChildren(); final List<Element> children = root.getChildren();
for (int i=0;!hasElements && i < children.size();i++) { for (int i = 0; !hasElements && i < children.size(); i++) {
Element child = (Element) children.get(i); final Element child = children.get(i);
hasElements = namespace.equals(child.getNamespace()); hasElements = namespace.equals(child.getNamespace());
} }
} }

View file

@ -1,15 +1,12 @@
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
/** /**
* A helper class that parses Numbers out of Strings in a lenient manner. * A helper class that parses Numbers out of Strings in a lenient manner.
* *
* <p> * <p>
* No method will throw any sort of Exception when parsing a string. * No method will throw any sort of Exception when parsing a string. All methods
* All methods accept any Java String or null as legal input, if the * accept any Java String or null as legal input, if the input is non null,
* input is non null, whitespace will be trimmed first, and then parsing * whitespace will be trimmed first, and then parsing will be attempted.
* will be attempted.
* </p> * </p>
* <p> * <p>
* :TODO: Add Integer, Float, and Double methods as needed. * :TODO: Add Integer, Float, and Double methods as needed.
@ -25,57 +22,60 @@ public class NumberParser {
/** /**
* Parses a Long out of a string. * Parses a Long out of a string.
* *
* @param str string to parse for a Long. * @param str string to parse for a Long.
* @return the Long represented by the given string, * @return the Long represented by the given string, It returns <b>null</b>
* It returns <b>null</b> if it was not possible to parse the the string. * if it was not possible to parse the the string.
*/ */
public static Long parseLong(String str) { public static Long parseLong(final String str) {
if (null != str) { if (null != str) {
try { try {
return new Long(Long.parseLong(str.trim())); return new Long(Long.parseLong(str.trim()));
} catch (Exception e) { } catch (final Exception e) {
// :IGNORE: // :IGNORE:
} }
} }
return null; return null;
} }
/** /**
* Parse an Integer from a String. If the String is not an integer <b>null</b> is returned * Parse an Integer from a String. If the String is not an integer
* and no exception is thrown. * <b>null</b> is returned and no exception is thrown.
* *
* @param str the String to parse * @param str the String to parse
* @return The Integer represented by the String, or null if it could not be parsed. * @return The Integer represented by the String, or null if it could not be
* parsed.
*/ */
public static Integer parseInt(String str) { public static Integer parseInt(final String str) {
if (null != str) { if (null != str) {
try { try {
return new Integer(Integer.parseInt(str.trim())); return new Integer(Integer.parseInt(str.trim()));
} catch (Exception e) { } catch (final Exception e) {
// :IGNORE: // :IGNORE:
} }
} }
return null; return null;
} }
/** /**
* Parse a Float from a String without exceptions. If the String is not a Float then null is returned * Parse a Float from a String without exceptions. If the String is not a
* Float then null is returned
* *
* @param str the String to parse * @param str the String to parse
* @return The Float represented by the String, or null if it could not be parsed. * @return The Float represented by the String, or null if it could not be
* parsed.
*/ */
public static Float parseFloat(String str) { public static Float parseFloat(final String str) {
if (null != str) { if (null != str) {
try { try {
return new Float(Float.parseFloat(str.trim())); return new Float(Float.parseFloat(str.trim()));
} catch (Exception e) { } catch (final Exception e) {
// :IGNORE: // :IGNORE:
} }
} }
return null; return null;
} }
/** /**
* Parse a float from a String, with a default value * Parse a float from a String, with a default value
* *
@ -83,22 +83,22 @@ public class NumberParser {
* @param def the value to return if the String cannot be parsed * @param def the value to return if the String cannot be parsed
* @return * @return
*/ */
public static float parseFloat(String str, float def) { public static float parseFloat(final String str, final float def) {
Float result = parseFloat(str); final Float result = parseFloat(str);
return (result == null) ? def : result.floatValue(); return result == null ? def : result.floatValue();
} }
/** /**
* Parses a long out of a string. * Parses a long out of a string.
* *
* @param str string to parse for a long. * @param str string to parse for a long.
* @param def default value to return if it is not possible to parse the the string. * @param def default value to return if it is not possible to parse the the
* string.
* @return the long represented by the given string, or the default. * @return the long represented by the given string, or the default.
*/ */
public static long parseLong(String str, long def) { public static long parseLong(final String str, final long def) {
Long ret = parseLong(str); final Long ret = parseLong(str);
return (null == ret) ? def : ret.longValue(); return null == ret ? def : ret.longValue();
} }
} }

View file

@ -16,127 +16,139 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.sun.syndication.io.DelegatingModuleGenerator; import com.sun.syndication.io.DelegatingModuleGenerator;
import com.sun.syndication.io.DelegatingModuleParser; import com.sun.syndication.io.DelegatingModuleParser;
import com.sun.syndication.io.WireFeedGenerator; import com.sun.syndication.io.WireFeedGenerator;
import com.sun.syndication.io.WireFeedParser; import com.sun.syndication.io.WireFeedParser;
import java.util.*;
/** /**
* <p> * <p>
*
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public abstract class PluginManager { public abstract class PluginManager {
private String[] _propertyValues; private final String[] _propertyValues;
private Map _pluginsMap; private Map _pluginsMap;
private List _pluginsList; private List _pluginsList;
private List _keys; private final List _keys;
private WireFeedParser _parentParser; private final WireFeedParser _parentParser;
private WireFeedGenerator _parentGenerator; private final WireFeedGenerator _parentGenerator;
/** /**
* Creates a PluginManager * Creates a PluginManager
* <p> * <p>
*
* @param propertyKey property key defining the plugins classes * @param propertyKey property key defining the plugins classes
* *
*/ */
protected PluginManager(String propertyKey) { protected PluginManager(final String propertyKey) {
this(propertyKey, null, null); this(propertyKey, null, null);
} }
protected PluginManager(String propertyKey, WireFeedParser parentParser, protected PluginManager(final String propertyKey, final WireFeedParser parentParser, final WireFeedGenerator parentGenerator) {
WireFeedGenerator parentGenerator) this._parentParser = parentParser;
{ this._parentGenerator = parentGenerator;
_parentParser = parentParser; this._propertyValues = PropertiesLoader.getPropertiesLoader().getTokenizedProperty(propertyKey, ", ");
_parentGenerator = parentGenerator;
_propertyValues = PropertiesLoader.getPropertiesLoader().getTokenizedProperty(propertyKey,", ");
loadPlugins(); loadPlugins();
_pluginsMap = Collections.unmodifiableMap(_pluginsMap); this._pluginsMap = Collections.unmodifiableMap(this._pluginsMap);
_pluginsList = Collections.unmodifiableList(_pluginsList); this._pluginsList = Collections.unmodifiableList(this._pluginsList);
_keys = Collections.unmodifiableList(new ArrayList(_pluginsMap.keySet())); this._keys = Collections.unmodifiableList(new ArrayList(this._pluginsMap.keySet()));
} }
protected abstract String getKey(Object obj); protected abstract String getKey(Object obj);
protected List getKeys() { protected List getKeys() {
return _keys; return this._keys;
} }
protected List getPlugins() { protected List getPlugins() {
return _pluginsList; return this._pluginsList;
} }
protected Map getPluginMap() { protected Map getPluginMap() {
return _pluginsMap; return this._pluginsMap;
} }
protected Object getPlugin(String key) { protected Object getPlugin(final String key) {
return _pluginsMap.get(key); return this._pluginsMap.get(key);
} }
// PRIVATE - LOADER PART // PRIVATE - LOADER PART
private void loadPlugins() { private void loadPlugins() {
List finalPluginsList = new ArrayList(); final List finalPluginsList = new ArrayList();
_pluginsList = new ArrayList(); this._pluginsList = new ArrayList();
_pluginsMap = new HashMap(); this._pluginsMap = new HashMap();
String className = null; String className = null;
try { try {
Class[] classes = getClasses(); final Class[] classes = getClasses();
for (int i=0;i<classes.length;i++) { for (final Class classe : classes) {
className = classes[i].getName(); className = classe.getName();
Object plugin = classes[i].newInstance(); final Object plugin = classe.newInstance();
if (plugin instanceof DelegatingModuleParser) { if (plugin instanceof DelegatingModuleParser) {
((DelegatingModuleParser) plugin).setFeedParser(_parentParser); ((DelegatingModuleParser) plugin).setFeedParser(this._parentParser);
} }
if (plugin instanceof DelegatingModuleGenerator) { if (plugin instanceof DelegatingModuleGenerator) {
((DelegatingModuleGenerator) plugin).setFeedGenerator(_parentGenerator); ((DelegatingModuleGenerator) plugin).setFeedGenerator(this._parentGenerator);
} }
_pluginsMap.put(getKey(plugin), plugin); this._pluginsMap.put(getKey(plugin), plugin);
_pluginsList.add(plugin); // to preserve the order of definition in the rome.properties files this._pluginsList.add(plugin); // to preserve the order of
// definition
// in the rome.properties files
} }
Iterator i = _pluginsMap.values().iterator(); Iterator i = this._pluginsMap.values().iterator();
while (i.hasNext()) { while (i.hasNext()) {
finalPluginsList.add(i.next()); // to remove overridden plugin impls finalPluginsList.add(i.next()); // to remove overridden plugin
// impls
} }
i = _pluginsList.iterator(); i = this._pluginsList.iterator();
while (i.hasNext()) { while (i.hasNext()) {
Object plugin = i.next(); final Object plugin = i.next();
if (!finalPluginsList.contains(plugin)) { if (!finalPluginsList.contains(plugin)) {
i.remove(); i.remove();
} }
} }
} } catch (final Exception ex) {
catch (Exception ex) { throw new RuntimeException("could not instantiate plugin " + className, ex);
throw new RuntimeException("could not instantiate plugin "+className,ex); } catch (final ExceptionInInitializerError er) {
}catch (ExceptionInInitializerError er) { throw new RuntimeException("could not instantiate plugin " + className, er);
throw new RuntimeException("could not instantiate plugin "+className,er);
} }
} }
/** /**
* Loads and returns the classes defined in the properties files. If the system property "rome.pluginmanager.useloadclass" is * Loads and returns the classes defined in the properties files. If the
* set to true then classLoader.loadClass will be used to load classes (instead of Class.forName). This is designed to improve * system property "rome.pluginmanager.useloadclass" is set to true then
* OSGi compatibility. Further information can be found in https://rome.dev.java.net/issues/show_bug.cgi?id=118 * classLoader.loadClass will be used to load classes (instead of
* Class.forName). This is designed to improve OSGi compatibility. Further
* information can be found in
* https://rome.dev.java.net/issues/show_bug.cgi?id=118
* <p> * <p>
*
* @return array containing the classes defined in the properties files. * @return array containing the classes defined in the properties files.
* @throws java.lang.ClassNotFoundException thrown if one of the classes defined in the properties file cannot be loaded * @throws java.lang.ClassNotFoundException thrown if one of the classes
* and hard failure is ON. * defined in the properties file cannot be loaded and hard
* * failure is ON.
*
*/ */
private Class[] getClasses() throws ClassNotFoundException { private Class[] getClasses() throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
List classes = new ArrayList(); final List classes = new ArrayList();
boolean useLoadClass = Boolean.valueOf(System.getProperty("rome.pluginmanager.useloadclass", "false")).booleanValue(); final boolean useLoadClass = Boolean.valueOf(System.getProperty("rome.pluginmanager.useloadclass", "false")).booleanValue();
for (int i = 0; i <_propertyValues.length; i++) { for (final String _propertyValue : this._propertyValues) {
Class mClass = (useLoadClass ? classLoader.loadClass(_propertyValues[i]) : Class.forName(_propertyValues[i], true, classLoader)); final Class mClass = useLoadClass ? classLoader.loadClass(_propertyValue) : Class.forName(_propertyValue, true, classLoader);
classes.add(mClass); classes.add(mClass);
} }
Class[] array = new Class[classes.size()]; final Class[] array = new Class[classes.size()];
classes.toArray(array); classes.toArray(array);
return array; return array;
} }

View file

@ -3,50 +3,52 @@ package com.sun.syndication.io.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
/** /**
* Properties loader that aggregates a master properties file and several extra properties files, * Properties loader that aggregates a master properties file and several extra
* all from the current classpath. * properties files, all from the current classpath.
* <P> * <P>
* The master properties file has to be in a distinct location than the extra properties files. * The master properties file has to be in a distinct location than the extra
* First the master properties file is loaded, then all the extra properties files in their order * properties files. First the master properties file is loaded, then all the
* of appearance in the classpath. * extra properties files in their order of appearance in the classpath.
* <P> * <P>
* Current use cases (plugin manager for parsers/converters/generators for feeds and modules * Current use cases (plugin manager for parsers/converters/generators for feeds
* and date formats) assume properties are list of tokens, that why the only method to get * and modules and date formats) assume properties are list of tokens, that why
* property values is the getTokenizedProperty(). * the only method to get property values is the getTokenizedProperty().
* <p> * <p>
* *
* @author Alejandro Abdelnur * @author Alejandro Abdelnur
* *
*/ */
public class PropertiesLoader { public class PropertiesLoader {
private static final String MASTER_PLUGIN_FILE = "com/sun/syndication/rome.properties"; private static final String MASTER_PLUGIN_FILE = "com/sun/syndication/rome.properties";
private static final String EXTRA_PLUGIN_FILE = "rome.properties"; private static final String EXTRA_PLUGIN_FILE = "rome.properties";
private static Map<ClassLoader, PropertiesLoader> clMap = new WeakHashMap<ClassLoader, PropertiesLoader>();
private static Map<ClassLoader, PropertiesLoader> clMap =
new WeakHashMap<ClassLoader, PropertiesLoader>();
/** /**
* Returns the PropertiesLoader singleton used by ROME to load plugin components. * Returns the PropertiesLoader singleton used by ROME to load plugin
* * components.
*
* @return PropertiesLoader singleton. * @return PropertiesLoader singleton.
* *
*/ */
public static PropertiesLoader getPropertiesLoader() { public static PropertiesLoader getPropertiesLoader() {
synchronized(PropertiesLoader.class) { synchronized (PropertiesLoader.class) {
PropertiesLoader loader = (PropertiesLoader) PropertiesLoader loader = clMap.get(Thread.currentThread().getContextClassLoader());
clMap.get(Thread.currentThread().getContextClassLoader());
if (loader == null) { if (loader == null) {
try { try {
loader = new PropertiesLoader(MASTER_PLUGIN_FILE, EXTRA_PLUGIN_FILE); loader = new PropertiesLoader(MASTER_PLUGIN_FILE, EXTRA_PLUGIN_FILE);
clMap.put(Thread.currentThread().getContextClassLoader(), loader); clMap.put(Thread.currentThread().getContextClassLoader(), loader);
} } catch (final IOException ex) {
catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
@ -54,100 +56,104 @@ public class PropertiesLoader {
} }
} }
private Properties[] _properties; private final Properties[] _properties;
/** /**
* Creates a PropertiesLoader. * Creates a PropertiesLoader.
* <p> * <p>
*
* @param masterFileLocation master file location, there must be only one. * @param masterFileLocation master file location, there must be only one.
* @param extraFileLocation extra file location, there may be many. * @param extraFileLocation extra file location, there may be many.
* @throws IOException thrown if one of the properties file could not be read. * @throws IOException thrown if one of the properties file could not be
* * read.
*
*/ */
private PropertiesLoader(String masterFileLocation,String extraFileLocation) throws IOException { private PropertiesLoader(final String masterFileLocation, final String extraFileLocation) throws IOException {
List<Properties> propertiesList = new ArrayList<Properties>(); final List<Properties> propertiesList = new ArrayList<Properties>();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try { try {
InputStream is = classLoader.getResourceAsStream(masterFileLocation); final InputStream is = classLoader.getResourceAsStream(masterFileLocation);
Properties p = new Properties(); final Properties p = new Properties();
p.load(is); p.load(is);
is.close(); is.close();
propertiesList.add(p); propertiesList.add(p);
} } catch (final IOException ioex) {
catch (IOException ioex) { final IOException ex = new IOException("could not load ROME master plugins file [" + masterFileLocation + "], " + ioex.getMessage());
IOException ex = new IOException("could not load ROME master plugins file ["+masterFileLocation+"], "+
ioex.getMessage());
ex.setStackTrace(ioex.getStackTrace()); ex.setStackTrace(ioex.getStackTrace());
throw ex; throw ex;
} }
Enumeration<URL> urls = classLoader.getResources(extraFileLocation); final Enumeration<URL> urls = classLoader.getResources(extraFileLocation);
while (urls.hasMoreElements()) { while (urls.hasMoreElements()) {
URL url = (URL) urls.nextElement(); final URL url = urls.nextElement();
Properties p = new Properties(); final Properties p = new Properties();
try { try {
InputStream is = url.openStream(); final InputStream is = url.openStream();
p.load(is); p.load(is);
is.close(); is.close();
} } catch (final IOException ioex) {
catch (IOException ioex) { final IOException ex = new IOException("could not load ROME extensions plugins file [" + url.toString() + "], " + ioex.getMessage());
IOException ex = new IOException("could not load ROME extensions plugins file ["+url.toString()+"], "+
ioex.getMessage());
ex.setStackTrace(ioex.getStackTrace()); ex.setStackTrace(ioex.getStackTrace());
throw ex; throw ex;
} }
propertiesList.add(p); propertiesList.add(p);
} }
_properties = new Properties[propertiesList.size()]; this._properties = new Properties[propertiesList.size()];
propertiesList.toArray(_properties); propertiesList.toArray(this._properties);
} }
/** /**
* Returns an array of tokenized values stored under a property key in all properties files. * Returns an array of tokenized values stored under a property key in all
* If the master file has this property its tokens will be the first ones in the array. * properties files. If the master file has this property its tokens will be
* the first ones in the array.
* <p> * <p>
*
* @param key property key to retrieve values * @param key property key to retrieve values
* @param separator String with all separator characters to tokenize from the values in all * @param separator String with all separator characters to tokenize from
* properties files. * the values in all properties files.
* @return all the tokens for the given property key from all the properties files. * @return all the tokens for the given property key from all the properties
* * files.
*
*/ */
public String[] getTokenizedProperty(String key,String separator) { public String[] getTokenizedProperty(final String key, final String separator) {
List<String> entriesList = new ArrayList<String>(); final List<String> entriesList = new ArrayList<String>();
for (int i=0;i<_properties.length;i++) { for (final Properties _propertie : this._properties) {
String values = _properties[i].getProperty(key); final String values = _propertie.getProperty(key);
if (values!=null) { if (values != null) {
StringTokenizer st = new StringTokenizer(values,separator); final StringTokenizer st = new StringTokenizer(values, separator);
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
String token = st.nextToken(); final String token = st.nextToken();
entriesList.add(token); entriesList.add(token);
} }
} }
} }
String[] entries = new String[entriesList.size()]; final String[] entries = new String[entriesList.size()];
entriesList.toArray(entries); entriesList.toArray(entries);
return entries; return entries;
} }
/** /**
* Returns an array of values stored under a property key in all properties files. * Returns an array of values stored under a property key in all properties
* If the master file has this property it will be the first ones in the array. * files. If the master file has this property it will be the first ones in
* the array.
* <p> * <p>
*
* @param key property key to retrieve values * @param key property key to retrieve values
* @return all the values for the given property key from all the properties files. * @return all the values for the given property key from all the properties
* * files.
*
*/ */
public String[] getProperty(String key) { public String[] getProperty(final String key) {
List<String> entriesList = new ArrayList<String>(); final List<String> entriesList = new ArrayList<String>();
for (int i=0;i<_properties.length;i++) { for (final Properties _propertie : this._properties) {
String values = _properties[i].getProperty(key); final String values = _propertie.getProperty(key);
if (values!=null) { if (values != null) {
entriesList.add(values); entriesList.add(values);
} }
} }
String[] entries = new String[entriesList.size()]; final String[] entries = new String[entriesList.size()];
entriesList.toArray(entries); entriesList.toArray(entries);
return entries; return entries;
} }

View file

@ -16,20 +16,23 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import com.sun.syndication.feed.WireFeed; import java.util.List;
import com.sun.syndication.feed.rss.*;
import com.sun.syndication.io.FeedException;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import java.util.List; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Image;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.rss.TextInput;
import com.sun.syndication.io.FeedException;
/** /**
* Feed Generator for RSS 0.90 * Feed Generator for RSS 0.90
* <p/> * <p/>
* *
* @author Elaine Chien * @author Elaine Chien
*/ */
public class RSS090Generator extends BaseWireFeedGenerator { public class RSS090Generator extends BaseWireFeedGenerator {
@ -46,14 +49,15 @@ public class RSS090Generator extends BaseWireFeedGenerator {
this("rss_0.9"); this("rss_0.9");
} }
protected RSS090Generator(String type) { protected RSS090Generator(final String type) {
super(type); super(type);
} }
public Document generate(WireFeed feed) throws FeedException { @Override
Channel channel = (Channel)feed; public Document generate(final WireFeed feed) throws FeedException {
Element root = createRootElement(channel); final Channel channel = (Channel) feed;
populateFeed(channel,root); final Element root = createRootElement(channel);
populateFeed(channel, root);
purgeUnusedNamespaceDeclarations(root); purgeUnusedNamespaceDeclarations(root);
return createDocument(root); return createDocument(root);
} }
@ -70,12 +74,12 @@ public class RSS090Generator extends BaseWireFeedGenerator {
return CONTENT_NS; return CONTENT_NS;
} }
protected Document createDocument(Element root) { protected Document createDocument(final Element root) {
return new Document(root); return new Document(root);
} }
protected Element createRootElement(Channel channel) { protected Element createRootElement(final Channel channel) {
Element root = new Element("RDF",getRDFNamespace()); final Element root = new Element("RDF", getRDFNamespace());
root.addNamespaceDeclaration(getFeedNamespace()); root.addNamespaceDeclaration(getFeedNamespace());
root.addNamespaceDeclaration(getRDFNamespace()); root.addNamespaceDeclaration(getRDFNamespace());
root.addNamespaceDeclaration(getContentNamespace()); root.addNamespaceDeclaration(getContentNamespace());
@ -83,89 +87,88 @@ public class RSS090Generator extends BaseWireFeedGenerator {
return root; return root;
} }
protected void populateFeed(Channel channel, Element parent) throws FeedException { protected void populateFeed(final Channel channel, final Element parent) throws FeedException {
addChannel(channel,parent); addChannel(channel, parent);
addImage(channel,parent); addImage(channel, parent);
addTextInput(channel,parent); addTextInput(channel, parent);
addItems(channel,parent); addItems(channel, parent);
generateForeignMarkup(parent, (List<Element>)channel.getForeignMarkup()); generateForeignMarkup(parent, channel.getForeignMarkup());
} }
protected void addChannel(Channel channel,Element parent) throws FeedException { protected void addChannel(final Channel channel, final Element parent) throws FeedException {
Element eChannel = new Element("channel", getFeedNamespace()); final Element eChannel = new Element("channel", getFeedNamespace());
populateChannel(channel,eChannel); populateChannel(channel, eChannel);
checkChannelConstraints(eChannel); checkChannelConstraints(eChannel);
parent.addContent(eChannel); parent.addContent(eChannel);
generateFeedModules(channel.getModules(),eChannel); generateFeedModules(channel.getModules(), eChannel);
} }
/** /**
* Populates the given channel with parsed data from the ROME element that holds the * Populates the given channel with parsed data from the ROME element that
* channel data. * holds the channel data.
* *
* @param channel the channel into which parsed data will be added. * @param channel the channel into which parsed data will be added.
* @param eChannel the XML element that holds the data for the channel. * @param eChannel the XML element that holds the data for the channel.
*/ */
protected void populateChannel(Channel channel,Element eChannel) { protected void populateChannel(final Channel channel, final Element eChannel) {
String title = channel.getTitle(); final String title = channel.getTitle();
if (title!=null) { if (title != null) {
eChannel.addContent(generateSimpleElement("title",title)); eChannel.addContent(generateSimpleElement("title", title));
} }
String link = channel.getLink(); final String link = channel.getLink();
if (link!=null) { if (link != null) {
eChannel.addContent(generateSimpleElement("link",link)); eChannel.addContent(generateSimpleElement("link", link));
} }
String description = channel.getDescription(); final String description = channel.getDescription();
if (description!=null) { if (description != null) {
eChannel.addContent(generateSimpleElement("description",description)); eChannel.addContent(generateSimpleElement("description", description));
} }
} }
// maxLen == -1 means unlimited. // maxLen == -1 means unlimited.
protected void checkNotNullAndLength(Element parent, String childName, int minLen, int maxLen) throws FeedException { protected void checkNotNullAndLength(final Element parent, final String childName, final int minLen, final int maxLen) throws FeedException {
Element child = parent.getChild(childName,getFeedNamespace()); final Element child = parent.getChild(childName, getFeedNamespace());
if (child == null) { if (child == null) {
throw new FeedException("Invalid "+getType()+" feed, missing "+parent.getName()+" "+childName); throw new FeedException("Invalid " + getType() + " feed, missing " + parent.getName() + " " + childName);
} }
checkLength(parent,childName,minLen,maxLen); checkLength(parent, childName, minLen, maxLen);
} }
// maxLen == -1 means unlimited. // maxLen == -1 means unlimited.
protected void checkLength(Element parent, String childName, int minLen, int maxLen) throws FeedException { protected void checkLength(final Element parent, final String childName, final int minLen, final int maxLen) throws FeedException {
Element child = parent.getChild(childName,getFeedNamespace()); final Element child = parent.getChild(childName, getFeedNamespace());
if (child != null) { if (child != null) {
if (minLen>0 && child.getText().length()<minLen) { if (minLen > 0 && child.getText().length() < minLen) {
throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "short of "+minLen+" length"); throw new FeedException("Invalid " + getType() + " feed, " + parent.getName() + " " + childName + "short of " + minLen + " length");
} }
if (maxLen>-1 && child.getText().length()>maxLen) { if (maxLen > -1 && child.getText().length() > maxLen) {
throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "exceeds "+maxLen+" length"); throw new FeedException("Invalid " + getType() + " feed, " + parent.getName() + " " + childName + "exceeds " + maxLen + " length");
} }
} }
} }
protected void addImage(final Channel channel, final Element parent) throws FeedException {
protected void addImage(Channel channel,Element parent) throws FeedException { final Image image = channel.getImage();
Image image = channel.getImage(); if (image != null) {
if (image!=null) { final Element eImage = new Element("image", getFeedNamespace());
Element eImage = new Element("image", getFeedNamespace()); populateImage(image, eImage);
populateImage(image,eImage);
checkImageConstraints(eImage); checkImageConstraints(eImage);
parent.addContent(eImage); parent.addContent(eImage);
} }
} }
protected void populateImage(Image image,Element eImage) { protected void populateImage(final Image image, final Element eImage) {
String title = image.getTitle(); final String title = image.getTitle();
if (title!=null) { if (title != null) {
eImage.addContent(generateSimpleElement("title",title)); eImage.addContent(generateSimpleElement("title", title));
} }
String url = image.getUrl(); final String url = image.getUrl();
if (url!=null) { if (url != null) {
eImage.addContent(generateSimpleElement("url",url)); eImage.addContent(generateSimpleElement("url", url));
} }
String link = image.getLink(); final String link = image.getLink();
if (link!=null) { if (link != null) {
eImage.addContent(generateSimpleElement("link",link)); eImage.addContent(generateSimpleElement("link", link));
} }
} }
@ -174,98 +177,98 @@ public class RSS090Generator extends BaseWireFeedGenerator {
return "textInput"; return "textInput";
} }
protected void addTextInput(Channel channel,Element parent) throws FeedException { protected void addTextInput(final Channel channel, final Element parent) throws FeedException {
TextInput textInput = channel.getTextInput(); final TextInput textInput = channel.getTextInput();
if (textInput!=null) { if (textInput != null) {
Element eTextInput = new Element(getTextInputLabel(), getFeedNamespace()); final Element eTextInput = new Element(getTextInputLabel(), getFeedNamespace());
populateTextInput(textInput,eTextInput); populateTextInput(textInput, eTextInput);
checkTextInputConstraints(eTextInput); checkTextInputConstraints(eTextInput);
parent.addContent(eTextInput); parent.addContent(eTextInput);
} }
} }
protected void populateTextInput(TextInput textInput,Element eTextInput) { protected void populateTextInput(final TextInput textInput, final Element eTextInput) {
String title = textInput.getTitle(); final String title = textInput.getTitle();
if (title!=null) { if (title != null) {
eTextInput.addContent(generateSimpleElement("title",title)); eTextInput.addContent(generateSimpleElement("title", title));
} }
String description = textInput.getDescription(); final String description = textInput.getDescription();
if (description!=null) { if (description != null) {
eTextInput.addContent(generateSimpleElement("description",description)); eTextInput.addContent(generateSimpleElement("description", description));
} }
String name = textInput.getName(); final String name = textInput.getName();
if (name!=null) { if (name != null) {
eTextInput.addContent(generateSimpleElement("name",name)); eTextInput.addContent(generateSimpleElement("name", name));
} }
String link = textInput.getLink(); final String link = textInput.getLink();
if (link!=null) { if (link != null) {
eTextInput.addContent(generateSimpleElement("link",link)); eTextInput.addContent(generateSimpleElement("link", link));
} }
} }
protected void addItems(Channel channel,Element parent) throws FeedException { protected void addItems(final Channel channel, final Element parent) throws FeedException {
List<Item> items = channel.getItems(); final List<Item> items = channel.getItems();
for (int i=0;i<items.size();i++) { for (int i = 0; i < items.size(); i++) {
addItem((Item)items.get(i),parent, i); addItem(items.get(i), parent, i);
} }
checkItemsConstraints(parent); checkItemsConstraints(parent);
} }
protected void addItem(Item item, Element parent, int index) throws FeedException { protected void addItem(final Item item, final Element parent, final int index) throws FeedException {
Element eItem = new Element("item", getFeedNamespace()); final Element eItem = new Element("item", getFeedNamespace());
populateItem(item,eItem, index); populateItem(item, eItem, index);
checkItemConstraints(eItem); checkItemConstraints(eItem);
generateItemModules(item.getModules(),eItem); generateItemModules(item.getModules(), eItem);
parent.addContent(eItem); parent.addContent(eItem);
} }
protected void populateItem(Item item, Element eItem, int index) { protected void populateItem(final Item item, final Element eItem, final int index) {
String title = item.getTitle(); final String title = item.getTitle();
if (title!=null) { if (title != null) {
eItem.addContent(generateSimpleElement("title",title)); eItem.addContent(generateSimpleElement("title", title));
} }
String link = item.getLink(); final String link = item.getLink();
if (link!=null) { if (link != null) {
eItem.addContent(generateSimpleElement("link",link)); eItem.addContent(generateSimpleElement("link", link));
} }
generateForeignMarkup(eItem, (List<Element>)item.getForeignMarkup()); generateForeignMarkup(eItem, item.getForeignMarkup());
} }
protected Element generateSimpleElement(String name, String value) { protected Element generateSimpleElement(final String name, final String value) {
Element element = new Element(name, getFeedNamespace()); final Element element = new Element(name, getFeedNamespace());
element.addContent(value); element.addContent(value);
return element; return element;
} }
protected void checkChannelConstraints(Element eChannel) throws FeedException { protected void checkChannelConstraints(final Element eChannel) throws FeedException {
checkNotNullAndLength(eChannel,"title", 0, 40); checkNotNullAndLength(eChannel, "title", 0, 40);
checkNotNullAndLength(eChannel,"description", 0, 500); checkNotNullAndLength(eChannel, "description", 0, 500);
checkNotNullAndLength(eChannel,"link", 0, 500); checkNotNullAndLength(eChannel, "link", 0, 500);
} }
protected void checkImageConstraints(Element eImage) throws FeedException { protected void checkImageConstraints(final Element eImage) throws FeedException {
checkNotNullAndLength(eImage,"title", 0, 40); checkNotNullAndLength(eImage, "title", 0, 40);
checkNotNullAndLength(eImage,"url", 0, 500); checkNotNullAndLength(eImage, "url", 0, 500);
checkNotNullAndLength(eImage,"link", 0, 500); checkNotNullAndLength(eImage, "link", 0, 500);
} }
protected void checkTextInputConstraints(Element eTextInput) throws FeedException { protected void checkTextInputConstraints(final Element eTextInput) throws FeedException {
checkNotNullAndLength(eTextInput,"title", 0, 40); checkNotNullAndLength(eTextInput, "title", 0, 40);
checkNotNullAndLength(eTextInput,"description", 0, 100); checkNotNullAndLength(eTextInput, "description", 0, 100);
checkNotNullAndLength(eTextInput,"name", 0, 500); checkNotNullAndLength(eTextInput, "name", 0, 500);
checkNotNullAndLength(eTextInput,"link", 0, 500); checkNotNullAndLength(eTextInput, "link", 0, 500);
} }
protected void checkItemsConstraints(Element parent) throws FeedException { protected void checkItemsConstraints(final Element parent) throws FeedException {
int count = parent.getChildren("item",getFeedNamespace()).size(); final int count = parent.getChildren("item", getFeedNamespace()).size();
if (count<1 || count>15) { if (count < 1 || count > 15) {
throw new FeedException("Invalid "+getType()+" feed, item count is "+count+" it must be between 1 an 15"); throw new FeedException("Invalid " + getType() + " feed, item count is " + count + " it must be between 1 an 15");
} }
} }
protected void checkItemConstraints(Element eItem) throws FeedException { protected void checkItemConstraints(final Element eItem) throws FeedException {
checkNotNullAndLength(eItem,"title", 0, 100); checkNotNullAndLength(eItem, "title", 0, 100);
checkNotNullAndLength(eItem,"link", 0, 500); checkNotNullAndLength(eItem, "link", 0, 500);
} }
} }

View file

@ -16,6 +16,15 @@
*/ */
package com.sun.syndication.io.impl; package com.sun.syndication.io.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.rss.Channel; import com.sun.syndication.feed.rss.Channel;
@ -23,14 +32,6 @@ import com.sun.syndication.feed.rss.Image;
import com.sun.syndication.feed.rss.Item; import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.rss.TextInput; import com.sun.syndication.feed.rss.TextInput;
import com.sun.syndication.io.FeedException; import com.sun.syndication.io.FeedException;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/** /**
*/ */
@ -39,35 +40,34 @@ public class RSS090Parser extends BaseWireFeedParser {
private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/"; private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/";
private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/"; private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI); private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI); private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
private static final Namespace CONTENT_NS = Namespace.getNamespace(CONTENT_URI); private static final Namespace CONTENT_NS = Namespace.getNamespace(CONTENT_URI);
public RSS090Parser() { public RSS090Parser() {
this("rss_0.9", RSS_NS); this("rss_0.9", RSS_NS);
} }
protected RSS090Parser(String type, Namespace ns) { protected RSS090Parser(final String type, final Namespace ns) {
super(type, ns); super(type, ns);
} }
public boolean isMyType(Document document) { @Override
public boolean isMyType(final Document document) {
boolean ok = false; boolean ok = false;
Element rssRoot = document.getRootElement(); final Element rssRoot = document.getRootElement();
Namespace defaultNS = rssRoot.getNamespace(); final Namespace defaultNS = rssRoot.getNamespace();
List<Namespace> additionalNSs = rssRoot.getAdditionalNamespaces(); final List<Namespace> additionalNSs = rssRoot.getAdditionalNamespaces();
ok = defaultNS!=null && defaultNS.equals(getRDFNamespace()); ok = defaultNS != null && defaultNS.equals(getRDFNamespace());
if (ok) { if (ok) {
if (additionalNSs==null) { if (additionalNSs == null) {
ok = false; ok = false;
} } else {
else {
ok = false; ok = false;
for (int i=0;!ok && i<additionalNSs.size();i++) { for (int i = 0; !ok && i < additionalNSs.size(); i++) {
ok = getRSSNamespace().equals(additionalNSs.get(i)); ok = getRSSNamespace().equals(additionalNSs.get(i));
} }
} }
@ -75,29 +75,33 @@ public class RSS090Parser extends BaseWireFeedParser {
return ok; return ok;
} }
public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException { @Override
public WireFeed parse(final Document document, final boolean validate) throws IllegalArgumentException, FeedException {
if (validate) { if (validate) {
validateFeed(document); validateFeed(document);
} }
Element rssRoot = document.getRootElement(); final Element rssRoot = document.getRootElement();
return parseChannel(rssRoot); return parseChannel(rssRoot);
} }
protected void validateFeed(Document document) throws FeedException { protected void validateFeed(final Document document) throws FeedException {
// TBD // TBD
// here we have to validate the Feed against a schema or whatever // here we have to validate the Feed against a schema or whatever
// not sure how to do it // not sure how to do it
// one posibility would be to inject our own schema for the feed (they don't exist out there) // one posibility would be to inject our own schema for the feed (they
// to the document, produce an ouput and attempt to parse it again with validation turned on. // don't exist out there)
// to the document, produce an ouput and attempt to parse it again with
// validation turned on.
// otherwise will have to check the document elements by hand. // otherwise will have to check the document elements by hand.
} }
/** /**
* Returns the namespace used by RSS elements in document of the RSS version the parser supports. * Returns the namespace used by RSS elements in document of the RSS version
* the parser supports.
* <P> * <P>
* This implementation returns the EMTPY namespace. * This implementation returns the EMTPY namespace.
* <p> * <p>
* *
* @return returns the EMPTY namespace. * @return returns the EMPTY namespace.
*/ */
protected Namespace getRSSNamespace() { protected Namespace getRSSNamespace() {
@ -105,11 +109,12 @@ public class RSS090Parser extends BaseWireFeedParser {
} }
/** /**
* Returns the namespace used by RDF elements in document of the RSS version the parser supports. * Returns the namespace used by RDF elements in document of the RSS version
* the parser supports.
* <P> * <P>
* This implementation returns the EMTPY namespace. * This implementation returns the EMTPY namespace.
* <p> * <p>
* *
* @return returns the EMPTY namespace. * @return returns the EMPTY namespace.
*/ */
protected Namespace getRDFNamespace() { protected Namespace getRDFNamespace() {
@ -121,7 +126,7 @@ public class RSS090Parser extends BaseWireFeedParser {
* <P> * <P>
* This implementation returns the EMTPY namespace. * This implementation returns the EMTPY namespace.
* <p> * <p>
* *
* @return returns the EMPTY namespace. * @return returns the EMPTY namespace.
*/ */
protected Namespace getContentNamespace() { protected Namespace getContentNamespace() {
@ -131,30 +136,31 @@ public class RSS090Parser extends BaseWireFeedParser {
/** /**
* Parses the root element of an RSS document into a Channel bean. * Parses the root element of an RSS document into a Channel bean.
* <p/> * <p/>
* It reads title, link and description and delegates to parseImage, parseItems * It reads title, link and description and delegates to parseImage,
* and parseTextInput. This delegation always passes the root element of the RSS * parseItems and parseTextInput. This delegation always passes the root
* document as different RSS version may have this information in different parts * element of the RSS document as different RSS version may have this
* of the XML tree (no assumptions made thanks to the specs variaty) * information in different parts of the XML tree (no assumptions made
* thanks to the specs variaty)
* <p/> * <p/>
* *
* @param rssRoot the root element of the RSS document to parse. * @param rssRoot the root element of the RSS document to parse.
* @return the parsed Channel bean. * @return the parsed Channel bean.
*/ */
protected WireFeed parseChannel(Element rssRoot) { protected WireFeed parseChannel(final Element rssRoot) {
Element eChannel = rssRoot.getChild("channel", getRSSNamespace()); final Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
Channel channel = new Channel(getType()); final Channel channel = new Channel(getType());
Element e = eChannel.getChild("title",getRSSNamespace()); Element e = eChannel.getChild("title", getRSSNamespace());
if (e!=null) { if (e != null) {
channel.setTitle(e.getText()); channel.setTitle(e.getText());
} }
e = eChannel.getChild("link",getRSSNamespace()); e = eChannel.getChild("link", getRSSNamespace());
if (e!=null) { if (e != null) {
channel.setLink(e.getText()); channel.setLink(e.getText());
} }
e = eChannel.getChild("description",getRSSNamespace()); e = eChannel.getChild("description", getRSSNamespace());
if (e!=null) { if (e != null) {
channel.setDescription(e.getText()); channel.setDescription(e.getText());
} }
@ -162,13 +168,13 @@ public class RSS090Parser extends BaseWireFeedParser {
channel.setTextInput(parseTextInput(rssRoot)); channel.setTextInput(parseTextInput(rssRoot));
// Unfortunately Microsoft's SSE extension has a special case of // Unfortunately Microsoft's SSE extension has a special case of
// effectively putting the sharing channel module inside the RSS tag // effectively putting the sharing channel module inside the RSS tag
// and not inside the channel itself. So we also need to look for // and not inside the channel itself. So we also need to look for
// channel modules from the root RSS element. // channel modules from the root RSS element.
List<Module> allFeedModules = new ArrayList<Module>(); final List<Module> allFeedModules = new ArrayList<Module>();
List<Module> rootModules = parseFeedModules(rssRoot); final List<Module> rootModules = parseFeedModules(rssRoot);
List<Module> channelModules = parseFeedModules(eChannel); final List<Module> channelModules = parseFeedModules(eChannel);
if (rootModules != null) { if (rootModules != null) {
allFeedModules.addAll(rootModules); allFeedModules.addAll(rootModules);
} }
@ -178,67 +184,69 @@ public class RSS090Parser extends BaseWireFeedParser {
channel.setModules(allFeedModules); channel.setModules(allFeedModules);
channel.setItems(parseItems(rssRoot)); channel.setItems(parseItems(rssRoot));
List<Element> foreignMarkup = final List<Element> foreignMarkup = extractForeignMarkup(eChannel, channel, getRSSNamespace());
extractForeignMarkup(eChannel, channel, getRSSNamespace());
if (foreignMarkup.size() > 0) { if (foreignMarkup.size() > 0) {
channel.setForeignMarkup(foreignMarkup); channel.setForeignMarkup(foreignMarkup);
} }
return channel; return channel;
} }
/** /**
* This method exists because RSS0.90 and RSS1.0 have the 'item' elements under the root elemment. * This method exists because RSS0.90 and RSS1.0 have the 'item' elements
* And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and RSS2.0 have the item elements under the 'channel' element. * under the root elemment. And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and
* RSS2.0 have the item elements under the 'channel' element.
* <p/> * <p/>
*/ */
protected List<Element> getItems(Element rssRoot) { protected List<Element> getItems(final Element rssRoot) {
return rssRoot.getChildren("item",getRSSNamespace()); return rssRoot.getChildren("item", getRSSNamespace());
} }
/** /**
* This method exists because RSS0.90 and RSS1.0 have the 'image' element under the root elemment. * This method exists because RSS0.90 and RSS1.0 have the 'image' element
* And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and RSS2.0 have it under the 'channel' element. * under the root elemment. And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and
* RSS2.0 have it under the 'channel' element.
* <p/> * <p/>
*/ */
protected Element getImage(Element rssRoot) { protected Element getImage(final Element rssRoot) {
return rssRoot.getChild("image",getRSSNamespace()); return rssRoot.getChild("image", getRSSNamespace());
} }
/** /**
* This method exists because RSS0.90 and RSS1.0 have the 'textinput' element under the root elemment. * This method exists because RSS0.90 and RSS1.0 have the 'textinput'
* And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and RSS2.0 have it under the 'channel' element. * element under the root elemment. And RSS0.91, RSS0.02, RSS0.93, RSS0.94
* and RSS2.0 have it under the 'channel' element.
* <p/> * <p/>
*/ */
protected Element getTextInput(Element rssRoot) { protected Element getTextInput(final Element rssRoot) {
return rssRoot.getChild("textinput",getRSSNamespace()); return rssRoot.getChild("textinput", getRSSNamespace());
} }
/** /**
* Parses the root element of an RSS document looking for image information. * Parses the root element of an RSS document looking for image information.
* <p/> * <p/>
* It reads title and url out of the 'image' element. * It reads title and url out of the 'image' element.
* <p/> * <p/>
* *
* @param rssRoot the root element of the RSS document to parse for image information. * @param rssRoot the root element of the RSS document to parse for image
* information.
* @return the parsed image bean. * @return the parsed image bean.
*/ */
protected Image parseImage(Element rssRoot) { protected Image parseImage(final Element rssRoot) {
Image image = null; Image image = null;
Element eImage = getImage(rssRoot); final Element eImage = getImage(rssRoot);
if (eImage!=null) { if (eImage != null) {
image = new Image(); image = new Image();
Element e = eImage.getChild("title",getRSSNamespace()); Element e = eImage.getChild("title", getRSSNamespace());
if (e!=null) { if (e != null) {
image.setTitle(e.getText()); image.setTitle(e.getText());
} }
e = eImage.getChild("url",getRSSNamespace()); e = eImage.getChild("url", getRSSNamespace());
if (e!=null) { if (e != null) {
image.setUrl(e.getText()); image.setUrl(e.getText());
} }
e = eImage.getChild("link",getRSSNamespace()); e = eImage.getChild("link", getRSSNamespace());
if (e!=null) { if (e != null) {
image.setLink(e.getText()); image.setLink(e.getText());
} }
} }
@ -246,22 +254,25 @@ public class RSS090Parser extends BaseWireFeedParser {
} }
/** /**
* Parses the root element of an RSS document looking for all items information. * Parses the root element of an RSS document looking for all items
* information.
* <p/> * <p/>
* It iterates through the item elements list, obtained from the getItems() method, and invoke parseItem() * It iterates through the item elements list, obtained from the getItems()
* for each item element. The resulting RSSItem of each item element is stored in a list. * method, and invoke parseItem() for each item element. The resulting
* RSSItem of each item element is stored in a list.
* <p/> * <p/>
* *
* @param rssRoot the root element of the RSS document to parse for all items information. * @param rssRoot the root element of the RSS document to parse for all
* items information.
* @return a list with all the parsed RSSItem beans. * @return a list with all the parsed RSSItem beans.
*/ */
protected List<Item> parseItems(Element rssRoot) { protected List<Item> parseItems(final Element rssRoot) {
Collection<Element> eItems = getItems(rssRoot); final Collection<Element> eItems = getItems(rssRoot);
List<Item> items = new ArrayList<Item>(); final List<Item> items = new ArrayList<Item>();
for (Iterator<Element> i=eItems.iterator();i.hasNext();) { for (final Element element : eItems) {
Element eItem = (Element) i.next(); final Element eItem = element;
items.add(parseItem(rssRoot,eItem)); items.add(parseItem(rssRoot, eItem));
} }
return items; return items;
} }
@ -271,33 +282,35 @@ public class RSS090Parser extends BaseWireFeedParser {
* <p/> * <p/>
* It reads title and link out of the 'item' element. * It reads title and link out of the 'item' element.
* <p/> * <p/>
* *
* @param rssRoot the root element of the RSS document in case it's needed for context. * @param rssRoot the root element of the RSS document in case it's needed
* for context.
* @param eItem the item element to parse. * @param eItem the item element to parse.
* @return the parsed RSSItem bean. * @return the parsed RSSItem bean.
*/ */
protected Item parseItem(Element rssRoot,Element eItem) { protected Item parseItem(final Element rssRoot, final Element eItem) {
Item item = new Item(); final Item item = new Item();
Element e = eItem.getChild("title",getRSSNamespace()); Element e = eItem.getChild("title", getRSSNamespace());
if (e!=null) { if (e != null) {
item.setTitle(e.getText()); item.setTitle(e.getText());
} }
e = eItem.getChild("link",getRSSNamespace()); e = eItem.getChild("link", getRSSNamespace());
if (e!=null) { if (e != null) {
item.setLink(e.getText()); item.setLink(e.getText());
item.setUri(e.getText()); item.setUri(e.getText());
} }
item.setModules(parseItemModules(eItem)); item.setModules(parseItemModules(eItem));
List<Element> foreignMarkup = final List<Element> foreignMarkup = extractForeignMarkup(eItem, item, getRSSNamespace());
extractForeignMarkup(eItem, item, getRSSNamespace()); // content:encoded elements are treated special, without a module, they
//content:encoded elements are treated special, without a module, they have to be removed from the foreign // have to be removed from the foreign
//markup to avoid duplication in case of read/write. Note that this fix will break if a content module is // markup to avoid duplication in case of read/write. Note that this fix
//used // will break if a content module is
Iterator<Element> iterator = foreignMarkup.iterator(); // used
final Iterator<Element> iterator = foreignMarkup.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Element ie = (Element)iterator.next(); final Element ie = iterator.next();
if (getContentNamespace().equals(ie.getNamespace()) && ie.getName().equals("encoded")) { if (getContentNamespace().equals(ie.getNamespace()) && ie.getName().equals("encoded")) {
iterator.remove(); iterator.remove();
} }
@ -308,40 +321,41 @@ public class RSS090Parser extends BaseWireFeedParser {
return item; return item;
} }
/** /**
* Parses the root element of an RSS document looking for text-input information. * Parses the root element of an RSS document looking for text-input
* information.
* <p/> * <p/>
* It reads title, description, name and link out of the 'textinput' or 'textInput' element. * It reads title, description, name and link out of the 'textinput' or
* 'textInput' element.
* <p/> * <p/>
* *
* @param rssRoot the root element of the RSS document to parse for text-input information. * @param rssRoot the root element of the RSS document to parse for
* text-input information.
* @return the parsed RSSTextInput bean. * @return the parsed RSSTextInput bean.
*/ */
protected TextInput parseTextInput(Element rssRoot) { protected TextInput parseTextInput(final Element rssRoot) {
TextInput textInput = null; TextInput textInput = null;
Element eTextInput = getTextInput(rssRoot); final Element eTextInput = getTextInput(rssRoot);
if (eTextInput!=null) { if (eTextInput != null) {
textInput = new TextInput(); textInput = new TextInput();
Element e = eTextInput.getChild("title",getRSSNamespace()); Element e = eTextInput.getChild("title", getRSSNamespace());
if (e!=null) { if (e != null) {
textInput.setTitle(e.getText()); textInput.setTitle(e.getText());
} }
e = eTextInput.getChild("description",getRSSNamespace()); e = eTextInput.getChild("description", getRSSNamespace());
if (e!=null) { if (e != null) {
textInput.setDescription(e.getText()); textInput.setDescription(e.getText());
} }
e = eTextInput.getChild("name",getRSSNamespace()); e = eTextInput.getChild("name", getRSSNamespace());
if (e!=null) { if (e != null) {
textInput.setName(e.getText()); textInput.setName(e.getText());
} }
e = eTextInput.getChild("link",getRSSNamespace()); e = eTextInput.getChild("link", getRSSNamespace());
if (e!=null) { if (e != null) {
textInput.setLink(e.getText()); textInput.setLink(e.getText());
} }
} }
return textInput; return textInput;
} }
} }

View file

@ -23,30 +23,30 @@ import org.jdom2.Element;
/** /**
* Feed Generator for RSS 0.91 * Feed Generator for RSS 0.91
* <p/> * <p/>
* *
* @author Elaine Chien * @author Elaine Chien
* *
*/ */
public class RSS091NetscapeGenerator extends RSS091UserlandGenerator { public class RSS091NetscapeGenerator extends RSS091UserlandGenerator {
private String _version; private String _version;
public RSS091NetscapeGenerator() { public RSS091NetscapeGenerator() {
this("rss_0.91N","0.91"); this("rss_0.91N", "0.91");
} }
protected RSS091NetscapeGenerator(String type,String version) { protected RSS091NetscapeGenerator(final String type, final String version) {
super(type,version); super(type, version);
} }
protected Document createDocument(Element root) { @Override
Document doc = new Document(root); protected Document createDocument(final Element root) {
DocType docType = new DocType(RSS091NetscapeParser.ELEMENT_NAME, final Document doc = new Document(root);
RSS091NetscapeParser.PUBLIC_ID, final DocType docType = new DocType(RSS091NetscapeParser.ELEMENT_NAME, RSS091NetscapeParser.PUBLIC_ID, RSS091NetscapeParser.SYSTEM_ID);
RSS091NetscapeParser.SYSTEM_ID);
doc.setDocType(docType); doc.setDocType(docType);
return doc; return doc;
} }
@Override
protected String getTextInputLabel() { protected String getTextInputLabel() {
return "textinput"; return "textinput";
} }
@ -54,6 +54,7 @@ public class RSS091NetscapeGenerator extends RSS091UserlandGenerator {
/** /**
* To be overriden by RSS 0.91 Netscape and RSS 0.94 * To be overriden by RSS 0.91 Netscape and RSS 0.94
*/ */
@Override
protected boolean isHourFormat24() { protected boolean isHourFormat24() {
return false; return false;
} }

Some files were not shown because too many files have changed in this diff Show more