Initial checkin of ROME core.

This commit is contained in:
kebernet 2011-04-01 01:56:20 +00:00
parent 99d443919c
commit 05ae793dc7
196 changed files with 29285 additions and 0 deletions

14
LICENSE Normal file
View file

@ -0,0 +1,14 @@
Copyright 2004 Sun Microsystems, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

191
pom.xml Normal file
View file

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.rometools</groupId>
<artifactId>rome</artifactId>
<name>ROME, RSS and atOM utilitiEs for Java</name>
<version>1.5-SNAPSHOT</version>
<packaging>jar</packaging>
<description>All Roads Lead to ROME. ROME is a set of Atom/RSS Java utilities that make it
easy to work in Java with most syndication formats. Today it accepts all flavors of RSS
(0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0), Atom 0.3 and Atom 1.0 feeds. Rome includes
a set of parsers and generators for the various flavors of feeds, as well as converters
to convert from one format to another. The parsers can give you back Java objects that
are either specific for the format you want to work with, or a generic normalized
SyndFeed object that lets you work on with the data without bothering about the
underlying format. </description>
<url>https://rome.dev.java.net/</url>
<issueManagement>
<url>https://rometools.jira.com/browse/ROME#selectedTab=com.atlassian.jira.plugin.system.project%3Aissues-panel</url>
</issueManagement>
<ciManagement>
<notifiers>
<notifier>
<configuration>
<address>dev@rome.dev.java.net</address>
</configuration>
</notifier>
</notifiers>
</ciManagement>
<inceptionYear>2004</inceptionYear>
<mailingLists>
<mailingList>
<name>dev@rome.dev.java.net</name>
<subscribe>
https://rome.dev.java.net/servlets/ProjectMailingListList</subscribe>
<unsubscribe>
https://rome.dev.java.net/servlets/ProjectMailingListList</unsubscribe>
<archive>
https://rome.dev.java.net/servlets/SummarizeList?listName=dev</archive>
</mailingList>
</mailingLists>
<developers>
<developer>
<name>Robert Cooper</name>
<url>http://www.screaming-penguin.com</url>
<timezone>-4</timezone>
<email>kebernet@gmail.com</email>
</developer>
<developer>
<name>Alejandro Abdelnur</name>
<url>http://blog.sun.com/roller/page/tucu/</url>
<timezone>0</timezone>
</developer>
<developer>
<name>Elaine Chien</name>
<timezone>0</timezone>
</developer>
<developer>
<name>Patrick Chanezon</name>
<url>http://www.chanezon.com/pat/weblog/</url>
<timezone>-9</timezone>
</developer>
</developers>
<scm>
<connection>scm:svn:https://rometools.jira.com/svn/ROME/trunk</connection>
<developerConnection>scm:svn:https://rometools.jira.com/svn/ROME/trunk</developerConnection>
<url>https://rometools.jira.com/source/browse/ROME</url>
</scm>
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<organization>
<name>ROME Project</name>
<url>http://www.rometools.org</url>
</organization>
<dependencies>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.0</version>
<configuration>
<goals>install</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.4</source>
<target>1.4</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.2</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<distributionManagement>
<repository>
<id>central.staging</id>
<name>Nexus Release Repository</name>
<url>http://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
<snapshotRepository>
<id>sonatype.snapshots</id>
<name>My Nexus Snapshots Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View file

@ -0,0 +1,47 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed;
/**
* @author Alejandro Abdelnur
*/
public interface CopyFrom {
/**
* Returns the interface the copyFrom works on.
* <p>
* This is useful when dealing with properties that may have multiple implementations.
* For example, Module.
* <p>
* @return the interface the copyFrom works on.
*/
public Class getInterface();
/**
* Copies all the properties of the given bean into this one.
* <p>
* Any existing properties in this bean are lost.
* <p>
* This method is useful for moving from one implementation of a bean interface to another.
* For example from the default SyndFeed bean implementation to a Hibernate ready implementation.
* <p>
* @param obj the instance to copy properties from.
*
*/
public void copyFrom(Object obj);
}

View file

@ -0,0 +1,222 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.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;
/**
* Parent class of the RSS (Channel) and Atom (Feed) feed beans.
* <p>
* NOTE: We don't like this class at this package level but the alternative would have
* been a proliferation of packages (one more level to hold atom and rss package with
* this class just in that package).
* <p>
* The format of the 'type' property must be [FEEDNAME]_[FEEDVERSION] with the FEEDNAME in lower case,
* for example: rss_0.9, rss_0.93, atom_0.3
* <p>
* @author Alejandro Abdelnur
*
*/
public abstract class WireFeed implements Cloneable, Serializable, Extendable {
private ObjectBean _objBean;
private String _feedType;
private String _encoding;
private List _modules;
private List _foreignMarkup;
/**
* Default constructor, for bean cloning purposes only.
* <p>
*
*/
protected WireFeed() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a feed for a given type.
* <p>
* @param type of the feed to create.
*
*/
protected WireFeed(String type) {
this();
_feedType = type;
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
if (other == null) {
return false;
}
// can't use foreign markup in equals, due to JDOM equals impl
Object fm = getForeignMarkup();
setForeignMarkup(((WireFeed)other).getForeignMarkup());
boolean ret = _objBean.equals(other);
// restore foreign markup
setForeignMarkup(fm);
return ret;
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Sets the feedType of a the feed. <b>Do not use</b>, for bean cloning purposes only.
* <p>
* @param feedType the feedType of the feed.
*
*/
public void setFeedType(String feedType) {
_feedType = feedType;
}
/**
* Returns the type of the feed.
*
* @return the type of the feed.
*/
public String getFeedType() {
return _feedType;
}
/**
* Returns the charset encoding of a the feed.
* <p>
* This property is not set by feed parsers. But it is used by feed generators
* to set the encoding in the XML prolog.
* <p>
* @return the charset encoding of the feed.
*
*/
public String getEncoding() {
return _encoding;
}
/**
* Sets the charset encoding of a the feed.
* <p>
* This property is not set by feed parsers. But it is used by feed generators
* to set the encoding in the XML prolog.
* <p>
* @param encoding the charset encoding of the feed.
*
*/
public void setEncoding(String encoding) {
_encoding = encoding;
}
/**
* Returns the channel modules.
* <p>
* @return a list of ModuleImpl elements with the channel modules,
* an empty list if none.
*
*/
public List getModules() {
return (_modules==null) ? (_modules=new ArrayList()) : _modules;
}
/**
* Sets the channel modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(_modules,uri);
}
/**
* Returns foreign markup found at channel level.
* <p>
* @return Opaque object to discourage use
*
*/
public Object getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
}
/**
* Sets foreign markup found at channel level.
* <p>
* @param foreignMarkup Opaque object to discourage use
*
*/
public void setForeignMarkup(Object foreignMarkup) {
_foreignMarkup = (List)foreignMarkup;
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for category elements of Atom feeds.
* <p>
* @author Dave Johnson (added for Atom 1.0)
*/
public class Category implements Cloneable, Serializable {
private ObjectBean _objBean;
private String _term;
private String _scheme;
private String _schemeResolved;
private String _label;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Category() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Get label for category.
* <p>
* @return Label for category.
*/
public String getLabel() {
return _label;
}
/**
* Set label for category.
* <p>
* @param label Label for category.
*/
public void setLabel(String label) {
this._label = label;
}
/**
* Get Scheme URI for category.
* <p>
* @return Scheme URI for category.
*/
public String getScheme() {
return _scheme;
}
/**
* Set scheme URI for category.
* <p>
* @param scheme Scheme URI for category.
*/
public void setScheme(String scheme) {
this._scheme = scheme;
}
public void setSchemeResolved(String schemeResolved) {
_schemeResolved = schemeResolved;
}
public String getSchemeResolved() {
return _schemeResolved != null ? _schemeResolved : _scheme;
}
/**
* Return term for category.
* <p>
* @return Term for category.
*/
public String getTerm() {
return _term;
}
/**
* Set term for category.
* <p>
* @param term Term for category.
*/
public void setTerm(String term) {
this._term = term;
}
}

View file

@ -0,0 +1,212 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* Bean for content elements of Atom feeds.
* <p>
* @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0)
*/
public class Content implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _type;
private String _value;
private String _src;
/** @since Atom 1.0 */
public static final String TEXT = "text";
/** @since Atom 1.0 */
public static final String HTML = "html";
/** @since Atom 1.0 */
public static final String XHTML = "xhtml";
/** Atom 0.3 only */
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;
private static final Set MODES = new HashSet();
static {
MODES.add(XML);
MODES.add(BASE64);
MODES.add(ESCAPED);
}
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Content() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the content type.
* <p>
* The type indicates how the value was/will-be encoded in the XML feed.
* </p>
* @since Atom 1.0
*/
public String getType() {
return _type;
}
/**
* Sets the content type.
* <p>
* The type indicates how the value was/will-be encoded in the XML feed.
* </p>
* @since Atom 1.0
*/
public void setType(String type) {
_type = type;
}
/**
* Returns the content mode (Atom 0.3 only).
* <p>
* The mode indicates how the value was/will-be encoded in the XML feed.
* <p>
* @return the content mode, <b>null</b> if none.
*/
public String getMode() {
return _mode;
}
/**
* Sets the content mode (Atom 0.3 only).
* <p>
* The mode indicates how the value was/will-be encoded in the XML feed.
* <p>
* @param mode the content mode, <b>null</b> if none.
*/
public void setMode(String mode) {
mode = (mode!=null) ? mode.toLowerCase() : null;
if (mode==null || !MODES.contains(mode)) {
throw new IllegalArgumentException("Invalid mode ["+mode+"]");
}
_mode = mode;
}
/**
* Returns the content value.
* <p>
* The return value should be decoded.
* <p>
* @return the content value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the content value.
* <p>
* The value being set should be decoded.
* <p>
* @param value the content value, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
/**
* Returns the src
* <p>
* @return Returns the src.
* @since Atom 1.0
*/
public String getSrc() {
return _src;
}
/**
* Set the src
* <p>
* @param src The src to set.
* @since Atom 1.0
*/
public void setSrc(String src) {
_src = src;
}
}

View file

@ -0,0 +1,550 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.Extendable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.Serializable;
import java.util.Iterator;
/**
* Bean for entry elements of Atom feeds.
* <p>
* @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0)
*/
public class Entry implements Cloneable, Serializable, Extendable {
private ObjectBean _objBean;
private String _xmlBase;
private List _authors;
private List _contributors;
private List _categories;
private List _contents;
private String _id;
private Date _published; // AKA issued
private String _rights;
private Feed _source;
private Content _summary;
private Content _title;
private Date _updated; // AKA modified
private List _alternateLinks;
private List _otherLinks;
private List _foreignMarkup;
private List _modules;
private Date _created; // Atom 0.3 only
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Entry() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
if (other == null) {
return false;
}
// can't use foreign markup in equals, due to JDOM equals impl
Object fm = getForeignMarkup();
setForeignMarkup(((Entry)other).getForeignMarkup());
boolean ret = _objBean.equals(other);
// restore foreign markup
setForeignMarkup(fm);
return ret;
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the entry title.
* <p>
* @return the entry title, <b>null</b> if none.
*
*/
public String getTitle() {
if (_title != null) return _title.getValue();
return null;
}
/**
* Sets the entry title.
* <p>
* @param title the entry title, <b>null</b> if none.
*
*/
public void setTitle(String title) {
if (_title == null) _title = new Content();
_title.setValue(title);
}
/**
* Returns the entry title as a text construct.
* <p>
* @return the entry title, <b>null</b> if none.
*
*/
public Content getTitleEx() {
return _title;
}
/**
* Sets the entry title as a text construct.
* <p>
* @param title the entry title, <b>null</b> if none.
*
*/
public void setTitleEx(Content title) {
_title = title;
}
/**
* Returns the entry alternate links.
* <p>
* @return a list of Link elements with the entry alternate links, an empty list if none.
*/
public List getAlternateLinks() {
return (_alternateLinks==null) ? (_alternateLinks=new ArrayList()) : _alternateLinks;
}
/**
* Sets the entry alternate links.
* <p>
* @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 alternateLinks) {
_alternateLinks = alternateLinks;
}
/**
* Returns the entry non-alternate links.
* <p>
* @return the list of Link elements with the entry non-alternate links to set,
* an empty list if none.
*/
public List getOtherLinks() {
return (_otherLinks==null) ? (_otherLinks=new ArrayList()) : _otherLinks;
}
/**
* Sets the entry non-alternate links.
* <p>
* @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 otherLinks) {
_otherLinks = otherLinks;
}
/**
* Returns the entry author.
* <p>
* @return the entry author, <b>null</b> if none.
*
*/
public List getAuthors() {
return (_authors==null) ? (_authors=new ArrayList()) : _authors;
}
/**
* Sets the author of the entry.
* <p>
* @param authors the author of the entry, <b>null</b> if none.
*
*/
public void setAuthors(List authors) {
_authors = authors;
}
/**
* Returns the entry contributors.
* <p>
* @return a list of Person elements with the entry contributors,
* an empty list if none.
*
*/
public List getContributors() {
return (_contributors==null) ? (_contributors=new ArrayList()) : _contributors;
}
/**
* Sets the entry contributors.
* <p>
* @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 contributors) {
_contributors = contributors;
}
/**
* Returns the entry ID.
* <p>
* @return the entry ID, <b>null</b> if none.
*
*/
public String getId() {
return _id;
}
/**
* Sets the entry ID.
* <p>
* @param id the entry ID, <b>null</b> if none.
*
*/
public void setId(String id) {
_id = id;
}
/**
* Returns the entry modified date (Atom 0.3, maps to {@link #getUpdated()}).
* <p>
* @return the entry modified date, <b>null</b> if none.
*/
public Date getModified() {
return _updated;
}
/**
* Sets the entry modified date (Atom 0.3, maps to {@link #setUpdated(java.util.Date)}).
* <p>
* @param modified the entry modified date, <b>null</b> if none.
*/
public void setModified(Date modified) {
_updated = modified;
}
/**
* Returns the entry issued date (Atom 0.3, maps to {@link #getPublished()}).
* <p>
* @return the entry issued date, <b>null</b> if none.
*/
public Date getIssued() {
return _published;
}
/**
* Sets the entry issued date (Atom 0.3, maps to {@link #setPublished(java.util.Date)}).
* <p>
* @param issued the entry issued date, <b>null</b> if none.
*/
public void setIssued(Date issued) {
_published = issued;
}
/**
* Returns the entry created date (Atom 0.3 only)
* <p>
* @return the entry created date, <b>null</b> if none.
*/
public Date getCreated() {
return _created;
}
/**
* Sets the entry created date (Atom 0.3 only)
* <p>
* @param created the entry created date, <b>null</b> if none.
*/
public void setCreated(Date created) {
_created = created;
}
/**
* Returns the entry summary.
* <p>
* @return the entry summary, <b>null</b> if none.
*
*/
public Content getSummary() {
return _summary;
}
/**
* Sets the entry summary.
* <p>
* @param summary the entry summary, <b>null</b> if none.
*
*/
public void setSummary(Content summary) {
_summary = summary;
}
/**
* Returns the entry contents.
* <p>
* @return a list of Content elements with the entry contents,
* an empty list if none.
*/
public List getContents() {
return (_contents==null) ? (_contents=new ArrayList()) : _contents;
}
/**
* Sets the entry contents.
* <p>
* @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 contents) {
_contents = contents;
}
/**
* Returns the entry modules.
* <p>
* @return a list of ModuleImpl elements with the entry modules,
* an emtpy list if none.
*
*/
public List getModules() {
return (_modules==null) ? (_modules=new ArrayList()) : _modules;
}
/**
* Sets the entry modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(_modules,uri);
}
/**
* Returns the published
* <p>
* @return Returns the published.
* @since Atom 1.0
*/
public Date getPublished() {
return _published;
}
/**
* Set the published
* <p>
* @param published The published to set.
* @since Atom 1.0
*/
public void setPublished(Date published) {
_published = published;
}
/**
* Returns the rights
* <p>
* @return Returns the rights.
* @since Atom 1.0
*/
public String getRights() {
return _rights;
}
/**
* Set the rights
* <p>
* @param rights The rights to set.
* @since Atom 1.0
*/
public void setRights(String rights) {
_rights = rights;
}
/**
* Returns the source
* <p>
* @return Returns the source.
*/
public Feed getSource() {
return _source;
}
/**
* Set the source
* <p>
* @param source The source to set.
*/
public void setSource(Feed source) {
_source = source;
}
/**
* Returns the updated
* <p>
* @return Returns the updated.
* @since Atom 1.0
*/
public Date getUpdated() {
return _updated;
}
/**
* Set the updated
* <p>
* @param updated The updated to set.
* @since Atom 1.0
*/
public void setUpdated(Date updated) {
_updated = updated;
}
/**
* Returns the categories
* <p>
* @return Returns the categories.
* @since Atom 1.0
*/
public List getCategories() {
return (_categories==null) ? (_categories=new ArrayList()) : _categories;
}
/**
* Set the categories
* <p>
* @param categories The categories to set.
* @since Atom 1.0
*/
public void setCategories(List categories) {
_categories = categories;
}
/**
* Returns the xmlBase
* <p>
* @return Returns the xmlBase.
* @since Atom 1.0
*/
public String getXmlBase() {
return _xmlBase;
}
/**
* Set the xmlBase
* <p>
* @param xmlBase The xmlBase to set.
* @since Atom 1.0
*/
public void setXmlBase(String xmlBase) {
_xmlBase = xmlBase;
}
/**
* Returns foreign markup found at entry level.
* <p>
* @return list of Opaque object to discourage use
*
*/
public Object getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
}
/**
* Sets foreign markup found at entry level.
* <p>
* @param foreignMarkup Opaque object to discourage use
*
*/
public void setForeignMarkup(Object foreignMarkup) {
_foreignMarkup = (List)foreignMarkup;
}
/**
* Returns true if entry is a media entry, i.e. has rel="edit-media".
*
* @return true if entry is a media entry
*/
public boolean isMediaEntry() {
boolean mediaEntry = false;
List links = getOtherLinks();
for (Iterator it = links.iterator(); it.hasNext();) {
Link link = (Link) it.next();
if ("edit-media".equals(link.getRel())) {
mediaEntry = true;
break;
}
}
return mediaEntry;
}
}

View file

@ -0,0 +1,525 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.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.Date;
import java.util.List;
/**
* Bean for Atom feeds.
* <p>
* It handles Atom feeds version 0.3 without loosing any feed information.
* <p>
* @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0)
*/
public class Feed extends WireFeed {
private String _xmlBase;
private List _categories;
private List _authors;
private List _contributors;
private Generator _generator;
private String _icon;
private String _id;
private String _logo;
private String _rights; // AKA copyright
private Content _subtitle; // AKA tagline
private Content _title;
private Date _updated; // AKA modified
private List _alternateLinks;
private List _otherLinks;
private List _entries;
private List _modules;
private Content _info; // Atom 0.3 only
private String _language; // Atom 0.3 only
/**
* Default constructor, for bean cloning purposes only.
*
*/
public Feed() {
}
/**
* Feed Constructor. All properties, except the type, are set to <b>null</b>.
* <p>
* @param type the type of the Atom feed.
*
*/
public Feed(String type) {
super(type);
}
/**
* Returns the feed language (Atom 0.3 only)
* <p>
* @return the feed language, <b>null</b> if none.
*
*/
public String getLanguage() {
return _language;
}
/**
* Sets the feed language (Atom 0.3 only)
* <p>
* @param language the feed language to set, <b>null</b> if none.
*
*/
public void setLanguage(String language) {
_language = language;
}
/**
* Returns the feed title.
* <p>
* @return the feed title, <b>null</b> if none.
*
*/
public String getTitle() {
if (_title != null) return _title.getValue();
return null;
}
/**
* Sets the feed title.
* <p>
* @param title the feed title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
if (_title == null) _title = new Content();
_title.setValue(title);
}
/**
* Returns the feed title.
* <p>
* @return the feed title, <b>null</b> if none.
*
*/
public Content getTitleEx() {
return _title;
}
/**
* Sets the feed title.
* <p>
* @param title the feed title to set, <b>null</b> if none.
*
*/
public void setTitleEx(Content title) {
_title = title;
}
/**
* Returns the feed alternate links.
* <p>
* @return a list of Link elements with the feed alternate links,
* an empty list if none.
*/
public List getAlternateLinks() {
return (_alternateLinks==null) ? (_alternateLinks=new ArrayList()) : _alternateLinks;
}
/**
* Sets the feed alternate links.
* <p>
* @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 alternateLinks) {
_alternateLinks = alternateLinks;
}
/**
* Returns the feed other links (non-alternate ones).
* <p>
* @return a list of Link elements with the feed other links (non-alternate ones),
* an empty list if none.
*/
public List getOtherLinks() {
return (_otherLinks==null) ? (_otherLinks=new ArrayList()) : _otherLinks;
}
/**
* Sets the feed other links (non-alternate ones).
* <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.
*/
public void setOtherLinks(List otherLinks) {
_otherLinks = otherLinks;
}
/**
* Returns the feed author.
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
public List getAuthors() {
return (_authors==null) ? (_authors=new ArrayList()) : _authors;
}
/**
* Sets the feed author.
* <p>
* @param authors the feed author to set, <b>null</b> if none.
*
*/
public void setAuthors(List authors) {
_authors = authors;
}
/**
* Returns the feed contributors.
* <p>
* @return a list of Person elements with the feed contributors,
* an empty list if none.
*
*/
public List getContributors() {
return (_contributors==null) ? (_contributors=new ArrayList()) : _contributors;
}
/**
* Sets the feed contributors.
* <p>
* @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 contributors) {
_contributors = contributors;
}
/**
* Returns the feed tag line (Atom 0.3, maps to {@link #getSubtitle()}).
* <p>
* @return the feed tag line, <b>null</b> if none.
*/
public Content getTagline() {
return _subtitle;
}
/**
* Sets the feed tagline (Atom 0.3, maps to {@link #setSubtitle(com.sun.syndication.feed.atom.Content)}).
* <p>
* @param tagline the feed tagline to set, <b>null</b> if none.
*/
public void setTagline(Content tagline) {
_subtitle = tagline;
}
/**
* Returns the feed ID.
* <p>
* @return the feed ID, <b>null</b> if none.
*
*/
public String getId() {
return _id;
}
/**
* Sets the feed ID.
* <p>
* @param id the feed ID to set, <b>null</b> if none.
*
*/
public void setId(String id) {
_id = id;
}
/**
* Returns the feed generator.
* <p>
* @return the feed generator, <b>null</b> if none.
*
*/
public Generator getGenerator() {
return _generator;
}
/**
* Sets the feed generator.
* <p>
* @param generator the feed generator to set, <b>null</b> if none.
*
*/
public void setGenerator(Generator generator) {
_generator = generator;
}
/**
* Returns the feed copyright (Atom 0.3, maps to {@link #getRights()}).
* <p>
* @return the feed copyright, <b>null</b> if none.
*/
public String getCopyright() {
return _rights;
}
/**
* Sets the feed copyright (Atom 0.3, maps to {@link #setRights(java.lang.String)}).
* <p>
* @param copyright the feed copyright to set, <b>null</b> if none.
*/
public void setCopyright(String copyright) {
_rights = copyright;
}
/**
* Returns the feed info (Atom 0.3 only)
* <p>
* @return the feed info, <b>null</b> if none.
*/
public Content getInfo() {
return _info;
}
/**
* Sets the feed info (Atom 0.3 only)
* <p>
* @param info the feed info to set, <b>null</b> if none.
*/
public void setInfo(Content info) {
_info = info;
}
/**
* Returns the feed modified date (Atom 0.3, maps to {@link #getUpdated()}).
* <p>
* @return the feed modified date, <b>null</b> if none.
*/
public Date getModified() {
return _updated;
}
/**
* Sets the feed modified date (Atom 0.3, maps to {@link #setUpdated(java.util.Date)}).
* <p>
* @param modified the feed modified date to set, <b>null</b> if none.
*/
public void setModified(Date modified) {
_updated = modified;
}
/**
* Returns the feed entries.
* <p>
* @return a list of Entry elements with the feed entries,
* an empty list if none.
*
*/
public List getEntries() {
return (_entries==null) ? (_entries=new ArrayList()) : _entries;
}
/**
* Sets the feed entries.
* <p>
* @param entries the list of Entry elements with the feed entries to set,
* an empty list or <b>null</b> if none.
*
*/
public void setEntries(List entries) {
_entries = entries;
}
/**
* Returns the feed modules.
* <p>
* @return a list of ModuleImpl elements with the feed modules,
* an empty list if none.
*
*/
public List getModules() {
return (_modules==null) ? (_modules=new ArrayList()) : _modules;
}
/**
* Sets the feed moduless.
* <p>
* @param modules the list of ModuleImpl elements with the feed moduless to set,
* an empty list or <b>null</b> if none.
*
*/
public void setModules(List modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(_modules,uri);
}
/**
* Returns the categories
* <p>
* @return Returns the categories.
* @since Atom 1.0
*/
public List getCategories() {
return (_categories==null) ? (_categories=new ArrayList()) : _categories;
}
/**
* Set the categories
* <p>
* @param categories The categories to set.
* @since Atom 1.0
*/
public void setCategories(List categories) {
_categories = categories;
}
/**
* Returns the icon
* <p>
* @return Returns the icon.
* @since Atom 1.0
*/
public String getIcon() {
return _icon;
}
/**
* Set the icon
* <p>
* @param icon The icon to set.
* @since Atom 1.0
*/
public void setIcon(String icon) {
_icon = icon;
}
/**
* Returns the logo
* <p>
* @return Returns the logo.
* @since Atom 1.0
*/
public String getLogo() {
return _logo;
}
/**
* Set the logo
* <p>
* @param logo The logo to set.
* @since Atom 1.0
*/
public void setLogo(String logo) {
_logo = logo;
}
/**
* Returns the rights
* <p>
* @return Returns the rights.
* @since Atom 1.0
*/
public String getRights() {
return _rights;
}
/**
* Set the rights
* <p>
* @param rights The rights to set.
* @since Atom 1.0
*/
public void setRights(String rights) {
_rights = rights;
}
/**
* Returns the subtitle
* <p>
* @return Returns the subtitle.
* @since Atom 1.0
*/
public Content getSubtitle() {
return _subtitle;
}
/**
* Set the subtitle
* <p>
* @param subtitle The subtitle to set.
* @since Atom 1.0
*/
public void setSubtitle(Content subtitle) {
_subtitle = subtitle;
}
/**
* Returns the updated
* <p>
* @return Returns the updated.
* @since Atom 1.0
*/
public Date getUpdated() {
return _updated;
}
/**
* Set the updated
* <p>
* @param updated The updated to set.
* @since Atom 1.0
*/
public void setUpdated(Date updated) {
_updated = updated;
}
/**
* Returns the xmlBase
* <p>
* @return Returns the xmlBase.
* @since Atom 1.0
*/
public String getXmlBase() {
return _xmlBase;
}
/**
* Set the xmlBase
* <p>
* @param xmlBase The xmlBase to set.
* @since Atom 1.0
*/
public void setXmlBase(String xmlBase) {
_xmlBase = xmlBase;
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for the generator element of Atom feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Generator implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _url;
private String _version;
private String _value;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Generator() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the generator URL.
* <p>
* @return the generator URL, <b>null</b> if none.
*
*/
public String getUrl() {
return _url;
}
/**
* Sets the generator URL.
* <p>
* @param url the generator URL, <b>null</b> if none.
*
*/
public void setUrl(String url) {
_url = url;
}
/**
* Returns the generator version.
* <p>
* @return the generator version, <b>null</b> if none.
*
*/
public String getVersion() {
return _version;
}
/**
* Sets the generator version.
* <p>
* @param version the generator version, <b>null</b> if none.
*
*/
public void setVersion(String version) {
_version = version;
}
/**
* Returns the generator value.
* <p>
* @return the generator value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the generator value.
* <p>
* @param value the generator value, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
}

View file

@ -0,0 +1,220 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.atom;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for link elements of Atom feeds.
* <p>
* @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0)
*/
public class Link implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _href;
private String _hrefResolved;
private String _rel = "alternate";
private String _type;
private String _hreflang;
private String _title;
private long _length;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Link() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the link rel.
* <p>
* @return the link rel, <b>null</b> if none.
*
*/
public String getRel() {
return _rel;
}
/**
* Sets the link rel.
* <p>
* @param rel the link rel,, <b>null</b> if none.
*
*/
public void setRel(String rel) {
//TODO add check, ask P@ about the check
_rel = rel;
}
/**
* Returns the link type.
* <p>
* @return the link type, <b>null</b> if none.
*
*/
public String getType() {
return _type;
}
/**
* Sets the link type.
* <p>
* @param type the link type, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = type;
}
/**
* Returns the link href.
* <p>
* @return the link href, <b>null</b> if none.
*
*/
public String getHref() {
return _href;
}
/**
* Sets the link href.
* <p>
* @param href the link href, <b>null</b> if none.
*
*/
public void setHref(String href) {
_href = href;
}
public void setHrefResolved(String hrefResolved) {
_hrefResolved = hrefResolved;
}
public String getHrefResolved() {
return _hrefResolved != null ? _hrefResolved : _href;
}
/**
* Returns the link title.
* <p>
* @return the link title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the link title.
* <p>
* @param title the link title, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the hreflang
* <p>
* @return Returns the hreflang.
* @since Atom 1.0
*/
public String getHreflang() {
return _hreflang;
}
/**
* Set the hreflang
* <p>
* @param hreflang The hreflang to set.
* @since Atom 1.0
*/
public void setHreflang(String hreflang) {
_hreflang = hreflang;
}
/**
* Returns the length
* <p>
* @return Returns the length.
*/
public long getLength() {
return _length;
}
/**
* Set the length
* <p>
* @param length The length to set.
*/
public void setLength(long length) {
_length = length;
}
}

View file

@ -0,0 +1,216 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.atom;
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;
import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
/**
* Bean for person elements of Atom feeds.
* <p>
* @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0)
*/
public class Person implements Cloneable,Serializable, Extendable
{
private ObjectBean _objBean;
private String _name;
private String _uri; // since Atom 1.0 (was called url)
private String _uriResolved;
private String _email;
private List _modules;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Person() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the person name.
* <p>
* @return the person name, <b>null</b> if none.
*
*/
public String getName() {
return _name;
}
/**
* Sets the personname.
* <p>
* @param name the person name, <b>null</b> if none.
*
*/
public void setName(String name) {
_name = name;
}
/**
* Returns the person URL (same as {@link #getUri()})
* <p>
* @return the person URL, <b>null</b> if none.
*/
public String getUrl() {
return _uri;
}
/**
* Sets the person URL (same as {@link #setUri(java.lang.String)})
* <p>
* @param url the person URL, <b>null</b> if none.
*/
public void setUrl(String url) {
_uri = url;
}
public void setUriResolved(String uriResolved) {
_uriResolved = uriResolved;
}
public String getUriResolved(String resolveURI) {
return _uriResolved != null ? _uriResolved : _uri;
}
/**
* Returns the person email.
* <p>
* @return the person email, <b>null</b> if none.
*
*/
public String getEmail() {
return _email;
}
/**
* Sets the person email.
* <p>
* @param email the person email, <b>null</b> if none.
*
*/
public void setEmail(String email) {
_email = email;
}
/**
* Returns the uri
* <p>
* @return Returns the uri.
* @since Atom 1.0
*/
public String getUri() {
return _uri;
}
/**
* Set the uri
* <p>
* @param uri The uri to set.
* @since Atom 1.0
*/
public void setUri(String uri) {
_uri = uri;
}
/**
* Returns the entry modules.
* <p>
* @return a list of ModuleImpl elements with the entry modules,
* an emtpy list if none.
*
*/
public List getModules() {
return (_modules==null) ? (_modules=new ArrayList()) : _modules;
}
/**
* Sets the entry modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(_modules,uri);
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.impl;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* Obtains all property descriptors from a bean (interface or implementation).
* <p>
* The java.beans.Introspector does not process the interfaces hierarchy chain, this one does.
* <p>
* @author Alejandro Abdelnur
*
*/
public class BeanIntrospector {
private static final Map _introspected = new HashMap();
public static synchronized PropertyDescriptor[] getPropertyDescriptors(Class klass) throws IntrospectionException {
PropertyDescriptor[] descriptors = (PropertyDescriptor[]) _introspected.get(klass);
if (descriptors==null) {
descriptors = getPDs(klass);
_introspected.put(klass,descriptors);
}
return descriptors;
}
private static PropertyDescriptor[] getPDs(Class klass) throws IntrospectionException {
Method[] methods = klass.getMethods();
Map getters = getPDs(methods,false);
Map setters = getPDs(methods,true);
List pds = merge(getters,setters);
PropertyDescriptor[] array = new PropertyDescriptor[pds.size()];
pds.toArray(array);
return array;
}
private static final String SETTER = "set";
private static final String GETTER = "get";
private static final String BOOLEAN_GETTER = "is";
private static Map getPDs(Method[] methods,boolean setters) throws IntrospectionException {
Map pds = new HashMap();
for (int i=0;i<methods.length;i++) {
String pName = null;
PropertyDescriptor pDescriptor = null;
if ((methods[i].getModifiers()&Modifier.PUBLIC)!=0) {
if (setters) {
if (methods[i].getName().startsWith(SETTER) &&
methods[i].getReturnType()==void.class && methods[i].getParameterTypes().length==1) {
pName = Introspector.decapitalize(methods[i].getName().substring(3));
pDescriptor = new PropertyDescriptor(pName,null,methods[i]);
}
}
else {
if (methods[i].getName().startsWith(GETTER) &&
methods[i].getReturnType()!=void.class && methods[i].getParameterTypes().length==0) {
pName = Introspector.decapitalize(methods[i].getName().substring(3));
pDescriptor = new PropertyDescriptor(pName,methods[i],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) {
pds.put(pName,pDescriptor);
}
}
return pds;
}
private static List merge(Map getters,Map setters) throws IntrospectionException {
List props = new ArrayList();
Set processedProps = new HashSet();
Iterator gs = getters.keySet().iterator();
while (gs.hasNext()) {
String name = (String) gs.next();
PropertyDescriptor getter = (PropertyDescriptor) getters.get(name);
PropertyDescriptor setter = (PropertyDescriptor) setters.get(name);
if (setter!=null) {
processedProps.add(name);
PropertyDescriptor prop = new PropertyDescriptor(name,getter.getReadMethod(),setter.getWriteMethod());
props.add(prop);
}
else {
props.add(getter);
}
}
Set writeOnlyProps = new HashSet(setters.keySet());
writeOnlyProps.removeAll(processedProps);
Iterator ss = writeOnlyProps.iterator();
while (ss.hasNext()) {
String name = (String) ss.next();
PropertyDescriptor setter = (PropertyDescriptor) setters.get(name);
props.add(setter);
}
return props;
}
}

View file

@ -0,0 +1,272 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.impl;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* Provides deep <b>Bean</b> clonning support.
* <p>
* It works on all read/write properties, recursively. It support all primitive types, Strings, Collections,
* Cloneable objects and multi-dimensional arrays of any of them.
* <p>
* @author Alejandro Abdelnur
*
*/
public class CloneableBean implements Serializable, Cloneable {
private static final Class[] NO_PARAMS_DEF = new Class[0];
private static final Object[] NO_PARAMS = new Object[0];
private Object _obj;
private Set _ignoreProperties;
/**
* Default constructor.
* <p>
* To be used by classes extending CloneableBean only.
* <p>
*
*/
protected CloneableBean() {
_obj = this;
}
/**
* Creates a CloneableBean to be used in a delegation pattern.
* <p>
* For example:
* <p>
* <code>
* public class Foo implements Cloneable {
* private CloneableBean _cloneableBean;
*
* public Foo() {
* _cloneableBean = new CloneableBean(this);
* }
*
* public Object clone() throws CloneNotSupportedException {
* return _cloneableBean.beanClone();
* }
*
* }
* </code>
* <p>
* @param obj object bean to clone.
*
*/
public CloneableBean(Object obj) {
this(obj,null);
}
/**
* Creates a CloneableBean to be used in a delegation pattern.
* <p>
* 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
* properties (properties that are actually references to other properties or
* properties of properties). For example SyndFeed and SyndEntry beans have
* convenience properties, publishedDate, author, copyright and categories all
* of them mapped to properties in the DC Module.
* <p>
* @param obj object bean to clone.
* @param ignoreProperties properties to ignore when cloning.
*
*/
public CloneableBean(Object obj,Set ignoreProperties) {
_obj = obj;
_ignoreProperties = (ignoreProperties!=null) ? ignoreProperties : Collections.EMPTY_SET;
}
/**
* Makes a deep bean clone of the object.
* <p>
* To be used by classes extending CloneableBean. Although it works also for classes using
* CloneableBean in a delegation pattern, for correctness those classes should use the
* @see #beanClone() beanClone method.
* <p>
* @return a clone of the object bean.
* @throws CloneNotSupportedException thrown if the object bean could not be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return beanClone();
}
/**
* Makes a deep bean clone of the object passed in the constructor.
* <p>
* To be used by classes using CloneableBean in a delegation pattern,
* @see #CloneableBean(Object) constructor.
*
* @return a clone of the object bean.
* @throws CloneNotSupportedException thrown if the object bean could not be cloned.
*
*/
public Object beanClone() throws CloneNotSupportedException {
Object clonedBean;
try {
clonedBean = _obj.getClass().newInstance();
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_obj.getClass());
if (pds!=null) {
for (int i=0;i<pds.length;i++) {
Method pReadMethod = pds[i].getReadMethod();
Method pWriteMethod = pds[i].getWriteMethod();
if (pReadMethod!=null && pWriteMethod!=null && // ensure it has getter and setter methods
!_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(_obj,NO_PARAMS);
if (value!=null) {
value = doClone(value);
pWriteMethod.invoke(clonedBean,new Object[]{value});
}
}
}
}
}
catch (CloneNotSupportedException cnsEx) {
throw cnsEx;
}
catch (Exception ex) {
System.out.println(ex);
ex.printStackTrace(System.out);
throw new CloneNotSupportedException("Cannot clone a "+_obj.getClass()+" object");
}
return clonedBean;
}
private Object doClone(Object value) throws Exception {
if (value!=null) {
Class vClass = value.getClass();
if (vClass.isArray()) {
value = cloneArray(value);
}
else
if (value instanceof Collection) {
value = cloneCollection((Collection)value);
}
else
if (value instanceof Map) {
value = cloneMap((Map)value);
}
else
if (isBasicType(vClass)) {
// NOTHING SPECIAL TO DO HERE, THEY ARE INMUTABLE
}
else
if (value instanceof Cloneable) {
Method cloneMethod = vClass.getMethod("clone",NO_PARAMS_DEF);
if (Modifier.isPublic(cloneMethod.getModifiers())) {
value = cloneMethod.invoke(value,NO_PARAMS);
}
else {
throw new CloneNotSupportedException("Cannot clone a "+value.getClass()+" object, clone() is not public");
}
}
else {
throw new CloneNotSupportedException("Cannot clone a "+vClass.getName()+" object");
}
}
return value;
}
private Object cloneArray(Object array) throws Exception {
Class elementClass = array.getClass().getComponentType();
int length = Array.getLength(array);
Object newArray = Array.newInstance(elementClass,length);
for (int i=0;i<length;i++) {
Object element = doClone(Array.get(array,i));
Array.set(newArray,i,element);
}
return newArray;
}
private Object cloneCollection(Collection collection) throws Exception {
Class mClass = collection.getClass();
Collection newColl = (Collection) mClass.newInstance();
Iterator i = collection.iterator();
while (i.hasNext()) {
Object element = doClone(i.next());
newColl.add(element);
}
return newColl;
}
private Object cloneMap(Map map) throws Exception {
Class mClass = map.getClass();
Map newMap = (Map) mClass.newInstance();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Object key = doClone(entry.getKey());
Object value = doClone(entry.getValue());
newMap.put(key,value);
}
return newMap;
}
private static final Set BASIC_TYPES = new HashSet();
static {
BASIC_TYPES.add(Boolean.class);
BASIC_TYPES.add(Byte.class);
BASIC_TYPES.add(Character.class);
BASIC_TYPES.add(Double.class);
BASIC_TYPES.add(Float.class);
BASIC_TYPES.add(Integer.class);
BASIC_TYPES.add(Long.class);
BASIC_TYPES.add(Short.class);
BASIC_TYPES.add(String.class);
}
private static final Map CONSTRUCTOR_BASIC_TYPES = new HashMap();
static {
CONSTRUCTOR_BASIC_TYPES.put(Boolean.class,new Class[]{Boolean.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(Double.class,new Class[]{Double.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(Long.class,new Class[]{Long.TYPE});
CONSTRUCTOR_BASIC_TYPES.put(Short.class,new Class[]{Short.TYPE});
CONSTRUCTOR_BASIC_TYPES.put(String.class,new Class[]{String.class});
}
private boolean isBasicType(Class vClass) {
return BASIC_TYPES.contains(vClass);
}
// THIS IS NOT NEEDED, BASIC TYPES ARE INMUTABLE, TUCU 20040710
/**
private Object cloneBasicType(Object value) throws Exception {
Class pClass = value.getClass();
Class[] defType = (Class[]) CONSTRUCTOR_BASIC_TYPES.get(pClass);
Constructor cons = pClass.getDeclaredConstructor(defType);
value = cons.newInstance(new Object[]{value});
return value;
}
**/
}

View file

@ -0,0 +1,169 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.impl;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.impl.BeanIntrospector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author Alejandro Abdelnur
*/
public class CopyFromHelper {
private static final Object[] NO_PARAMS = new Object[0];
private Class _beanInterfaceClass;
private Map _baseInterfaceMap; //ENTRIES(propertyName,interface.class)
private Map _baseImplMap; //ENTRIES(interface.class,implementation.class)
public CopyFromHelper(Class beanInterfaceClass,Map basePropInterfaceMap,Map basePropClassImplMap) {
_beanInterfaceClass = beanInterfaceClass;
_baseInterfaceMap = basePropInterfaceMap;
_baseImplMap = basePropClassImplMap;
}
public void copy(Object target,Object source) {
try {
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanInterfaceClass);
if (pds!=null) {
for (int i=0;i<pds.length;i++) {
String propertyName = pds[i].getName();
Method pReadMethod = pds[i].getReadMethod();
Method pWriteMethod = pds[i].getWriteMethod();
if (pReadMethod!=null && pWriteMethod!=null && // ensure it has getter and setter methods
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods
pReadMethod.getParameterTypes().length==0 && // filter getter methods that take parameters
_baseInterfaceMap.containsKey(propertyName)) { // only copies properties defined as copyFrom-able
Object value = pReadMethod.invoke(source,NO_PARAMS);
if (value!=null) {
Class baseInterface = (Class) _baseInterfaceMap.get(propertyName);
value = doCopy(value,baseInterface);
pWriteMethod.invoke(target,new Object[]{value});
}
}
}
}
}
catch (Exception ex) {
throw new RuntimeException("Could not do a copyFrom "+ex, ex);
}
}
private CopyFrom createInstance(Class interfaceClass) throws Exception {
if( _baseImplMap.get(interfaceClass) == null ){
return null;
}
else {
return (CopyFrom) ((Class)_baseImplMap.get(interfaceClass)).newInstance();
}
}
private Object doCopy(Object value,Class baseInterface) throws Exception {
if (value!=null) {
Class vClass = value.getClass();
if (vClass.isArray()) {
value = doCopyArray(value,baseInterface);
}
else
if (value instanceof Collection) {
value = doCopyCollection((Collection)value,baseInterface);
}
else
if (value instanceof Map) {
value = doCopyMap((Map)value,baseInterface);
}
else
if (isBasicType(vClass)) {
// value = value; // nothing to do here
if (value instanceof Date) { // because Date it is not inmutable
value = ((Date)value).clone();
}
}
else { // it goes CopyFrom
if (value instanceof CopyFrom) {
CopyFrom source = (CopyFrom) value;
CopyFrom target = createInstance(source.getInterface());
target = target == null ? (CopyFrom) value.getClass().newInstance() : target;
target.copyFrom(source);
value = target;
}
else {
throw new Exception("unsupported class for 'copyFrom' "+value.getClass());
}
}
}
return value;
}
private Object doCopyArray(Object array,Class baseInterface) throws Exception {
Class elementClass = array.getClass().getComponentType();
int length = Array.getLength(array);
Object newArray = Array.newInstance(elementClass,length);
for (int i=0;i<length;i++) {
Object element = doCopy(Array.get(array,i),baseInterface);
Array.set(newArray,i,element);
}
return newArray;
}
private Object doCopyCollection(Collection collection,Class baseInterface) throws Exception {
// expecting SETs or LISTs only, going default implementation of them
Collection newColl = (collection instanceof Set) ? (Collection)new HashSet() : (Collection)new ArrayList();
Iterator i = collection.iterator();
while (i.hasNext()) {
Object element = doCopy(i.next(),baseInterface);
newColl.add(element);
}
return newColl;
}
private Object doCopyMap(Map map,Class baseInterface) throws Exception {
Map newMap = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Object key = entry.getKey(); // we are assuming string KEYS
Object element = doCopy(entry.getValue(),baseInterface);
newMap.put(key,element);
}
return newMap;
}
private static final Set BASIC_TYPES = new HashSet();
static {
BASIC_TYPES.add(Boolean.class);
BASIC_TYPES.add(Byte.class);
BASIC_TYPES.add(Character.class);
BASIC_TYPES.add(Double.class);
BASIC_TYPES.add(Float.class);
BASIC_TYPES.add(Integer.class);
BASIC_TYPES.add(Long.class);
BASIC_TYPES.add(Short.class);
BASIC_TYPES.add(String.class);
BASIC_TYPES.add(Date.class);
}
private boolean isBasicType(Class vClass) {
return BASIC_TYPES.contains(vClass);
}
}

View file

@ -0,0 +1,231 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.impl;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.io.Serializable;
/**
* Provides deep <b>Bean</b> equals() and hashCode() functionality for Java Beans.
* <p>
* It works on all read/write properties, recursively. It support all primitive types, Strings, Collections,
* bean-like objects and multi-dimensional arrays of any of them.
* <p>
* The hashcode is calculated by getting the hashcode of the Bean String representation.
* <p>
* @author Alejandro Abdelnur
*
*/
public class EqualsBean implements Serializable {
private static final Object[] NO_PARAMS = new Object[0];
private Class _beanClass;
private Object _obj;
/**
* Default constructor.
* <p>
* To be used by classes extending EqualsBean only.
* <p>
* @param beanClass the class/interface to be used for property scanning.
*
*/
protected EqualsBean(Class beanClass) {
_beanClass = beanClass;
_obj = this;
}
/**
* Creates a EqualsBean to be used in a delegation pattern.
* <p>
* For example:
* <p>
* <code>
* public class Foo implements FooI {
* private EqualsBean _equalsBean;
*
* public Foo() {
* _equalsBean = new EqualsBean(FooI.class);
* }
*
* public boolean equals(Object obj) {
* return _equalsBean.beanEquals(obj);
* }
*
* public int hashCode() {
* return _equalsBean.beanHashCode();
* }
*
* }
* </code>
* <p>
* @param beanClass the class/interface to be used for property scanning.
* @param obj object bean to test equality.
*
*/
public EqualsBean(Class beanClass,Object obj) {
if (!beanClass.isInstance(obj)) {
throw new IllegalArgumentException(obj.getClass()+" is not instance of "+beanClass);
}
_beanClass = beanClass;
_obj = obj;
}
/**
* Indicates whether some other object is "equal to" this object as defined by the Object equals() method.
* <p>
* To be used by classes extending EqualsBean. Although it works also for classes using
* EqualsBean in a delegation pattern, for correctness those classes should use the
* @see #beanEquals(Object) beanEquals method.
* <p>
* @param obj he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object obj) {
return beanEquals(obj);
}
/**
* Indicates whether some other object is "equal to" the object passed in the constructor,
* as defined by the Object equals() method.
* <p>
* To be used by classes using EqualsBean in a delegation pattern,
* @see #EqualsBean(Class,Object) constructor.
* <p>
* @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.
*
*/
public boolean beanEquals(Object obj) {
Object bean1 = _obj;
Object bean2 = obj;
boolean eq;
if (bean2==null) {
eq = false;
}
else
if (bean1==null && bean2==null) {
eq = true;
}
else
if (bean1==null || bean2==null) {
eq = false;
}
else {
if (!_beanClass.isInstance(bean2)) {
eq = false;
}
else {
eq = true;
try {
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanClass);
if (pds!=null) {
for (int i = 0; eq && i<pds.length; i++) {
Method pReadMethod = pds[i].getReadMethod();
if (pReadMethod!=null && // ensure it has a getter method
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods
pReadMethod.getParameterTypes().length==0) { // filter getter methods that take parameters
Object value1 = pReadMethod.invoke(bean1, NO_PARAMS);
Object value2 = pReadMethod.invoke(bean2, NO_PARAMS);
eq = doEquals(value1, value2);
}
}
}
}
catch (Exception ex) {
throw new RuntimeException("Could not execute equals()", ex);
}
}
}
return eq;
}
/**
* Returns the hashcode for this object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* The hashcode is calculated by getting the hashcode of the Bean String representation.
* <p>
* To be used by classes extending EqualsBean. Although it works also for classes using
* EqualsBean in a delegation pattern, for correctness those classes should use the
* @see #beanHashCode() beanHashCode method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return beanHashCode();
}
/**
* Returns the hashcode for the object passed in the constructor.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* The hashcode is calculated by getting the hashcode of the Bean String representation.
* <p>
* To be used by classes using EqualsBean in a delegation pattern,
* @see #EqualsBean(Class,Object) constructor.
* <p>
* @return the hashcode of the bean object.
*
*/
public int beanHashCode() {
return _obj.toString().hashCode();
}
private boolean doEquals(Object obj1, Object obj2) {
boolean eq = obj1==obj2;
if (!eq && obj1!=null && obj2!=null) {
Class classObj1 = obj1.getClass();
Class classObj2 = obj2.getClass();
if (classObj1.isArray() && classObj2.isArray()) {
eq = equalsArray(obj1, obj2);
}
else {
eq = obj1.equals(obj2);
}
}
return eq;
}
private boolean equalsArray(Object array1, Object array2) {
boolean eq;
int length1 = Array.getLength(array1);
int length2 = Array.getLength(array2);
if (length1==length2) {
eq = true;
for (int i = 0; eq && i<length1; i++) {
Object e1 = Array.get(array1, i);
Object e2 = Array.get(array2, i);
eq = doEquals(e1, e2);
}
}
else {
eq = false;
}
return eq;
}
}

View file

@ -0,0 +1,124 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.impl;
import com.sun.syndication.feed.impl.CloneableBean;
import com.sun.syndication.feed.impl.EqualsBean;
import java.io.Serializable;
import java.util.Set;
/**
* Convenience class providing clone(), toString(), equals() and hashCode() functionality for Java Beans.
* <p>
* It works on all read/write properties, recursively.
* <p>
* It uses the CloneableBean, EqualsBean and ToStringBean classes in a delegation pattern.
* <p>
* <h3>ObjectBean programming conventions</h3>
* <P>
* All ObjectBean subclasses having properties that return collections they should never
* return null if the property has been set to <b>null</b> or if a collection has not been set.
* They should create and return an empty collection, this empty collection instance should
* also be set to the corresponding property.
* <P>
* All ObjectBean subclasses properties should be live references.
* <p>
* @author Alejandro Abdelnur
*
*/
public class ObjectBean implements Serializable, Cloneable {
private EqualsBean _equalsBean;
private ToStringBean _toStringBean;
private CloneableBean _cloneableBean;
/**
* Constructor.
* <p>
* @param beanClass the class/interface to be used for property scanning.
*
*/
public ObjectBean(Class beanClass,Object obj) {
this(beanClass,obj,null);
}
/**
* Constructor.
* <p>
* 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
* properties (properties that are actually references to other properties or
* properties of properties). For example SyndFeed and SyndEntry beans have
* convenience properties, publishedDate, author, copyright and categories all
* of them mapped to properties in the DC Module.
* <p>
* @param beanClass the class/interface to be used for property scanning.
* @param ignoreProperties properties to ignore when cloning.
*
*/
public ObjectBean(Class beanClass,Object obj,Set ignoreProperties) {
_equalsBean = new EqualsBean(beanClass,obj);
_toStringBean = new ToStringBean(beanClass,obj);
_cloneableBean = new CloneableBean(obj,ignoreProperties);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _cloneableBean.beanClone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _equalsBean.beanEquals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _equalsBean.beanHashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _toStringBean.toString();
}
}

View file

@ -0,0 +1,240 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.impl;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import java.io.Serializable;
/**
* Provides deep <b>Bean</b> toString support.
* <p>
* It works on all read/write properties, recursively. It support all primitive types, Strings, Collections,
* ToString objects and multi-dimensional arrays of any of them.
* <p>
* @author Alejandro Abdelnur
*
*/
public class ToStringBean implements Serializable {
private static final ThreadLocal PREFIX_TL = new ThreadLocal() {
public Object get() {
Object o = super.get();
if (o==null) {
o = new Stack();
set(o);
}
return o;
}
};
private static final Object[] NO_PARAMS = new Object[0];
private Class _beanClass;
private Object _obj;
/**
* Default constructor.
* <p>
* To be used by classes extending ToStringBean only.
* <p>
* @param beanClass indicates the class to scan for properties, normally an interface class.
*
*/
protected ToStringBean(Class beanClass) {
_beanClass = beanClass;
_obj = this;
}
/**
* Creates a ToStringBean to be used in a delegation pattern.
* <p>
* For example:
* <p>
* <code>
* public class Foo implements ToString {
*
* public String toString(String prefix) {
* ToStringBean tsb = new ToStringBean(this);
* return tsb.toString(prefix);
* }
*
* public String toString() {
* return toString("Foo");
* }
*
* }
* </code>
* <p>
* @param beanClass indicates the class to scan for properties, normally an interface class.
* @param obj object bean to create String representation.
*
*/
public ToStringBean(Class beanClass,Object obj) {
_beanClass = beanClass;
_obj = obj;
}
/**
* Returns the String representation of the bean given in the constructor.
* <p>
* It uses the Class name as the prefix.
* <p>
* @return bean object String representation.
*
*/
public String toString() {
Stack stack = (Stack) PREFIX_TL.get();
String[] tsInfo = (String[]) ((stack.isEmpty()) ? null : stack.peek());
String prefix;
if (tsInfo==null) {
String className = _obj.getClass().getName();
prefix = className.substring(className.lastIndexOf(".")+1);
}
else {
prefix = tsInfo[0];
tsInfo[1] = prefix;
}
return toString(prefix);
}
/**
* Returns the String representation of the bean given in the constructor.
* <p>
* @param prefix to use for bean properties.
* @return bean object String representation.
*
*/
private String toString(String prefix) {
StringBuffer sb = new StringBuffer(128);
try {
PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(_beanClass);
if (pds!=null) {
for (int i=0;i<pds.length;i++) {
String pName = pds[i].getName();
Method pReadMethod = pds[i].getReadMethod();
if (pReadMethod!=null && // ensure it has a getter method
pReadMethod.getDeclaringClass()!=Object.class && // filter Object.class getter methods
pReadMethod.getParameterTypes().length==0) { // filter getter methods that take parameters
Object value = pReadMethod.invoke(_obj,NO_PARAMS);
printProperty(sb,prefix+"."+pName,value);
}
}
}
}
catch (Exception ex) {
sb.append("\n\nEXCEPTION: Could not complete "+_obj.getClass()+".toString(): "+ex.getMessage()+"\n");
}
return sb.toString();
}
private void printProperty(StringBuffer sb,String prefix,Object value) {
if (value==null) {
sb.append(prefix).append("=null\n");
}
else
if (value.getClass().isArray()) {
printArrayProperty(sb,prefix,value);
}
else
if (value instanceof Map) {
Map map = (Map) value;
Iterator i = map.entrySet().iterator();
if (i.hasNext()) {
while (i.hasNext()) {
Map.Entry me = (Map.Entry) i.next();
String ePrefix = prefix+"["+me.getKey()+"]";
Object eValue = me.getValue();
//NEW
String[] tsInfo = new String[2];
tsInfo[0] = ePrefix;
Stack stack = (Stack) PREFIX_TL.get();
stack.push(tsInfo);
String s = (eValue!=null) ? eValue.toString() : "null";
stack.pop();
if (tsInfo[1]==null) {
sb.append(ePrefix).append("=").append(s).append("\n");
}
else {
sb.append(s);
}
}
}
else {
sb.append(prefix).append("=[]\n");
}
}
else
if (value instanceof Collection) {
Collection collection = (Collection) value;
Iterator i = collection.iterator();
if (i.hasNext()) {
int c = 0;
while (i.hasNext()) {
String cPrefix = prefix+"["+(c++)+"]";
Object cValue = i.next();
//NEW
String[] tsInfo = new String[2];
tsInfo[0] = cPrefix;
Stack stack = (Stack) PREFIX_TL.get();
stack.push(tsInfo);
String s = (cValue!=null) ? cValue.toString() : "null";
stack.pop();
if (tsInfo[1]==null) {
sb.append(cPrefix).append("=").append(s).append("\n");
}
else {
sb.append(s);
}
}
}
else {
sb.append(prefix).append("=[]\n");
}
}
else {
String[] tsInfo = new String[2];
tsInfo[0] = prefix;
Stack stack = (Stack) PREFIX_TL.get();
stack.push(tsInfo);
String s = value.toString();
stack.pop();
if (tsInfo[1]==null) {
sb.append(prefix).append("=").append(s).append("\n");
}
else {
sb.append(s);
}
}
}
private void printArrayProperty(StringBuffer sb, String prefix,Object array) {
int length = Array.getLength(array);
for (int i=0;i<length;i++) {
Object obj = Array.get(array,i);
printProperty(sb,prefix+"["+i+"]",obj);
}
}
}

View file

@ -0,0 +1,563 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.CopyFrom;
import java.util.List;
import java.util.Date;
/**
* Dublin Core Module.
* <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>.
* @author Alejandro Abdelnur
*
*/
public interface DCModule extends Module,CopyFrom {
/**
* URI of the Dublin Core Module (http://purl.org/dc/elements/1.1/).
*
*/
String URI = "http://purl.org/dc/elements/1.1/";
/**
* Returns the DublinCore module titles.
* <p>
* @return a list of Strings representing the DublinCore module title,
* an empty list if none.
*
*/
List getTitles();
/**
* Sets the DublinCore module titles.
* <p>
* @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 titles);
/**
* Gets the DublinCore module title. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module title, <b>null</b> if none.
*/
String getTitle();
/**
* Sets the DublinCore module title. Convenience method that can be used
* when there is only one title to set.
* <p>
* @param title the DublinCore module title to set, <b>null</b> if none.
*
*/
void setTitle(String title);
/**
* Returns the DublinCore module creator.
* <p>
* @return a list of Strings representing the DublinCore module creator,
* an empty list if none.
*
*/
List getCreators();
/**
* Sets the DublinCore module creators.
* <p>
* @param creators the list of String representing the DublinCore module
* creators to set, an empty list or <b>null</b> if none.
*
*/
void setCreators(List creators);
/**
* Gets the DublinCore module creator. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module creator, <b>null</b> if none.
*/
String getCreator();
/**
* Sets the DublinCore module creator. Convenience method that can be used
* when there is only one creator to set.
* <p>
* @param creator the DublinCore module creator to set, <b>null</b> if none.
*
*/
void setCreator(String creator);
/**
* Returns the DublinCore module subjects.
* <p>
* @return a list of DCSubject elements with the DublinCore module subjects,
* an empty list if none.
*
*/
List getSubjects();
/**
* Sets the DublinCore module subjects.
* <p>
* @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 subjects);
/**
* Gets the DublinCore module subject. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module subject, <b>null</b> if none.
*/
DCSubject getSubject();
/**
* Sets the DCSubject element. Convenience method that can be used when
* there is only one subject to set.
* <p>
* @param subject the DublinCore module subject to set, <b>null</b> if none.
*
*/
void setSubject(DCSubject subject);
/**
* Returns the DublinCore module description.
* <p>
* @return a list of Strings representing the DublinCore module description,
* an empty list if none.
*
*/
List getDescriptions();
/**
* Sets the DublinCore module descriptions.
* <p>
* @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 descriptions);
/**
* Gets the DublinCore module description. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module description, <b>null</b> if none.
*/
String getDescription();
/**
* Sets the DublinCore module description. Convenience method that can be
* used when there is only one description to set.
* <p>
* @param description the DublinCore module description to set, <b>null</b> if none.
*
*/
void setDescription(String description);
/**
* Returns the DublinCore module publisher.
* <p>
* @return a list of Strings representing the DublinCore module publisher,
* an empty list if none.
*
*/
List getPublishers();
/**
* Sets the DublinCore module publishers.
* <p>
* @param publishers the list of String representing the DublinCore module
* publishers to set, an empty list or <b>null</b> if none.
*
*/
void setPublishers(List publishers);
/**
* Gets the DublinCore module publisher. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module publisher, <b>null</b> if none.
*/
String getPublisher();
/**
* Sets the DublinCore module publisher. Convenience method that can be used when
* there is only one publisher to set.
* <p>
* @param publisher the DublinCore module publisher to set, <b>null</b> if none.
*
*/
void setPublisher(String publisher);
/**
* Returns the DublinCore module contributor.
* <p>
* @return a list of Strings representing the DublinCore module contributor,
* an empty list if none.
*
*/
List getContributors();
/**
* Sets the DublinCore module contributors.
* <p>
* @param contributors the list of String representing the DublinCore module
* contributors to set, an empty list or <b>null</b> if none.
*
*/
void setContributors(List contributors);
/**
* Gets the DublinCore module contributor. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module contributor, <b>null</b> if none.
*/
String getContributor();
/**
* Sets the DublinCore module contributor. Convenience method that can be
* used when there is only one contributor to set.
* <p>
* @param contributor the DublinCore module contributor to set, <b>null</b> if none.
*
*/
void setContributor(String contributor);
/**
* Returns the DublinCore module date.
* <p>
* @return a list of Strings representing the DublinCore module date,
* an empty list if none.
*
*/
List getDates();
/**
* Sets the DublinCore module dates.
* <p>
* @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 dates);
/**
* Gets the DublinCore module date. Convenience method that can be used to
* obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module date, <b>null</b> if none.
*/
Date getDate();
/**
* Sets the DublinCore module date. Convenience method that can be used
* when there is only one date to set.
* <p>
* @param date the DublinCore module date to set, <b>null</b> if none.
*
*/
void setDate(Date date);
/**
* Returns the DublinCore module type.
* <p>
* @return a list of Strings representing the DublinCore module type,
* an empty list if none.
*
*/
List getTypes();
/**
* Sets the DublinCore module types.
* <p>
* @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 types);
/**
* Gets the DublinCore module type. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module type, <b>null</b> if none.
*/
String getType();
/**
* Sets the DublinCore module type. Convenience method that can be used
* when there is only one type to set.
* <p>
* @param type the DublinCore module type to set, <b>null</b> if none.
*
*/
void setType(String type);
/**
* Returns the DublinCore module format.
* <p>
* @return a list of Strings representing the DublinCore module format,
* an empty list if none.
*
*/
List getFormats();
/**
* Sets the DublinCore module formats.
* <p>
* @param formats the list of String representing the DublinCore module
* formats to set, an empty list or <b>null</b> if none.
*
*/
void setFormats(List formats);
/**
* Gets the DublinCore module format. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module format, <b>null</b> if none.
*/
String getFormat();
/**
* Sets the DublinCore module format. Convenience method that can be used
* when there is only one format to set.
* <p>
* @param format the DublinCore module format to set, <b>null</b> if none.
*
*/
void setFormat(String format);
/**
* Returns the DublinCore module identifier.
* <p>
* @return a list of Strings representing the DublinCore module identifier,
* an empty list if none.
*
*/
List getIdentifiers();
/**
* Sets the DublinCore module identifiers.
* <p>
* @param identifiers the list of String representing the DublinCore module
* identifiers to set, an empty list or <b>null</b> if none.
*
*/
void setIdentifiers(List identifiers);
/**
* Gets the DublinCore module identifier. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module identifier, <b>null</b> if none.
*/
String getIdentifier();
/**
* Sets the DublinCore module identifier. Convenience method that can be
* used when there is only one identifier to set.
* <p>
* @param identifier the DublinCore module identifier to set, <b>null</b> if none.
*
*/
void setIdentifier(String identifier);
/**
* Returns the DublinCore module source.
* <p>
* @return a list of Strings representing the DublinCore module source,
* an empty list if none.
*
*/
List getSources();
/**
* Sets the DublinCore module sources.
* <p>
* @param sources the list of String representing the DublinCore module
* sources to set, an empty list or <b>null</b> if none.
*
*/
void setSources(List sources);
/**
* Gets the DublinCore module subject. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module creator, <b>null</b> if none.
*/
String getSource();
/**
* Sets the DublinCore module source. Convenience method that can be used
* when there is only one source to set.
* <p>
* @param source the DublinCore module source to set, <b>null</b> if none.
*
*/
void setSource(String source);
/**
* Returns the DublinCore module language.
* <p>
* @return a list of Strings representing the DublinCore module language,
* an empty list if none.
*
*/
List getLanguages();
/**
* Sets the DublinCore module languages.
* <p>
* @param languages the list of String representing the DublinCore module
* languages to set, an empty list or <b>null</b> if none.
*
*/
void setLanguages(List languages);
/**
* Gets the DublinCore module language. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module language, <b>null</b> if none.
*/
String getLanguage();
/**
* Sets the DublinCore module language. Convenience method that can be used
* when there is only one language to set.
* <p>
* @param language the DublinCore module language to set, <b>null</b> if none.
*
*/
void setLanguage(String language);
/**
* Returns the DublinCore module relation.
* <p>
* @return a list of Strings representing the DublinCore module relation,
* an empty list if none.
*
*/
List getRelations();
/**
* Sets the DublinCore module relations.
* <p>
* @param relations the list of String representing the DublinCore module
* relations to set, an empty list or <b>null</b> if none.
*
*/
void setRelations(List relations);
/**
* Gets the DublinCore module relation. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module relation, <b>null</b> if none.
*/
String getRelation();
/**
* Sets the DublinCore module relation. Convenience method that can be used
* when there is only one relation to set.
* <p>
* @param relation the DublinCore module relation to set, <b>null</b> if none.
*
*/
void setRelation(String relation);
/**
* Returns the DublinCore module coverage.
* <p>
* @return a list of Strings representing the DublinCore module coverage,
* an empty list if none.
*
*/
List getCoverages();
/**
* Sets the DublinCore module coverages.
* <p>
* @param coverages the list of String representing the DublinCore module
* coverages to set, an empty list or <b>null</b> if none.
*
*/
void setCoverages(List coverages);
/**
* Gets the DublinCore module coverage. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module coverage, <b>null</b> if none.
*/
String getCoverage();
/**
* Sets the DublinCore module coverage. Convenience method that can be used
* when there is only one coverage to set.
* <p>
* @param coverage the DublinCore module coverage to set, <b>null</b> if none.
*
*/
void setCoverage(String coverage);
/**
* Returns the DublinCore module rights.
* <p>
* @return a list of Strings representing the DublinCore module rights,
* an empty list if none.
*
*/
List getRightsList();
/**
* Sets the DublinCore module rightss.
* <p>
* @param rights the list of String representing the DublinCore module
* rights to set, an empty list or <b>null</b> if none.
*
*/
void setRightsList(List rights);
/**
* Gets the DublinCore module right. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module right, <b>null</b> if none.
*/
String getRights();
/**
* Sets the DublinCore module rights. Convenience method that can be used
* when there is only one rights to set.
* <p>
* @param rights the DublinCore module rights to set, <b>null</b> if none.
*
*/
void setRights(String rights);
}

View file

@ -0,0 +1,840 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.impl.ObjectBean;
import java.util.*;
/**
* Dublin Core ModuleImpl, default implementation.
* <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>.
* @author Alejandro Abdelnur
*
*/
public class DCModuleImpl extends ModuleImpl implements DCModule {
private ObjectBean _objBean;
private List _title;
private List _creator;
private List _subject;
private List _description;
private List _publisher;
private List _contributors;
private List _date;
private List _type;
private List _format;
private List _identifier;
private List _source;
private List _language;
private List _relation;
private List _coverage;
private List _rights;
/**
* Properties to be ignored when cloning.
*/
private static final Set IGNORE_PROPERTIES = new HashSet();
/**
* Unmodifiable Set containing the convenience properties of this class.
* <p>
* Convenience properties are mapped to Modules, for cloning the convenience
* properties can be ignored as the will be copied as part of the module
* cloning.
*/
public static final Set CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
static {
IGNORE_PROPERTIES.add("title");
IGNORE_PROPERTIES.add("creator");
IGNORE_PROPERTIES.add("subject");
IGNORE_PROPERTIES.add("description");
IGNORE_PROPERTIES.add("publisher");
IGNORE_PROPERTIES.add("contributor");
IGNORE_PROPERTIES.add("date");
IGNORE_PROPERTIES.add("type");
IGNORE_PROPERTIES.add("format");
IGNORE_PROPERTIES.add("identifier");
IGNORE_PROPERTIES.add("source");
IGNORE_PROPERTIES.add("language");
IGNORE_PROPERTIES.add("relation");
IGNORE_PROPERTIES.add("coverage");
IGNORE_PROPERTIES.add("rights");
}
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public DCModuleImpl() {
super(DCModule.class, URI);
_objBean = new ObjectBean(DCModule.class, this, CONVENIENCE_PROPERTIES);
}
/**
* Returns the DublinCore module titles.
* <p>
* @return a list of Strings representing the DublinCore module title,
* an empty list if none.
*
*/
public List getTitles() {
return (_title == null) ? (_title = new ArrayList()) : _title;
}
/**
* Sets the DublinCore module titles.
* <p>
* @param titles the list of String representing the DublinCore module
* titles to set, an empty list or <b>null</b> if none.
*
*/
public void setTitles(List titles) {
_title = titles;
}
/**
* Gets the DublinCore module title. Convenience method that can be used to
* obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module title, <b>null</b> if none.
*/
public String getTitle() {
return ((_title != null) && (_title.size() > 0)) ? (String) _title.get(0) : null;
}
/**
* Sets the DublinCore module title. Convenience method that can be used
* when there is only one title to set.
* <p>
* @param title the DublinCore module title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = new ArrayList();
_title.add(title);
}
/**
* Returns the DublinCore module creator.
* <p>
* @return a list of Strings representing the DublinCore module creator,
* an empty list if none.
*
*/
public List getCreators() {
return (_creator == null) ? (_creator = new ArrayList()) : _creator;
}
/**
* Sets the DublinCore module creators.
* <p>
* @param creators the list of String representing the DublinCore module
* creators to set, an empty list or <b>null</b> if none.
*
*/
public void setCreators(List creators) {
_creator = creators;
}
/**
* Gets the DublinCore module title. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module title, <b>null</b> if none.
*/
public String getCreator() {
return ((_creator != null) && (_creator.size() > 0)) ? (String) _creator.get(0) : null;
}
/**
* Sets the DublinCore module creator. Convenience method that can be used
* when there is only one creator to set.
* <p>
* @param creator the DublinCore module creator to set, <b>null</b> if none.
*
*/
public void setCreator(String creator) {
_creator = new ArrayList();
_creator.add(creator);
}
/**
* Returns the DublinCore module subjects.
* <p>
* @return a list of DCSubject elements with the DublinCore module subjects,
* an empty list if none.
*
*/
public List getSubjects() {
return (_subject == null) ? (_subject = new ArrayList()) : _subject;
}
/**
* Sets the DublinCore module subjects.
* <p>
* @param subjects the list of DCSubject elements with the DublinCore
* module subjects to set, an empty list or <b>null</b> if none.
*
*/
public void setSubjects(List subjects) {
_subject = subjects;
}
/**
* Gets the DublinCore module subject. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module subject, <b>null</b> if none.
*/
public DCSubject getSubject() {
return ((_subject != null) && (_subject.size() > 0)) ?
(DCSubject) _subject.get(0) : null;
}
/**
* Sets the DCSubject element. Convenience method that can be used when
* there is only one subject to set.
* <p>
* @param subject the DublinCore module subject to set, <b>null</b> if none.
*
*/
public void setSubject(DCSubject subject) {
_subject = new ArrayList();
_subject.add(subject);
}
/**
* Returns the DublinCore module description.
* <p>
* @return a list of Strings representing the DublinCore module
* description, an empty list if none.
*
*/
public List getDescriptions() {
return (_description == null) ? (_description = new ArrayList()) : _description;
}
/**
* Sets the DublinCore module descriptions.
* <p>
* @param descriptions the list of String representing the DublinCore
* module descriptions to set, an empty list or <b>null</b> if none.
*
*/
public void setDescriptions(List descriptions) {
_description = descriptions;
}
/**
* Gets the DublinCore module description. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module description, <b>null</b> if none.
*/
public String getDescription() {
return ((_description != null) && (_description.size() > 0)) ?
(String) _description.get(0) : null;
}
/**
* Sets the DublinCore module description. Convenience method that can be
* used when there is only one description to set.
* <p>
* @param description the DublinCore module description to set, <b>null</b> if none.
*
*/
public void setDescription(String description) {
_description = new ArrayList();
_description.add(description);
}
/**
* Returns the DublinCore module publisher.
* <p>
* @return a list of Strings representing the DublinCore module publisher,
* an empty list if none.
*
*/
public List getPublishers() {
return (_publisher == null) ? (_publisher = new ArrayList()) : _publisher;
}
/**
* Sets the DublinCore module publishers.
* <p>
* @param publishers the list of String representing the DublinCore module
* publishers to set, an empty list or <b>null</b> if none.
*
*/
public void setPublishers(List publishers) {
_publisher = publishers;
}
/**
* Gets the DublinCore module title. Convenience method that can be used to
* obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module title, <b>null</b> if none.
*/
public String getPublisher() {
return ((_publisher != null) && (_publisher.size() > 0)) ?
(String) _publisher.get(0) : null;
}
/**
* Sets the DublinCore module publisher. Convenience method that can be
* used when there is only one publisher to set.
* <p>
* @param publisher the DublinCore module publisher to set, <b>null</b> if none.
*
*/
public void setPublisher(String publisher) {
_publisher = new ArrayList();
_publisher.add(publisher);
}
/**
* Returns the DublinCore module contributor.
* <p>
* @return a list of Strings representing the DublinCore module contributor,
* an empty list if none.
*
*/
public List getContributors() {
return (_contributors == null) ? (_contributors = new ArrayList()) : _contributors;
}
/**
* Sets the DublinCore module contributors.
* <p>
* @param contributors the list of String representing the DublinCore
* module contributors to set, an empty list or <b>null</b> if none.
*
*/
public void setContributors(List contributors) {
_contributors = contributors;
}
/**
* Gets the DublinCore module contributor. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module contributor, <b>null</b> if none.
*/
public String getContributor() {
return ((_contributors != null) && (_contributors.size() > 0)) ?
(String) _contributors.get(0) : null;
}
/**
* Sets the DublinCore module contributor. Convenience method that can be
* used when there is only one contributor to set.
* <p>
* @param contributor the DublinCore module contributor to set, <b>null</b> if none.
*
*/
public void setContributor(String contributor) {
_contributors = new ArrayList();
_contributors.add(contributor);
}
/**
* Returns the DublinCore module date.
* <p>
* @return a list of Strings representing the DublinCore module date,
* an empty list if none.
*
*/
public List getDates() {
return (_date == null) ? (_date = new ArrayList()) : _date;
}
/**
* Sets the DublinCore module dates.
* <p>
* @param dates the list of Date representing the DublinCore module dates
* to set, an empty list or <b>null</b> if none.
*
*/
public void setDates(List dates) {
_date = dates;
}
/**
* Gets the DublinCore module date. Convenience method that can be used to
* obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module date, <b>null</b> if none.
*/
public Date getDate() {
return ((_date != null) && (_date.size() > 0)) ?
(Date) _date.get(0) : null;
}
/**
* Sets the DublinCore module date. Convenience method that can be used
* when there is only one date to set.
* <p>
* @param date the DublinCore module date to set, <b>null</b> if none.
*
*/
public void setDate(Date date) {
_date = new ArrayList();
_date.add(date);
}
/**
* Returns the DublinCore module type.
* <p>
* @return a list of Strings representing the DublinCore module type,
* an empty list if none.
*
*/
public List getTypes() {
return (_type == null) ? (_type = new ArrayList()) : _type;
}
/**
* Sets the DublinCore module types.
* <p>
* @param types the list of String representing the DublinCore module types
* to set, an empty list or <b>null</b> if none.
*
*/
public void setTypes(List types) {
_type = types;
}
/**
* Gets the DublinCore module type. Convenience method that can be used to
* obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module type, <b>null</b> if none.
*/
public String getType() {
return ((_type != null) && (_type.size() > 0)) ?
(String) _type.get(0) : null;
}
/**
* Sets the DublinCore module type. Convenience method that can be used
* when there is only one type to set.
* <p>
* @param type the DublinCore module type to set, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = new ArrayList();
_type.add(type);
}
/**
* Returns the DublinCore module format.
* <p>
* @return a list of Strings representing the DublinCore module format,
* an empty list if none.
*
*/
public List getFormats() {
return (_format == null) ? (_format = new ArrayList()) : _format;
}
/**
* Sets the DublinCore module formats.
* <p>
* @param formats the list of String representing the DublinCore module
* formats to set, an empty list or <b>null</b> if none.
*
*/
public void setFormats(List formats) {
_format = formats;
}
/**
* Gets the DublinCore module format. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module format, <b>null</b> if none.
*/
public String getFormat() {
return ((_format != null) && (_format.size() > 0)) ?
(String) _format.get(0) : null;
}
/**
* Sets the DublinCore module format. Convenience method that can be used
* when there is only one format to set.
* <p>
* @param format the DublinCore module format to set, <b>null</b> if none.
*
*/
public void setFormat(String format) {
_format = new ArrayList();
_format.add(format);
}
/**
* Returns the DublinCore module identifier.
* <p>
* @return a list of Strings representing the DublinCore module identifier,
* an empty list if none.
*
*/
public List getIdentifiers() {
return (_identifier == null) ? (_identifier = new ArrayList()) : _identifier;
}
/**
* Sets the DublinCore module identifiers.
* <p>
* @param identifiers the list of String representing the DublinCore module
* identifiers to set, an empty list or <b>null</b> if none.
*
*/
public void setIdentifiers(List identifiers) {
_identifier = identifiers;
}
/**
* Gets the DublinCore module identifier. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module identifier, <b>null</b> if none.
*/
public String getIdentifier() {
return ((_identifier != null) && (_identifier.size() > 0)) ?
(String) _identifier.get(0) : null;
}
/**
* Sets the DublinCore module identifier. Convenience method that can be
* used when there is only one identifier to set.
* <p>
* @param identifier the DublinCore module identifier to set, <b>null</b> if none.
*
*/
public void setIdentifier(String identifier) {
_identifier = new ArrayList();
_identifier.add(identifier);
}
/**
* Returns the DublinCore module source.
* <p>
* @return a list of Strings representing the DublinCore module source,
* an empty list if none.
*
*/
public List getSources() {
return (_source == null) ? (_source = new ArrayList()) : _source;
}
/**
* Sets the DublinCore module sources.
* <p>
* @param sources the list of String representing the DublinCore module
* sources to set, an empty list or <b>null</b> if none.
*
*/
public void setSources(List sources) {
_source = sources;
}
/**
* Gets the DublinCore module source. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module source, <b>null</b> if none.
*/
public String getSource() {
return ((_source != null) && (_source.size() > 0)) ?
(String) _source.get(0) : null;
}
/**
* Sets the DublinCore module source. Convenience method that can be used
* when there is only one source to set.
* <p>
* @param source the DublinCore module source to set, <b>null</b> if none.
*
*/
public void setSource(String source) {
_source = new ArrayList();
_source.add(source);
}
/**
* Returns the DublinCore module language.
* <p>
* @return a list of Strings representing the DublinCore module language,
* an empty list if none.
*
*/
public List getLanguages() {
return (_language == null) ? (_language = new ArrayList()) : _language;
}
/**
* Sets the DublinCore module languages.
* <p>
* @param languages the list of String representing the DublinCore module
* languages to set, an empty list or <b>null</b> if none.
*
*/
public void setLanguages(List languages) {
_language = languages;
}
/**
* Gets the DublinCore module language. Convenience method that can be
* used to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module langauge, <b>null</b> if none.
*/
public String getLanguage() {
return ((_language != null) && (_language.size() > 0)) ?
(String) _language.get(0) : null;
}
/**
* Sets the DublinCore module language. Convenience method that can be used
* when there is only one language to set.
* <p>
* @param language the DublinCore module language to set, <b>null</b> if none.
*
*/
public void setLanguage(String language) {
_language = new ArrayList();
_language.add(language);
}
/**
* Returns the DublinCore module relation.
* <p>
* @return a list of Strings representing the DublinCore module relation,
* an empty list if none.
*
*/
public List getRelations() {
return (_relation == null) ? (_relation = new ArrayList()) : _relation;
}
/**
* Sets the DublinCore module relations.
* <p>
* @param relations the list of String representing the DublinCore module
* relations to set, an empty list or <b>null</b> if none.
*
*/
public void setRelations(List relations) {
_relation = relations;
}
/**
* Gets the DublinCore module relation. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module relation, <b>null</b> if none.
*/
public String getRelation() {
return ((_relation != null) && (_relation.size() > 0)) ?
(String) _relation.get(0) : null;
}
/**
* Sets the DublinCore module relation. Convenience method that can be used
* when there is only one relation to set.
* <p>
* @param relation the DublinCore module relation to set, <b>null</b> if none.
*
*/
public void setRelation(String relation) {
_relation = new ArrayList();
_relation.add(relation);
}
/**
* Returns the DublinCore module coverage.
* <p>
* @return a list of Strings representing the DublinCore module coverage,
* an empty list if none.
*
*/
public List getCoverages() {
return (_coverage == null) ? (_coverage = new ArrayList()) : _coverage;
}
/**
* Sets the DublinCore module coverages.
* <p>
* @param coverages the list of String representing the DublinCore module
* coverages to set, an empty list or <b>null</b> if none.
*
*/
public void setCoverages(List coverages) {
_coverage = coverages;
}
/**
* Gets the DublinCore module coverage. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module coverage, <b>null</b> if none.
*/
public String getCoverage() {
return ((_coverage != null) && (_coverage.size() > 0)) ?
(String) _coverage.get(0) : null;
}
/**
* Sets the DublinCore module coverage. Convenience method that can be used
* when there is only one coverage to set.
* <p>
* @param coverage the DublinCore module coverage to set, <b>null</b> if none.
*
*/
public void setCoverage(String coverage) {
_coverage = new ArrayList();
_coverage.add(coverage);
}
/**
* Returns the DublinCore module rights.
* <p>
* @return a list of Strings representing the DublinCore module rights,
* an empty list if none.
*
*/
public List getRightsList() {
return (_rights == null) ? (_rights = new ArrayList()) : _rights;
}
/**
* Sets the DublinCore module rights.
* <p>
* @param rights the list of String representing the DublinCore module
* rights to set, an empty list or <b>null</b> if none.
*
*/
public void setRightsList(List rights) {
_rights = rights;
}
/**
* Gets the DublinCore module rights. Convenience method that can be used
* to obtain the first item, <b>null</b> if none.
* <p>
* @return the first DublinCore module rights, <b>null</b> if none.
*/
public String getRights() {
return ((_rights != null) && (_rights.size() > 0)) ?
(String) _rights.get(0) : null;
}
/**
* Sets the DublinCore module rights. Convenience method that can be used
* when there is only one rights to set.
* <p>
* @param rights the DublinCore module rights to set, <b>null</b> if none.
*
*/
public void setRights(String rights) {
_rights = new ArrayList();
_rights.add(rights);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public final Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public final boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public final int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public final String toString() {
return _objBean.toString();
}
public final Class getInterface() {
return DCModule.class;
}
public final void copyFrom(Object obj) {
COPY_FROM_HELPER.copy(this,obj);
}
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("titles", String.class);
basePropInterfaceMap.put("creators", String.class);
basePropInterfaceMap.put("subjects", DCSubject.class);
basePropInterfaceMap.put("descriptions", String.class);
basePropInterfaceMap.put("publishers", String.class);
basePropInterfaceMap.put("contributors", String.class);
basePropInterfaceMap.put("dates", Date.class);
basePropInterfaceMap.put("types", String.class);
basePropInterfaceMap.put("formats", String.class);
basePropInterfaceMap.put("identifiers", String.class);
basePropInterfaceMap.put("sources", String.class);
basePropInterfaceMap.put("languages", String.class);
basePropInterfaceMap.put("relations", String.class);
basePropInterfaceMap.put("coverages", String.class);
basePropInterfaceMap.put("rightsList", String.class);
Map basePropClassImplMap = new HashMap();
basePropClassImplMap.put(DCSubject.class,DCSubjectImpl.class);
COPY_FROM_HELPER = new CopyFromHelper(DCModule.class,basePropInterfaceMap,basePropClassImplMap);
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.CopyFrom;
/**
* Subject of the Dublin Core ModuleImpl.
* <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>.
* @author Alejandro Abdelnur
*
*/
public interface DCSubject extends Cloneable,CopyFrom {
/**
* Returns the DublinCore subject taxonomy URI.
* <p>
* @return the DublinCore subject taxonomy URI, <b>null</b> if none.
*
*/
String getTaxonomyUri();
/**
* Sets the DublinCore subject taxonomy URI.
* <p>
* @param taxonomyUri the DublinCore subject taxonomy URI to set, <b>null</b> if none.
*
*/
void setTaxonomyUri(String taxonomyUri);
/**
* Returns the DublinCore subject value.
* <p>
* @return the DublinCore subject value, <b>null</b> if none.
*
*/
String getValue();
/**
* Sets the DublinCore subject value.
* <p>
* @param value the DublinCore subject value to set, <b>null</b> if none.
*
*/
void setValue(String value);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,152 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.io.Serializable;
/**
* Subject of the Dublin Core ModuleImpl, default implementation.
* <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/dc/">Dublin Core module</a>.
* @author Alejandro Abdelnur
*
*/
public class DCSubjectImpl implements Cloneable,Serializable, DCSubject {
private ObjectBean _objBean;
private String _taxonomyUri;
private String _value;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public DCSubjectImpl() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the DublinCore subject taxonomy URI.
* <p>
* @return the DublinCore subject taxonomy URI, <b>null</b> if none.
*
*/
public String getTaxonomyUri() {
return _taxonomyUri;
}
/**
* Sets the DublinCore subject taxonomy URI.
* <p>
* @param taxonomyUri the DublinCore subject taxonomy URI to set, <b>null</b> if none.
*
*/
public void setTaxonomyUri(String taxonomyUri) {
_taxonomyUri = taxonomyUri;
}
/**
* Returns the DublinCore subject value.
* <p>
* @return the DublinCore subject value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the DublinCore subject value.
* <p>
* @param value the DublinCore subject value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
public Class getInterface() {
return DCSubject.class;
}
public void copyFrom(Object obj) {
COPY_FROM_HELPER.copy(this,obj);
}
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("taxonomyUri",String.class);
basePropInterfaceMap.put("value",String.class);
Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(DCSubject.class,basePropInterfaceMap,basePropClassImplMap);
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import java.util.List;
/**
* Objects that can have modules are Extendable.
* @author Dave Johnson
*/
public interface Extendable {
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri);
/**
* Returns the entry modules.
* <p>
* @return a list of ModuleImpl elements with the entry modules,
* an empty list if none.
*
*/
List getModules();
/**
* Sets the entry modules.
* <p>
* @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 modules);
}

View file

@ -0,0 +1,48 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.CopyFrom;
import java.io.Serializable;
/**
* Base class for modules describing Metadata of feeds. Examples of such modules are
* the Dublin Core and Syndication modules.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface Module extends Cloneable,CopyFrom,Serializable{
/**
* Returns the URI of the module.
* <p>
* @return URI of the module.
*
*/
String getUri();
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,99 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Base class for modules describing Metadata of feeds, default implementations.
* Examples of such modules are the Dublin Core and Syndication modules.
* <p>
* @author Alejandro Abdelnur
*
*/
public abstract class ModuleImpl implements Cloneable,Serializable,Module {
private ObjectBean _objBean;
private String _uri;
/**
* Constructor.
* <p>
* @param uri URI of the module.
*
*/
protected ModuleImpl(Class beanClass,String uri) {
_objBean = new ObjectBean(beanClass,this);
_uri = uri;
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the URI of the module.
* <p>
* @return URI of the module.
*
*/
public String getUri() {
return _uri;
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import java.util.Date;
/**
* Syndication ModuleImpl.
* <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/syndication/">Syndication module</a>.
* @author Alejandro Abdelnur
*
*/
public interface SyModule extends Module {
/**
* URI of the Syndication ModuleImpl (http://purl.org/rss/1.0/modules/syndication/).
*
*/
String URI = "http://purl.org/rss/1.0/modules/syndication/";
String HOURLY = new String("hourly");
String DAILY = new String("daily");
String WEEKLY = new String("weekly");
String MONTHLY = new String("monthly");
String YEARLY = new String("yearly");
/**
* Returns the Syndication module update period.
* <p>
* @return the Syndication module update period, <b>null</b> if none.
*
*/
String getUpdatePeriod();
/**
* Sets the Syndication module update period.
* <p>
* @param updatePeriod the Syndication module update period to set, <b>null</b> if none.
*
*/
void setUpdatePeriod(String updatePeriod);
/**
* Returns the Syndication module update frequency.
* <p>
* @return the Syndication module update frequency, <b>null</b> if none.
*
*/
int getUpdateFrequency();
/**
* Sets the Syndication module update frequency.
* <p>
* @param updateFrequency the Syndication module update frequency to set, <b>null</b> if none.
*
*/
void setUpdateFrequency(int updateFrequency);
/**
* Returns the Syndication module update base date.
* <p>
* @return the Syndication module update base date, <b>null</b> if none.
*
*/
Date getUpdateBase();
/**
* Sets the Syndication module update base date.
* <p>
* @param updateBase the Syndication module update base date to set, <b>null</b> if none.
*
*/
void setUpdateBase(Date updateBase);
}

View file

@ -0,0 +1,139 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.*;
/**
* Syndication ModuleImpl, default implementation.
* <p>
* @see <a href="http://web.resource.org/rss/1.0/modules/syndication/">Syndication module</a>.
* @author Alejandro Abdelnur
*
*/
public class SyModuleImpl extends ModuleImpl implements SyModule {
private static final Set PERIODS = new HashSet();
static {
PERIODS.add(HOURLY );
PERIODS.add(DAILY );
PERIODS.add(WEEKLY );
PERIODS.add(MONTHLY);
PERIODS.add(YEARLY );
}
private String _updatePeriod;
private int _updateFrequency;
private Date _updateBase;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyModuleImpl() {
super(SyModule.class,URI);
}
/**
* Returns the Syndication module update period.
* <p>
* @return the Syndication module update period, <b>null</b> if none.
*
*/
public String getUpdatePeriod() {
return _updatePeriod;
}
/**
* Sets the Syndication module update period.
* <p>
* @param updatePeriod the Syndication module update period to set, <b>null</b> if none.
*
*/
public void setUpdatePeriod(String updatePeriod) {
if (!PERIODS.contains(updatePeriod)) {
throw new IllegalArgumentException("Invalid period ["+updatePeriod+"]");
}
_updatePeriod = updatePeriod;
}
/**
* Returns the Syndication module update frequency.
* <p>
* @return the Syndication module update frequency, <b>null</b> if none.
*
*/
public int getUpdateFrequency() {
return _updateFrequency;
}
/**
* Sets the Syndication module update frequency.
* <p>
* @param updateFrequency the Syndication module update frequency to set, <b>null</b> if none.
*
*/
public void setUpdateFrequency(int updateFrequency) {
_updateFrequency = updateFrequency;
}
/**
* Returns the Syndication module update base date.
* <p>
* @return the Syndication module update base date, <b>null</b> if none.
*
*/
public Date getUpdateBase() {
return _updateBase;
}
/**
* Sets the Syndication module update base date.
* <p>
* @param updateBase the Syndication module update base date to set, <b>null</b> if none.
*
*/
public void setUpdateBase(Date updateBase) {
_updateBase = updateBase;
}
public Class getInterface() {
return SyModule.class;
}
public void copyFrom(Object obj) {
COPY_FROM_HELPER.copy(this,obj);
}
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("updatePeriod",String.class);
basePropInterfaceMap.put("updateFrequency",Integer.TYPE);
basePropInterfaceMap.put("updateBase",Date.class);
Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyModule.class,basePropInterfaceMap,basePropClassImplMap);
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.module.impl;
import com.sun.syndication.feed.module.Module;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class ModuleUtils {
public static List cloneModules(List modules) {
List cModules = null;
if (modules!=null) {
cModules = new ArrayList();
for (int i=0;i<modules.size();i++) {
Module module = (Module) modules.get(i);
try {
Object c = module.clone();
cModules.add(c);
}
catch (Exception ex) {
throw new RuntimeException("Cloning modules",ex);
}
}
}
return cModules;
}
public static Module getModule(List modules,String uri) {
Module module = null;
for (int i=0;module==null && modules!=null && i<modules.size();i++) {
module = (Module) modules.get(i);
if (!module.getUri().equals(uri)) {
module = null;
}
}
return module;
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for categories of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Category implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _domain;
private String _value;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Category() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the category domain.
* <p>
* @return the category domain, <b>null</b> if none.
*
*/
public String getDomain() {
return _domain;
}
/**
* Sets the category domain.
* <p>
* @param domain the category domain to set, <b>null</b> if none.
*
*/
public void setDomain(String domain) {
_domain = domain;
}
/**
* Returns the category value.
* <p>
* @return the category value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the category value.
* <p>
* @param value the category value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
}

View file

@ -0,0 +1,583 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import java.util.*;
/**
* Bean for RSS feeds.
* <p>
* It handles all RSS versions (0.9, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0)
* without losing information.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Channel extends WireFeed {
public static final String SUNDAY = "sunday";
public static final String MONDAY = "monday";
public static final String TUESDAY = "tuesday";
public static final String WEDNESDAY = "wednesday";
public static final String THURSDAY = "thursday";
public static final String FRIDAY = "friday";
public static final String SATURDAY = "saturday";
private static final Set DAYS = new HashSet();
static {
DAYS.add(SUNDAY );
DAYS.add(MONDAY );
DAYS.add(TUESDAY );
DAYS.add(WEDNESDAY);
DAYS.add(THURSDAY );
DAYS.add(FRIDAY );
DAYS.add(SATURDAY );
}
private String _title;
private String _description;
private String _link;
private String _uri;
private Image _image;
private List _items;
private TextInput _textInput;
private String _language;
private String _rating;
private String _copyright;
private Date _pubDate;
private Date _lastBuildDate;
private String _docs;
private String _managingEditor;
private String _webMaster;
private List _skipHours;
private List _skipDays;
private Cloud _cloud;
private List _categories;
private String _generator;
private int _ttl = -1;
private List _modules;
/**
* Default constructor, for bean cloning purposes only.
*
*/
public Channel() {
}
/**
* Channel Constructor. All properties, except the type, are set to <b>null</b>.
* <p>
* @param type the type of the RSS feed.
*
*/
public Channel(String type) {
super(type);
}
/**
* Returns the channel title.
* <p>
* @return the channel title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the channel title.
* <p>
* @param title the channel title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the channel description.
* <p>
* @return the channel description, <b>null</b> if none.
*
*/
public String getDescription() {
return _description;
}
/**
* Sets the channel description.
* <p>
* @param description the channel description to set, <b>null</b> if none.
*
*/
public void setDescription(String description) {
_description = description;
}
/**
* Returns the channel link.
* <p>
* @return the channel link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the channel link.
* <p>
* @param link the channel link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
/**
* Returns the channel uri.
* <p>
* @return the channel uri, <b>null</b> if none.
*/
public String getUri() {
return _uri;
}
/**
* Sets the channel uri.
* <p>
* @param uri the channel uri, <b>null</b> if none.
*/
public void setUri(String uri) {
_uri = uri;
}
/**
* Returns the channel image.
* <p>
* @return the channel image, <b>null</b> if none.
*
*/
public Image getImage() {
return _image;
}
/**
* Sets the channel image.
* <p>
* @param image the channel image to set, <b>null</b> if none.
*
*/
public void setImage(Image image) {
_image = image;
}
/**
* Returns the channel items.
* <p>
* @return a list of Item elements with the channel items,
* an empty list if none.
*
*/
public List getItems() {
return (_items==null) ? (_items=new ArrayList()) : _items;
}
/**
* Sets the channel items.
* <p>
* @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 items) {
_items = items;
}
/**
* Returns the channel text input.
* <p>
* @return the channel text input, <b>null</b> if none.
*
*/
public TextInput getTextInput() {
return _textInput;
}
/**
* Sets the channel text input.
* <p>
* @param textInput the channel text input to set, <b>null</b> if none.
*
*/
public void setTextInput(TextInput textInput) {
_textInput = textInput;
}
/**
* Returns the channel language.
* <p>
* @return the channel language, <b>null</b> if none.
*
*/
public String getLanguage() {
return _language;
}
/**
* Sets the channel language.
* <p>
* @param language the channel language to set, <b>null</b> if none.
*
*/
public void setLanguage(String language) {
_language = language;
}
/**
* Returns the channel rating.
* <p>
* @return the channel rating, <b>null</b> if none.
*
*/
public String getRating() {
return _rating;
}
/**
* Sets the channel rating.
* <p>
* @param rating the channel rating to set, <b>null</b> if none.
*
*/
public void setRating(String rating) {
_rating = rating;
}
/**
* Returns the channel copyright.
* <p>
* @return the channel copyright, <b>null</b> if none.
*
*/
public String getCopyright() {
return _copyright;
}
/**
* Sets the channel copyright.
* <p>
* @param copyright the channel copyright to set, <b>null</b> if none.
*
*/
public void setCopyright(String copyright) {
_copyright = copyright;
}
/**
* Returns the channel publishing date.
* <p>
* @return the channel publishing date, <b>null</b> if none.
*
*/
public Date getPubDate() {
return _pubDate;
}
/**
* Sets the channel publishing date.
* <p>
* @param pubDate the channel publishing date to set, <b>null</b> if none.
*
*/
public void setPubDate(Date pubDate) {
_pubDate = pubDate;
}
/**
* Returns the channel last build date.
* <p>
* @return the channel last build date, <b>null</b> if none.
*
*/
public Date getLastBuildDate() {
return _lastBuildDate;
}
/**
* Sets the channel last build date.
* <p>
* @param lastBuildDate the channel last build date to set, <b>null</b> if none.
*
*/
public void setLastBuildDate(Date lastBuildDate) {
_lastBuildDate = lastBuildDate;
}
/**
* Returns the channel docs.
* <p>
* @return the channel docs, <b>null</b> if none.
*
*/
public String getDocs() {
return _docs;
}
/**
* Sets the channel docs.
* <p>
* @param docs the channel docs to set, <b>null</b> if none.
*
*/
public void setDocs(String docs) {
_docs = docs;
}
/**
* Returns the channel managing editor.
* <p>
* @return the channel managing editor, <b>null</b> if none.
*
*/
public String getManagingEditor() {
return _managingEditor;
}
/**
* Sets the channel managing editor.
* <p>
* @param managingEditor the channel managing editor to set, <b>null</b> if none.
*
*/
public void setManagingEditor(String managingEditor) {
_managingEditor = managingEditor;
}
/**
* Returns the channel web master.
* <p>
* @return the channel web master, <b>null</b> if none.
*
*/
public String getWebMaster() {
return _webMaster;
}
/**
* Sets the channel web master.
* <p>
* @param webMaster the channel web master to set, <b>null</b> if none.
*
*/
public void setWebMaster(String webMaster) {
_webMaster = webMaster;
}
/**
* Returns the channel skip hours.
* <p>
* @return a list of Integer elements with the channel skip hours,
* an empty list if none.
*
*/
public List getSkipHours() {
return (_skipHours!=null) ? _skipHours : new ArrayList();
}
/**
* Sets the channel skip hours.
* <p>
* @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 skipHours) {
if (skipHours!=null) {
for (int i=0;i<skipHours.size();i++) {
Integer iHour = (Integer) skipHours.get(i);
if (iHour!=null) {
int hour = iHour.intValue();
if (hour<0 || hour>24) {
throw new IllegalArgumentException("Invalid hour ["+hour+"]");
}
}
else {
throw new IllegalArgumentException("Invalid hour [null]");
}
}
}
_skipHours = skipHours;
}
/**
* Returns the channel skip days.
* <p>
* @return a list of Day elements with the channel skip days,
* an empty list if none.
*
*/
public List getSkipDays() {
return (_skipDays!=null) ? _skipDays : new ArrayList();
}
/**
* Sets the channel skip days.
* <p>
* @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 skipDays) {
if (skipDays!=null) {
for (int i=0;i<skipDays.size();i++) {
String day = (String) skipDays.get(i);
if (day!=null) {
day = day.toLowerCase();
if (!DAYS.contains(day)) {
throw new IllegalArgumentException("Invalid day ["+day+"]");
}
skipDays.set(i,day);
}
else {
throw new IllegalArgumentException("Invalid day [null]");
}
}
}
_skipDays = skipDays;
}
/**
* Returns the channel cloud.
* <p>
* @return the channel cloud, <b>null</b> if none.
*
*/
public Cloud getCloud() {
return _cloud;
}
/**
* Sets the channel cloud.
* <p>
* @param cloud the channel cloud to set, <b>null</b> if none.
*
*/
public void setCloud(Cloud cloud) {
_cloud = cloud;
}
/**
* Returns the channel categories.
* <p>
* @return a list of Category elements with the channel categories,
* an empty list if none.
*
*/
public List getCategories() {
return (_categories==null) ? (_categories=new ArrayList()) : _categories;
}
/**
* Sets the channel categories.
* <p>
* @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 categories) {
_categories = categories;
}
/**
* Returns the channel generator.
* <p>
* @return the channel generator, <b>null</b> if none.
*
*/
public String getGenerator() {
return _generator;
}
/**
* Sets the channel generator.
* <p>
* @param generator the channel generator to set, <b>null</b> if none.
*
*/
public void setGenerator(String generator) {
_generator = generator;
}
/**
* Returns the channel time to live.
* <p>
* @return the channel time to live, <b>null</b> if none.
*
*/
public int getTtl() {
return _ttl;
}
/**
* Sets the channel time to live.
* <p>
* @param ttl the channel time to live to set, <b>null</b> if none.
*
*/
public void setTtl(int ttl) {
_ttl = ttl;
}
/**
* Returns the channel modules.
* <p>
* @return a list of ModuleImpl elements with the channel modules,
* an empty list if none.
*
*/
public List getModules() {
return (_modules==null) ? (_modules=new ArrayList()) : _modules;
}
/**
* Sets the channel modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(_modules,uri);
}
}

View file

@ -0,0 +1,190 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for clouds of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Cloud implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _domain;
private int _port;
private String _path;
private String _registerProcedure;
private String _protocol;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Cloud() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the cloud domain.
* <p>
* @return the cloud domain, <b>null</b> if none.
*
*/
public String getDomain() {
return _domain;
}
/**
* Sets the cloud domain.
* <p>
* @param domain the cloud domain to set, <b>null</b> if none.
*
*/
public void setDomain(String domain) {
_domain = domain;
}
/**
* Returns the cloud port.
* <p>
* @return the cloud port, <b>null</b> if none.
*
*/
public int getPort() {
return _port;
}
/**
* Sets the cloud port.
* <p>
* @param port the cloud port to set, <b>null</b> if none.
*
*/
public void setPort(int port) {
_port = port;
}
/**
* Returns the cloud path.
* <p>
* @return the cloud path, <b>null</b> if none.
*
*/
public String getPath() {
return _path;
}
/**
* Sets the cloud path.
* <p>
* @param path the cloud path to set, <b>null</b> if none.
*
*/
public void setPath(String path) {
_path = path;
}
/**
* Returns the cloud register procedure.
* <p>
* @return the cloud register procedure, <b>null</b> if none.
*
*/
public String getRegisterProcedure() {
return _registerProcedure;
}
/**
* Sets the cloud register procedure.
* <p>
* @param registerProcedure the cloud register procedure to set, <b>null</b> if none.
*
*/
public void setRegisterProcedure(String registerProcedure) {
_registerProcedure = registerProcedure;
}
/**
* Returns the cloud protocol.
* <p>
* @return the cloud protocol, <b>null</b> if none.
*
*/
public String getProtocol() {
return _protocol;
}
/**
* Sets the cloud protocol.
* <p>
* @param protocol the cloud protocol to set, <b>null</b> if none.
*
*/
public void setProtocol(String protocol) {
_protocol = protocol;
}
}

View file

@ -0,0 +1,130 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for item descriptions of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Content implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _type;
private String _value;
public static final String HTML = "html";
public static final String TEXT = "text";
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Content() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the description type.
* <p>
* @return the description type, <b>null</b> if none.
*
*/
public String getType() {
return _type;
}
/**
* Sets the description type.
* <p>
* @param type the description type to set, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = type;
}
/**
* Returns the description value.
* <p>
* @return the description value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the description value.
* <p>
* @param value the description value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for item descriptions of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Description implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _type;
private String _value;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Description() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the description type.
* <p>
* @return the description type, <b>null</b> if none.
*
*/
public String getType() {
return _type;
}
/**
* Sets the description type.
* <p>
* @param type the description type to set, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = type;
}
/**
* Returns the description value.
* <p>
* @return the description value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the description value.
* <p>
* @param value the description value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
}

View file

@ -0,0 +1,148 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for item enclosures of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Enclosure implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _url;
private long _length;
private String _type;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Enclosure() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the enclosure URL.
* <p>
* @return the enclosure URL, <b>null</b> if none.
*
*/
public String getUrl() {
return _url;
}
/**
* Sets the enclosure URL.
* <p>
* @param url the enclosure URL to set, <b>null</b> if none.
*
*/
public void setUrl(String url) {
_url = url;
}
/**
* Returns the enclosure length.
* <p>
* @return the enclosure length, <b>0</b> if none.
*
*/
public long getLength() {
return _length;
}
/**
* Sets the enclosure length.
* <p>
* @param length the enclosure length to set, <b>0</b> if none.
*
*/
public void setLength(long length) {
_length = length;
}
/**
* Returns the enclosure type.
* <p>
* @return the enclosure type, <b>null</b> if none.
*
*/
public String getType() {
return _type;
}
/**
* Sets the enclosure type.
* <p>
* @param type the enclosure type to set, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = type;
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for item GUIDs of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Guid implements Cloneable,Serializable {
private ObjectBean _objBean;
private boolean _permaLink;
private String _value;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Guid() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the guid perma link.
* <p>
* @return the guid perma link, <b>null</b> if none.
*
*/
public boolean isPermaLink() {
return _permaLink;
}
/**
* Sets the guid perma link.
* <p>
* @param permaLink the guid perma link to set, <b>null</b> if none.
*
*/
public void setPermaLink(boolean permaLink) {
_permaLink = permaLink;
}
/**
* Returns the guid value.
* <p>
* @return the guid value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the guid value.
* <p>
* @param value the guid value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
}

View file

@ -0,0 +1,211 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for images of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Image implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _title;
private String _url;
private String _link;
private int _width = -1;
private int _height = -1;
private String _description;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Image() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the image title.
* <p>
* @return the image title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the image title.
* <p>
* @param title the image title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the image URL.
* <p>
* @return the image URL, <b>null</b> if none.
*
*/
public String getUrl() {
return _url;
}
/**
* Sets the image URL.
* <p>
* @param url the image URL to set, <b>null</b> if none.
*
*/
public void setUrl(String url) {
_url = url;
}
/**
* Returns the image link.
* <p>
* @return the image link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the image link.
* <p>
* @param link the image link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
/**
* Returns the image width.
* <p>
* @return the image width, <b>null</b> if none.
*
*/
public int getWidth() {
return _width;
}
/**
* Sets the image width.
* <p>
* @param width the image width to set, <b>null</b> if none.
*
*/
public void setWidth(int width) {
_width = width;
}
/**
* Returns the image height.
* <p>
* @return the image height, <b>null</b> if none.
*
*/
public int getHeight() {
return _height;
}
/**
* Sets the image height.
* <p>
* @param height the image height to set, <b>null</b> if none.
*
*/
public void setHeight(int height) {
_height = height;
}
/**
* Returns the image description.
* <p>
* @return the image description, <b>null</b> if none.
*
*/
public String getDescription() {
return _description;
}
/**
* Sets the image description.
* <p>
* @param description the image description to set, <b>null</b> if none.
*
*/
public void setDescription(String description) {
_description = description;
}
}

View file

@ -0,0 +1,435 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.Serializable;
/**
* Bean for items of RSS feeds.
* <p>
* It handles all RSS versions without loosing information.
* <p>
* For RSS1.0 it supports Dublin Core and Syndication modules. Note that
* those modules currently support simple syntax format only.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Item implements Cloneable, Serializable, Extendable {
private ObjectBean _objBean;
private String _title;
private String _link;
private String _uri;
private Description _description;
private Content _content;
private Source _source;
private List _enclosures;
private List _categories;
private Guid _guid;
private String _comments;
private String _author;
private Date _pubDate;
private Date _expirationDate;
private List _modules;
private List _foreignMarkup;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Item() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
if (other == null) {
return false;
}
// can't use foreign markup in equals, due to JDOM equals impl
Object fm = getForeignMarkup();
setForeignMarkup(((Item)other).getForeignMarkup());
boolean ret = _objBean.equals(other);
// restore foreign markup
setForeignMarkup(fm);
return ret;
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the item title.
* <p>
* @return the item title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the item title.
* <p>
* @param title the item title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the item link.
* <p>
* @return the item link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the item link.
* <p>
* @param link the item link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
/**
* Returns the item uri.
* <p>
* @return the item uri, <b>null</b> if none.
*/
public String getUri() {
return _uri;
}
/**
* Sets the item uri.
* <p>
* @param uri the item uri to set, <b>null</b> if none.
*/
public void setUri(String uri) {
_uri = uri;
}
/**
* Returns the item description.
* <p>
* @return the item description, <b>null</b> if none.
*
*/
public Description getDescription() {
return _description;
}
/**
* Sets the item description.
* <p>
* @param description the item description to set, <b>null</b> if none.
*
*/
public void setDescription(Description description) {
_description = description;
}
/**
* Returns the item content.
* <p>
* @return the item content, <b>null</b> if none.
*
*/
public Content getContent() {
return _content;
}
/**
* Sets the item content.
* <p>
* @param content the item content to set, <b>null</b> if none.
*
*/
public void setContent(Content content) {
_content = content;
}
/**
* Returns the item source.
* <p>
* @return the item source, <b>null</b> if none.
*
*/
public Source getSource() {
return _source;
}
/**
* Sets the item source.
* <p>
* @param source the item source to set, <b>null</b> if none.
*
*/
public void setSource(Source source) {
_source = source;
}
/**
* Returns the item enclosures.
* <p>
* @return a list of Enclosure elements with the item enclosures,
* an empty list if none.
*
*/
public List getEnclosures() {
return (_enclosures==null) ? (_enclosures=new ArrayList()) : _enclosures;
}
/**
* Sets the item enclosures.
* <p>
* @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 enclosures) {
_enclosures = enclosures;
}
/**
* Returns the item categories.
* <p>
* @return a list of Category elements with the item categories,
* an empty list if none.
*
*/
public List getCategories() {
return (_categories==null) ? (_categories=new ArrayList()) : _categories;
}
/**
* Sets the item categories.
* <p>
* @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 categories) {
_categories = categories;
}
/**
* Returns the item GUID.
* <p>
* @return the item GUID, <b>null</b> if none.
*
*/
public Guid getGuid() {
return _guid;
}
/**
* Sets the item GUID.
* <p>
* @param guid the item GUID to set, <b>null</b> if none.
*
*/
public void setGuid(Guid guid) {
_guid = guid;
}
/**
* Returns the item comments.
* <p>
* @return the item comments, <b>null</b> if none.
*
*/
public String getComments() {
return _comments;
}
/**
* Sets the item comments.
* <p>
* @param comments the item comments to set, <b>null</b> if none.
*
*/
public void setComments(String comments) {
_comments = comments;
}
/**
* Returns the item author.
* <p>
* @return the item author, <b>null</b> if none.
*
*/
public String getAuthor() {
return _author;
}
/**
* Sets the item author.
* <p>
* @param author the item author to set, <b>null</b> if none.
*
*/
public void setAuthor(String author) {
_author = author;
}
/**
* Returns the item modules.
* <p>
* @return a list of ModuleImpl elements with the item modules,
* an empty list if none.
*
*/
public List getModules() {
return (_modules==null) ? (_modules=new ArrayList()) : _modules;
}
/**
* Sets the item modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(_modules,uri);
}
/**
* Returns the item publishing date.
* <p>
* @return the item publishing date, <b>null</b> if none.
*
*/
public Date getPubDate() {
return _pubDate;
}
/**
* Sets the item publishing date.
* <p>
* @param pubDate the item publishing date to set, <b>null</b> if none.
*
*/
public void setPubDate(Date pubDate) {
_pubDate = pubDate;
}
/**
* Returns the item expiration date.
* <p>
* @return the item expiration date, <b>null</b> if none.
*
*/
public Date getExpirationDate() {
return _expirationDate;
}
/**
* Sets the item expiration date.
* <p>
* @param expirationDate the item expiration date to set, <b>null</b> if none.
*
*/
public void setExpirationDate(Date expirationDate) {
_expirationDate = expirationDate;
}
/**
* Returns foreign markup found at item level.
* <p>
* @return Opaque object to discourage use
*
*/
public Object getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
}
/**
* Sets foreign markup found at item level.
* <p>
* @param foreignMarkup Opaque object to discourage use
*
*/
public void setForeignMarkup(Object foreignMarkup) {
_foreignMarkup = (List)foreignMarkup;
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for item sources of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Source implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _url;
private String _value;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public Source() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the source URL.
* <p>
* @return the source URL, <b>null</b> if none.
*
*/
public String getUrl() {
return _url;
}
/**
* Sets the source URL.
* <p>
* @param url the source URL to set, <b>null</b> if none.
*
*/
public void setUrl(String url) {
_url = url;
}
/**
* Returns the source value.
* <p>
* @return the source value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the source value.
* <p>
* @param value the source value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
}

View file

@ -0,0 +1,169 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.rss;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Bean for text input of RSS feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class TextInput implements Cloneable,Serializable {
private ObjectBean _objBean;
private String _title;
private String _description;
private String _name;
private String _link;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public TextInput() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the text input title.
* <p>
* @return the text input title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the text input title.
* <p>
* @param title the text input title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the text input description.
* <p>
* @return the text input description, <b>null</b> if none.
*
*/
public String getDescription() {
return _description;
}
/**
* Sets the text input description.
* <p>
* @param description the text input description to set, <b>null</b> if none.
*
*/
public void setDescription(String description) {
_description = description;
}
/**
* Returns the text input name.
* <p>
* @return the text input name, <b>null</b> if none.
*
*/
public String getName() {
return _name;
}
/**
* Sets the text input name.
* <p>
* @param name the text input name to set, <b>null</b> if none.
*
*/
public void setName(String name) {
_name = name;
}
/**
* Returns the text input link.
* <p>
* @return the text input link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the text input link.
* <p>
* @param link the text input link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.synd.SyndFeed;
/**
* Interface that defines the functionality to convert a SyndFeedImpl
* to a real feed (RSS or Atom) and vice versa.
* <p>
* Each implementation knows how to deal with a specific type (version)
* of a real feed.
* <p>
* Implementations must be thread safe.
* <p>
* TODO: explain how developers can plugin their own implementations.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface Converter {
/**
* Returns the type (version) of the real feed this converter handles.
* <p>
* @see WireFeed for details on the format of this string.
* <p>
* @return the real feed type.
*
*/
public String getType();
/**
* Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl.
* <p>
* It assumes the given SyndFeedImpl has no properties set.
* <p>
* @param feed real feed to copy/convert.
* @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real feed.
*
*/
public void copyInto(WireFeed feed,SyndFeed syndFeed);
/**
* Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl.
* <p>
* @param syndFeed SyndFeedImpl to copy/convert value from.
* @return a real feed with copied/converted values of the SyndFeedImpl.
*
*/
public WireFeed createRealFeed(SyndFeed syndFeed);
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
/**
* Bean interface for categories of SyndFeedImpl feeds and entries.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface SyndCategory extends Cloneable {
/**
* Returns the category name.
* <p>
* @return the category name, <b>null</b> if none.
*
*/
String getName();
/**
* Sets the category name.
* <p>
* @param name the category name to set, <b>null</b> if none.
*
*/
void setName(String name);
/**
* Returns the category taxonomy URI.
* <p>
* @return the category taxonomy URI, <b>null</b> if none.
*
*/
String getTaxonomyUri();
/**
* Sets the category taxonomy URI.
* <p>
* @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none.
*
*/
void setTaxonomyUri(String taxonomyUri);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,276 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.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;
/**
* Bean for categories of SyndFeedImpl feeds and entries.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndCategoryImpl implements Serializable,SyndCategory {
private ObjectBean _objBean;
private DCSubject _subject;
/**
* For implementations extending SyndContentImpl to be able to use the ObjectBean functionality
* with extended interfaces.
* <p>
* @param subject the DC subject to wrap.
*/
SyndCategoryImpl(DCSubject subject) {
_objBean = new ObjectBean(SyndCategory.class,this);
_subject = subject;
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Package private constructor, used by SyndCategoryListFacade.
* <p>
* @return the DC subject being wrapped.
*
*/
DCSubject getSubject() {
return _subject;
}
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyndCategoryImpl() {
this(new DCSubjectImpl());
}
/**
* Returns the category name.
* <p>
* @return the category name, <b>null</b> if none.
*
*/
public String getName() {
return _subject.getValue();
}
/**
* Sets the category name.
* <p>
* @param name the category name to set, <b>null</b> if none.
*
*/
public void setName(String name) {
_subject.setValue(name);
}
/**
* Returns the category taxonomy URI.
* <p>
* @return the category taxonomy URI, <b>null</b> if none.
*
*/
public String getTaxonomyUri() {
return _subject.getTaxonomyUri();
}
/**
* Sets the category taxonomy URI.
* <p>
* @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none.
*
*/
public void setTaxonomyUri(String taxonomyUri) {
_subject.setTaxonomyUri(taxonomyUri);
}
}
/**
* List implementation for SyndCategoryImpl elements. To be directly used by the SyndFeedImpl
* and SyndEntryImpl classes only.
* <p>
* It acts as a facade on top of the DCSubjectImpl elements of the underlying list
* and remains in synch with it. It is possible to work on either list, the categories
* one or the subjects one and they remain in synch.
* <p>
* This is necessary because the SyndFeedImpl categories are just a convenience to access
* the DublinCore subjects.
* <P>
* All this mess to avoid making DCSubjectImpl implement SyndCategory (which it would be odd).
* <p>
* @author Alejandro Abdelnur
*
*/
class SyndCategoryListFacade extends AbstractList {
private List _subjects;
/**
* Default constructor. Creates and empty list.
*/
public SyndCategoryListFacade() {
this(new ArrayList());
}
/**
* Creates a facade list of categories on top the given subject list.
* <P>
* @param subjects the list of subjects to create the facade.
*
*/
public SyndCategoryListFacade(List subjects) {
_subjects = subjects;
}
/**
* Gets the category by index.
* <p>
* @param index the index position to retrieve the category.
* @return the SyndCategoryImpl in position index, <b>null</b> if none.
*
*/
public Object get(int index) {
return new SyndCategoryImpl((DCSubject) _subjects.get(index));
}
/**
* Returns the size of the list.
* <p>
* @return the size of the list.
*
*/
public int size() {
return _subjects.size();
}
/**
* Sets a category in an existing position in the list.
* <p>
* @param index position to set the category.
* @param obj the SyndCategoryImpl object to set.
* @return the SyndCategoryImpl object that is being replaced, <b>null</b> if none.
*
*/
public Object set(int index,Object obj) {
SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
DCSubject subject = (sCat!=null) ? sCat.getSubject() : null;
subject = (DCSubject) _subjects.set(index,subject);
return (subject!=null) ? new SyndCategoryImpl(subject) : null;
}
/**
* Adds a category to the list.
* <p>
* @param index position to add the category.
* @param obj the SyndCategoryImpl object to add.
*
*/
public void add(int index,Object obj) {
SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
DCSubject subject = (sCat!=null) ? sCat.getSubject() : null;
_subjects.add(index,subject);
}
/**
* Removes a category element from a specific position.
* <p>
* @param index position to remove the category from.
* @return the SyndCategoryImpl being removed from position index, <b>null</b> if none.
*
*/
public Object remove(int index) {
DCSubject subject = (DCSubject) _subjects.remove(index);
return (subject!=null) ? new SyndCategoryImpl(subject) : null;
}
/**
* Returns a list with the DCSubject elements of the SyndCategoryImpl list facade.
* To be used by the SyndFeedImpl class only.
* <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.
*
*/
public static List convertElementsSyndCategoryToSubject(List cList) {
List sList = null;
if (cList!=null) {
sList = new ArrayList();
for (int i=0;i<cList.size();i++) {
SyndCategoryImpl sCat = (SyndCategoryImpl) cList.get(i);
DCSubject subject = null;
if (sCat!=null) {
subject = sCat.getSubject();
}
sList.add(subject);
}
}
return sList;
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom;
/**
* Bean interface for content of SyndFeedImpl entries.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface SyndContent extends Cloneable,CopyFrom {
/**
* Returns the content type.
* <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed.
* <p>
* @return the content type, <b>null</b> if none.
*
*/
String getType();
/**
* Sets the content type.
* <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed.
* <p>
* @param type the content type to set, <b>null</b> if none.
*
*/
void setType(String type);
/**
* Gets the content mode (needed for Atom 0.3 support).
* @return type the content, <b>null</b> if none.
*
*/
String getMode();
/**
* Sets the content mode (needed for Atom 0.3 support).
* @param mode the content mode to set, <b>null</b> if none.
*
*/
void setMode(String mode);
/**
* Returns the content value.
* <p>
* @return the content value, <b>null</b> if none.
*
*/
String getValue();
/**
* Sets the content value.
* <p>
* @param value the content value to set, <b>null</b> if none.
*
*/
void setValue(String value);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,176 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.io.Serializable;
/**
* Bean for content of SyndFeedImpl entries.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndContentImpl implements Serializable,SyndContent {
private ObjectBean _objBean;
private String _type;
private String _value;
private String _mode;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyndContentImpl() {
_objBean = new ObjectBean(SyndContent.class,this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the content type.
* <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed.
* <p>
* @return the content type, <b>null</b> if none.
*
*/
public String getType() {
return _type;
}
/**
* Sets the content type.
* <p>
* When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed.
* <p>
* @param type the content type to set, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = type;
}
/**
* Returns the content mode.
* @return the content mode, <b>null</b> if none.
*
*/
public String getMode() {
return _mode;
}
/**
* Sets the content mode.
* @param mode the content mode to set, <b>null</b> if none.
*
*/
public void setMode(String mode) {
_mode = mode;
}
/**
* Returns the content value.
* <p>
* @return the content value, <b>null</b> if none.
*
*/
public String getValue() {
return _value;
}
/**
* Sets the content value.
* <p>
* @param value the content value to set, <b>null</b> if none.
*
*/
public void setValue(String value) {
_value = value;
}
public Class getInterface() {
return SyndContent.class;
}
public void copyFrom(Object obj) {
COPY_FROM_HELPER.copy(this,obj);
}
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("type",String.class);
basePropInterfaceMap.put("value",String.class);
Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyndContent.class,basePropInterfaceMap,basePropClassImplMap);
}
}

View file

@ -0,0 +1,57 @@
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom;
/**
* @author Alejandro Abdelnur
*/
public interface SyndEnclosure extends Cloneable, CopyFrom {
/**
* Returns the enclosure URL.
* <p>
* @return the enclosure URL, <b>null</b> if none.
*
*/
public String getUrl();
/**
* Sets the enclosure URL.
* <p>
* @param url the enclosure URL to set, <b>null</b> if none.
*
*/
public void setUrl(String url);
/**
* Returns the enclosure length.
* <p>
* @return the enclosure length, <b>0</b> if none.
*
*/
public long getLength();
/**
* Sets the enclosure length.
* <p>
* @param length the enclosure length to set, <b>0</b> if none.
*
*/
public void setLength(long length);
/**
* Returns the enclosure type.
* <p>
* @return the enclosure type, <b>null</b> if none.
*
*/
public String getType();
/**
* Sets the enclosure type.
* <p>
* @param type the enclosure type to set, <b>null</b> if none.
*
*/
public void setType(String type);
}

View file

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

View file

@ -0,0 +1,385 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import java.util.Date;
import java.util.List;
import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.module.Extendable;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.rss.Item;
/**
* Bean interface for entries of SyndFeedImpl feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface SyndEntry extends Cloneable, CopyFrom, Extendable {
/**
* Returns the entry URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* The returned URI is a normalized URI as specified in RFC 2396bis.
* <p>
* @return the entry URI, <b>null</b> if none.
*
*/
String getUri();
/**
* Sets the entry URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* @param uri the entry URI to set, <b>null</b> if none.
*
*/
void setUri(String uri);
/**
* Returns the entry title.
* <p>
* @return the entry title, <b>null</b> if none.
*
*/
String getTitle();
/**
* Sets the entry title.
* <p>
* @param title the entry title to set, <b>null</b> if none.
*
*/
void setTitle(String title);
/**
* Returns the entry title as a text construct.
* <p>
* @return the entry title, <b>null</b> if none.
*
*/
SyndContent getTitleEx();
/**
* Sets the entry title as a text construct.
* <p>
* @param title the entry title to set, <b>null</b> if none.
*
*/
void setTitleEx(SyndContent title);
/**
* Returns the entry link.
* <p>
* @return the entry link, <b>null</b> if none.
*
*/
String getLink();
/**
* Sets the entry link.
* <p>
* @param link the entry link to set, <b>null</b> if none.
*
*/
void setLink(String link);
/**
* Returns the entry links
* <p>
* @return the entry links, <b>null</b> if none.
*
*/
List getLinks();
/**
* Sets the entry links.
* <p>
* @param links the entry links to set, <b>null</b> if none.
*
*/
void setLinks(List links);
/**
* Returns the entry description.
* <p>
* @return the entry description, <b>null</b> if none.
*
*/
SyndContent getDescription();
/**
* Sets the entry description.
* <p>
* @param description the entry description to set, <b>null</b> if none.
*
*/
void setDescription(SyndContent description);
/**
* Returns the entry contents.
* <p>
* @return a list of SyndContentImpl elements with the entry contents,
* an empty list if none.
*
*/
List getContents();
/**
* Sets the entry contents.
* <p>
* @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 contents);
/**
* Returns the entry enclosures.
* <p>
* @return a list of SyndEnclosure elements with the entry enclosures,
* an empty list if none.
*
*/
public List getEnclosures();
/**
* Sets the entry enclosures.
* <p>
* @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 enclosures);
/**
* Returns the entry published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @return the entry published date, <b>null</b> if none.
*
*/
Date getPublishedDate();
/**
* Sets the entry published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @param publishedDate the entry published date to set, <b>null</b> if none.
*
*/
void setPublishedDate(Date publishedDate);
/**
* Returns the entry updated date.
* <p>
* @return the entry updated date, <b>null</b> if none.
*
*/
Date getUpdatedDate();
/**
* Sets the entry updated date.
* <p>
* @param updatedDate the entry updated date to set, <b>null</b> if none.
*
*/
void setUpdatedDate(Date updatedDate);
/**
* Returns the entry authors.
* <p>
* 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
* Dublin Core module creator.
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
List getAuthors();
/**
* Sets the entry author.
* <p>
* For Atom feeds, this sets the authors as a list of SyndPerson
* objects, for RSS feeds this method is a convenience method, it maps
* to the Dublin Core module creator.
* <p>
* @param authors the feed author to set, <b>null</b> if none.
*
*/
void setAuthors(List authors);
/**
* Returns the name of the first entry author in the collection of authors.
* <p>
* 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
* Dublin Core module creator.
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
String getAuthor();
/**
* Sets the entry author.
* <p>
* For Atom feeds, this sets the feed author's name, for RSS feeds
* this method is a convenience method, it maps to the Dublin Core
* module creator.
* <p>
* @param author the feed author to set, <b>null</b> if none.
*/
void setAuthor(String author);
/**
* Returns the feed author.
* <p>
* For Atom feeds, this returns the contributors as a list of
* SyndPerson objects
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
List getContributors();
/**
* Sets the feed contributors.
* <p>
* Returns contributors as a list of SyndPerson objects.
* <p>
* @param contributors the feed contributors to set, <b>null</b> if none.
*
*/
void setContributors(List contributors);
/**
* Returns the entry categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @return a list of SyndCategoryImpl elements with the entry categories,
* an empty list if none.
*
*/
List getCategories();
/**
* Sets the entry categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @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 categories);
/**
* Returns the entry source.
* <p>
* This returns the entry source as a SyndFeed
* <p>
* @return the SyndFeed to which this entry is attributed
*
*/
SyndFeed getSource();
/**
* Sets the entry source feed (for use if different from containing feed)
* <p>
* @param source the original SyndFeed that contained this article
*
*/
void setSource(SyndFeed source);
/**
* Return the original item this SyndEntry is generated from.
* The type of the object returned depends on the original type of
* the feed. Atom 0.3/1.0 will return com.sun.syndication.feed.atom.Entry,
* while RSS will return com.sun.syndication.feed.rss.Item.java.
* If this entry was not generated from a WireFeed, or the SyndFeed
* was not set to preserve the WireFeed then it will return null
*
* @return the WireFeed Item or Entry this Entry is generated from, or null
*/
Object getWireEntry();
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri);
/**
* Returns the entry modules.
* <p>
* @return a list of ModuleImpl elements with the entry modules,
* an empty list if none.
*
*/
List getModules();
/**
* Sets the entry modules.
* <p>
* @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 modules);
/**
* Returns foreign markup found at channel level.
* <p>
* @return Opaque object to discourage use
*
*/
public Object getForeignMarkup();
/**
* Sets foreign markup found at channel level.
* <p>
* @param foreignMarkup Opaque object to discourage use
*
*/
public void setForeignMarkup(Object foreignMarkup);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,571 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.module.*;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.synd.impl.URINormalizer;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.*;
import java.io.Serializable;
/**
* Bean for entries of SyndFeedImpl feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndEntryImpl implements Serializable,SyndEntry {
private ObjectBean _objBean;
private String _uri;
private String _link;
private Date _updatedDate;
private SyndContent _title;
private SyndContent _description;
private List _links;
private List _contents; // deprecated by Atom 1.0
private List _modules;
private List _enclosures;
private List _authors;
private List _contributors;
private SyndFeed _source;
private List _foreignMarkup;
private Object wireEntry; // com.sun.syndication.feed.atom.Entry or com.sun.syndication.feed.rss.Item
// ISSUE: some converters assume this is never null
private List _categories = new ArrayList();
private static final Set IGNORE_PROPERTIES = new HashSet();
/**
* Unmodifiable Set containing the convenience properties of this class.
* <p>
* Convenience properties are mapped to Modules, for cloning the convenience properties
* can be ignored as the will be copied as part of the module cloning.
*/
public static final Set CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
static {
IGNORE_PROPERTIES.add("publishedDate");
IGNORE_PROPERTIES.add("author");
}
/**
* For implementations extending SyndEntryImpl to be able to use the ObjectBean functionality
* with extended interfaces.
* <p>
* @param beanClass
* @param convenienceProperties set containing the convenience properties of the SyndEntryImpl
* (the are ignored during cloning, check CloneableBean for details).
*
*/
protected SyndEntryImpl(Class beanClass,Set convenienceProperties) {
_objBean = new ObjectBean(beanClass,this,convenienceProperties);
}
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyndEntryImpl() {
this(SyndEntry.class,IGNORE_PROPERTIES);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
if (other == null) {
return false;
}
// while ObjectBean does this check this method does a cast to obtain the foreign markup
// so we need to check before doing so.
if (!(other instanceof SyndEntryImpl)) {
return false;
}
// can't use foreign markup in equals, due to JDOM equals impl
Object fm = getForeignMarkup();
setForeignMarkup(((SyndEntryImpl)other).getForeignMarkup());
boolean ret = _objBean.equals(other);
// restore foreign markup
setForeignMarkup(fm);
return ret;
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the entry URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* The returned URI is a normalized URI as specified in RFC 2396bis.
* <p>
* @return the entry URI, <b>null</b> if none.
*
*/
public String getUri() {
return _uri;
}
/**
* Sets the entry URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* @param uri the entry URI to set, <b>null</b> if none.
*
*/
public void setUri(String uri) {
_uri = URINormalizer.normalize(uri);
}
/**
* Returns the entry title.
* <p>
* @return the entry title, <b>null</b> if none.
*
*/
public String getTitle() {
if (_title != null) return _title.getValue();
return null;
}
/**
* Sets the entry title.
* <p>
* @param title the entry title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
if (_title == null) _title = new SyndContentImpl();
_title.setValue(title);
}
/**
* Returns the entry title as a text construct.
* <p>
* @return the entry title, <b>null</b> if none.
*
*/
public SyndContent getTitleEx() {
return _title;
}
/**
* Sets the entry title as a text construct.
* <p>
* @param title the entry title to set, <b>null</b> if none.
*
*/
public void setTitleEx(SyndContent title) {
_title = title;
}
/**
* Returns the entry link.
* <p>
* @return the entry link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the entry link.
* <p>
* @param link the entry link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
/**
* Returns the entry description.
* <p>
* @return the entry description, <b>null</b> if none.
*
*/
public SyndContent getDescription() {
return _description;
}
/**
* Sets the entry description.
* <p>
* @param description the entry description to set, <b>null</b> if none.
*
*/
public void setDescription(SyndContent description) {
_description = description;
}
/**
* Returns the entry contents.
* <p>
* @return a list of SyndContentImpl elements with the entry contents,
* an empty list if none.
*
*/
public List getContents() {
return (_contents==null) ? (_contents=new ArrayList()) : _contents;
}
/**
* Sets the entry contents.
* <p>
* @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 contents) {
_contents = contents;
}
/**
* Returns the entry enclosures.
* <p>
* @return a list of SyndEnclosure elements with the entry enclosures,
* an empty list if none.
*
*/
public List getEnclosures() {
return (_enclosures==null) ? (_enclosures=new ArrayList()) : _enclosures;
}
/**
* Sets the entry enclosures.
* <p>
* @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 enclosures) {
_enclosures = enclosures;
}
/**
* Returns the entry published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @return the entry published date, <b>null</b> if none.
*
*/
public Date getPublishedDate() {
return getDCModule().getDate();
}
/**
* Sets the entry published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @param publishedDate the entry published date to set, <b>null</b> if none.
*
*/
public void setPublishedDate(Date publishedDate) {
getDCModule().setDate(publishedDate);
}
/**
* Returns the entry categories.
* <p>
* @return a list of SyndCategoryImpl elements with the entry categories,
* an empty list if none.
*
*/
public List getCategories() {
return _categories;
}
/**
* Sets the entry categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @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 categories) {
_categories = categories;
}
/**
* Returns the entry modules.
* <p>
* @return a list of ModuleImpl elements with the entry modules,
* an empty list if none.
*
*/
public List getModules() {
if (_modules==null) {
_modules=new ArrayList();
}
if (ModuleUtils.getModule(_modules,DCModule.URI)==null) {
_modules.add(new DCModuleImpl());
}
return _modules;
}
/**
* Sets the entry modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(getModules(),uri);
}
/**
* Returns the Dublin Core module of the feed.
* @return the DC module, it's never <b>null</b>
*
*/
private DCModule getDCModule() {
return (DCModule) getModule(DCModule.URI);
}
public Class getInterface() {
return SyndEntry.class;
}
public void copyFrom(Object obj) {
COPY_FROM_HELPER.copy(this,obj);
}
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("uri",String.class);
basePropInterfaceMap.put("title",String.class);
basePropInterfaceMap.put("link",String.class);
basePropInterfaceMap.put("uri",String.class);
basePropInterfaceMap.put("description",SyndContent.class);
basePropInterfaceMap.put("contents",SyndContent.class);
basePropInterfaceMap.put("enclosures",SyndEnclosure.class);
basePropInterfaceMap.put("modules",Module.class);
Map basePropClassImplMap = new HashMap();
basePropClassImplMap.put(SyndContent.class,SyndContentImpl.class);
basePropClassImplMap.put(SyndEnclosure.class,SyndEnclosureImpl.class);
basePropClassImplMap.put(DCModule.class,DCModuleImpl.class);
basePropClassImplMap.put(SyModule.class,SyModuleImpl.class);
COPY_FROM_HELPER = new CopyFromHelper(SyndEntry.class,basePropInterfaceMap,basePropClassImplMap);
}
/**
* Returns the links
* <p>
* @return Returns the links.
*/
public List getLinks() {
return (_links==null) ? (_links=new ArrayList()) : _links;
}
/**
* Set the links
* <p>
* @param links The links to set.
*/
public void setLinks(List links) {
_links = links;
}
/**
* Returns the updatedDate
* <p>
* @return Returns the updatedDate.
*/
public Date getUpdatedDate() {
return _updatedDate;
}
/**
* Set the updatedDate
* <p>
* @param updatedDate The updatedDate to set.
*/
public void setUpdatedDate(Date updatedDate) {
_updatedDate = updatedDate;
}
public List getAuthors() {
return (_authors==null) ? (_authors=new ArrayList()) : _authors;
}
/* (non-Javadoc)
* @see com.sun.syndication.feed.synd.SyndEntry#setAuthors(java.util.List)
*/
public void setAuthors(List authors) {
_authors = authors;
}
/**
* Returns the entry author.
* <p>
* This method is a convenience method, it maps to the Dublin Core module creator.
* <p>
* @return the entry author, <b>null</b> if none.
*
*/
public String getAuthor() {
String author;
// Start out looking for one or more authors in _authors. For non-Atom
// feeds, _authors may actually be null.
if ((_authors != null) && (_authors.size() > 0)) {
author = ((SyndPerson)_authors.get(0)).getName();
} else {
author = getDCModule().getCreator();
}
if (author == null) {
author = "";
}
return author;
}
/**
* Sets the entry author.
* <p>
* This method is a convenience method, it maps to the Dublin Core module creator.
* <p>
* @param author the entry author to set, <b>null</b> if none.
*
*/
public void setAuthor(String author) {
// Get the DCModule so that we can check to see if "creator" is already
// set.
DCModule dcModule = getDCModule();
String currentValue = dcModule.getCreator();
if ((currentValue == null) || (currentValue.length() == 0)) {
getDCModule().setCreator(author);
}
}
public List getContributors() {
return (_contributors==null) ? (_contributors=new ArrayList()) : _contributors;
}
/* (non-Javadoc)
* @see com.sun.syndication.feed.synd.SyndEntry#setContributors(java.util.List)
*/
public void setContributors(List contributors) {
_contributors = contributors;
}
public SyndFeed getSource() {
return _source;
}
public void setSource(SyndFeed source) {
_source = source;
}
/**
* Returns foreign markup found at channel level.
* <p>
* @return list of JDOM nodes containing channel-level foreign markup,
* an empty list if none.
*
*/
public Object getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
}
/**
* Sets foreign markup found at channel level.
* <p>
* @param foreignMarkup list of JDOM nodes containing channel-level foreign markup,
* an empty list if none.
*
*/
public void setForeignMarkup(Object foreignMarkup) {
_foreignMarkup = (List)foreignMarkup;
}
public Object getWireEntry() {
return wireEntry;
}
public void setWireEntry(Object wireEntry) {
this.wireEntry = wireEntry;
}
}

View file

@ -0,0 +1,516 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.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.List;
/**
* Bean interface for all types of feeds.
* <p>
* It handles all RSS versions and Atom 0.3, it normalizes all info, it may lose information.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
/**
* Returns the real feed types the SyndFeedImpl supports when converting from and to.
* <p>
* @return the real feed type supported.
*/
List getSupportedFeedTypes();
/**
* Creates a real feed containing the information of the SyndFeedImpl.
* <p>
* The feed type of the created WireFeed is taken from the SyndFeedImpl feedType property.
* <p>
* @return the real feed.
*
*/
WireFeed createWireFeed();
/**
* Creates a real feed containing the information of the SyndFeedImpl.
* <p>
* @param feedType the feed type for the WireFeed to be created.
* @return the real feed.
*
*/
WireFeed createWireFeed(String feedType);
/**
* Returns the WireFeed this SyndFeed was created from.
* Will return null if 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
*
*/
WireFeed originalWireFeed();
/**
*
* @return true if this SyndFeed preserves the WireFeed it was created from
*/
boolean isPreservingWireFeed();
/**
* Returns the wire feed type the feed had/will-have when converted from/to a WireFeed.
* <p>
* @return the feed type, <b>null</b> if none.
*
*/
String getFeedType();
/**
* Sets the wire feed type the feed will-have when coverted to a WireFeed.
* <p>
* @param feedType the feed type to set, <b>null</b> if none.
*
*/
void setFeedType(String feedType);
/**
* Returns the charset encoding of a the feed. This is not set by Rome parsers.
* <p>
* @return the charset encoding of the feed.
*
*/
public String getEncoding();
/**
* Sets the charset encoding of a the feed. This is not set by Rome parsers.
* <p>
* @param encoding the charset encoding of the feed.
*
*/
public void setEncoding(String encoding);
/**
* Returns the feed URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* The returned URI is a normalized URI as specified in RFC 2396bis.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @return the feed URI, <b>null</b> if none.
*
*/
String getUri();
/**
* Sets the feed URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @param uri the feed URI to set, <b>null</b> if none.
*
*/
void setUri(String uri);
/**
* Returns the feed title.
* <p>
* @return the feed title, <b>null</b> if none.
*
*/
String getTitle();
/**
* Sets the feed title.
* <p>
* @param title the feed title to set, <b>null</b> if none.
*
*/
void setTitle(String title);
/**
* Returns the feed title.
* <p>
* @return the feed title, <b>null</b> if none.
*
*/
SyndContent getTitleEx();
/**
* Sets the feed title.
* <p>
* @param title the feed title to set, <b>null</b> if none.
*
*/
void setTitleEx(SyndContent title);
/**
* Returns the feed link.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @return the feed link, <b>null</b> if none.
*
*/
String getLink();
/**
* Sets the feed link.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @param link the feed link to set, <b>null</b> if none.
*
*/
void setLink(String link);
/**
* Returns the entry links
* <p>
* @return the entry links, <b>null</b> if none.
*
*/
List getLinks();
/**
* Sets the entry links.
* <p>
* @param links the entry links to set, <b>null</b> if none.
*
*/
void setLinks(List links);
/**
* Returns the feed description.
* <p>
* @return the feed description, <b>null</b> if none.
*
*/
String getDescription();
/**
* Sets the feed description.
* <p>
* @param description the feed description to set, <b>null</b> if none.
*
*/
void setDescription(String description);
/**
* Returns the feed description as a text construct.
* <p>
* @return the feed description, <b>null</b> if none.
*
*/
SyndContent getDescriptionEx();
/**
* Sets the feed description as a text construct.
* <p>
* @param description the feed description to set, <b>null</b> if none.
*
*/
void setDescriptionEx(SyndContent description);
/**
* Returns the feed published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @return the feed published date, <b>null</b> if none.
*
*/
Date getPublishedDate();
/**
* Sets the feed published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @param publishedDate the feed published date to set, <b>null</b> if none.
*
*/
void setPublishedDate(Date publishedDate);
/**
* Returns the feed authors.
* <p>
* 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
* Dublin Core module creator.
* <p>
* @return the feed authors, <b>null</b> if none.
*
*/
List getAuthors();
/**
* Sets the feed authors.
* <p>
* For Atom feeds, this sets the authors as a list of SyndPerson
* objects, for RSS feeds this method is a convenience method, it maps
* to the Dublin Core module creator.
* <p>
* @param authors the feed authors to set, <b>null</b> if none.
*
*/
void setAuthors(List authors);
/**
* Returns the name of the first feed author in the collection of authors.
* <p>
* 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
* Dublin Core module creator.
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
String getAuthor();
/**
* Sets the feed author.
* <p>
* For Atom feeds, this sets the feed author's name, for RSS feeds
* this method is a convenience method, it maps to the Dublin Core
* module creator.
* <p>
* @param author the feed author to set, <b>null</b> if none.
*
*/
void setAuthor(String author);
/**
* Returns the feed author.
* <p>
* For Atom feeds, this returns the contributors as a list of
* SyndPerson objects
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
public List getContributors();
/**
* Sets the feed author.
* <p>
* Returns contributors as a list of SyndPerson objects.
* <p>
* @param contributors the feed contributors to set, <b>null</b> if none.
*
*/
void setContributors(List contributors);
/**
* Returns the feed copyright.
* <p>
* This method is a convenience method, it maps to the Dublin Core module rights.
* <p>
* @return the feed copyright, <b>null</b> if none.
*
*/
String getCopyright();
/**
* Sets the feed copyright.
* <p>
* This method is a convenience method, it maps to the Dublin Core module rights.
* <p>
* @param copyright the feed copyright to set, <b>null</b> if none.
*
*/
void setCopyright(String copyright);
/**
* Returns the feed image.
* <p>
* @return the feed image, <b>null</b> if none.
*
*/
SyndImage getImage();
/**
* Sets the feed image.
* <p>
* @param image the feed image to set, <b>null</b> if none.
*
*/
void setImage(SyndImage image);
/**
* Returns the feed categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @return a list of SyndCategoryImpl elements with the feed categories,
* an empty list if none.
*
*/
List getCategories();
/**
* Sets the feed categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @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 categories);
/**
* Returns the feed entries.
* <p>
* @return a list of SyndEntryImpl elements with the feed entries,
* an empty list if none.
*
*/
List getEntries();
/**
* Sets the feed entries.
* <p>
* @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 entries);
/**
* Returns the feed language.
* <p>
* This method is a convenience method, it maps to the Dublin Core module language.
* <p>
* @return the feed language, <b>null</b> if none.
*
*/
String getLanguage();
/**
* Sets the feed language.
* <p>
* This method is a convenience method, it maps to the Dublin Core module language.
* <p>
* @param language the feed language to set, <b>null</b> if none.
*
*/
void setLanguage(String language);
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri);
/**
* Returns the feed modules.
* <p>
* @return a list of ModuleImpl elements with the feed modules,
* an empty list if none.
*
*/
List getModules();
/**
* Sets the feed modules.
* <p>
* @param modules the list of ModuleImpl elements with the feed modules to set,
* an empty list or <b>null</b> if none.
*
*/
void setModules(List modules);
/**
* Returns foreign markup found at channel level.
* <p>
* @return Opaque object to discourage use
*
*/
public Object getForeignMarkup();
/**
* Sets foreign markup found at channel level.
* <p>
* @param foreignMarkup Opaque object to discourage use
*
*/
public void setForeignMarkup(Object foreignMarkup);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,771 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.*;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.synd.impl.Converters;
import com.sun.syndication.feed.synd.impl.URINormalizer;
import java.util.*;
import java.io.Serializable;
/**
* Bean for all types of feeds.
* <p>
* It handles all RSS versions, Atom 0.3 and Atom 1.0, it normalizes all info, it may lose information.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndFeedImpl implements Serializable, SyndFeed {
private ObjectBean _objBean;
private String _encoding;
private String _uri;
private SyndContent _title;
private SyndContent _description;
private String _feedType;
private String _link;
private List _links;
private SyndImage _image;
private List _entries;
private List _modules;
private List _authors;
private List _contributors;
private List _foreignMarkup;
private WireFeed wireFeed = null;
private boolean preserveWireFeed = false;
private static final Converters CONVERTERS = new Converters();
private static final Set IGNORE_PROPERTIES = new HashSet();
/**
* Unmodifiable Set containing the convenience properties of this class.
* <p>
* Convenience properties are mapped to Modules, for cloning the convenience properties
* can be ignored as the will be copied as part of the module cloning.
*/
public static final Set CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
static {
IGNORE_PROPERTIES.add("publishedDate");
IGNORE_PROPERTIES.add("author");
IGNORE_PROPERTIES.add("copyright");
IGNORE_PROPERTIES.add("categories");
IGNORE_PROPERTIES.add("language");
}
/**
* Returns the real feed types the SyndFeedImpl supports when converting from and to.
* <p>
* @return the real feed type supported.
*/
public List getSupportedFeedTypes() {
return CONVERTERS.getSupportedFeedTypes();
}
/**
* For implementations extending SyndFeedImpl to be able to use the ObjectBean functionality
* with extended interfaces.
* <p>
* @param beanClass
* @param convenienceProperties set containing the convenience properties of the SyndEntryImpl
* (the are ignored during cloning, check CloneableBean for details).
*
*/
protected SyndFeedImpl(Class beanClass,Set convenienceProperties) {
_objBean = new ObjectBean(beanClass,this,convenienceProperties);
}
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyndFeedImpl() {
this(null);
}
/**
* Creates a SyndFeedImpl and populates all its properties out of the
* given RSS Channel or Atom Feed properties.
* <p>
* @param feed the RSS Channel or the Atom Feed to populate the properties from.
*
*/
public SyndFeedImpl(WireFeed feed) {
this(feed, false);
}
/**
* Creates a SyndFeedImpl and populates all its properties out of the
* given RSS Channel or Atom Feed properties, while optionally preserving
* the WireFeed for access via the orignalWireFeed() method.
*
* @param feed
* @param preserveWireFeed
*/
public SyndFeedImpl(WireFeed feed, boolean preserveWireFeed) {
this(SyndFeed.class,IGNORE_PROPERTIES);
if (preserveWireFeed) {
this.wireFeed = feed;
this.preserveWireFeed = preserveWireFeed;
}
if (feed!=null) {
_feedType = feed.getFeedType();
Converter converter = CONVERTERS.getConverter(_feedType);
if (converter==null) {
throw new IllegalArgumentException("Invalid feed type ["+_feedType+"]");
}
converter.copyInto(feed,this);
}
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
if (other == null) {
return false;
}
// can't use foreign markup in equals, due to JDOM equals impl
Object fm = getForeignMarkup();
setForeignMarkup(((SyndFeedImpl)other).getForeignMarkup());
boolean ret = _objBean.equals(other);
// restore foreign markup
setForeignMarkup(fm);
return ret;
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Creates a real feed containing the information of the SyndFeedImpl.
* <p>
* The feed type of the created WireFeed is taken from the SyndFeedImpl feedType property.
* <p>
* @return the real feed.
*
*/
public WireFeed createWireFeed() {
return createWireFeed(_feedType);
}
/**
* Creates a real feed containing the information of the SyndFeedImpl.
* <p>
* @param feedType the feed type for the WireFeed to be created.
* @return the real feed.
*
*/
public WireFeed createWireFeed(String feedType) {
if (feedType==null) {
throw new IllegalArgumentException("Feed type cannot be null");
}
Converter converter = CONVERTERS.getConverter(feedType);
if (converter==null) {
throw new IllegalArgumentException("Invalid feed type ["+feedType+"]");
}
return converter.createRealFeed(this);
}
/**
* Returns the WireFeed this SyndFeed was created from.
* Will return null if the original feed is not stored or if this SyndFeed was not created from a WireFeed.
* <br />
* Note: The wire feed returned here will NOT contain any modifications done on this SyndFeed since it was created.
* That is in contrast to the createWireFeed method, which will reflect the current state of the SyndFeed
*
* @return The WireFeed this was created from, or null
*
*/
public WireFeed originalWireFeed() {
return wireFeed;
}
/**
* Returns the wire feed type the feed had/will-have when coverted from/to a WireFeed.
* <p>
* @return the feed type, <b>null</b> if none.
*
*/
public String getFeedType() {
return _feedType;
}
/**
* Sets the wire feed type the feed will-have when coverted to a WireFeed.
* <p>
* @param feedType the feed type to set, <b>null</b> if none.
*
*/
public void setFeedType(String feedType) {
_feedType = feedType;
}
/**
* Returns the charset encoding of a the feed. This is not set by Rome parsers.
* <p>
* @return the charset encoding of the feed.
*
*/
public String getEncoding() {
return _encoding;
}
/**
* Sets the charset encoding of a the feed. This is not set by Rome parsers.
* <p>
* @param encoding the charset encoding of the feed.
*
*/
public void setEncoding(String encoding) {
_encoding = encoding;
}
/**
* Returns the feed URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* The returned URI is a normalized URI as specified in RFC 2396bis.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @return the feed URI, <b>null</b> if none.
*
*/
public String getUri() {
return _uri;
}
/**
* Sets the feed URI.
* <p>
* 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,
* <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @param uri the feed URI to set, <b>null</b> if none.
*
*/
public void setUri(String uri) {
_uri = URINormalizer.normalize(uri);
}
/**
* Returns the feed title.
* <p>
* @return the feed title, <b>null</b> if none.
*
*/
public String getTitle() {
if (_title != null) return _title.getValue();
return null;
}
/**
* Sets the feed title.
* <p>
* @param title the feed title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
if (_title == null) _title = new SyndContentImpl();
_title.setValue(title);
}
/**
* Returns the feed title as a text construct.
* <p>
* @return the feed title, <b>null</b> if none.
*
*/
public SyndContent getTitleEx() {
return _title;
}
/**
* Sets the feed title as a text construct.
* <p>
* @param title the feed title to set, <b>null</b> if none.
*
*/
public void setTitleEx(SyndContent title) {
_title = title;
}
/**
* Returns the feed link.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @return the feed link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the feed link.
* <p>
* 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
* is the URL that the item is accessible under, the URI is the
* permanent identifier which the aggregator should use to reference
* this item. Often the URI will use some standardized identifier scheme
* such as DOI's so that items can be identified even if they appear in
* multiple feeds with different "links" (they might be on different
* hosting platforms but be the same item). Also, though rare, there
* could be multiple items with the same link but a different URI and
* associated metadata which need to be treated as distinct entities.
* In the RSS 1.0 case the URI must be a valid RDF URI reference.
* <p>
* @param link the feed link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
/**
* Returns the feed description.
* <p>
* @return the feed description, <b>null</b> if none.
*
*/
public String getDescription() {
if (_description != null) return _description.getValue();
return null;
}
/**
* Sets the feed description.
* <p>
* @param description the feed description to set, <b>null</b> if none.
*
*/
public void setDescription(String description) {
if (_description == null) _description = new SyndContentImpl();
_description.setValue(description);
}
/**
* Returns the feed description as a text construct.
* <p>
* @return the feed description, <b>null</b> if none.
*
*/
public SyndContent getDescriptionEx() {
return _description;
}
/**
* Sets the feed description as a text construct.
* <p>
* @param description the feed description to set, <b>null</b> if none.
*
*/
public void setDescriptionEx(SyndContent description) {
_description = description;
}
/**
* Returns the feed published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @return the feed published date, <b>null</b> if none.
*
*/
public Date getPublishedDate() {
return getDCModule().getDate();
}
/**
* Sets the feed published date.
* <p>
* This method is a convenience method, it maps to the Dublin Core module date.
* <p>
* @param publishedDate the feed published date to set, <b>null</b> if none.
*
*/
public void setPublishedDate(Date publishedDate) {
getDCModule().setDate(publishedDate);
}
/**
* Returns the feed copyright.
* <p>
* This method is a convenience method, it maps to the Dublin Core module rights.
* <p>
* @return the feed copyright, <b>null</b> if none.
*
*/
public String getCopyright() {
return getDCModule().getRights();
}
/**
* Sets the feed copyright.
* <p>
* This method is a convenience method, it maps to the Dublin Core module rights.
* <p>
* @param copyright the feed copyright to set, <b>null</b> if none.
*
*/
public void setCopyright(String copyright) {
getDCModule().setRights(copyright);
}
/**
* Returns the feed image.
* <p>
* @return the feed image, <b>null</b> if none.
*
*/
public SyndImage getImage() {
return _image;
}
/**
* Sets the feed image.
* <p>
* @param image the feed image to set, <b>null</b> if none.
*
*/
public void setImage(SyndImage image) {
_image = image;
}
/**
* Returns the feed categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @return a list of SyndCategoryImpl elements with the feed categories,
* an empty list if none.
*
*/
public List getCategories() {
return new SyndCategoryListFacade(getDCModule().getSubjects());
}
/**
* Sets the feed categories.
* <p>
* This method is a convenience method, it maps to the Dublin Core module subjects.
* <p>
* @param categories the list of SyndCategoryImpl elements with the feed categories to set,
* an empty list or <b>null</b> if none.
*
*/
public void setCategories(List categories) {
getDCModule().setSubjects(SyndCategoryListFacade.convertElementsSyndCategoryToSubject(categories));
}
/**
* Returns the feed entries.
* <p>
* @return a list of SyndEntryImpl elements with the feed entries,
* an empty list if none.
*
*/
public List getEntries() {
return (_entries==null) ? (_entries=new ArrayList()) : _entries;
}
/**
* Sets the feed entries.
* <p>
* @param entries the list of SyndEntryImpl elements with the feed entries to set,
* an empty list or <b>null</b> if none.
*
*/
public void setEntries(List entries) {
_entries = entries;
}
/**
* Returns the feed language.
* <p>
* This method is a convenience method, it maps to the Dublin Core module language.
* <p>
* @return the feed language, <b>null</b> if none.
*
*/
public String getLanguage() {
return getDCModule().getLanguage();
}
/**
* Sets the feed language.
* <p>
* This method is a convenience method, it maps to the Dublin Core module language.
* <p>
* @param language the feed language to set, <b>null</b> if none.
*
*/
public void setLanguage(String language) {
getDCModule().setLanguage(language);
}
/**
* Returns the feed modules.
* <p>
* @return a list of ModuleImpl elements with the feed modules,
* an empty list if none.
*
*/
public List getModules() {
if (_modules==null) {
_modules=new ArrayList();
}
if (ModuleUtils.getModule(_modules,DCModule.URI)==null) {
_modules.add(new DCModuleImpl());
}
return _modules;
}
/**
* Sets the feed modules.
* <p>
* @param modules the list of ModuleImpl elements with the feed modules to set,
* an empty list or <b>null</b> if none.
*
*/
public void setModules(List modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(getModules(),uri);
}
/**
* Returns the Dublin Core module of the feed.
* @return the DC module, it's never <b>null</b>
*
*/
private DCModule getDCModule() {
return (DCModule) getModule(DCModule.URI);
}
public Class getInterface() {
return SyndFeed.class;
}
public void copyFrom(Object obj) {
COPY_FROM_HELPER.copy(this,obj);
}
// TODO We need to find out how to refactor this one in a nice reusable way.
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("feedType",String.class);
basePropInterfaceMap.put("encoding",String.class);
basePropInterfaceMap.put("uri",String.class);
basePropInterfaceMap.put("title",String.class);
basePropInterfaceMap.put("link",String.class);
basePropInterfaceMap.put("description",String.class);
basePropInterfaceMap.put("image",SyndImage.class);
basePropInterfaceMap.put("entries",SyndEntry.class);
basePropInterfaceMap.put("modules",Module.class);
Map basePropClassImplMap = new HashMap();
basePropClassImplMap.put(SyndEntry.class,SyndEntryImpl.class);
basePropClassImplMap.put(SyndImage.class,SyndImageImpl.class);
basePropClassImplMap.put(DCModule.class,DCModuleImpl.class);
basePropClassImplMap.put(SyModule.class,SyModuleImpl.class);
COPY_FROM_HELPER = new CopyFromHelper(SyndFeed.class,basePropInterfaceMap,basePropClassImplMap);
}
/**
* Returns the links
* <p>
* @return Returns the links.
*/
public List getLinks() {
return (_links==null) ? (_links=new ArrayList()) : _links;
}
/**
* Set the links
* <p>
* @param links The links to set.
*/
public void setLinks(List links) {
_links = links;
}
public List getAuthors() {
return (_authors==null) ? (_authors=new ArrayList()) : _authors;
}
public void setAuthors(List authors) {
this._authors = authors;
}
/**
* Returns the feed author.
* <p>
* This method is a convenience method, it maps to the Dublin Core module creator.
* <p>
* @return the feed author, <b>null</b> if none.
*
*/
public String getAuthor() {
return getDCModule().getCreator();
}
/**
* Sets the feed author.
* <p>
* This method is a convenience method, it maps to the Dublin Core module creator.
* <p>
* @param author the feed author to set, <b>null</b> if none.
*
*/
public void setAuthor(String author) {
getDCModule().setCreator(author);
}
public List getContributors() {
return (_contributors==null) ? (_contributors=new ArrayList()) : _contributors;
}
public void setContributors(List contributors) {
this._contributors = contributors;
}
/**
* Returns foreign markup found at channel level.
* <p>
* @return Opaque object to discourage use
*
*/
public Object getForeignMarkup() {
return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
}
/**
* Sets foreign markup found at channel level.
* <p>
* @param foreignMarkup Opaque object to discourage use
*
*/
public void setForeignMarkup(Object foreignMarkup) {
_foreignMarkup = (List)foreignMarkup;
}
public boolean isPreservingWireFeed() {
return preserveWireFeed;
}
}

View file

@ -0,0 +1,101 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.CopyFrom;
/**
* Bean interface for images of SyndFeedImpl feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface SyndImage extends Cloneable,CopyFrom {
/**
* Returns the image title.
* <p>
* @return the image title, <b>null</b> if none.
*
*/
String getTitle();
/**
* Sets the image title.
* <p>
* @param title the image title to set, <b>null</b> if none.
*
*/
void setTitle(String title);
/**
* Returns the image URL.
* <p>
* @return the image URL, <b>null</b> if none.
*
*/
String getUrl();
/**
* Sets the image URL.
* <p>
* @param url the image URL to set, <b>null</b> if none.
*
*/
void setUrl(String url);
/**
* Returns the image link.
* <p>
* @return the image link, <b>null</b> if none.
*
*/
String getLink();
/**
* Sets the image link.
* <p>
* @param link the image link to set, <b>null</b> if none.
*
*/
void setLink(String link);
/**
* Returns the image description.
* <p>
* @return the image description, <b>null</b> if none.
*
*/
String getDescription();
/**
* Sets the image description.
* <p>
* @param description the image description to set, <b>null</b> if none.
*
*/
void setDescription(String description);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,195 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.CopyFromHelper;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.io.Serializable;
/**
* Bean for images of SyndFeedImpl feeds.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndImageImpl implements Serializable,SyndImage {
private ObjectBean _objBean;
private String _title;
private String _url;
private String _link;
private String _description;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyndImageImpl() {
_objBean = new ObjectBean(SyndImage.class,this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the image title.
* <p>
* @return the image title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the image title.
* <p>
* @param title the image title to set, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the image URL.
* <p>
* @return the image URL, <b>null</b> if none.
*
*/
public String getUrl() {
return _url;
}
/**
* Sets the image URL.
* <p>
* @param url the image URL to set, <b>null</b> if none.
*
*/
public void setUrl(String url) {
_url = url;
}
/**
* Returns the image link.
* <p>
* @return the image link, <b>null</b> if none.
*
*/
public String getLink() {
return _link;
}
/**
* Sets the image link.
* <p>
* @param link the image link to set, <b>null</b> if none.
*
*/
public void setLink(String link) {
_link = link;
}
/**
* Returns the image description.
* <p>
* @return the image description, <b>null</b> if none.
*
*/
public String getDescription() {
return _description;
}
/**
* Sets the image description.
* <p>
* @param description the image description to set, <b>null</b> if none.
*
*/
public void setDescription(String description) {
_description = description;
}
public Class getInterface() {
return SyndImage.class;
}
public void copyFrom(Object syndImage) {
COPY_FROM_HELPER.copy(this,syndImage);
}
private static final CopyFromHelper COPY_FROM_HELPER;
static {
Map basePropInterfaceMap = new HashMap();
basePropInterfaceMap.put("title",String.class);
basePropInterfaceMap.put("url",String.class);
basePropInterfaceMap.put("link",String.class);
basePropInterfaceMap.put("description",String.class);
Map basePropClassImplMap = Collections.EMPTY_MAP;
COPY_FROM_HELPER = new CopyFromHelper(SyndImage.class,basePropInterfaceMap,basePropClassImplMap);
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
/**
* Represents a link or enclosure associated with entry.
* @author Dave Johnson
*/
public interface SyndLink {
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public abstract Object clone() throws CloneNotSupportedException;
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public abstract boolean equals(Object other);
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public abstract int hashCode();
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public abstract String toString();
/**
* Returns the link rel.
* <p>
* @return the link rel, <b>null</b> if none.
*
*/
public abstract String getRel();
/**
* Sets the link rel.
* <p>
* @param rel the link rel,, <b>null</b> if none.
*
*/
public abstract void setRel(String rel);
/**
* Returns the link type.
* <p>
* @return the link type, <b>null</b> if none.
*
*/
public abstract String getType();
/**
* Sets the link type.
* <p>
* @param type the link type, <b>null</b> if none.
*
*/
public abstract void setType(String type);
/**
* Returns the link href.
* <p>
* @return the link href, <b>null</b> if none.
*
*/
public abstract String getHref();
/**
* Sets the link href.
* <p>
* @param href the link href, <b>null</b> if none.
*
*/
public abstract void setHref(String href);
/**
* Returns the link title.
* <p>
* @return the link title, <b>null</b> if none.
*
*/
public abstract String getTitle();
/**
* Sets the link title.
* <p>
* @param title the link title, <b>null</b> if none.
*
*/
public abstract void setTitle(String title);
/**
* Returns the hreflang
* <p>
* @return Returns the hreflang.
*/
public abstract String getHreflang();
/**
* Set the hreflang
* <p>
* @param hreflang The hreflang to set.
*/
public abstract void setHreflang(String hreflang);
/**
* Returns the length
* <p>
* @return Returns the length.
*/
public abstract long getLength();
/**
* Set the length
* <p>
* @param length The length to set.
*/
public abstract void setLength(long length);
}

View file

@ -0,0 +1,209 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.impl.ObjectBean;
import java.io.Serializable;
/**
* Represents a link or an enclosure.
* <p>
* @author Alejandro Abdelnur
* @author Dave Johnson (updated for Atom 1.0)
*/
public class SyndLinkImpl implements Cloneable,Serializable, SyndLink {
private ObjectBean _objBean;
private String _href;
private String _rel;
private String _type;
private String _hreflang;
private String _title;
private long _length;
/**
* Default constructor. All properties are set to <b>null</b>.
* <p>
*
*/
public SyndLinkImpl() {
_objBean = new ObjectBean(this.getClass(),this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the link rel.
* <p>
* @return the link rel, <b>null</b> if none.
*
*/
public String getRel() {
return _rel;
}
/**
* Sets the link rel.
* <p>
* @param rel the link rel,, <b>null</b> if none.
*
*/
public void setRel(String rel) {
//TODO add check, ask P@ about the check
_rel = rel;
}
/**
* Returns the link type.
* <p>
* @return the link type, <b>null</b> if none.
*
*/
public String getType() {
return _type;
}
/**
* Sets the link type.
* <p>
* @param type the link type, <b>null</b> if none.
*
*/
public void setType(String type) {
_type = type;
}
/**
* Returns the link href.
* <p>
* @return the link href, <b>null</b> if none.
*
*/
public String getHref() {
return _href;
}
/**
* Sets the link href.
* <p>
* @param href the link href, <b>null</b> if none.
*
*/
public void setHref(String href) {
_href = href;
}
/**
* Returns the link title.
* <p>
* @return the link title, <b>null</b> if none.
*
*/
public String getTitle() {
return _title;
}
/**
* Sets the link title.
* <p>
* @param title the link title, <b>null</b> if none.
*
*/
public void setTitle(String title) {
_title = title;
}
/**
* Returns the hreflang
* <p>
* @return Returns the hreflang.
*/
public String getHreflang() {
return _hreflang;
}
/**
* Set the hreflang
* <p>
* @param hreflang The hreflang to set.
*/
public void setHreflang(String hreflang) {
_hreflang = hreflang;
}
/**
* Returns the length
* <p>
* @return Returns the length.
*/
public long getLength() {
return _length;
}
/**
* Set the length
* <p>
* @param length The length to set.
*/
public void setLength(long length) {
_length = length;
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd;
import com.sun.syndication.feed.module.Extendable;
/**
* Bean interface for authors and contributors of SyndFeedImpl feeds and entries.
* <p>
* @author Dave Johnson
*
*/
public interface SyndPerson extends Cloneable, Extendable
{
/**
* Returns name of person
*/
public String getName();
/**
* Sets name of person.
*/
public void setName(String name);
/**
* Returns URI of person.
*/
public String getUri();
/**
* Sets URI of person.
*/
public void setUri(String uri);
/**
* Returns email of person.
*/
public String getEmail();
/**
* Sets email of person.
*/
public void setEmail(String email);
/**
* Creates a deep clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException;
}

View file

@ -0,0 +1,189 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.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 com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import java.util.AbstractList;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
/**
* Bean for authors and contributors of SyndFeedImpl feeds and entries.
* <p>
* @author Dave Johnson
*
*/
public class SyndPersonImpl implements Serializable, SyndPerson {
private ObjectBean _objBean;
private String _name;
private String _uri;
private String _email;
private List _modules;
/**
* For implementations extending SyndContentImpl to be able to use the ObjectBean functionality
* with extended interfaces.
*/
public SyndPersonImpl() {
_objBean = new ObjectBean(SyndPerson.class,this);
}
/**
* Creates a deep 'bean' clone of the object.
* <p>
* @return a clone of the object.
* @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
*
*/
public Object clone() throws CloneNotSupportedException {
return _objBean.clone();
}
/**
* Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
* <p>
* @param other he reference object with which to compare.
* @return <b>true</b> if 'this' object is equal to the 'other' object.
*
*/
public boolean equals(Object other) {
return _objBean.equals(other);
}
/**
* Returns a hashcode value for the object.
* <p>
* It follows the contract defined by the Object hashCode() method.
* <p>
* @return the hashcode of the bean object.
*
*/
public int hashCode() {
return _objBean.hashCode();
}
/**
* Returns the String representation for the object.
* <p>
* @return String representation for the object.
*
*/
public String toString() {
return _objBean.toString();
}
/**
* Returns the person name.
* <p>
* @return the person name, <b>null</b> if none.
*
*/
public String getName() {
return _name;
}
/**
* Sets the category name.
* <p>
* @param name the category name to set, <b>null</b> if none.
*
*/
public void setName(String name) {
_name = name;
}
/**
* Returns the person's e-mail address.
* <p>
* @return the person's e-mail address, <b>null</b> if none.
*
*/
public String getEmail() {
return _email;
}
/**
* Sets the person's e-mail address.
* <p>
* @param email The person's e-mail address to set, <b>null</b> if none.
*
*/
public void setEmail(String email) {
_email = email;
}
/**
* Returns the person's URI.
* <p>
* @return the person's URI, <b>null</b> if none.
*
*/
public String getUri() {
return _uri;
}
/**
* Sets the person's URI.
* <p>
* @param uri the peron's URI to set, <b>null</b> if none.
*
*/
public void setUri(String uri) {
_uri = uri;
}
/**
* Returns the person modules.
* <p>
* @return a list of ModuleImpl elements with the person modules,
* an empty list if none.
*/
public List getModules()
{
if (_modules==null) {
_modules=new ArrayList();
}
return _modules;
}
/**
* Sets the person modules.
* <p>
* @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 modules) {
_modules = modules;
}
/**
* Returns the module identified by a given URI.
* <p>
* @param uri the URI of the ModuleImpl.
* @return The module with the given URI, <b>null</b> if none.
*/
public Module getModule(String uri) {
return ModuleUtils.getModule(getModules(),uri);
}
}

View file

@ -0,0 +1,501 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
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.Feed;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Person;
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.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl;
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.SyndContent;
import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl;
import com.sun.syndication.feed.synd.SyndPerson;
import com.sun.syndication.feed.synd.SyndPersonImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Iterator;
/**
*/
public class ConverterForAtom03 implements Converter {
private String _type;
public ConverterForAtom03() {
this("atom_0.3");
}
protected ConverterForAtom03(String type) {
_type = type;
}
public String getType() {
return _type;
}
public void copyInto(WireFeed feed,SyndFeed syndFeed) {
Feed aFeed = (Feed) feed;
syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules()));
if (((List)feed.getForeignMarkup()).size() > 0) {
syndFeed.setForeignMarkup(feed.getForeignMarkup());
}
syndFeed.setEncoding(aFeed.getEncoding());
syndFeed.setUri(aFeed.getId());
syndFeed.setTitle(aFeed.getTitle());
// use first alternate links as THE link
if (aFeed.getAlternateLinks() != null
&& aFeed.getAlternateLinks().size() > 0) {
Link theLink = (Link)aFeed.getAlternateLinks().get(0);
syndFeed.setLink(theLink.getHrefResolved());
}
// lump alternate and other links together
List syndLinks = new ArrayList();
if (aFeed.getAlternateLinks() != null
&& aFeed.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks()));
}
if (aFeed.getOtherLinks() != null
&& aFeed.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks()));
}
syndFeed.setLinks(syndLinks);
Content tagline = aFeed.getTagline();
if (tagline!=null) {
syndFeed.setDescription(tagline.getValue());
}
List aEntries = aFeed.getEntries();
if (aEntries!=null) {
syndFeed.setEntries(createSyndEntries(aEntries, syndFeed.isPreservingWireFeed()));
}
// Core Atom language/author/copyright/modified elements have precedence
// over DC equivalent info.
String language = aFeed.getLanguage();
if (language!=null) {
syndFeed.setLanguage(language);
}
List authors = aFeed.getAuthors();
if (authors!=null && authors.size() > 0) {
syndFeed.setAuthors(createSyndPersons(authors));
}
String copyright = aFeed.getCopyright();
if (copyright!=null) {
syndFeed.setCopyright(copyright);
}
Date date = aFeed.getModified();
if (date!=null) {
syndFeed.setPublishedDate(date);
}
}
protected List createSyndLinks(List aLinks) {
ArrayList sLinks = new ArrayList();
for (Iterator iter = aLinks.iterator(); iter.hasNext();) {
Link link = (Link)iter.next();
if (!link.getRel().equals("enclosure")) {
SyndLink sLink = createSyndLink(link);
sLinks.add(sLink);
}
}
return sLinks;
}
public SyndLink createSyndLink(Link link) {
SyndLink syndLink = new SyndLinkImpl();
syndLink.setRel( link.getRel());
syndLink.setType( link.getType());
syndLink.setHref( link.getHrefResolved());
syndLink.setTitle( link.getTitle());
return syndLink;
}
protected List createSyndEntries(List atomEntries, boolean preserveWireItems) {
List syndEntries = new ArrayList();
for (int i=0;i<atomEntries.size();i++) {
syndEntries.add(createSyndEntry((Entry) atomEntries.get(i), preserveWireItems));
}
return syndEntries;
}
protected SyndEntry createSyndEntry(Entry entry, boolean preserveWireItem) {
SyndEntryImpl syndEntry = new SyndEntryImpl();
if (preserveWireItem) {
syndEntry.setWireEntry(entry);
}
syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules()));
if (((List)entry.getForeignMarkup()).size() > 0) {
syndEntry.setForeignMarkup((List)entry.getForeignMarkup());
}
syndEntry.setTitle(entry.getTitle());
// if there is exactly one alternate link, use that as THE link
if (entry.getAlternateLinks() != null
&& entry.getAlternateLinks().size() == 1) {
Link theLink = (Link)entry.getAlternateLinks().get(0);
syndEntry.setLink(theLink.getHrefResolved());
}
// Create synd enclosures from enclosure links
List syndEnclosures = new ArrayList();
if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
List oLinks = entry.getOtherLinks();
for (Iterator iter = oLinks.iterator(); iter.hasNext(); ) {
Link thisLink = (Link)iter.next();
if ("enclosure".equals(thisLink.getRel()))
syndEnclosures.add(createSyndEnclosure(entry, thisLink));
}
}
syndEntry.setEnclosures(syndEnclosures);
// lump alternate and other links together
List syndLinks = new ArrayList();
if (entry.getAlternateLinks() != null
&& entry.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getAlternateLinks()));
}
if (entry.getOtherLinks() != null
&& entry.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getOtherLinks()));
}
syndEntry.setLinks(syndLinks);
String id = entry.getId();
if (id!=null) {
syndEntry.setUri(entry.getId());
}
else {
syndEntry.setUri(syndEntry.getLink());
}
Content content = entry.getSummary();
if (content==null) {
List contents = entry.getContents();
if (contents!=null && contents.size()>0) {
content = (Content) contents.get(0);
}
}
if (content!=null) {
SyndContent sContent = new SyndContentImpl();
sContent.setType(content.getType());
sContent.setValue(content.getValue());
syndEntry.setDescription(sContent);
}
List contents = entry.getContents();
if (contents.size()>0) {
List sContents = new ArrayList();
for (int i=0;i<contents.size();i++) {
content = (Content) contents.get(i);
SyndContent sContent = new SyndContentImpl();
sContent.setType(content.getType());
sContent.setValue(content.getValue());
sContent.setMode(content.getMode());
sContents.add(sContent);
}
syndEntry.setContents(sContents);
}
List authors = entry.getAuthors();
if (authors!=null && authors.size() > 0) {
syndEntry.setAuthors(createSyndPersons(authors));
SyndPerson person0 = (SyndPerson)syndEntry.getAuthors().get(0);
syndEntry.setAuthor(person0.getName());
}
Date date = entry.getModified();
if (date==null) {
date = entry.getIssued();
if (date==null) {
date = entry.getCreated();
}
}
if (date!=null) {
syndEntry.setPublishedDate(date);
}
return syndEntry;
}
public SyndEnclosure createSyndEnclosure(Entry entry, Link link) {
SyndEnclosure syndEncl = new SyndEnclosureImpl();
syndEncl.setUrl(link.getHrefResolved());
syndEncl.setType(link.getType());
syndEncl.setLength(link.getLength());
return syndEncl;
}
public WireFeed createRealFeed(SyndFeed syndFeed) {
Feed aFeed = new Feed(getType());
aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
aFeed.setEncoding(syndFeed.getEncoding());
aFeed.setId(syndFeed.getUri());
SyndContent sTitle = syndFeed.getTitleEx();
if (sTitle != null) {
Content title = new Content();
if (sTitle.getType() != null) {
title.setType(sTitle.getType());
}
if (sTitle.getMode() != null) {
title.setMode(sTitle.getMode());
}
title.setValue(sTitle.getValue());
aFeed.setTitleEx(title);
}
// separate SyndEntry's links collection into alternate and other links
List alternateLinks = new ArrayList();
List otherLinks = new ArrayList();
List slinks = syndFeed.getLinks();
if (slinks != null) {
for (Iterator iter=slinks.iterator(); iter.hasNext();) {
SyndLink syndLink = (SyndLink)iter.next();
Link link = createAtomLink(syndLink);
if (link.getRel() == null ||
"".equals(link.getRel().trim()) ||
"alternate".equals(link.getRel())) {
alternateLinks.add(link);
} else {
otherLinks.add(link);
}
}
}
// no alternate link? then use THE link if there is one
if (alternateLinks.size() == 0 && syndFeed.getLink() != null) {
Link link = new Link();
link.setRel("alternate");
link.setHref(syndFeed.getLink());
alternateLinks.add(link);
}
if (alternateLinks.size() > 0) aFeed.setAlternateLinks(alternateLinks);
if (otherLinks.size() > 0) aFeed.setOtherLinks(otherLinks);
String sDesc = syndFeed.getDescription();
if (sDesc!=null) {
Content tagline = new Content();
tagline.setValue(sDesc);
aFeed.setTagline(tagline);
}
aFeed.setLanguage(syndFeed.getLanguage());
List authors = syndFeed.getAuthors();
if (authors!=null && authors.size() > 0) {
aFeed.setAuthors(createAtomPersons(authors));
}
aFeed.setCopyright(syndFeed.getCopyright());
aFeed.setModified(syndFeed.getPublishedDate());
List sEntries = syndFeed.getEntries();
if (sEntries!=null) {
aFeed.setEntries(createAtomEntries(sEntries));
}
return aFeed;
}
protected static List createAtomPersons(List sPersons) {
List persons = new ArrayList();
for (Iterator iter = sPersons.iterator(); iter.hasNext(); ) {
SyndPerson sPerson = (SyndPerson)iter.next();
Person person = new Person();
person.setName(sPerson.getName());
person.setUri(sPerson.getUri());
person.setEmail(sPerson.getEmail());
person.setModules(sPerson.getModules());
persons.add(person);
}
return persons;
}
protected static List createSyndPersons(List aPersons) {
List persons = new ArrayList();
for (Iterator iter = aPersons.iterator(); iter.hasNext(); ) {
Person aPerson = (Person)iter.next();
SyndPerson person = new SyndPersonImpl();
person.setName(aPerson.getName());
person.setUri(aPerson.getUri());
person.setEmail(aPerson.getEmail());
person.setModules(aPerson.getModules());
persons.add(person);
}
return persons;
}
protected List createAtomEntries(List syndEntries) {
List atomEntries = new ArrayList();
for (int i=0;i<syndEntries.size();i++) {
atomEntries.add(createAtomEntry((SyndEntry)syndEntries.get(i)));
}
return atomEntries;
}
protected Entry createAtomEntry(SyndEntry sEntry) {
Entry aEntry = new Entry();
aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
aEntry.setId(sEntry.getUri());
SyndContent sTitle = sEntry.getTitleEx();
if (sTitle!=null) {
Content title = new Content();
if (sTitle.getType() != null) {
title.setType(sTitle.getType());
}
if (sTitle.getMode() != null) {
title.setMode(sTitle.getMode());
}
title.setValue(sTitle.getValue());
aEntry.setTitleEx(title);
}
// separate SyndEntry's links collection into alternate and other links
List alternateLinks = new ArrayList();
List otherLinks = new ArrayList();
List slinks = sEntry.getLinks();
if (slinks != null) {
for (Iterator iter=slinks.iterator(); iter.hasNext();) {
SyndLink syndLink = (SyndLink)iter.next();
Link link = createAtomLink(syndLink);
if (link.getRel() == null ||
"".equals(link.getRel().trim()) ||
"alternate".equals(link.getRel())) {
alternateLinks.add(link);
} else {
otherLinks.add(link);
}
}
}
// no alternate link? then use THE link if there is one
if (alternateLinks.size() == 0 && sEntry.getLink() != null) {
Link link = new Link();
link.setRel("alternate");
link.setHref(sEntry.getLink());
alternateLinks.add(link);
}
List sEnclosures = sEntry.getEnclosures();
if (sEnclosures != null) {
for (Iterator iter=sEnclosures.iterator(); iter.hasNext();) {
SyndEnclosure syndEnclosure = (SyndEnclosure) iter.next();
Link link = createAtomEnclosure(syndEnclosure);
otherLinks.add(link);
}
}
if (alternateLinks.size() > 0) aEntry.setAlternateLinks(alternateLinks);
if (otherLinks.size() > 0) aEntry.setOtherLinks(otherLinks);
SyndContent sContent = sEntry.getDescription();
if (sContent!=null) {
Content content = new Content();
content.setType(sContent.getType());
content.setValue(sContent.getValue());
content.setMode(Content.ESCAPED);
aEntry.setSummary(content);
}
List contents = sEntry.getContents();
if (contents.size()>0) {
List aContents = new ArrayList();
for (int i=0;i<contents.size();i++) {
sContent = (SyndContentImpl) contents.get(i);
Content content = new Content();
content.setType(sContent.getType());
content.setValue(sContent.getValue());
content.setMode(sContent.getMode());
aContents.add(content);
}
aEntry.setContents(aContents);
}
List sAuthors = sEntry.getAuthors();
if (sAuthors!=null && sAuthors.size() > 0) {
aEntry.setAuthors(createAtomPersons(sAuthors));
} else if (sEntry.getAuthor() != null) {
Person person = new Person();
person.setName(sEntry.getAuthor());
List authors = new ArrayList();
authors.add(person);
aEntry.setAuthors(authors);
}
aEntry.setModified(sEntry.getPublishedDate());
aEntry.setIssued(sEntry.getPublishedDate());
return aEntry;
}
public Link createAtomLink(SyndLink syndLink) {
Link link = new Link();
link.setRel( syndLink.getRel());
link.setType( syndLink.getType());
link.setHref( syndLink.getHref());
link.setTitle( syndLink.getTitle());
return link;
}
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;
}
}

View file

@ -0,0 +1,562 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Category;
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.Link;
import com.sun.syndication.feed.atom.Person;
import com.sun.syndication.feed.module.impl.ModuleUtils;
import com.sun.syndication.feed.synd.Converter;
import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndCategoryImpl;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl;
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 {
private String _type;
public ConverterForAtom10() {
this("atom_1.0");
}
protected ConverterForAtom10(String type) {
_type = type;
}
public String getType() {
return _type;
}
public void copyInto(WireFeed feed, SyndFeed syndFeed) {
Feed aFeed = (Feed) feed;
syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules()));
if (((List)feed.getForeignMarkup()).size() > 0) {
syndFeed.setForeignMarkup((List)feed.getForeignMarkup());
}
syndFeed.setEncoding(aFeed.getEncoding());
syndFeed.setUri(aFeed.getId());
Content aTitle = aFeed.getTitleEx();
if (aTitle != null) {
SyndContent c = new SyndContentImpl();
c.setType(aTitle.getType());
c.setValue(aTitle.getValue());
syndFeed.setTitleEx(c);
}
Content aSubtitle = aFeed.getSubtitle();
if (aSubtitle!=null) {
SyndContent c = new SyndContentImpl();
c.setType(aSubtitle.getType());
c.setValue(aSubtitle.getValue());
syndFeed.setDescriptionEx(c);
}
// use first alternate links as THE link
if (aFeed.getAlternateLinks() != null
&& aFeed.getAlternateLinks().size() > 0) {
Link theLink = (Link)aFeed.getAlternateLinks().get(0);
syndFeed.setLink(theLink.getHrefResolved());
}
// lump alternate and other links together
List syndLinks = new ArrayList();
if (aFeed.getAlternateLinks() != null
&& aFeed.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks()));
}
if (aFeed.getOtherLinks() != null
&& aFeed.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks()));
}
syndFeed.setLinks(syndLinks);
List aEntries = aFeed.getEntries();
if (aEntries!=null) {
syndFeed.setEntries(createSyndEntries(aFeed, aEntries, syndFeed.isPreservingWireFeed()));
}
// Core Atom language/author/copyright/modified elements have precedence
// over DC equivalent info.
List authors = aFeed.getAuthors();
if (authors!=null && authors.size() > 0) {
syndFeed.setAuthors(ConverterForAtom03.createSyndPersons(authors));
}
List contributors = aFeed.getContributors();
if (contributors!=null && contributors.size() > 0) {
syndFeed.setContributors(ConverterForAtom03.createSyndPersons(contributors));
}
String rights = aFeed.getRights();
if (rights!=null) {
syndFeed.setCopyright(rights);
}
Date date = aFeed.getUpdated();
if (date!=null) {
syndFeed.setPublishedDate(date);
}
}
protected List createSyndLinks(List aLinks) {
ArrayList sLinks = new ArrayList();
for (Iterator iter = aLinks.iterator(); iter.hasNext();) {
Link link = (Link)iter.next();
SyndLink sLink = createSyndLink(link);
sLinks.add(sLink);
}
return sLinks;
}
protected List createSyndEntries(Feed feed, List atomEntries, boolean preserveWireItems) {
List syndEntries = new ArrayList();
for (int i=0;i<atomEntries.size();i++) {
syndEntries.add(createSyndEntry(feed, (Entry) atomEntries.get(i), preserveWireItems));
}
return syndEntries;
}
protected SyndEntry createSyndEntry(Feed feed, Entry entry, boolean preserveWireItem) {
SyndEntryImpl syndEntry = new SyndEntryImpl();
if (preserveWireItem) {
syndEntry.setWireEntry(entry);
}
syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules()));
if (((List)entry.getForeignMarkup()).size() > 0) {
syndEntry.setForeignMarkup((List)entry.getForeignMarkup());
}
Content eTitle = entry.getTitleEx();
if (eTitle != null) {
syndEntry.setTitleEx(createSyndContent(eTitle));
}
Content summary = entry.getSummary();
if (summary!=null) {
syndEntry.setDescription(createSyndContent(summary));
}
List contents = entry.getContents();
if (contents != null && contents.size() > 0) {
List sContents = new ArrayList();
for (Iterator iter=contents.iterator(); iter.hasNext();) {
Content content = (Content)iter.next();
sContents.add(createSyndContent(content));
}
syndEntry.setContents(sContents);
}
List authors = entry.getAuthors();
if (authors!=null && authors.size() > 0) {
syndEntry.setAuthors(ConverterForAtom03.createSyndPersons(authors));
SyndPerson person0 = (SyndPerson)syndEntry.getAuthors().get(0);
syndEntry.setAuthor(person0.getName());
}
List contributors = entry.getContributors();
if (contributors!=null && contributors.size() > 0) {
syndEntry.setContributors(ConverterForAtom03.createSyndPersons(contributors));
}
Date date = entry.getPublished();
if (date!=null) {
syndEntry.setPublishedDate(date);
}
date = entry.getUpdated();
if (date!=null) {
syndEntry.setUpdatedDate(date);
}
List categories = entry.getCategories();
if (categories!=null) {
List syndCategories = new ArrayList();
for (Iterator iter=categories.iterator(); iter.hasNext();) {
Category c = (Category)iter.next();
SyndCategory syndCategory = new SyndCategoryImpl();
syndCategory.setName(c.getTerm());
syndCategory.setTaxonomyUri(c.getSchemeResolved());
// TODO: categories MAY have labels
// syndCategory.setLabel(c.getLabel());
syndCategories.add(syndCategory);
}
syndEntry.setCategories(syndCategories);
}
// use first alternate link as THE link
if (entry.getAlternateLinks() != null
&& entry.getAlternateLinks().size() > 0) {
Link theLink = (Link)entry.getAlternateLinks().get(0);
syndEntry.setLink(theLink.getHrefResolved());
}
// Create synd enclosures from enclosure links
List syndEnclosures = new ArrayList();
if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
List oLinks = entry.getOtherLinks();
for (Iterator iter = oLinks.iterator(); iter.hasNext(); ) {
Link thisLink = (Link)iter.next();
if ("enclosure".equals(thisLink.getRel()))
syndEnclosures.add(
createSyndEnclosure(feed, entry, thisLink));
}
}
syndEntry.setEnclosures(syndEnclosures);
// lump alternate and other links together
List syndLinks = new ArrayList();
if (entry.getAlternateLinks() != null
&& entry.getAlternateLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getAlternateLinks()));
}
if (entry.getOtherLinks() != null
&& entry.getOtherLinks().size() > 0) {
syndLinks.addAll(createSyndLinks(entry.getOtherLinks()));
}
syndEntry.setLinks(syndLinks);
String id = entry.getId();
if (id!=null) {
syndEntry.setUri(entry.getId());
}
else {
syndEntry.setUri(syndEntry.getLink());
}
// Convert source element Feed into SyndFeed and assign as SyndEntry
// source
Feed source = entry.getSource();
if (source != null) {
SyndFeed syndSource = new SyndFeedImpl(source);
syndEntry.setSource(syndSource);
}
return syndEntry;
}
public SyndEnclosure createSyndEnclosure(Feed feed, Entry entry,
Link link) {
SyndEnclosure syndEncl = new SyndEnclosureImpl();
syndEncl.setUrl(link.getHrefResolved());
syndEncl.setType(link.getType());
syndEncl.setLength(link.getLength());
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) {
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(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;
}
public WireFeed createRealFeed(SyndFeed syndFeed) {
Feed aFeed = new Feed(getType());
aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
aFeed.setEncoding(syndFeed.getEncoding());
aFeed.setId(syndFeed.getUri());
SyndContent sTitle = syndFeed.getTitleEx();
if (sTitle != null) {
Content title = new Content();
title.setType(sTitle.getType());
title.setValue(sTitle.getValue());
aFeed.setTitleEx(title);
}
SyndContent sDesc = syndFeed.getDescriptionEx();
if (sDesc != null) {
Content subtitle = new Content();
subtitle.setType(sDesc.getType());
subtitle.setValue(sDesc.getValue());
aFeed.setSubtitle(subtitle);
}
// separate SyndEntry's links collection into alternate and other links
List alternateLinks = new ArrayList();
List otherLinks = new ArrayList();
List slinks = syndFeed.getLinks();
if (slinks != null) {
for (Iterator iter=slinks.iterator(); iter.hasNext();) {
SyndLink syndLink = (SyndLink)iter.next();
Link link = createAtomLink(syndLink);
if (link.getRel() == null ||
"".equals(link.getRel().trim()) ||
"alternate".equals(link.getRel())) {
alternateLinks.add(link);
} else {
otherLinks.add(link);
}
}
}
// no alternate link? then use THE link if there is one
if (alternateLinks.size() == 0 && syndFeed.getLink() != null) {
Link link = new Link();
link.setRel("alternate");
link.setHref(syndFeed.getLink());
alternateLinks.add(link);
}
if (alternateLinks.size() > 0) aFeed.setAlternateLinks(alternateLinks);
if (otherLinks.size() > 0) aFeed.setOtherLinks(otherLinks);
List sCats = syndFeed.getCategories();
List aCats = new ArrayList();
if (sCats != null) {
for (Iterator iter=sCats.iterator(); iter.hasNext();) {
SyndCategory sCat = (SyndCategory)iter.next();
Category aCat = new Category();
aCat.setTerm(sCat.getName());
// TODO: aCat.setLabel(sCat.getLabel());
aCat.setScheme(sCat.getTaxonomyUri());
aCats.add(aCat);
}
}
if (aCats.size() > 0) aFeed.setCategories(aCats);
List authors = syndFeed.getAuthors();
if (authors!=null && authors.size() > 0) {
aFeed.setAuthors(ConverterForAtom03.createAtomPersons(authors));
}
List contributors = syndFeed.getContributors();
if (contributors!=null && contributors.size() > 0) {
aFeed.setContributors(ConverterForAtom03.createAtomPersons(contributors));
}
aFeed.setRights(syndFeed.getCopyright());
aFeed.setUpdated(syndFeed.getPublishedDate());
List sEntries = syndFeed.getEntries();
if (sEntries!=null) {
aFeed.setEntries(createAtomEntries(sEntries));
}
if (((List)syndFeed.getForeignMarkup()).size() > 0) {
aFeed.setForeignMarkup(syndFeed.getForeignMarkup());
}
return aFeed;
}
protected SyndContent createSyndContent(Content content) {
SyndContent sContent = new SyndContentImpl();
sContent.setType(content.getType());
sContent.setValue(content.getValue());
return sContent;
}
protected List createAtomEntries(List syndEntries) {
List atomEntries = new ArrayList();
for (int i=0;i<syndEntries.size();i++) {
atomEntries.add(createAtomEntry((SyndEntry)syndEntries.get(i)));
}
return atomEntries;
}
protected Content createAtomContent(SyndContent sContent) {
Content content = new Content();
content.setType(sContent.getType());
content.setValue(sContent.getValue());
return content;
}
protected List createAtomContents(List syndContents) {
List atomContents = new ArrayList();
for (int i=0;i<syndContents.size();i++) {
atomContents.add(createAtomContent((SyndContent)syndContents.get(i)));
}
return atomContents;
}
protected Entry createAtomEntry(SyndEntry sEntry) {
Entry aEntry = new Entry();
aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
aEntry.setId(sEntry.getUri());
SyndContent sTitle = sEntry.getTitleEx();
if (sTitle!=null) {
Content title = new Content();
title.setType(sTitle.getType());
title.setValue(sTitle.getValue());
aEntry.setTitleEx(title);
}
SyndContent sDescription = sEntry.getDescription();
if (sDescription!=null) {
Content summary = new Content();
summary.setType(sDescription.getType());
summary.setValue(sDescription.getValue());
aEntry.setSummary(summary);
}
// separate SyndEntry's links collection into alternate and other links
List alternateLinks = new ArrayList();
List otherLinks = new ArrayList();
List slinks = sEntry.getLinks();
List enclosures = sEntry.getEnclosures();
boolean linkRelEnclosureExists = false;
if (slinks != null) {
for (Iterator iter=slinks.iterator(); iter.hasNext();) {
SyndLink syndLink = (SyndLink)iter.next();
Link link = createAtomLink(syndLink);
// Set this flag if there's a link of rel = enclosure so that
// enclosures won't be duplicated when pulled from
// SyndEntry.getEnclosures()
if (syndLink.getRel() != null &&
"enclosure".equals(syndLink.getRel())) {
linkRelEnclosureExists = true;
}
if (link.getRel() == null ||
"".equals(link.getRel().trim()) ||
"alternate".equals(syndLink.getRel())) {
alternateLinks.add(link);
} else {
otherLinks.add(link);
}
}
}
// no alternate link? then use THE link if there is one
if (alternateLinks.size() == 0 && sEntry.getLink() != null) {
Link link = new Link();
link.setRel("alternate");
link.setHref(sEntry.getLink());
alternateLinks.add(link);
}
// add SyndEnclosures as links with rel="enclosure" ONLY if
// there are no SyndEntry.getLinks() with rel="enclosure"
if (enclosures != null && linkRelEnclosureExists == false) {
for (Iterator iter=enclosures.iterator(); iter.hasNext();) {
SyndEnclosure syndEncl = (SyndEnclosure)iter.next();
Link link = createAtomEnclosure(syndEncl);
otherLinks.add(link);
}
}
if (alternateLinks.size() > 0) aEntry.setAlternateLinks(alternateLinks);
if (otherLinks.size() > 0) aEntry.setOtherLinks(otherLinks);
List sCats = sEntry.getCategories();
List aCats = new ArrayList();
if (sCats != null) {
for (Iterator iter=sCats.iterator(); iter.hasNext();) {
SyndCategory sCat = (SyndCategory)iter.next();
Category aCat = new Category();
aCat.setTerm(sCat.getName());
// TODO: aCat.setLabel(sCat.getLabel());
aCat.setScheme(sCat.getTaxonomyUri());
aCats.add(aCat);
}
}
if (aCats.size() > 0) aEntry.setCategories(aCats);
List syndContents = sEntry.getContents();
aEntry.setContents(createAtomContents(syndContents));
List authors = sEntry.getAuthors();
if (authors!=null && authors.size() > 0) {
aEntry.setAuthors(ConverterForAtom03.createAtomPersons(authors));
} else if (sEntry.getAuthor() != null) {
Person person = new Person();
person.setName(sEntry.getAuthor());
authors = new ArrayList();
authors.add(person);
aEntry.setAuthors(authors);
}
List contributors = sEntry.getContributors();
if (contributors!=null && contributors.size() > 0) {
aEntry.setContributors(ConverterForAtom03.createAtomPersons(contributors));
}
aEntry.setPublished(sEntry.getPublishedDate());
// Fix for issue #41 "Use updated instead of published"
// 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
if (sEntry.getUpdatedDate() != null) {
aEntry.setUpdated(sEntry.getUpdatedDate());
} else {
aEntry.setUpdated(sEntry.getPublishedDate());
}
if (((List)sEntry.getForeignMarkup()).size() > 0) {
aEntry.setForeignMarkup((List)sEntry.getForeignMarkup());
}
SyndFeed sSource = sEntry.getSource();
if (sSource != null) {
Feed aSource = (Feed) sSource.createWireFeed(getType());
aEntry.setSource(aSource);
}
return aEntry;
}
}

View file

@ -0,0 +1,172 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.impl.ModuleUtils;
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.synd.*;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class ConverterForRSS090 implements Converter {
private String _type;
public ConverterForRSS090() {
this("rss_0.9");
}
protected ConverterForRSS090(String type) {
_type = type;
}
public String getType() {
return _type;
}
public void copyInto(WireFeed feed,SyndFeed syndFeed) {
syndFeed.setModules(ModuleUtils.cloneModules(feed.getModules()));
if (((List)feed.getForeignMarkup()).size() > 0) {
syndFeed.setForeignMarkup(feed.getForeignMarkup());
}
syndFeed.setEncoding(feed.getEncoding());
Channel channel = (Channel) feed;
syndFeed.setTitle(channel.getTitle());
syndFeed.setLink(channel.getLink());
syndFeed.setDescription(channel.getDescription());
Image image = channel.getImage();
if (image!=null) {
syndFeed.setImage(createSyndImage(image));
}
List items = channel.getItems();
if (items!=null) {
syndFeed.setEntries(createSyndEntries(items, syndFeed.isPreservingWireFeed()));
}
}
protected SyndImage createSyndImage(Image rssImage) {
SyndImage syndImage = new SyndImageImpl();
syndImage.setTitle(rssImage.getTitle());
syndImage.setUrl(rssImage.getUrl());
syndImage.setLink(rssImage.getLink());
return syndImage;
}
protected List createSyndEntries(List rssItems, boolean preserveWireItems) {
List syndEntries = new ArrayList();
for (int i=0;i<rssItems.size();i++) {
syndEntries.add(createSyndEntry((Item) rssItems.get(i), preserveWireItems));
}
return syndEntries;
}
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntryImpl syndEntry = new SyndEntryImpl();
if (preserveWireItem) {
syndEntry.setWireEntry(item);
}
syndEntry.setModules(ModuleUtils.cloneModules(item.getModules()));
if (((List)item.getForeignMarkup()).size() > 0) {
syndEntry.setForeignMarkup(item.getForeignMarkup());
}
syndEntry.setUri(item.getUri());
syndEntry.setLink(item.getLink());
syndEntry.setTitle(item.getTitle());
syndEntry.setLink(item.getLink());
return syndEntry;
}
public WireFeed createRealFeed(SyndFeed syndFeed) {
return createRealFeed(getType(),syndFeed);
}
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) {
Channel channel = new Channel(type);
channel.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
channel.setEncoding(syndFeed.getEncoding());
channel.setTitle(syndFeed.getTitle());
if (syndFeed.getLink() != null) {
channel.setLink(syndFeed.getLink());
}
else
if (syndFeed.getLinks().size() > 0) {
channel.setLink(((SyndLink)syndFeed.getLinks().get(0)).getHref());
}
channel.setDescription(syndFeed.getDescription());
SyndImage sImage = syndFeed.getImage();
if (sImage!=null) {
channel.setImage(createRSSImage(sImage));
}
List sEntries = syndFeed.getEntries();
if (sEntries!=null) {
channel.setItems(createRSSItems(sEntries));
}
if (((List)syndFeed.getForeignMarkup()).size() > 0) {
channel.setForeignMarkup(syndFeed.getForeignMarkup());
}
return channel;
}
protected Image createRSSImage(SyndImage sImage) {
Image image = new Image();
image.setTitle(sImage.getTitle());
image.setUrl(sImage.getUrl());
image.setLink(sImage.getLink());
return image;
}
protected List createRSSItems(List sEntries) {
List list = new ArrayList();
for (int i=0;i<sEntries.size();i++) {
list.add(createRSSItem((SyndEntry)sEntries.get(i)));
}
return list;
}
protected Item createRSSItem(SyndEntry sEntry) {
Item item = new Item();
item.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
item.setTitle(sEntry.getTitle());
item.setLink(sEntry.getLink());
if (((List)sEntry.getForeignMarkup()).size() > 0) {
item.setForeignMarkup(sEntry.getForeignMarkup());
}
String uri = sEntry.getUri();
if (uri != null) {
item.setUri(uri);
}
return item;
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
/**
*/
public class ConverterForRSS091Netscape extends ConverterForRSS091Userland {
public ConverterForRSS091Netscape() {
this("rss_0.91N");
}
protected ConverterForRSS091Netscape(String type) {
super(type);
}
}

View file

@ -0,0 +1,153 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Content;
import com.sun.syndication.feed.rss.Description;
import com.sun.syndication.feed.rss.Image;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndImage;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndPerson;
import java.util.*;
/**
*/
public class ConverterForRSS091Userland extends ConverterForRSS090 {
public ConverterForRSS091Userland() {
this("rss_0.91U");
}
protected ConverterForRSS091Userland(String type) {
super(type);
}
public void copyInto(WireFeed feed,SyndFeed syndFeed) {
Channel channel = (Channel) feed;
super.copyInto(channel,syndFeed);
syndFeed.setLanguage(channel.getLanguage()); //c
syndFeed.setCopyright(channel.getCopyright()); //c
Date pubDate = channel.getPubDate();
if (pubDate!=null) {
syndFeed.setPublishedDate(pubDate); //c
} else if (channel.getLastBuildDate() != null) {
syndFeed.setPublishedDate(channel.getLastBuildDate()); //c
}
String author = channel.getManagingEditor();
if (author!=null) {
List creators = ((DCModule) syndFeed.getModule(DCModule.URI)).getCreators();
if (!creators.contains(author)) {
Set s = new HashSet(); // using a set to remove duplicates
s.addAll(creators); // DC creators
s.add(author); // feed native author
creators.clear();
creators.addAll(s);
}
}
}
protected SyndImage createSyndImage(Image rssImage) {
SyndImage syndImage = super.createSyndImage(rssImage);
syndImage.setDescription(rssImage.getDescription());
return syndImage;
}
// for rss -> synd
// rss.content -> synd.content
// rss.description -> synd.description
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
Description desc = item.getDescription();
if (desc != null) {
SyndContent descContent = new SyndContentImpl();
descContent.setType(desc.getType());
descContent.setValue(desc.getValue());
syndEntry.setDescription(descContent);
}
Content cont = item.getContent();
if (cont != null) {
SyndContent content = new SyndContentImpl();
content.setType(cont.getType());
content.setValue(cont.getValue());
List syndContents = new ArrayList();
syndContents.add(content);
syndEntry.setContents(syndContents);
}
return syndEntry;
}
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) {
Channel channel = (Channel) super.createRealFeed(type,syndFeed);
channel.setLanguage(syndFeed.getLanguage()); //c
channel.setCopyright(syndFeed.getCopyright()); //c
channel.setPubDate(syndFeed.getPublishedDate()); //c
if (syndFeed.getAuthors()!=null && syndFeed.getAuthors().size() > 0) {
SyndPerson author = (SyndPerson)syndFeed.getAuthors().get(0);
channel.setManagingEditor(author.getName());
}
return channel;
}
protected Image createRSSImage(SyndImage sImage) {
Image image = super.createRSSImage(sImage);
image.setDescription(sImage.getDescription());
return image;
}
// for synd -> rss
// synd.content -> rss.content
// synd.description -> rss.description
protected Item createRSSItem(SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry);
SyndContent sContent = sEntry.getDescription();
if (sContent!=null) {
item.setDescription(createItemDescription(sContent));
}
List contents = sEntry.getContents();
if (contents != null && contents.size() > 0) {
SyndContent syndContent = (SyndContent)contents.get(0);
Content cont = new Content();
cont.setValue(syndContent.getValue());
cont.setType(syndContent.getType());
item.setContent(cont);
}
return item;
}
protected Description createItemDescription(SyndContent sContent) {
Description desc = new Description();
desc.setValue(sContent.getValue());
desc.setType(sContent.getType());
return desc;
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.sun.syndication.feed.rss.Category;
import com.sun.syndication.feed.rss.Enclosure;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndCategoryImpl;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl;
import com.sun.syndication.feed.synd.SyndEntry;
/**
*/
public class ConverterForRSS092 extends ConverterForRSS091Userland {
public ConverterForRSS092() {
this("rss_0.92");
}
protected ConverterForRSS092(String type) {
super(type);
}
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
List cats = item.getCategories();
if (cats.size()>0) {
Set s = new LinkedHashSet(); // using a set to 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(s)); //c
}
List enclosures = item.getEnclosures();
if (enclosures.size()>0) {
syndEntry.setEnclosures(createSyndEnclosures(enclosures));
}
return syndEntry;
}
protected List createSyndCategories(List rssCats) {
List syndCats = new ArrayList();
for (int i=0;i<rssCats.size();i++) {
Category rssCat = (Category) rssCats.get(i);
SyndCategory sCat = new SyndCategoryImpl();
sCat.setTaxonomyUri(rssCat.getDomain());
sCat.setName(rssCat.getValue());
syndCats.add(sCat);
}
return syndCats;
}
protected List createSyndEnclosures(List enclosures) {
List sEnclosures = new ArrayList();
for (int i=0;i<enclosures.size();i++) {
Enclosure enc = (Enclosure) enclosures.get(i);
SyndEnclosure sEnc = new SyndEnclosureImpl();
sEnc.setUrl(enc.getUrl());
sEnc.setType(enc.getType());
sEnc.setLength(enc.getLength());
sEnclosures.add(sEnc);
}
return sEnclosures;
}
protected Item createRSSItem(SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry);
List sCats = sEntry.getCategories(); //c
if (sCats.size()>0) {
item.setCategories(createRSSCategories(sCats));
}
List sEnclosures = sEntry.getEnclosures();
if (sEnclosures.size()>0) {
item.setEnclosures(createEnclosures(sEnclosures));
}
return item;
}
protected List createRSSCategories(List sCats) {
List cats = new ArrayList();
for (int i=0;i<sCats.size();i++) {
SyndCategory sCat = (SyndCategory) sCats.get(i);
Category cat = new Category();
cat.setDomain(sCat.getTaxonomyUri());
cat.setValue(sCat.getName());
cats.add(cat);
}
return cats;
}
protected List createEnclosures(List sEnclosures) {
List enclosures = new ArrayList();
for (int i=0;i<sEnclosures.size();i++) {
SyndEnclosure sEnc = (SyndEnclosure) sEnclosures.get(i);
Enclosure enc = new Enclosure();
enc.setUrl(sEnc.getUrl());
enc.setType(sEnc.getType());
enc.setLength(sEnc.getLength());
enclosures.add(enc);
}
return enclosures;
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndEntry;
import java.util.Date;
/**
*/
public class ConverterForRSS093 extends ConverterForRSS092 {
public ConverterForRSS093() {
this("rss_0.93");
}
protected ConverterForRSS093(String type) {
super(type);
}
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
Date pubDate = item.getPubDate();
if (pubDate!=null) {
syndEntry.setPublishedDate(pubDate); //c
}
return syndEntry;
}
protected Item createRSSItem(SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry);
item.setPubDate(sEntry.getPublishedDate()); //c
return item;
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Guid;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
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 ConverterForRSS094() {
this("rss_0.94");
}
protected ConverterForRSS094(String type) {
super(type);
}
public void copyInto(WireFeed feed,SyndFeed syndFeed) {
Channel channel = (Channel) feed;
super.copyInto(channel,syndFeed);
List cats = channel.getCategories(); //c
if (cats.size()>0) {
Set s = new HashSet(); // using a set to remove duplicates
s.addAll(createSyndCategories(cats)); // feed native categories (as syndcat)
s.addAll(syndFeed.getCategories()); // DC subjects (as syndcat)
syndFeed.setCategories(new ArrayList(s));
}
}
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
// adding native feed author to DC creators list
String author = item.getAuthor();
if (author!=null) {
List creators = ((DCModule)syndEntry.getModule(DCModule.URI)).getCreators();
if (!creators.contains(author)) {
Set s = new HashSet(); // using a set to remove duplicates
s.addAll(creators); // DC creators
s.add(author); // feed native author
creators.clear();
creators.addAll(s);
}
}
Guid guid = item.getGuid();
if (guid!=null) {
syndEntry.setUri(guid.getValue());
if (item.getLink()==null && guid.isPermaLink()) {
syndEntry.setLink(guid.getValue());
}
}
else {
syndEntry.setUri(item.getLink());
}
return syndEntry;
}
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) {
Channel channel = (Channel) super.createRealFeed(type,syndFeed);
List cats = syndFeed.getCategories(); //c
if (cats.size()>0) {
channel.setCategories(createRSSCategories(cats));
}
return channel;
}
protected Item createRSSItem(SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry);
if (sEntry.getAuthors()!=null && sEntry.getAuthors().size() > 0) {
SyndPerson author = (SyndPerson)sEntry.getAuthors().get(0);
item.setAuthor(author.getEmail());
}
Guid guid = null;
String uri = sEntry.getUri();
if (uri!=null) {
guid = new Guid();
guid.setPermaLink(false);
guid.setValue(uri);
}
else {
String link = sEntry.getLink();
if (link!=null) {
guid = new Guid();
guid.setPermaLink(true);
guid.setValue(link);
}
}
item.setGuid(guid);
return item;
}
}

View file

@ -0,0 +1,131 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Content;
import com.sun.syndication.feed.rss.Description;
import com.sun.syndication.feed.rss.Item;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class ConverterForRSS10 extends ConverterForRSS090 {
public ConverterForRSS10() {
this("rss_1.0");
}
protected ConverterForRSS10(String type) {
super(type);
}
public void copyInto(WireFeed feed,SyndFeed syndFeed) {
Channel channel = (Channel) feed;
super.copyInto(channel,syndFeed);
if (channel.getUri() != null) {
syndFeed.setUri(channel.getUri());
} else {
// if URI is not set use the value for link
syndFeed.setUri(channel.getLink());
}
}
// for rss -> synd
// rss.content -> synd.content
// rss.description -> synd.description
protected SyndEntry createSyndEntry(Item item, boolean preserveWireItem) {
SyndEntry syndEntry = super.createSyndEntry(item, preserveWireItem);
Description desc = item.getDescription();
if (desc!=null) {
SyndContent descContent = new SyndContentImpl();
descContent.setType(desc.getType());
descContent.setValue(desc.getValue());
syndEntry.setDescription(descContent);
}
Content cont = item.getContent();
if (cont!=null) {
SyndContent contContent = new SyndContentImpl();
contContent.setType(cont.getType());
contContent.setValue(cont.getValue());
List contents = new ArrayList();
contents.add(contContent);
syndEntry.setContents(contents);
}
return syndEntry;
}
protected WireFeed createRealFeed(String type,SyndFeed syndFeed) {
Channel channel = (Channel) super.createRealFeed(type,syndFeed);
if (syndFeed.getUri() != null) {
channel.setUri(syndFeed.getUri());
} else {
// if URI is not set use the value for link
channel.setUri(syndFeed.getLink());
}
return channel;
}
// for synd -> rss
// synd.content -> rss.content
// synd.description -> rss.description
protected Item createRSSItem(SyndEntry sEntry) {
Item item = super.createRSSItem(sEntry);
SyndContent desc = sEntry.getDescription();
if (desc!=null) {
item.setDescription(createItemDescription(desc));
}
List contents = sEntry.getContents();
if (contents!=null && contents.size() > 0) {
item.setContent(createItemContent((SyndContent)contents.get(0)));
}
String uri = sEntry.getUri();
if (uri != null) {
item.setUri(uri);
}
return item;
}
protected Description createItemDescription(SyndContent sContent) {
Description desc = new Description();
desc.setValue(sContent.getValue());
desc.setType(sContent.getType());
return desc;
}
protected Content createItemContent(SyndContent sContent) {
Content cont = new Content();
cont.setValue(sContent.getValue());
cont.setType(sContent.getType());
return cont;
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
/**
*/
public class ConverterForRSS20 extends ConverterForRSS094 {
public ConverterForRSS20() {
this("rss_2.0");
}
protected ConverterForRSS20(String type) {
super(type);
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.feed.synd.impl;
import com.sun.syndication.io.impl.PluginManager;
import com.sun.syndication.feed.synd.Converter;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: tucu
* Date: May 21, 2004
* Time: 5:26:04 PM
* To change this template use Options | File Templates.
*/
public class Converters extends PluginManager {
/**
* Converter.classes= [className] ...
*
*/
public static final String CONVERTERS_KEY = "Converter.classes";
public Converters() {
super(CONVERTERS_KEY);
}
public Converter getConverter(String feedType) {
return (Converter) getPlugin(feedType);
}
protected String getKey(Object obj) {
return ((Converter)obj).getType();
}
public List getSupportedFeedTypes() {
return getKeys();
}
}

View file

@ -0,0 +1,23 @@
package com.sun.syndication.feed.synd.impl;
/**
* Utility class for normalizing an URI as specified in RFC 2396bis.
* <p>
* @author Alejandro Abdelnur
*/
public class URINormalizer {
/**
* Normalizes an URI as specified in RFC 2396bis.
* <p>
* @param uri to normalize.
* @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) {
String normalizedUri = null;
if (uri!=null) {
normalizedUri = uri; //TODO THIS HAS TO BE IMPLEMENTED
}
return normalizedUri;
}
}

View file

@ -0,0 +1,17 @@
package com.sun.syndication.io;
/**
* 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
* generation of their particular namespace. Examples of such parsers
* include the SSE091Generator.
*/
public interface DelegatingModuleGenerator extends ModuleGenerator {
/**
* Provides a parent wirefeed reference to this ModuleParser,
* or "plugin-in".
*
* @param feedGenerator the parent wirefeed generator for this plugin.
*/
void setFeedGenerator(WireFeedGenerator feedGenerator);
}

View file

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

View file

@ -0,0 +1,49 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
/**
* Exception thrown by WireFeedInput, WireFeedOutput, WireFeedParser and WireFeedGenerator instances if they
* can not parse or generate a feed.
* <p>
* @author Alejandro Abdelnur
*
*/
public class FeedException extends Exception {
/**
* Creates a FeedException with a message.
* <p>
* @param msg exception message.
*
*/
public FeedException(String msg) {
super(msg);
}
/**
* Creates a FeedException with a message and a root cause exception.
* <p>
* @param msg exception message.
* @param rootCause root cause exception.
*
*/
public FeedException(String msg,Throwable rootCause) {
super(msg,rootCause);
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.WireFeed;
import org.jdom.Element;
import java.util.Set;
/**
* Injects module metadata into a XML node (JDOM element).
* <p>
* ModuleGenerator instances must thread safe.
* <p>
* TODO: explain how developers can plugin their own implementations.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface ModuleGenerator {
/**
* Returns the namespace URI this generator handles.
* <p>
* @return the namespace URI.
*
*/
public String getNamespaceUri();
/**
* Returns a set with all the URIs (JDOM Namespace elements) this module generator uses.
* <p/>
* It is used by the the feed generators to add their namespace definition in
* the root element of the generated document (forward-missing of Java 5.0 Generics).
* <p/>
*
* @return a set with all the URIs (JDOM Namespace elements) this module generator uses.
*/
public Set getNamespaces();
/**
* Generates and injects module metadata into an XML node (JDOM element).
* <p>
* @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.
*/
public void generate(Module module,Element element);
}

View file

@ -0,0 +1,50 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.module.Module;
import org.jdom.Element;
/**
* Parses module metadata from a XML node (JDOM element).
* <p>
* ModuleParser instances must thread safe.
* <p>
* TODO: explain how developers can plugin their own implementations.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface ModuleParser {
/**
* Returns the namespace URI this parser handles.
* <p>
* @return the namespace URI.
*
*/
public String getNamespaceUri();
/**
* Parses the XML node (JDOM element) extracting module information.
* <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.
*
*/
public Module parse(Element element);
}

View file

@ -0,0 +1,78 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import org.jdom.input.JDOMParseException;
/**
* Exception thrown by WireFeedInput instance if it can not parse a feed.
* <p>
* @author Elaine Chien
*
*/
public class ParsingFeedException extends FeedException {
/**
* Creates a FeedException with a message.
* <p>
* @param msg exception message.
*
*/
public ParsingFeedException(String msg) {
super(msg);
}
/**
* Creates a FeedException with a message and a root cause exception.
* <p>
* @param msg exception message.
* @param rootCause root cause exception.
*
*/
public ParsingFeedException(String msg, Throwable 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
* 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() {
return (getCause() instanceof JDOMParseException)?
((JDOMParseException)getCause()).getColumnNumber(): -1;
}
}

View file

@ -0,0 +1,27 @@
package com.sun.syndication.io;
import org.jdom.JDOMException;
import org.xml.sax.XMLReader;
/*
* 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
* we need to set it and catch the exception if it fails. We also need 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.
*
*/
public class SAXBuilder extends org.jdom.input.SAXBuilder {
public SAXBuilder(boolean _validate) {
super(_validate);
}
public XMLReader createParser() throws JDOMException {
return super.createParser();
}
}

View file

@ -0,0 +1,181 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import org.jdom.Document;
import org.xml.sax.InputSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
/**
* Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C DOM Document or JDom DOcument)
* into an SyndFeedImpl.
* <p>
* It delegates to a WireFeedInput to handle all feed types.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndFeedInput {
private WireFeedInput _feedInput;
private boolean preserveWireFeed = false;
/**
* Creates a SyndFeedInput instance with input validation turned off.
* <p>
*
*/
public SyndFeedInput() {
this(false);
}
/**
* Creates a SyndFeedInput instance.
* <p>
* @param validate indicates if the input should be validated. NOT IMPLEMENTED YET (validation does not happen)
*
*/
public SyndFeedInput(boolean validate) {
_feedInput = new WireFeedInput(validate);
}
/**
* Enables XML healing in the WiredFeedInput instance.
* <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog.
* <p>
* Healing resolves HTML entities (from literal to code number) in the reader.
* <p>
* The healing is done only with the build(File) and build(Reader) signatures.
* <p>
* By default is TRUE.
* <p>
* @param heals TRUE enables stream healing, FALSE disables it.
*
*/
public void setXmlHealerOn(boolean heals) {
_feedInput.setXmlHealerOn(heals);
}
/**
* Indicates if the WiredFeedInput instance will XML heal (if necessary) the character stream.
* <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog.
* <p>
* Healing resolves HTML entities (from literal to code number) in the reader.
* <p>
* The healing is done only with the build(File) and build(Reader) signatures.
* <p>
* By default is TRUE.
* <p>
* @return TRUE if healing is enabled, FALSE if not.
*
*/
public boolean getXmlHealerOn() {
return _feedInput.getXmlHealerOn();
}
/**
* Builds SyndFeedImpl from a file.
* <p>
* @param file file to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the file.
* @throws FileNotFoundException thrown if the file could not be found.
* @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 FeedException if the feed could not be parsed
*
*/
public SyndFeed build(File file) throws FileNotFoundException,IOException,IllegalArgumentException,FeedException {
return new SyndFeedImpl(_feedInput.build(file), preserveWireFeed);
}
/**
* Builds SyndFeedImpl from an Reader.
* <p>
* @param reader Reader to read to create the SyndFeedImpl.
* @return the SyndFeedImpl read from the Reader.
* @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
*
*/
public SyndFeed build(Reader reader) throws IllegalArgumentException,FeedException {
return new SyndFeedImpl(_feedInput.build(reader), preserveWireFeed);
}
/**
* Builds SyndFeedImpl from an W3C SAX InputSource.
* <p>
* @param is W3C SAX InputSource to read to create the SyndFeedImpl.
* @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 FeedException if the feed could not be parsed
*
*/
public SyndFeed build(InputSource is) throws IllegalArgumentException,FeedException {
return new SyndFeedImpl(_feedInput.build(is), preserveWireFeed);
}
/**
* Builds SyndFeedImpl from an W3C DOM document.
* <p>
* @param document W3C DOM document to read to create the SyndFeedImpl.
* @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 FeedException if the feed could not be parsed
*
*/
public SyndFeed build(org.w3c.dom.Document document) throws IllegalArgumentException,FeedException {
return new SyndFeedImpl(_feedInput.build(document), preserveWireFeed);
}
/**
* Builds SyndFeedImpl from an JDOM document.
* <p>
* @param document JDOM document to read to create the SyndFeedImpl.
* @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 FeedException if the feed could not be parsed
*
*/
public SyndFeed build(Document document) throws IllegalArgumentException,FeedException {
return new SyndFeedImpl(_feedInput.build(document), preserveWireFeed);
}
/**
*
* @return true if the WireFeed is made available in the SyndFeed. False by default.
*/
public boolean isPreserveWireFeed() {
return preserveWireFeed;
}
/**
*
* @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;
}
}

View file

@ -0,0 +1,186 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.synd.SyndFeed;
import org.jdom.Document;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
/**
* Generates an XML document (String, File, OutputStream, Writer, W3C DOM document or JDOM document)
* out of an SyndFeedImpl..
* <p>
* It delegates to a WireFeedOutput to generate all feed types.
* <p>
* @author Alejandro Abdelnur
*
*/
public class SyndFeedOutput {
private WireFeedOutput _feedOutput;
/**
* Creates a SyndFeedOutput instance.
* <p>
*
*/
public SyndFeedOutput() {
_feedOutput = new WireFeedOutput();
}
/**
* Creates a String with the XML representation for the given SyndFeedImpl.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as
* the feed encoding property.
* <p>
* @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.
* @throws FeedException thrown if the XML representation for the feed could not be created.
*
*/
public String outputString(SyndFeed feed) throws FeedException {
return _feedOutput.outputString(feed.createWireFeed());
}
/**
* Creates a String with the XML representation for the given SyndFeedImpl.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as
* the feed encoding property.
* <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 prettyPrint pretty-print XML (true) oder collapsed
* @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.
*
*/
public String outputString(SyndFeed feed,boolean prettyPrint) throws FeedException {
return _feedOutput.outputString(feed.createWireFeed(),prettyPrint);
}
/**
* Creates a File containing with the XML representation for the given SyndFeedImpl.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform
* default charset encoding is used to 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>
* @param feed Abstract feed to create XML representation from. The type of 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 FeedException thrown if the XML representation for the feed could not be created.
*
*/
public void output(SyndFeed feed,File file) throws IOException, FeedException {
_feedOutput.output(feed.createWireFeed(),file);
}
/**
* Creates a File containing with the XML representation for the given SyndFeedImpl.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform
* default charset encoding is used to 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>
* @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 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 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 {
_feedOutput.output(feed.createWireFeed(),file,prettyPrint);
}
/**
* Writes to an Writer the XML representation for the given SyndFeedImpl.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as
* the feed encoding property.
* <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 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 {
_feedOutput.output(feed.createWireFeed(),writer);
}
/**
* Writes to an Writer the XML representation for the given SyndFeedImpl.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as
* the feed encoding property.
* <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 prettyPrint pretty-print XML (true) oder collapsed
* @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,boolean prettyPrint) throws IOException, FeedException {
_feedOutput.output(feed.createWireFeed(),writer,prettyPrint);
}
/**
* Creates a W3C DOM document for the given SyndFeedImpl.
* <p>
* This method does not use the feed encoding property.
* <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.
* @return the W3C DOM document for the given SyndFeedImpl.
* @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 {
return _feedOutput.outputW3CDom(feed.createWireFeed());
}
/**
* Creates a JDOM document for the given SyndFeedImpl.
* <p>
* This method does not use the feed encoding property.
* <p>
* @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.
* @throws FeedException thrown if the JDOM document for the feed could not be created.
*
*/
public Document outputJDom(SyndFeed feed) throws FeedException {
return _feedOutput.outputJDom(feed.createWireFeed());
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.FeedException;
import org.jdom.Document;
/**
* Generates an XML document (JDOM) out of a feed for a specific real feed type.
* <p>
* WireFeedGenerator instances must thread safe.
* <p>
* TODO: explain how developers can plugin their own implementations.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface WireFeedGenerator {
/**
* Returns the type of feed the generator creates.
* <p>
* @see WireFeed for details on the format of this string.
* <p>
* @return the type of feed the generator creates.
*
*/
public String getType();
/**
* Creates an XML document (JDOM) for the given feed bean.
* <p>
* @param feed the feed bean to generate the XML document from.
* @return the generated XML document (JDOM).
* @throws IllegalArgumentException thrown if the type of the given feed bean does not
* match with the type of the WireFeedGenerator.
* @throws FeedException thrown if the XML Document could not be created.
*
*/
public Document generate(WireFeed feed) throws IllegalArgumentException,FeedException;
}

View file

@ -0,0 +1,334 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.DOMBuilder;
import org.jdom.input.JDOMParseException;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.impl.FeedParsers;
import com.sun.syndication.io.impl.XmlFixerReader;
/**
* Parses an XML document (File, InputStream, Reader, W3C SAX InputSource, W3C DOM Document or JDom DOcument)
* into an WireFeed (RSS/Atom).
* <p>
* 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).
* <p>
* The WireFeedInput useds liberal parsers.
* <p>
* @author Alejandro Abdelnur
*
*/
public class WireFeedInput {
private static Map clMap = new WeakHashMap();
private static FeedParsers getFeedParsers() {
synchronized(WireFeedInput.class) {
FeedParsers parsers = (FeedParsers)
clMap.get(Thread.currentThread().getContextClassLoader());
if (parsers == null) {
parsers = new FeedParsers();
clMap.put(Thread.currentThread().getContextClassLoader(), parsers);
}
return parsers;
}
}
private static final InputSource EMPTY_INPUTSOURCE = new InputSource(new ByteArrayInputStream(new byte[0]));
private static final EntityResolver RESOLVER = new EmptyEntityResolver();
private static class EmptyEntityResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) {
if(systemId != null && systemId.endsWith(".dtd")) return EMPTY_INPUTSOURCE;
return null;
}
}
private boolean _validate;
private boolean _xmlHealerOn;
/**
* Returns the list of supported input feed types.
* <p>
* @see WireFeed for details on the format of these strings.
* <p>
* @return a list of String elements with the supported input feed types.
*
*/
public static List getSupportedFeedTypes() {
return getFeedParsers().getSupportedFeedTypes();
}
/**
* Creates a WireFeedInput instance with input validation turned off.
* <p>
*
*/
public WireFeedInput() {
this (false);
}
/**
* Creates a WireFeedInput instance.
* <p>
* @param validate indicates if the input should be validated. NOT IMPLEMENTED YET (validation does not happen)
*
*/
public WireFeedInput(boolean validate) {
_validate = false; // TODO FIX THIS THINGY
_xmlHealerOn = true;
}
/**
* Enables XML healing in the WiredFeedInput instance.
* <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog.
* <p>
* Healing resolves HTML entities (from literal to code number) in the reader.
* <p>
* The healing is done only with the build(File) and build(Reader) signatures.
* <p>
* By default is TRUE.
* <p>
* @param heals TRUE enables stream healing, FALSE disables it.
*
*/
public void setXmlHealerOn(boolean heals) {
_xmlHealerOn = heals;
}
/**
* Indicates if the WiredFeedInput instance will XML heal (if necessary) the character stream.
* <p>
* Healing trims leading chars from the stream (empty spaces and comments) until the XML prolog.
* <p>
* Healing resolves HTML entities (from literal to code number) in the reader.
* <p>
* The healing is done only with the build(File) and build(Reader) signatures.
* <p>
* By default is TRUE.
* <p>
* @return TRUE if healing is enabled, FALSE if not.
*
*/
public boolean getXmlHealerOn() {
return _xmlHealerOn;
}
/**
* Builds an WireFeed (RSS or Atom) from a file.
* <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
* <p>
* @param file file to read to create the WireFeed.
* @return the WireFeed read from the file.
* @throws FileNotFoundException thrown if the file could not be found.
* @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 FeedException if the feed could not be parsed
*
*/
public WireFeed build(File file) throws FileNotFoundException,IOException,IllegalArgumentException,FeedException {
WireFeed feed;
Reader reader = new FileReader(file);
if (_xmlHealerOn) {
reader = new XmlFixerReader(reader);
}
feed = build(reader);
reader.close();
return feed;
}
/**
* Builds an WireFeed (RSS or Atom) from an Reader.
* <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
* <p>
* @param reader Reader to read to create the WireFeed.
* @return the WireFeed read from the Reader.
* @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
*
*/
public WireFeed build(Reader reader) throws IllegalArgumentException,FeedException {
SAXBuilder saxBuilder = createSAXBuilder();
try {
if (_xmlHealerOn) {
reader = new XmlFixerReader(reader);
}
Document document = saxBuilder.build(reader);
return build(document);
}
catch (JDOMParseException ex) {
throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
}
catch (IllegalArgumentException ex) {
throw ex;
}
catch (Exception ex) {
throw new ParsingFeedException("Invalid XML",ex);
}
}
/**
* Builds an WireFeed (RSS or Atom) from an W3C SAX InputSource.
* <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
* <p>
* @param is W3C SAX InputSource to read to create the WireFeed.
* @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 FeedException if the feed could not be parsed
*
*/
public WireFeed build(InputSource is) throws IllegalArgumentException,FeedException {
SAXBuilder saxBuilder = createSAXBuilder();
try {
Document document = saxBuilder.build(is);
return build(document);
}
catch (JDOMParseException ex) {
throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
}
catch (IllegalArgumentException ex) {
throw ex;
}
catch (Exception ex) {
throw new ParsingFeedException("Invalid XML",ex);
}
}
/**
* Builds an WireFeed (RSS or Atom) from an W3C DOM document.
* <p>
* NOTE: This method delages to the 'AsbtractFeed WireFeedInput#build(org.jdom.Document)'.
* <p>
* @param document W3C DOM document to read to create the WireFeed.
* @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 FeedException if the feed could not be parsed
*
*/
public WireFeed build(org.w3c.dom.Document document) throws IllegalArgumentException,FeedException {
DOMBuilder domBuilder = new DOMBuilder();
try {
Document jdomDoc = domBuilder.build(document);
return build(jdomDoc);
}
catch (IllegalArgumentException ex) {
throw ex;
}
catch (Exception ex) {
throw new ParsingFeedException("Invalid XML",ex);
}
}
/**
* Builds an WireFeed (RSS or Atom) from an JDOM document.
* <p>
* NOTE: All other build methods delegate to this method.
* <p>
* @param document JDOM document to read to create the WireFeed.
* @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 FeedException if the feed could not be parsed
*
*/
public WireFeed build(Document document) throws IllegalArgumentException,FeedException {
WireFeedParser parser = getFeedParsers().getParserFor(document);
if (parser==null) {
throw new IllegalArgumentException("Invalid document");
}
return parser.parse(document, _validate);
}
/**
* Creates and sets up a org.jdom.input.SAXBuilder for parsing.
*
* @return a new org.jdom.input.SAXBuilder object
*/
protected SAXBuilder createSAXBuilder() {
SAXBuilder saxBuilder = new SAXBuilder(_validate);
saxBuilder.setEntityResolver(RESOLVER);
//
// 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
// we need to set it and catch the exception if it fails. We also need 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.
try {
XMLReader parser = saxBuilder.createParser();
try {
parser.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxBuilder.setFeature("http://xml.org/sax/features/external-general-entities", false);
} catch (SAXNotRecognizedException e) {
// ignore
} catch (SAXNotSupportedException e) {
// 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 {
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 (SAXNotRecognizedException e) {
// ignore
} catch (SAXNotSupportedException e) {
// ignore
}
} catch (JDOMException e) {
throw new IllegalStateException("JDOM could not create a SAX parser");
}
saxBuilder.setExpandEntities(false);
return saxBuilder;
}
}

View file

@ -0,0 +1,274 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.impl.FeedGenerators;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.output.DOMOutputter;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import java.io.IOException;
import java.io.Writer;
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)
* out of an WireFeed (RSS/Atom).
* <p>
* It generates all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and
* Atom 0.3 feeds. Generators are plugable (they must implement the ModuleParser interface).
* <p>
* @author Alejandro Abdelnur
*
*/
public class WireFeedOutput {
private static Map clMap = new WeakHashMap();
private static FeedGenerators getFeedGenerators() {
synchronized(WireFeedOutput.class) {
FeedGenerators generators = (FeedGenerators)
clMap.get(Thread.currentThread().getContextClassLoader());
if (generators == null) {
generators = new FeedGenerators();
clMap.put(Thread.currentThread().getContextClassLoader(), generators);
}
return generators;
}
}
/**
* Returns the list of supported output feed types.
* <p>
* @see WireFeed for details on the format of these strings.
* <p>
* @return a list of String elements with the supported output feed types.
*
*/
public static List getSupportedFeedTypes() {
return getFeedGenerators().getSupportedFeedTypes();
}
/**
* Creates a FeedOuput instance.
* <p>
*
*/
public WireFeedOutput() {
}
/**
* Creates a String with the XML representation for the given WireFeed.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as
* the feed encoding property.
* <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <p>
* @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.
* @throws IllegalArgumentException thrown if the feed type of the 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 {
return outputString(feed, true);
}
/**
* Creates a String with the XML representation for the given WireFeed.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure that if the String is written to a character stream the stream charset is the same as
* the feed encoding property.
* <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <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 prettyPrint pretty-print XML (true) oder collapsed
* @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 FeedException thrown if the XML representation for the feed could not be created.
*
*/
public String outputString(WireFeed feed, boolean prettyPrint) throws IllegalArgumentException,FeedException {
Document doc = outputJDom(feed);
String encoding = feed.getEncoding();
Format format = prettyPrint ? Format.getPrettyFormat() : Format.getCompactFormat();
if (encoding!=null) {
format.setEncoding(encoding);
}
XMLOutputter outputter = new XMLOutputter(format);
return outputter.outputString(doc);
}
/**
* Creates a File containing with the XML representation for the given WireFeed.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform
* default charset encoding is used to 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>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <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 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 FeedException thrown if the XML representation for the feed could not be created.
*
*/
public void output(WireFeed feed,File file) throws IllegalArgumentException,IOException,FeedException {
output(feed,file,true);
}
/**
* Creates a File containing with the XML representation for the given WireFeed.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. The platform
* default charset encoding is used to 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>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <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 file the file where to write the XML representation for the given WireFeed.
* @param prettyPrint pretty-print XML (true) oder collapsed
* @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 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 {
Writer writer = new FileWriter(file);
output(feed,writer,prettyPrint);
writer.close();
}
/**
* Writes to an Writer the XML representation for the given WireFeed.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure the Writer instance is using the same charset encoding.
* <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <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 writer Writer 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 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 {
output(feed,writer,true);
}
/**
* Writes to an Writer the XML representation for the given WireFeed.
* <p>
* If the feed encoding is not NULL, it will be used in the XML prolog encoding attribute. It is the responsibility
* of the developer to ensure the Writer instance is using the same charset encoding.
* <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <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 writer Writer to write the XML representation for the given WireFeed.
* @param prettyPrint pretty-print XML (true) oder collapsed
* @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,boolean prettyPrint) throws IllegalArgumentException,IOException, FeedException {
Document doc = outputJDom(feed);
String encoding = feed.getEncoding();
Format format = prettyPrint ? Format.getPrettyFormat() : Format.getCompactFormat();
if (encoding!=null) {
format.setEncoding(encoding);
}
XMLOutputter outputter = new XMLOutputter(format);
outputter.output(doc,writer);
}
/**
* Creates a W3C DOM document for the given WireFeed.
* <p>
* This method does not use the feed encoding property.
* <p>
* NOTE: This method delages to the 'Document WireFeedOutput#outputJDom(WireFeed)'.
* <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.
* @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 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 {
Document doc = outputJDom(feed);
DOMOutputter outputter = new DOMOutputter();
try {
return outputter.output(doc);
}
catch (JDOMException jdomEx) {
throw new FeedException("Could not create DOM",jdomEx);
}
}
/**
* Creates a JDOM document for the given WireFeed.
* <p>
* This method does not use the feed encoding property.
* <p>
* NOTE: All other output methods delegate to this method.
* <p>
* @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.
* @throws IllegalArgumentException thrown if the feed type of the 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 {
String type = feed.getFeedType();
WireFeedGenerator generator = getFeedGenerators().getGenerator(type);
if (generator==null) {
throw new IllegalArgumentException("Invalid feed type ["+type+"]");
}
if (!generator.getType().equals(type)) {
throw new IllegalArgumentException("WireFeedOutput type["+type+"] and WireFeed type ["+
type+"] don't match");
}
return generator.generate(feed);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.io.FeedException;
import org.jdom.Document;
/**
* Parses an XML document (JDOM) into a feed bean.
* <p>
* WireFeedParser instances must thread safe.
* <p>
* TODO: explain how developers can plugin their own implementations.
* <p>
* @author Alejandro Abdelnur
*
*/
public interface WireFeedParser {
/**
* Returns the type of feed the parser handles.
* <p>
* @see WireFeed for details on the format of this string.
* <p>
* @return the type of feed the parser handles.
*
*/
public String getType();
/**
* Inspects an XML Document (JDOM) to check if it can parse it.
* <p>
* It checks if the given document if the type of feeds the parser understands.
* <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.
*
*/
public boolean isMyType(Document document);
/**
* Parses an XML document (JDOM Document) into a feed bean.
* <p>
* @param document XML document (JDOM) to parse.
* @param validate indicates if the feed should be strictly validated (NOT YET IMPLEMENTED).
* @return the resulting feed bean.
* @throws IllegalArgumentException thrown if the parser cannot handle the 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;
}

View file

@ -0,0 +1,694 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.text.MessageFormat;
/**
* Character stream that handles (or at least attemtps to) all the necessary Voodo to figure out
* the charset encoding of the XML document within the stream.
* <p>
* IMPORTANT: This class is not related in any way to the org.xml.sax.XMLReader. This one IS a
* character stream.
* <p>
* All this has to be done without consuming characters from the stream, if not the XML parser
* will not recognized the document as a valid XML. This is not 100% true, but it's close enough
* (UTF-8 BOM is not handled by all parsers right now, XmlReader handles it and things work in all
* parsers).
* <p>
* The XmlReader class handles the charset encoding of XML documents in Files, raw streams and
* HTTP streams by offering a wide set of constructors.
* <P>
* By default the charset encoding detection is lenient, the constructor with the lenient flag
* can be used for an script (following HTTP MIME and XML specifications).
* All this is nicely explained by Mark Pilgrim in his blog,
* <a href="http://diveintomark.org/archives/2004/02/13/xml-media-types">
* Determining the character encoding of a feed</a>.
* <p>
* @author Alejandro Abdelnur
*
*/
public class XmlReader extends Reader {
private static final int BUFFER_SIZE = 4096;
private static final String UTF_8 = "UTF-8";
private static final String US_ASCII = "US-ASCII";
private static final String UTF_16BE = "UTF-16BE";
private static final String UTF_16LE = "UTF-16LE";
private static final String UTF_16 = "UTF-16";
private static String _staticDefaultEncoding = null;
private Reader _reader;
private String _encoding;
private String _defaultEncoding;
/**
* Sets the default encoding to use if none is set in HTTP content-type,
* XML prolog and the rules based on content-type are not adequate.
* <p/>
* If it is set to NULL the content-type based rules are used.
* <p/>
* By default it is NULL.
* <p/>
*
* @param encoding charset encoding to default to.
*/
public static void setDefaultEncoding(String encoding) {
_staticDefaultEncoding = encoding;
}
/**
* Returns the default encoding to use if none is set in HTTP content-type,
* XML prolog and the rules based on content-type are not adequate.
* <p/>
* If it is NULL the content-type based rules are used.
* <p/>
*
* @return the default encoding to use.
*/
public static String getDefaultEncoding() {
return _staticDefaultEncoding;
}
/**
* Creates a Reader for a File.
* <p>
* It looks for the UTF-8 BOM first, if none sniffs the XML prolog charset, if this is also
* missing defaults to UTF-8.
* <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter
* for details.
* <p>
* @param file File to create a Reader from.
* @throws IOException thrown if there is a problem reading the file.
*
*/
public XmlReader(File file) throws IOException {
this(new FileInputStream(file));
}
/**
* Creates a Reader for a raw InputStream.
* <p>
* It follows the same logic used for files.
* <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter
* for details.
* <p>
* @param is InputStream to create a Reader from.
* @throws IOException thrown if there is a problem reading the stream.
*
*/
public XmlReader(InputStream is) throws IOException {
this(is,true);
}
/**
* Creates a Reader for a raw InputStream and uses the provided default encoding if none is determined.
* <p>
* It follows the same logic used for files.
* <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts
* the following:
* <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
* <p>
* Else if the XML prolog had a charset encoding that encoding is used.
* <p>
* Else if the content type had a charset encoding that encoding is used.
* <p>
* Else 'UTF-8' is used.
* <p>
* If lenient detection is indicated an XmlReaderException is never thrown.
* <p>
* @param is InputStream to create a Reader from.
* @param lenient indicates if the charset encoding detection should be relaxed.
* @param defaultEncoding default encoding to use if one cannot be detected.
* @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.
*
*/
public XmlReader(InputStream is, boolean lenient, String defaultEncoding)
throws IOException, XmlReaderException {
_defaultEncoding = (defaultEncoding == null) ? _staticDefaultEncoding : defaultEncoding;
try {
doRawStream(is,lenient);
}
catch (XmlReaderException ex) {
if (!lenient) {
throw ex;
}
else {
doLenientDetection(null,ex);
}
}
}
/**
* Creates a Reader for a raw InputStream.
* <p>
* It follows the same logic used for files.
* <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts
* the following:
* <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
* <p>
* Else if the XML prolog had a charset encoding that encoding is used.
* <p>
* Else if the content type had a charset encoding that encoding is used.
* <p>
* Else 'UTF-8' is used.
* <p>
* If lenient detection is indicated an XmlReaderException is never thrown.
* <p>
* @param is InputStream to create a Reader from.
* @param lenient indicates if the charset encoding detection should be relaxed.
* @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.
*
*/
public XmlReader(InputStream is,boolean lenient) throws IOException, XmlReaderException {
this(is, lenient, null);
}
/**
* Creates a Reader using the InputStream of a URL.
* <p>
* If the URL is not of type HTTP and there is not 'content-type' header in the fetched
* data it uses the same logic used for Files.
* <p>
* If the URL is a HTTP Url or there is a 'content-type' header in the fetched
* data it uses the same logic used for an InputStream with content-type.
* <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter
* for details.
* <p>
* @param url URL to create a Reader from.
* @throws IOException thrown if there is a problem reading the stream of the URL.
*
*/
public XmlReader(URL url) throws IOException {
this(url.openConnection());
}
/**
* Creates a Reader using the InputStream of a URLConnection.
* <p>
* 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.
* <p>
* If the URLConnection is a HTTP Url or there is a 'content-type' header in the fetched
* data it uses the same logic used for an InputStream with content-type.
* <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter
* for details.
* <p>
* @param conn URLConnection to create a Reader from.
* @throws IOException thrown if there is a problem reading the stream of the URLConnection.
*
*/
public XmlReader(URLConnection conn) throws IOException {
_defaultEncoding = _staticDefaultEncoding;
boolean lenient = true;
if (conn instanceof HttpURLConnection) {
try {
doHttpStream(conn.getInputStream(),conn.getContentType(),lenient);
}
catch (XmlReaderException ex) {
doLenientDetection(conn.getContentType(),ex);
}
}
else
if (conn.getContentType()!=null) {
try {
doHttpStream(conn.getInputStream(),conn.getContentType(),lenient);
}
catch (XmlReaderException ex) {
doLenientDetection(conn.getContentType(),ex);
}
}
else {
try {
doRawStream(conn.getInputStream(),lenient);
}
catch (XmlReaderException ex) {
doLenientDetection(null,ex);
}
}
}
/**
* Creates a Reader using an InputStream and the associated content-type header.
* <p>
* First it checks if the stream has BOM. If there is not BOM checks the content-type encoding.
* If there is not content-type encoding checks the XML prolog encoding. If there is not XML
* prolog encoding uses the default encoding mandated by the content-type MIME type.
* <p>
* It does a lenient charset encoding detection, check the constructor with the lenient parameter
* for details.
* <p>
* @param is InputStream to create the reader from.
* @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.
*
*/
public XmlReader(InputStream is,String httpContentType) throws IOException {
this(is,httpContentType,true);
}
/**
* Creates a Reader using an InputStream and the associated content-type header.
* <p>
* First it checks if the stream has BOM. If there is not BOM checks the content-type encoding.
* If there is not content-type encoding checks the XML prolog encoding. If there is not XML
* prolog encoding uses the default encoding mandated by the content-type MIME type.
* <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts
* the following:
* <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
* <p>
* Else if the XML prolog had a charset encoding that encoding is used.
* <p>
* Else if the content type had a charset encoding that encoding is used.
* <p>
* Else 'UTF-8' is used.
* <p>
* If lenient detection is indicated and XmlReaderException is never thrown.
* <p>
* @param is InputStream to create the reader from.
* @param httpContentType content-type header to use for the resolution of 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.
* @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.
*
*/
public XmlReader(InputStream is,String httpContentType,boolean lenient, String defaultEncoding)
throws IOException, XmlReaderException {
_defaultEncoding = (defaultEncoding == null) ? _staticDefaultEncoding : defaultEncoding;
try {
doHttpStream(is,httpContentType,lenient);
}
catch (XmlReaderException ex) {
if (!lenient) {
throw ex;
}
else {
doLenientDetection(httpContentType,ex);
}
}
}
/**
* Creates a Reader using an InputStream and the associated content-type header.
* <p>
* First it checks if the stream has BOM. If there is not BOM checks the content-type encoding.
* If there is not content-type encoding checks the XML prolog encoding. If there is not XML
* prolog encoding uses the default encoding mandated by the content-type MIME type.
* <p>
* If lenient detection is indicated and the detection above fails as per specifications it then attempts
* the following:
* <p>
* If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
* <p>
* Else if the XML prolog had a charset encoding that encoding is used.
* <p>
* Else if the content type had a charset encoding that encoding is used.
* <p>
* Else 'UTF-8' is used.
* <p>
* If lenient detection is indicated and XmlReaderException is never thrown.
* <p>
* @param is InputStream to create the reader from.
* @param httpContentType content-type header to use for the resolution of 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 XmlReaderException thrown if the charset encoding could not be determined according to the specs.
*
*/
public XmlReader(InputStream is, String httpContentType, boolean lenient)
throws IOException, XmlReaderException {
this(is, httpContentType, lenient, null);
}
private void doLenientDetection(String httpContentType,XmlReaderException ex) throws IOException {
if (httpContentType!=null) {
if (httpContentType.startsWith("text/html")) {
httpContentType = httpContentType.substring("text/html".length());
httpContentType = "text/xml" + httpContentType;
try {
doHttpStream(ex.getInputStream(),httpContentType,true);
ex = null;
}
catch (XmlReaderException ex2) {
ex = ex2;
}
}
}
if (ex!=null) {
String encoding = ex.getXmlEncoding();
if (encoding==null) {
encoding = ex.getContentTypeEncoding();
}
if (encoding==null) {
encoding = (_defaultEncoding == null) ? UTF_8 : _defaultEncoding;
}
prepareReader(ex.getInputStream(),encoding);
}
}
/**
* Returns the charset encoding of the XmlReader.
* <p>
* @return charset encoding.
*
*/
public String getEncoding() {
return _encoding;
}
public int read(char[] buf,int offset,int len) throws IOException {
return _reader.read(buf,offset,len);
}
/**
* Closes the XmlReader stream.
* <p>
* @throws IOException thrown if there was a problem closing the stream.
*
*/
public void close() throws IOException {
_reader.close();
}
private void doRawStream(InputStream is,boolean lenient) throws IOException {
BufferedInputStream pis = new BufferedInputStream(is, BUFFER_SIZE);
String bomEnc = getBOMEncoding(pis);
String xmlGuessEnc = getXMLGuessEncoding(pis);
String xmlEnc = getXmlProlog(pis,xmlGuessEnc);
String encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, pis);
prepareReader(pis,encoding);
}
private void doHttpStream(InputStream is,String httpContentType,boolean lenient) throws IOException {
BufferedInputStream pis = new BufferedInputStream(is, BUFFER_SIZE);
String cTMime = getContentTypeMime(httpContentType);
String cTEnc = getContentTypeEncoding(httpContentType);
String bomEnc = getBOMEncoding(pis);
String xmlGuessEnc = getXMLGuessEncoding(pis);
String xmlEnc = getXmlProlog(pis,xmlGuessEnc);
String encoding = calculateHttpEncoding(cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc, pis,lenient);
prepareReader(pis,encoding);
}
private void prepareReader(InputStream is,String encoding) throws IOException {
_reader = new InputStreamReader(is,encoding);
_encoding = encoding;
}
// InputStream is passed for XmlReaderException creation only
private String calculateRawEncoding(String bomEnc, String xmlGuessEnc, String xmlEnc, InputStream is) throws IOException {
String encoding;
if (bomEnc==null) {
if (xmlGuessEnc==null || xmlEnc==null) {
encoding = (_defaultEncoding == null) ? UTF_8 : _defaultEncoding;
}
else
if (xmlEnc.equals(UTF_16) && (xmlGuessEnc.equals(UTF_16BE) || xmlGuessEnc.equals(UTF_16LE))) {
encoding = xmlGuessEnc;
}
else {
encoding = xmlEnc;
}
}
else
if (bomEnc.equals(UTF_8)) {
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)) {
throw new XmlReaderException(RAW_EX_1.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}),
bomEnc,xmlGuessEnc,xmlEnc,is);
}
encoding = UTF_8;
}
else
if (bomEnc.equals(UTF_16BE) || bomEnc.equals(UTF_16LE)) {
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)) {
throw new XmlReaderException(RAW_EX_1.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}),
bomEnc,xmlGuessEnc,xmlEnc,is);
}
encoding =bomEnc;
}
else {
throw new XmlReaderException(RAW_EX_2.format(new Object[]{bomEnc,xmlGuessEnc,xmlEnc}),
bomEnc,xmlGuessEnc,xmlEnc,is);
}
return encoding;
}
// 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 {
String encoding;
if (lenient & xmlEnc!=null) {
encoding = xmlEnc;
}
else {
boolean appXml = isAppXml(cTMime);
boolean textXml = isTextXml(cTMime);
if (appXml || textXml) {
if (cTEnc==null) {
if (appXml) {
encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, is);
}
else {
encoding = (_defaultEncoding == null) ? US_ASCII : _defaultEncoding;
}
}
else
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;
}
else {
throw new XmlReaderException(HTTP_EX_2.format(new Object[]{cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc}),
cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc,is);
}
}
else {
encoding = cTEnc;
}
}
else {
throw new XmlReaderException(HTTP_EX_3.format(new Object[]{cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc}),
cTMime,cTEnc,bomEnc,xmlGuessEnc,xmlEnc,is);
}
}
return encoding;
}
// returns MIME type or NULL if httpContentType is NULL
private static String getContentTypeMime(String httpContentType) {
String mime = null;
if (httpContentType!=null) {
int i = httpContentType.indexOf(";");
mime = ((i==-1) ? httpContentType : httpContentType.substring(0,i)).trim();
}
return mime;
}
private static final Pattern CHARSET_PATTERN = Pattern.compile("charset=([.[^; ]]*)");
// returns charset parameter value, NULL if not present, NULL if httpContentType is NULL
private static String getContentTypeEncoding(String httpContentType) {
String encoding = null;
if (httpContentType!=null) {
int i = httpContentType.indexOf(";");
if (i>-1) {
String postMime = httpContentType.substring(i+1);
Matcher m = CHARSET_PATTERN.matcher(postMime);
encoding = (m.find()) ? m.group(1) : null;
encoding = (encoding!=null) ? encoding.toUpperCase() : null;
}
if (encoding != null &&
((encoding.startsWith("\"") && encoding.endsWith("\"")) ||
(encoding.startsWith("'") && encoding.endsWith("'"))
)) {
encoding = encoding.substring(1, encoding.length() - 1);
}
}
return encoding;
}
// returns the BOM in the stream, NULL if not present,
// if there was BOM the in the stream it is consumed
private static String getBOMEncoding(BufferedInputStream is) throws IOException {
String encoding = null;
int[] bytes = new int[3];
is.mark(3);
bytes[0] = is.read();
bytes[1] = is.read();
bytes[2] = is.read();
if (bytes[0] == 0xFE && bytes[1] == 0xFF) {
encoding = UTF_16BE;
is.reset();
is.read();
is.read();
}
else
if (bytes[0] == 0xFF && bytes[1] == 0xFE) {
encoding = UTF_16LE;
is.reset();
is.read();
is.read();
}
else
if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
encoding = UTF_8;
}
else {
is.reset();
}
return encoding;
}
// returns the best guess for the encoding by looking the first bytes of the stream, '<?'
private static String getXMLGuessEncoding(BufferedInputStream is) throws IOException {
String encoding = null;
int[] bytes = new int[4];
is.mark(4);
bytes[0] = is.read();
bytes[1] = is.read();
bytes[2] = is.read();
bytes[3] = is.read();
is.reset();
if (bytes[0] == 0x00 && bytes[1] == 0x3C && bytes[2] == 0x00 && bytes[3] == 0x3F) {
encoding = UTF_16BE;
}
else
if (bytes[0] == 0x3C && bytes[1] == 0x00 && bytes[2] == 0x3F && bytes[3] == 0x00) {
encoding = UTF_16LE;
}
else
if (bytes[0] == 0x3C && bytes[1] == 0x3F && bytes[2] == 0x78 && bytes[3] == 0x6D) {
encoding = UTF_8;
}
return encoding;
}
private static final Pattern ENCODING_PATTERN =
Pattern.compile("<\\?xml.*encoding[\\s]*=[\\s]*((?:\".[^\"]*\")|(?:'.[^']*'))", Pattern.MULTILINE);
// returns the encoding declared in the <?xml encoding=...?>, NULL if none
private static String getXmlProlog(BufferedInputStream is,String guessedEnc) throws IOException {
String encoding = null;
if (guessedEnc!=null) {
byte[] bytes = new byte[BUFFER_SIZE];
is.mark(BUFFER_SIZE);
int offset = 0;
int max = BUFFER_SIZE;
int c = is.read(bytes,offset,max);
int firstGT = -1;
while (c!=-1 && firstGT==-1 && offset< BUFFER_SIZE) {
offset += c;
max -= c;
c = is.read(bytes,offset,max);
firstGT = new String(bytes, 0, offset).indexOf(">");
}
if (firstGT == -1) {
if (c == -1) {
throw new IOException("Unexpected end of XML stream");
}
else {
throw new IOException("XML prolog or ROOT element not found on first " + offset + " bytes");
}
}
int bytesRead = offset;
if (bytesRead>0) {
is.reset();
Reader reader = new InputStreamReader(new ByteArrayInputStream(bytes,0,firstGT + 1), guessedEnc);
BufferedReader bReader = new BufferedReader(reader);
StringBuffer prolog = new StringBuffer();
String line = bReader.readLine();
while (line != null) {
prolog.append(line);
line = bReader.readLine();
}
Matcher m = ENCODING_PATTERN.matcher(prolog);
if (m.find()) {
encoding = m.group(1).toUpperCase();
encoding = encoding.substring(1,encoding.length()-1);
}
}
}
return encoding;
}
// indicates if the MIME type belongs to the APPLICATION XML family
private static boolean isAppXml(String mime) {
return mime!=null &&
(mime.equals("application/xml") ||
mime.equals("application/xml-dtd") ||
mime.equals("application/xml-external-parsed-entity") ||
(mime.startsWith("application/") && mime.endsWith("+xml")));
}
// indicates if the MIME type belongs to the TEXT XML family
private static boolean isTextXml(String mime) {
return mime!=null &&
(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(
"Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] encoding mismatch");
private static final MessageFormat RAW_EX_2 = new MessageFormat(
"Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] unknown BOM");
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");
private static final MessageFormat HTTP_EX_2 = new MessageFormat(
"Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], encoding mismatch");
private static final MessageFormat HTTP_EX_3 = new MessageFormat(
"Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], Invalid MIME");
}

View file

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

View file

@ -0,0 +1,365 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.*;
import com.sun.syndication.io.FeedException;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import java.io.StringReader;
import java.util.List;
/**
* Feed Generator for Atom
* <p/>
*
* @author Elaine Chien
*
*/
public class Atom03Generator extends BaseWireFeedGenerator {
private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_03_URI);
private String _version;
public Atom03Generator() {
this("atom_0.3","0.3");
}
protected Atom03Generator(String type,String version) {
super(type);
_version = version;
}
protected String getVersion() {
return _version;
}
protected Namespace getFeedNamespace() {
return ATOM_NS;
}
public Document generate(WireFeed wFeed) throws FeedException {
Feed feed = (Feed) wFeed;
Element root = createRootElement(feed);
populateFeed(feed,root);
purgeUnusedNamespaceDeclarations(root);
return createDocument(root);
}
protected Document createDocument(Element root) {
return new Document(root);
}
protected Element createRootElement(Feed feed) {
Element root = new Element("feed",getFeedNamespace());
root.addNamespaceDeclaration(getFeedNamespace());
Attribute version = new Attribute("version", getVersion());
root.setAttribute(version);
generateModuleNamespaceDefs(root);
return root;
}
protected void populateFeed(Feed feed,Element parent) throws FeedException {
addFeed(feed,parent);
addEntries(feed,parent);
}
protected void addFeed(Feed feed, Element parent) throws FeedException {
Element eFeed = parent;
populateFeedHeader(feed,eFeed);
checkFeedHeaderConstraints(eFeed);
generateFeedModules(feed.getModules(),eFeed);
generateForeignMarkup(eFeed, (List)feed.getForeignMarkup());
}
protected void addEntries(Feed feed,Element parent) throws FeedException {
List items = feed.getEntries();
for (int i=0;i<items.size();i++) {
addEntry((Entry)items.get(i),parent);
}
checkEntriesConstraints(parent);
}
protected void addEntry(Entry entry,Element parent) throws FeedException {
Element eEntry = new Element("entry", getFeedNamespace());
populateEntry(entry,eEntry);
checkEntryConstraints(eEntry);
generateItemModules(entry.getModules(),eEntry);
parent.addContent(eEntry);
}
protected void populateFeedHeader(Feed feed, Element eFeed) throws FeedException {
if (feed.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, feed.getTitleEx());
eFeed.addContent(titleElement);
}
List links = feed.getAlternateLinks();
for (int i = 0; i < links.size(); i++) {
eFeed.addContent(generateLinkElement((Link)links.get(i)));
}
links = feed.getOtherLinks();
for (int i = 0; i < links.size(); i++) {
eFeed.addContent(generateLinkElement((Link)links.get(i)));
}
if (feed.getAuthors()!=null && feed.getAuthors().size() > 0) {
Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)feed.getAuthors().get(0));
eFeed.addContent(authorElement);
}
List contributors = feed.getContributors();
for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i));
eFeed.addContent(contributorElement);
}
if (feed.getTagline() != null) {
Element taglineElement = new Element("tagline", getFeedNamespace());
fillContentElement(taglineElement, feed.getTagline());
eFeed.addContent(taglineElement);
}
if (feed.getId() != null) {
eFeed.addContent(generateSimpleElement("id", feed.getId()));
}
if (feed.getGenerator() != null) {
eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
}
if (feed.getCopyright() != null) {
eFeed.addContent(generateSimpleElement("copyright", feed.getCopyright()));
}
if (feed.getInfo() != null) {
Element infoElement = new Element("info", getFeedNamespace());
fillContentElement(infoElement, feed.getInfo());
eFeed.addContent(infoElement);
}
if (feed.getModified() != null) {
Element modifiedElement = new Element("modified", getFeedNamespace());
modifiedElement.addContent(DateParser.formatW3CDateTime(feed.getModified()));
eFeed.addContent(modifiedElement);
}
}
protected void populateEntry(Entry entry, Element eEntry) throws FeedException {
if (entry.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, entry.getTitleEx());
eEntry.addContent(titleElement);
}
List links = entry.getAlternateLinks();
for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i)));
}
links = entry.getOtherLinks();
for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i)));
}
if (entry.getAuthors()!=null && entry.getAuthors().size() > 0) {
Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)entry.getAuthors().get(0));
eEntry.addContent(authorElement);
}
List contributors = entry.getContributors();
for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i));
eEntry.addContent(contributorElement);
}
if (entry.getId() != null) {
eEntry.addContent(generateSimpleElement("id", entry.getId()));
}
if (entry.getModified() != null) {
Element modifiedElement = new Element("modified", getFeedNamespace());
modifiedElement.addContent(DateParser.formatW3CDateTime(entry.getModified()));
eEntry.addContent(modifiedElement);
}
if (entry.getIssued() != null) {
Element issuedElement = new Element("issued", getFeedNamespace());
issuedElement.addContent(DateParser.formatW3CDateTime(entry.getIssued()));
eEntry.addContent(issuedElement);
}
if (entry.getCreated() != null) {
Element createdElement = new Element("created", getFeedNamespace());
createdElement.addContent(DateParser.formatW3CDateTime(entry.getCreated()));
eEntry.addContent(createdElement);
}
if (entry.getSummary() != null) {
Element summaryElement = new Element("summary", getFeedNamespace());
fillContentElement(summaryElement, entry.getSummary());
eEntry.addContent(summaryElement);
}
List contents = entry.getContents();
for (int i = 0; i < contents.size(); i++) {
Element contentElement = new Element("content", getFeedNamespace());
fillContentElement(contentElement, (Content)contents.get(i));
eEntry.addContent(contentElement);
}
generateForeignMarkup(eEntry, (List)entry.getForeignMarkup());
}
protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException {
}
protected void checkEntriesConstraints(Element parent) throws FeedException {
}
protected void checkEntryConstraints(Element eEntry) throws FeedException {
}
protected Element generateLinkElement(Link link) {
Element linkElement = new Element("link", getFeedNamespace());
if (link.getRel() != null) {
Attribute relAttribute = new Attribute("rel", link.getRel().toString());
linkElement.setAttribute(relAttribute);
}
if (link.getType() != null) {
Attribute typeAttribute = new Attribute("type", link.getType());
linkElement.setAttribute(typeAttribute);
}
if (link.getHref() != null) {
Attribute hrefAttribute = new Attribute("href", link.getHref());
linkElement.setAttribute(hrefAttribute);
}
return linkElement;
}
protected void fillPersonElement(Element element, Person person) {
if (person.getName() != null) {
element.addContent(generateSimpleElement("name", person.getName()));
}
if (person.getUrl() != null) {
element.addContent(generateSimpleElement("url", person.getUrl()));
}
if (person.getEmail() != null) {
element.addContent(generateSimpleElement("email", person.getEmail()));
}
}
protected Element generateTagLineElement(Content tagline) {
Element taglineElement = new Element("tagline", getFeedNamespace());
if (tagline.getType() != null) {
Attribute typeAttribute = new Attribute("type", tagline.getType());
taglineElement.setAttribute(typeAttribute);
}
if (tagline.getValue() != null) {
taglineElement.addContent(tagline.getValue());
}
return taglineElement;
}
protected void fillContentElement(Element contentElement, Content content)
throws FeedException {
if (content.getType() != null) {
Attribute typeAttribute = new Attribute("type", content.getType());
contentElement.setAttribute(typeAttribute);
}
String mode = content.getMode();
if (mode != null) {
Attribute modeAttribute = new Attribute("mode", content.getMode().toString());
contentElement.setAttribute(modeAttribute);
}
if (content.getValue() != null) {
if (mode == null || mode.equals(Content.ESCAPED)) {
contentElement.addContent(content.getValue());
} else if (mode.equals(Content.BASE64)) {
contentElement.addContent(Base64.encode(content.getValue()));
} else if (mode.equals(Content.XML)) {
StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
tmpDocString.append(content.getValue());
tmpDocString.append("</tmpdoc>");
StringReader tmpDocReader = new StringReader(tmpDocString.toString());
Document tmpDoc;
try {
SAXBuilder saxBuilder = new SAXBuilder();
tmpDoc = saxBuilder.build(tmpDocReader);
}
catch (Exception ex) {
throw new FeedException("Invalid XML",ex);
}
List children = tmpDoc.getRootElement().removeContent();
contentElement.addContent(children);
}
}
}
protected Element generateGeneratorElement(Generator generator) {
Element generatorElement = new Element("generator", getFeedNamespace());
if (generator.getUrl() != null) {
Attribute urlAttribute = new Attribute("url", generator.getUrl());
generatorElement.setAttribute(urlAttribute);
}
if (generator.getVersion() != null) {
Attribute versionAttribute = new Attribute("version", generator.getVersion());
generatorElement.setAttribute(versionAttribute);
}
if (generator.getValue() != null) {
generatorElement.addContent(generator.getValue());
}
return generatorElement;
}
protected Element generateSimpleElement(String name, String value) {
Element element = new Element(name, getFeedNamespace());
element.addContent(value);
return element;
}
}

View file

@ -0,0 +1,341 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.*;
import com.sun.syndication.io.FeedException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.output.XMLOutputter;
import java.util.*;
/**
*/
public class Atom03Parser extends BaseWireFeedParser {
private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
private static final Namespace ATOM_03_NS = Namespace.getNamespace(ATOM_03_URI);
public Atom03Parser() {
this("atom_0.3", ATOM_03_NS);
}
protected Atom03Parser(String type, Namespace ns) {
super(type, ns);
}
protected Namespace getAtomNamespace() {
return ATOM_03_NS;
}
public boolean isMyType(Document document) {
Element rssRoot = document.getRootElement();
Namespace defaultNS = rssRoot.getNamespace();
return (defaultNS!=null) && defaultNS.equals(getAtomNamespace());
}
public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException {
if (validate) {
validateFeed(document);
}
Element rssRoot = document.getRootElement();
return parseFeed(rssRoot);
}
protected void validateFeed(Document document) throws FeedException {
// TBD
// here we have to validate the Feed against a schema or whatever
// not sure how to do it
// one posibility would be to produce an ouput and attempt to parse it again
// with validation turned on.
// otherwise will have to check the document elements by hand.
}
protected WireFeed parseFeed(Element eFeed) {
com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
Element e = eFeed.getChild("title",getAtomNamespace());
if (e!=null) {
feed.setTitleEx(parseContent(e));
}
List eList = eFeed.getChildren("link",getAtomNamespace());
feed.setAlternateLinks(parseAlternateLinks(eList));
feed.setOtherLinks(parseOtherLinks(eList));
e = eFeed.getChild("author",getAtomNamespace());
if (e!=null) {
List authors = new ArrayList();
authors.add(parsePerson(e));
feed.setAuthors(authors);
}
eList = eFeed.getChildren("contributor",getAtomNamespace());
if (eList.size()>0) {
feed.setContributors(parsePersons(eList));
}
e = eFeed.getChild("tagline",getAtomNamespace());
if (e!=null) {
feed.setTagline(parseContent(e));
}
e = eFeed.getChild("id",getAtomNamespace());
if (e!=null) {
feed.setId(e.getText());
}
e = eFeed.getChild("generator",getAtomNamespace());
if (e!=null) {
Generator gen = new Generator();
gen.setValue(e.getText());
String att = getAttributeValue(e, "url");
if (att!=null) {
gen.setUrl(att);
}
att = getAttributeValue(e, "version");
if (att!=null) {
gen.setVersion(att);
}
feed.setGenerator(gen);
}
e = eFeed.getChild("copyright",getAtomNamespace());
if (e!=null) {
feed.setCopyright(e.getText());
}
e = eFeed.getChild("info",getAtomNamespace());
if (e!=null) {
feed.setInfo(parseContent(e));
}
e = eFeed.getChild("modified",getAtomNamespace());
if (e!=null) {
feed.setModified(DateParser.parseDate(e.getText()));
}
feed.setModules(parseFeedModules(eFeed));
eList = eFeed.getChildren("entry",getAtomNamespace());
if (eList.size()>0) {
feed.setEntries(parseEntries(eList));
}
List foreignMarkup =
extractForeignMarkup(eFeed, feed, getAtomNamespace());
if (foreignMarkup.size() > 0) {
feed.setForeignMarkup(foreignMarkup);
}
return feed;
}
private Link parseLink(Element eLink) {
Link link = new Link();
String att = getAttributeValue(eLink, "rel");
if (att!=null) {
link.setRel(att);
}
att = getAttributeValue(eLink, "type");
if (att!=null) {
link.setType(att);
}
att = getAttributeValue(eLink, "href");
if (att!=null) {
link.setHref(att);
}
return link;
}
// List(Elements) -> List(Link)
private List parseLinks(List eLinks,boolean alternate) {
List links = new ArrayList();
for (int i=0;i<eLinks.size();i++) {
Element eLink = (Element) eLinks.get(i);
String rel = getAttributeValue(eLink, "rel");
if (alternate) {
if ("alternate".equals(rel)) {
links.add(parseLink(eLink));
}
}
else {
if (!("alternate".equals(rel))) {
links.add(parseLink(eLink));
}
}
}
return (links.size()>0) ? links : null;
}
// List(Elements) -> List(Link)
private List parseAlternateLinks(List eLinks) {
return parseLinks(eLinks,true);
}
// List(Elements) -> List(Link)
private List parseOtherLinks(List eLinks) {
return parseLinks(eLinks,false);
}
private Person parsePerson(Element ePerson) {
Person person = new Person();
Element e = ePerson.getChild("name",getAtomNamespace());
if (e!=null) {
person.setName(e.getText());
}
e = ePerson.getChild("url",getAtomNamespace());
if (e!=null) {
person.setUrl(e.getText());
}
e = ePerson.getChild("email",getAtomNamespace());
if (e!=null) {
person.setEmail(e.getText());
}
return person;
}
// List(Elements) -> List(Persons)
private List parsePersons(List ePersons) {
List persons = new ArrayList();
for (int i=0;i<ePersons.size();i++) {
persons.add(parsePerson((Element)ePersons.get(i)));
}
return (persons.size()>0) ? persons : null;
}
private Content parseContent(Element e) {
String value = null;
String type = getAttributeValue(e, "type");
type = (type!=null) ? type : "text/plain";
String mode = getAttributeValue(e, "mode");
if (mode == null) {
mode = Content.XML; // default to xml content
}
if (mode.equals(Content.ESCAPED)) {
// do nothing XML Parser took care of this
value = e.getText();
}
else
if (mode.equals(Content.BASE64)) {
value = Base64.decode(e.getText());
}
else
if (mode.equals(Content.XML)) {
XMLOutputter outputter = new XMLOutputter();
List eContent = e.getContent();
Iterator i = eContent.iterator();
while (i.hasNext()) {
org.jdom.Content c = (org.jdom.Content) i.next();
if (c instanceof Element) {
Element eC = (Element) c;
if (eC.getNamespace().equals(getAtomNamespace())) {
((Element)c).setNamespace(Namespace.NO_NAMESPACE);
}
}
}
value = outputter.outputString(eContent);
}
Content content = new Content();
content.setType(type);
content.setMode(mode);
content.setValue(value);
return content;
}
// List(Elements) -> List(Entries)
private List parseEntries(List eEntries) {
List entries = new ArrayList();
for (int i=0;i<eEntries.size();i++) {
entries.add(parseEntry((Element)eEntries.get(i)));
}
return (entries.size()>0) ? entries : null;
}
private Entry parseEntry(Element eEntry) {
Entry entry = new Entry();
Element e = eEntry.getChild("title",getAtomNamespace());
if (e!=null) {
entry.setTitleEx(parseContent(e));
}
List eList = eEntry.getChildren("link",getAtomNamespace());
entry.setAlternateLinks(parseAlternateLinks(eList));
entry.setOtherLinks(parseOtherLinks(eList));
e = eEntry.getChild("author",getAtomNamespace());
if (e!=null) {
List authors = new ArrayList();
authors.add(parsePerson(e));
entry.setAuthors(authors);
}
eList = eEntry.getChildren("contributor",getAtomNamespace());
if (eList.size()>0) {
entry.setContributors(parsePersons(eList));
}
e = eEntry.getChild("id",getAtomNamespace());
if (e!=null) {
entry.setId(e.getText());
}
e = eEntry.getChild("modified",getAtomNamespace());
if (e!=null) {
entry.setModified(DateParser.parseDate(e.getText()));
}
e = eEntry.getChild("issued",getAtomNamespace());
if (e!=null) {
entry.setIssued(DateParser.parseDate(e.getText()));
}
e = eEntry.getChild("created",getAtomNamespace());
if (e!=null) {
entry.setCreated(DateParser.parseDate(e.getText()));
}
e = eEntry.getChild("summary",getAtomNamespace());
if (e!=null) {
entry.setSummary(parseContent(e));
}
eList = eEntry.getChildren("content",getAtomNamespace());
if (eList.size()>0) {
List content = new ArrayList();
for (int i=0;i<eList.size();i++) {
content.add(parseContent((Element)eList.get(i)));
}
entry.setContents(content);
}
entry.setModules(parseItemModules(eEntry));
List foreignMarkup =
extractForeignMarkup(eEntry, entry, getAtomNamespace());
if (foreignMarkup.size() > 0) {
entry.setForeignMarkup(foreignMarkup);
}
return entry;
}
}

View file

@ -0,0 +1,473 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Category;
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;
import com.sun.syndication.io.WireFeedOutput;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import org.jdom.output.XMLOutputter;
/**
* Feed Generator for Atom
* <p/>
*
* @author Elaine Chien
* @author Dave Johnson (updated for Atom 1.0)
*
*/
public class Atom10Generator extends BaseWireFeedGenerator {
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 String _version;
public Atom10Generator() {
this("atom_1.0","1.0");
}
protected Atom10Generator(String type,String version) {
super(type);
_version = version;
}
protected String getVersion() {
return _version;
}
protected Namespace getFeedNamespace() {
return ATOM_NS;
}
public Document generate(WireFeed wFeed) throws FeedException {
Feed feed = (Feed) wFeed;
Element root = createRootElement(feed);
populateFeed(feed,root);
purgeUnusedNamespaceDeclarations(root);
return createDocument(root);
}
protected Document createDocument(Element root) {
return new Document(root);
}
protected Element createRootElement(Feed feed) {
Element root = new Element("feed",getFeedNamespace());
root.addNamespaceDeclaration(getFeedNamespace());
//Attribute version = new Attribute("version", getVersion());
//root.setAttribute(version);
if (feed.getXmlBase() != null) {
root.setAttribute("base", feed.getXmlBase(), Namespace.XML_NAMESPACE);
}
generateModuleNamespaceDefs(root);
return root;
}
protected void populateFeed(Feed feed,Element parent) throws FeedException {
addFeed(feed,parent);
addEntries(feed,parent);
}
protected void addFeed(Feed feed,Element parent) throws FeedException {
Element eFeed = parent;
populateFeedHeader(feed,eFeed);
generateForeignMarkup(eFeed, (List)feed.getForeignMarkup());
checkFeedHeaderConstraints(eFeed);
generateFeedModules(feed.getModules(),eFeed);
}
protected void addEntries(Feed feed,Element parent) throws FeedException {
List items = feed.getEntries();
for (int i=0;i<items.size();i++) {
addEntry((Entry)items.get(i),parent);
}
checkEntriesConstraints(parent);
}
protected void addEntry(Entry entry,Element parent) throws FeedException {
Element eEntry = new Element("entry", getFeedNamespace());
if (entry.getXmlBase() != null) {
eEntry.setAttribute("base", entry.getXmlBase(), Namespace.XML_NAMESPACE);
}
populateEntry(entry,eEntry);
generateForeignMarkup(eEntry, (List)entry.getForeignMarkup());
checkEntryConstraints(eEntry);
generateItemModules(entry.getModules(),eEntry);
parent.addContent(eEntry);
}
protected void populateFeedHeader(Feed feed,Element eFeed) throws FeedException {
if (feed.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, feed.getTitleEx());
eFeed.addContent(titleElement);
}
List links = feed.getAlternateLinks();
if (links != null) for (int i = 0; i < links.size(); i++) {
eFeed.addContent(generateLinkElement((Link)links.get(i)));
}
links = feed.getOtherLinks();
if (links != null) for (int j = 0; j < links.size(); j++) {
eFeed.addContent(generateLinkElement((Link)links.get(j)));
}
List cats = feed.getCategories();
if (cats != null) for (Iterator iter=cats.iterator(); iter.hasNext();) {
eFeed.addContent(generateCategoryElement((Category)iter.next()));
}
List authors = feed.getAuthors();
if (authors != null && authors.size() > 0) {
for (int i = 0; i < authors.size(); i++) {
Element authorElement = new Element("author", getFeedNamespace());
fillPersonElement(authorElement, (Person)feed.getAuthors().get(i));
eFeed.addContent(authorElement);
}
}
List contributors = feed.getContributors();
if (contributors != null && contributors.size() > 0) {
for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i));
eFeed.addContent(contributorElement);
}
}
if (feed.getSubtitle() != null) {
Element subtitleElement = new Element("subtitle", getFeedNamespace());
fillContentElement(subtitleElement, feed.getSubtitle());
eFeed.addContent(subtitleElement);
}
if (feed.getId() != null) {
eFeed.addContent(generateSimpleElement("id", feed.getId()));
}
if (feed.getGenerator() != null) {
eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
}
if (feed.getRights() != null) {
eFeed.addContent(generateSimpleElement("rights", feed.getRights()));
}
if (feed.getIcon() != null) {
eFeed.addContent(generateSimpleElement("icon", feed.getIcon()));
}
if (feed.getLogo() != null) {
eFeed.addContent(generateSimpleElement("logo", feed.getLogo()));
}
if (feed.getUpdated() != null) {
Element updatedElement = new Element("updated", getFeedNamespace());
updatedElement.addContent(DateParser.formatW3CDateTime(feed.getUpdated()));
eFeed.addContent(updatedElement);
}
}
protected void populateEntry(Entry entry, Element eEntry) throws FeedException {
if (entry.getTitleEx() != null) {
Element titleElement = new Element("title", getFeedNamespace());
fillContentElement(titleElement, entry.getTitleEx());
eEntry.addContent(titleElement);
}
List links = entry.getAlternateLinks();
if (links != null) {
for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i)));
}
}
links = entry.getOtherLinks();
if (links != null) {
for (int i = 0; i < links.size(); i++) {
eEntry.addContent(generateLinkElement((Link)links.get(i)));
}
}
List cats = entry.getCategories();
if (cats != null) {
for (int i = 0; i < cats.size(); i++) {
eEntry.addContent(generateCategoryElement((Category)cats.get(i)));
}
}
List 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 contributors = entry.getContributors();
if (contributors != null && contributors.size() > 0) {
for (int i = 0; i < contributors.size(); i++) {
Element contributorElement = new Element("contributor", getFeedNamespace());
fillPersonElement(contributorElement, (Person)contributors.get(i));
eEntry.addContent(contributorElement);
}
}
if (entry.getId() != null) {
eEntry.addContent(generateSimpleElement("id", entry.getId()));
}
if (entry.getUpdated() != null) {
Element updatedElement = new Element("updated", getFeedNamespace());
updatedElement.addContent(DateParser.formatW3CDateTime(entry.getUpdated()));
eEntry.addContent(updatedElement);
}
if (entry.getPublished() != null) {
Element publishedElement = new Element("published", getFeedNamespace());
publishedElement.addContent(DateParser.formatW3CDateTime(entry.getPublished()));
eEntry.addContent(publishedElement);
}
if (entry.getContents() != null && entry.getContents().size() > 0) {
Element contentElement = new Element("content", getFeedNamespace());
Content content = (Content)entry.getContents().get(0);
fillContentElement(contentElement, content);
eEntry.addContent(contentElement);
}
if (entry.getSummary() != null) {
Element summaryElement = new Element("summary", getFeedNamespace());
fillContentElement(summaryElement, entry.getSummary());
eEntry.addContent(summaryElement);
}
if (entry.getSource() != null) {
Element sourceElement = new Element("source", getFeedNamespace());
populateFeedHeader(entry.getSource(), sourceElement);
eEntry.addContent(sourceElement);
}
}
protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException {
}
protected void checkEntriesConstraints(Element parent) throws FeedException {
}
protected void checkEntryConstraints(Element eEntry) throws FeedException {
}
protected Element generateCategoryElement(Category cat) {
Element catElement = new Element("category", getFeedNamespace());
if (cat.getTerm() != null) {
Attribute termAttribute = new Attribute("term", cat.getTerm());
catElement.setAttribute(termAttribute);
}
if (cat.getLabel() != null) {
Attribute labelAttribute = new Attribute("label", cat.getLabel());
catElement.setAttribute(labelAttribute);
}
if (cat.getScheme() != null) {
Attribute schemeAttribute = new Attribute("scheme", cat.getScheme());
catElement.setAttribute(schemeAttribute);
}
return catElement;
}
protected Element generateLinkElement(Link link) {
Element linkElement = new Element("link", getFeedNamespace());
if (link.getRel() != null) {
Attribute relAttribute = new Attribute("rel", link.getRel());
linkElement.setAttribute(relAttribute);
}
if (link.getType() != null) {
Attribute typeAttribute = new Attribute("type", link.getType());
linkElement.setAttribute(typeAttribute);
}
if (link.getHref() != null) {
Attribute hrefAttribute = new Attribute("href", link.getHref());
linkElement.setAttribute(hrefAttribute);
}
if (link.getHreflang() != null) {
Attribute hreflangAttribute = new Attribute("hreflang", link.getHreflang());
linkElement.setAttribute(hreflangAttribute);
}
if (link.getTitle() != null) {
Attribute title = new Attribute("title", link.getTitle());
linkElement.setAttribute(title);
}
if (link.getLength() != 0) {
Attribute lenght = new Attribute("length", Long.toString(link.getLength()));
linkElement.setAttribute(lenght);
}
return linkElement;
}
protected void fillPersonElement(Element element, Person person) {
if (person.getName() != null) {
element.addContent(generateSimpleElement("name", person.getName()));
}
if (person.getUri() != null) {
element.addContent(generateSimpleElement("uri", person.getUri()));
}
if (person.getEmail() != null) {
element.addContent(generateSimpleElement("email", person.getEmail()));
}
generatePersonModules(person.getModules(), element);
}
protected Element generateTagLineElement(Content tagline) {
Element taglineElement = new Element("subtitle", getFeedNamespace());
if (tagline.getType() != null) {
Attribute typeAttribute = new Attribute("type", tagline.getType());
taglineElement.setAttribute(typeAttribute);
}
if (tagline.getValue() != null) {
taglineElement.addContent(tagline.getValue());
}
return taglineElement;
}
protected void fillContentElement(Element contentElement, Content content)
throws FeedException {
String type = content.getType();
String atomType = type;
if (type != null) {
// 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
if ("text/plain".equals(type)) atomType = Content.TEXT;
else if ("text/html".equals(type)) atomType = Content.HTML;
else if ("application/xhtml+xml".equals(type)) atomType = Content.XHTML;
Attribute typeAttribute = new Attribute("type", atomType);
contentElement.setAttribute(typeAttribute);
}
String href = content.getSrc();
if (href != null) {
Attribute srcAttribute = new Attribute("src", href);
contentElement.setAttribute(srcAttribute);
}
if (content.getValue() != null) {
if (atomType != null && (atomType.equals(Content.XHTML) || (atomType.indexOf("/xml")) != -1 ||
(atomType.indexOf("+xml")) != -1)) {
StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
tmpDocString.append(content.getValue());
tmpDocString.append("</tmpdoc>");
StringReader tmpDocReader = new StringReader(tmpDocString.toString());
Document tmpDoc;
try {
SAXBuilder saxBuilder = new SAXBuilder();
tmpDoc = saxBuilder.build(tmpDocReader);
}
catch (Exception ex) {
throw new FeedException("Invalid XML",ex);
}
List children = tmpDoc.getRootElement().removeContent();
contentElement.addContent(children);
} else {
// must be type html, text or some other non-XML format
// JDOM will escape property for XML
contentElement.addContent(content.getValue());
}
}
}
protected Element generateGeneratorElement(Generator generator) {
Element generatorElement = new Element("generator", getFeedNamespace());
if (generator.getUrl() != null) {
Attribute urlAttribute = new Attribute("uri", generator.getUrl());
generatorElement.setAttribute(urlAttribute);
}
if (generator.getVersion() != null) {
Attribute versionAttribute = new Attribute("version", generator.getVersion());
generatorElement.setAttribute(versionAttribute);
}
if (generator.getValue() != null) {
generatorElement.addContent(generator.getValue());
}
return generatorElement;
}
protected Element generateSimpleElement(String name, String value) {
Element element = new Element(name, getFeedNamespace());
element.addContent(value);
return element;
}
/**
* Utility method to serialize an entry to writer.
*/
public static void serializeEntry(Entry entry, Writer writer)
throws IllegalArgumentException, FeedException, IOException {
// Build a feed containing only the entry
List entries = new ArrayList();
entries.add(entry);
Feed feed1 = new Feed();
feed1.setFeedType("atom_1.0");
feed1.setEntries(entries);
// Get Rome to output feed as a JDOM document
WireFeedOutput wireFeedOutput = new WireFeedOutput();
Document feedDoc = wireFeedOutput.outputJDom(feed1);
// Grab entry element from feed and get JDOM to serialize it
Element entryElement= (Element)feedDoc.getRootElement().getChildren().get(0);
XMLOutputter outputter = new XMLOutputter();
outputter.output(entryElement, writer);
}
}

View file

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

View file

@ -0,0 +1,201 @@
package com.sun.syndication.io.impl;
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/**
* Encodes/decodes byte arrays and Strings into/from a base 64 String.
* <p>
* @author Alejandro Abdelnur
*
*/
public class Base64 {
/**
* Encodes a String into a base 64 String. The resulting encoding is chunked at 76 bytes.
* <p>
* @param s String to encode.
* @return encoded string.
*
*/
public static String encode(String s) {
byte[] sBytes = s.getBytes();
sBytes = encode(sBytes);
s = new String(sBytes);
return s;
}
/**
* Decodes a base 64 String into a String.
* <p>
* @param s String to decode.
* @return encoded string.
* @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 {
s = s.replaceAll("\n", "");
s = s.replaceAll("\r", "");
byte[] sBytes = s.getBytes();
sBytes = decode(sBytes);
s = new String(sBytes);
return s;
}
private static final byte[] ALPHASET =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".getBytes();
private static final int I6O2 = 255 - 3;
private static final int O6I2 = 3;
private static final int I4O4 = 255 - 15;
private static final int O4I4 = 15;
private static final int I2O6 = 255 - 63;
private static final int O2I6 = 63;
/**
* Encodes a byte array into a base 64 byte array.
* <p>
* @param dData byte array to encode.
* @return encoded byte array.
*
*/
public static byte[] encode(byte[] dData) {
if (dData==null) {
throw new IllegalArgumentException("Cannot encode null");
}
byte[] eData = new byte[((dData.length+2)/3)*4];
int eIndex = 0;
for (int i = 0; i<dData.length; i += 3) {
int d1;
int d2=0;
int d3=0;
int e1;
int e2;
int e3;
int e4;
int pad=0;
d1 = dData[i];
if ((i+1)<dData.length) {
d2 = dData[i+1];
if ((i+2)<dData.length) {
d3 = dData[i+2];
}
else {
pad =1;
}
}
else {
pad =2;
}
e1 = ALPHASET[(d1&I6O2)>>2];
e2 = ALPHASET[(d1&O6I2)<<4 | (d2&I4O4)>>4];
e3 = ALPHASET[(d2&O4I4)<<2 | (d3&I2O6)>>6];
e4 = ALPHASET[(d3&O2I6)];
eData[eIndex++] = (byte)e1;
eData[eIndex++] = (byte)e2;
eData[eIndex++] = (pad<2) ?(byte)e3 : (byte)'=';
eData[eIndex++] = (pad<1) ?(byte)e4 : (byte)'=';
}
return eData;
}
private final static int[] CODES = new int[256];
static {
for (int i=0;i<CODES.length;i++) {
CODES[i] = 64;
}
for (int i=0;i<ALPHASET.length;i++) {
CODES[ALPHASET[i]] = i;
}
}
/**
* Dencodes a com.sun.syndication.io.impl.Base64 byte array.
* <p>
* @param eData byte array to decode.
* @return decoded byte array.
* @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) {
if (eData==null) {
throw new IllegalArgumentException("Cannot decode null");
}
byte[] cleanEData = (byte[]) eData.clone();
int cleanELength = 0;
for (int i=0;i<eData.length;i++) {
if (eData[i]<256 && CODES[eData[i]]<64) {
cleanEData[cleanELength++] = eData[i];
}
}
int dLength = (cleanELength/4)*3;
switch (cleanELength%4) {
case 3:
dLength += 2;
break;
case 2:
dLength++;
break;
}
byte[] dData = new byte[dLength];
int dIndex = 0;
for (int i = 0; i < eData.length; i += 4) {
if ((i + 3) > eData.length) {
throw new IllegalArgumentException("byte array is not a valid com.sun.syndication.io.impl.Base64 encoding");
}
int e1 = CODES[cleanEData[i]];
int e2 = CODES[cleanEData[i+1]];
int e3 = CODES[cleanEData[i+2]];
int e4 = CODES[cleanEData[i+3]];
dData[dIndex++] = (byte) ((e1<<2)|(e2>>4));
if (dIndex<dData.length) {
dData[dIndex++] = (byte) ((e2<<4) | (e3>>2));
}
if (dIndex<dData.length) {
dData[dIndex++] = (byte) ((e3<<6) | (e4));
}
}
return dData;
}
public static void main(String[] args) throws Exception {
String s =
"\nPGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+V2UncmUgcHJvcG9zaW5nIDxhIGhy\n"+
"ZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9jb3Jwb3JhdGUvc29mdHdhcmVfcHJpbmNpcGxlcy5odG1sIj5z\n"+
"b21lIGd1aWRlbGluZXMgPC9hPnRvIGhlbHAgY3VyYiB0aGUgcHJvYmxlbSBvZiBJbnRlcm5ldCBzb2Z0d2Fy\n"+
"ZSB0aGF0IGluc3RhbGxzIGl0c2VsZiB3aXRob3V0IHRlbGxpbmcgeW91LCBvciBiZWhhdmVzIGJhZGx5IG9u\n"+
"Y2UgaXQgZ2V0cyBvbiB5b3VyIGNvbXB1dGVyLiBXZSd2ZSBiZWVuIGhlYXJpbmcgYSBsb3Qgb2YgY29tcGxh\n"+
"aW50cyBhYm91dCB0aGlzIGxhdGVseSBhbmQgaXQgc2VlbXMgdG8gYmUgZ2V0dGluZyB3b3JzZS4gV2UgdGhp\n"+
"bmsgaXQncyBpbXBvcnRhbnQgdGhhdCB5b3UgcmV0YWluIGNvbnRyb2wgb2YgeW91ciBjb21wdXRlciBhbmQg\n"+
"dGhhdCB0aGVyZSBiZSBzb21lIGNsZWFyIHN0YW5kYXJkcyBpbiBvdXIgaW5kdXN0cnkuIExldCB1cyBrbm93\n"+
"IGlmIHlvdSB0aGluayB0aGVzZSBndWlkZWxpbmVzIGFyZSB1c2VmdWwgb3IgaWYgeW91IGhhdmUgc3VnZ2Vz\n"+
"dGlvbnMgdG8gaW1wcm92ZSB0aGVtLgo8YnIgLz4KPGJyIC8+Sm9uYXRoYW4gUm9zZW5iZXJnCjxiciAvPgo8\n"+
"L2Rpdj4K\n";
System.out.println(decode(s));
}
}

View file

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

View file

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

View file

@ -0,0 +1,212 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.module.DCSubject;
import com.sun.syndication.io.ModuleGenerator;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.Namespace;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
/**
* Feed Generator for DublinCore Module.
* <p/>
*
* @author Elaine Chien
*
*/
public class DCModuleGenerator implements ModuleGenerator {
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 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 TAXO_NS = Namespace.getNamespace("taxo", TAXO_URI);
private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI);
private static final Set NAMESPACES;
static {
Set nss = new HashSet();
nss.add(DC_NS);
nss.add(TAXO_NS);
nss.add(RDF_NS);
NAMESPACES = Collections.unmodifiableSet(nss);
}
public final String getNamespaceUri() {
return DC_URI;
}
private final Namespace getDCNamespace() {
return DC_NS;
}
private final Namespace getRDFNamespace() {
return RDF_NS;
}
private final Namespace getTaxonomyNamespace() {
return TAXO_NS;
}
/**
* Returns a set with all the URIs (JDOM Namespace elements) this module
* generator uses.
* <p/>
* It is used by the the feed generators to add their namespace definition
* in the root element of the generated document (forward-missing of
* Java 5.0 Generics).
* <p/>
*
* @return a set with all the URIs this module generator uses.
*/
public final Set getNamespaces() {
return NAMESPACES;
}
/**
* Populate an element tree with elements for a module.
* <p>
* @param module the module to populate from.
* @param element the root element to attach child elements to.
*/
public final void generate(Module module, Element element) {
DCModule dcModule = (DCModule) module;
if (dcModule.getTitle() != null) {
element.addContent(generateSimpleElementList("title", dcModule.getTitles()));
}
if (dcModule.getCreator() != null) {
element.addContent(generateSimpleElementList("creator", dcModule.getCreators()));
}
List subjects = dcModule.getSubjects();
for (int i = 0; i < subjects.size(); i++) {
element.addContent(generateSubjectElement((DCSubject) subjects.get(i)));
}
if (dcModule.getDescription() != null) {
element.addContent(generateSimpleElementList("description", dcModule.getDescriptions()));
}
if (dcModule.getPublisher() != null) {
element.addContent(generateSimpleElementList("publisher", dcModule.getPublishers()));
}
if (dcModule.getContributors() != null) {
element.addContent(generateSimpleElementList("contributor", dcModule.getContributors()));
}
if (dcModule.getDate() != null) {
for (Iterator i = dcModule.getDates().iterator(); i.hasNext();) {
element.addContent(generateSimpleElement("date",
DateParser.formatW3CDateTime((Date) i.next())));
}
}
if (dcModule.getType() != null) {
element.addContent(generateSimpleElementList("type", dcModule.getTypes()));
}
if (dcModule.getFormat() != null) {
element.addContent(generateSimpleElementList("format", dcModule.getFormats()));
}
if (dcModule.getIdentifier() != null) {
element.addContent(generateSimpleElementList("identifier", dcModule.getIdentifiers()));
}
if (dcModule.getSource() != null) {
element.addContent(generateSimpleElementList("source", dcModule.getSources()));
}
if (dcModule.getLanguage() != null) {
element.addContent(generateSimpleElementList("language", dcModule.getLanguages()));
}
if (dcModule.getRelation() != null) {
element.addContent(generateSimpleElementList("relation", dcModule.getRelations()));
}
if (dcModule.getCoverage() != null) {
element.addContent(generateSimpleElementList("coverage", dcModule.getCoverages()));
}
if (dcModule.getRights() != null) {
element.addContent(generateSimpleElementList("rights", dcModule.getRightsList()));
}
}
/**
* Utility method to generate an element for a subject.
* <p>
* @param subject the subject to generate an element for.
* @return the element for the subject.
*/
protected final Element generateSubjectElement(DCSubject subject) {
Element subjectElement = new Element("subject", getDCNamespace());
if (subject.getTaxonomyUri() != null) {
Element descriptionElement = new Element("Description", getRDFNamespace());
Element topicElement = new Element("topic", getTaxonomyNamespace());
Attribute resourceAttribute = new Attribute("resource", subject.getTaxonomyUri(), getRDFNamespace());
topicElement.setAttribute(resourceAttribute);
descriptionElement.addContent(topicElement);
if (subject.getValue() != null) {
Element valueElement = new Element("value", getRDFNamespace());
valueElement.addContent(subject.getValue());
descriptionElement.addContent(valueElement);
}
subjectElement.addContent(descriptionElement);
} else {
subjectElement.addContent(subject.getValue());
}
return subjectElement;
}
/**
* Utility method to generate a single element containing a string.
* <p>
* @param name the name of the elment to generate.
* @param value the value of the text in the element.
* @return the element generated.
*/
protected final Element generateSimpleElement(String name, String value) {
Element element = new Element(name, getDCNamespace());
element.addContent(value);
return element;
}
/**
* Utility method to generate a list of simple elements.
* <p>
* @param name the name of the element list to generate.
* @param value the list of values for the elements.
* @return a list of Elements created.
*/
protected final List generateSimpleElementList(String name, List value) {
List elements = new ArrayList();
for (Iterator i = value.iterator(); i.hasNext();) {
elements.add(generateSimpleElement(name, (String) i.next()));
}
return elements;
}
}

View file

@ -0,0 +1,231 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.DCModuleImpl;
import com.sun.syndication.feed.module.DCSubjectImpl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.feed.module.DCModule;
import com.sun.syndication.feed.module.DCSubject;
import com.sun.syndication.io.ModuleParser;
import com.sun.syndication.io.WireFeedParser;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.Namespace;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Parser for the Dublin Core module.
*/
public class DCModuleParser implements ModuleParser {
private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/";
private static final Namespace DC_NS = Namespace.getNamespace(DCModule.URI);
private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
private static final Namespace TAXO_NS = Namespace.getNamespace(TAXO_URI);
public final String getNamespaceUri() {
return DCModule.URI;
}
private final Namespace getDCNamespace() {
return DC_NS;
}
private final Namespace getRDFNamespace() {
return RDF_NS;
}
private final Namespace getTaxonomyNamespace() {
return TAXO_NS;
}
/**
* Parse an element tree and return the module found in it.
* <p>
* @param dcRoot the root element containing the module elements.
* @return the module parsed from the element tree, <i>null</i> if none.
*/
public Module parse(Element dcRoot) {
boolean foundSomething = false;
DCModule dcm = new DCModuleImpl();
List eList = dcRoot.getChildren("title", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setTitles(parseElementList(eList));
}
eList = dcRoot.getChildren("creator", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setCreators(parseElementList(eList));
}
eList = dcRoot.getChildren("subject", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setSubjects(parseSubjects(eList));
}
eList = dcRoot.getChildren("description", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setDescriptions(parseElementList(eList));
}
eList = dcRoot.getChildren("publisher", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setPublishers(parseElementList(eList));
}
eList = dcRoot.getChildren("contributor", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setContributors(parseElementList(eList));
}
eList = dcRoot.getChildren("date", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setDates(parseElementListDate(eList));
}
eList = dcRoot.getChildren("type", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setTypes(parseElementList(eList));
}
eList = dcRoot.getChildren("format", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setFormats(parseElementList(eList));
}
eList = dcRoot.getChildren("identifier", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setIdentifiers(parseElementList(eList));
}
eList = dcRoot.getChildren("source", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setSources(parseElementList(eList));
}
eList = dcRoot.getChildren("language", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setLanguages(parseElementList(eList));
}
eList = dcRoot.getChildren("relation", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setRelations(parseElementList(eList));
}
eList = dcRoot.getChildren("coverage", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setCoverages(parseElementList(eList));
}
eList = dcRoot.getChildren("rights", getDCNamespace());
if (eList.size() > 0) {
foundSomething = true;
dcm.setRightsList(parseElementList(eList));
}
return (foundSomething) ? dcm : null;
}
/**
* Utility method to parse a taxonomy from an element.
* <p>
* @param desc the taxonomy description element.
* @return the string contained in the resource of the element.
*/
protected final String getTaxonomy(Element desc) {
String d = null;
Element taxo = desc.getChild("topic", getTaxonomyNamespace());
if (taxo!=null) {
Attribute a = taxo.getAttribute("resource", getRDFNamespace());
if (a!=null) {
d = a.getValue();
}
}
return d;
}
/**
* Utility method to parse a list of subjects out of a list of elements.
* <p>
* @param eList the element list to parse.
* @return a list of subjects parsed from the elements.
*/
protected final List parseSubjects(List eList) {
List subjects = new ArrayList();
for (Iterator i = eList.iterator(); i.hasNext();) {
Element eSubject = (Element) i.next();
Element eDesc = eSubject.getChild("Description", getRDFNamespace());
if (eDesc != null) {
String taxonomy = getTaxonomy(eDesc);
List eValues = eDesc.getChildren("value", getRDFNamespace());
for (Iterator v = eValues.iterator(); v.hasNext();) {
Element eValue = (Element) v.next();
DCSubject subject = new DCSubjectImpl();
subject.setTaxonomyUri(taxonomy);
subject.setValue(eValue.getText());
subjects.add(subject);
}
} else {
DCSubject subject = new DCSubjectImpl();
subject.setValue(eSubject.getText());
subjects.add(subject);
}
}
return subjects;
}
/**
* Utility method to parse a list of strings out of a list of elements.
* <p>
* @param eList the list of elements to parse.
* @return the list of strings
*/
protected final List parseElementList(List eList) {
List values= new ArrayList();
for (Iterator i = eList.iterator(); i.hasNext();) {
Element e = (Element) i.next();
values.add(e.getText());
}
return values;
}
/**
* Utility method to parse a list of dates out of a list of elements.
* <p>
* @param eList the list of elements to parse.
* @return the list of dates.
*/
protected final List parseElementListDate(List eList) {
List values = new ArrayList();
for (Iterator i = eList.iterator(); i.hasNext();) {
Element e = (Element) i.next();
values.add(DateParser.parseDate(e.getText()));
}
return values;
}
}

View file

@ -0,0 +1,285 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.util.Date;
import java.util.TimeZone;
import java.util.Locale;
/**
* A helper class that parses Dates out of Strings with date time in RFC822 and W3CDateTime
* formats plus the variants Atom (0.3) and RSS (0.9, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0)
* specificators added to those formats.
* <p/>
* It uses the JDK java.text.SimpleDateFormat class attemtping the parse using a mask for
* each one of the possible formats.
* <p/>
*
* @author Alejandro Abdelnur
*
*/
public class DateParser {
private static String[] ADDITIONAL_MASKS;
static {
ADDITIONAL_MASKS = PropertiesLoader.getPropertiesLoader().getTokenizedProperty("datetime.extra.masks","|");
}
// 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[] 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"
};
// 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"
};
/**
* 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 DateParser() {
}
/**
* Parses a Date out of a string using an array of masks.
* <p/>
* It uses the masks in order until one of them succedes or all fail.
* <p/>
*
* @param masks array of masks to use for parsing the string
* @param sDate string to parse for a date.
* @return the Date represented by the given string using one of the given 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) {
sDate = (sDate!=null) ? sDate.trim() : null;
ParsePosition pp = null;
Date d = null;
for (int i=0;d==null && i<masks.length;i++) {
DateFormat df = new SimpleDateFormat(masks[i],Locale.US);
//df.setLenient(false);
df.setLenient(true);
try {
pp = new ParsePosition(0);
d = df.parse(sDate,pp);
if (pp.getIndex()!=sDate.length()) {
d = null;
}
//System.out.println("pp["+pp.getIndex()+"] s["+sDate+" m["+masks[i]+"] d["+d+"]");
}
catch (Exception ex1) {
//System.out.println("s: "+sDate+" m: "+masks[i]+" d: "+null);
}
}
return d;
}
/**
* Parses a Date out of a String with a date in RFC822 format.
* <p/>
* It parsers the following formats:
* <ul>
* <li>"EEE, dd MMM yyyy HH:mm:ss 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 z"</li>
* <li>"dd MMM yyyy HH:mm:ss 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 z"</li>
* </ul>
* <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
* <p/>
* @param sDate string to parse for a date.
* @return the Date represented by the given RFC822 string.
* It returns <b>null</b> if it was not possible to parse the given string into a Date.
*
*/
public static Date parseRFC822(String sDate) {
int utIndex = sDate.indexOf(" UT");
if (utIndex>-1) {
String pre = sDate.substring(0,utIndex);
String post = sDate.substring(utIndex+3);
sDate = pre + " GMT" + post;
}
return parseUsingMask(RFC822_MASKS,sDate);
}
/**
* Parses a Date out of a String with a date in W3C date-time format.
* <p/>
* It parsers the following formats:
* <ul>
* <li>"yyyy-MM-dd'T'HH:mm:ssz"</li>
* <li>"yyyy-MM-dd'T'HH:mmz"</li>
* <li>"yyyy-MM-dd"</li>
* <li>"yyyy-MM"</li>
* <li>"yyyy"</li>
* </ul>
* <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
* <p/>
* @param sDate string to parse for a date.
* @return the Date represented by the given W3C date-time string.
* It returns <b>null</b> if it was not possible to parse the given string into a Date.
*
*/
public static Date parseW3CDateTime(String sDate) {
// if sDate has time on it, it injects 'GTM' before de TZ displacement to
// allow the SimpleDateFormat parser to parse it properly
int tIndex = sDate.indexOf("T");
if (tIndex>-1) {
if (sDate.endsWith("Z")) {
sDate = sDate.substring(0,sDate.length()-1)+"+00:00";
}
int tzdIndex = sDate.indexOf("+",tIndex);
if (tzdIndex==-1) {
tzdIndex = sDate.indexOf("-",tIndex);
}
if (tzdIndex>-1) {
String pre = sDate.substring(0,tzdIndex);
int secFraction = pre.indexOf(",");
if (secFraction>-1) {
pre = pre.substring(0,secFraction);
}
String post = sDate.substring(tzdIndex);
sDate = pre + "GMT" + post;
}
}
else {
sDate += "T00:00GMT";
}
return parseUsingMask(W3CDATETIME_MASKS,sDate);
}
/**
* Parses a Date out of a String with a date in W3C date-time format or
* in a RFC822 format.
* <p>
* @param sDate string to parse for a date.
* @return the Date represented by the given W3C date-time string.
* It returns <b>null</b> if it was not possible to parse the given string into a Date.
*
* */
public static Date parseDate(String sDate) {
Date d = parseW3CDateTime(sDate);
if (d==null) {
d = parseRFC822(sDate);
if (d==null && ADDITIONAL_MASKS.length>0) {
d = parseUsingMask(ADDITIONAL_MASKS,sDate);
}
}
return d;
}
/**
* create a RFC822 representation of a date.
* <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
* <p/>
* @param date Date to parse
* @return the RFC822 represented by the given Date
* It returns <b>null</b> if it was not possible to parse the date.
*
*/
public static String formatRFC822(Date date) {
SimpleDateFormat dateFormater = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'",Locale.US);
dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormater.format(date);
}
/**
* create a W3C Date Time representation of a date.
* <p/>
* Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
* <p/>
* @param date Date to parse
* @return the W3C Date Time represented by the given Date
* It returns <b>null</b> if it was not possible to parse the date.
*
*/
public static String formatW3CDateTime(Date date) {
SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.US);
dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormater.format(date);
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.io.WireFeedGenerator;
import java.util.List;
/**
* Generates an XML document (JDOM Document) out of a Feed.
* <p>
* It can generate all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and
* Atom 0.3 feed.
* <p>
* WireFeedGenerator instances are thread safe.
* <p>
* Generators for a specific type must extend this class and register in the generator list.
* (Right now registration is hardcoded in the WireFeedGenerator constructor).
* <p>
* @author Alejandro Abdelnur
*
*/
public class FeedGenerators extends PluginManager {
/**
* WireFeedGenerator.classes= [className] ...
*
*/
public static final String FEED_GENERATORS_KEY = "WireFeedGenerator.classes";
public FeedGenerators() {
super(FEED_GENERATORS_KEY);
}
public WireFeedGenerator getGenerator(String feedType) {
return (WireFeedGenerator) getPlugin(feedType);
}
protected String getKey(Object obj) {
return ((WireFeedGenerator)obj).getType();
}
public List getSupportedFeedTypes() {
return getKeys();
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.io.WireFeedParser;
import org.jdom.Document;
import java.util.List;
/**
* Parses an XML document (JDOM Document) into a Feed.
* <p>
* 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.
* <p>
* The WireFeedParser is a liberal parser.
* <p>
* WireFeedParser instances are thread safe.
* <p>
* Parsers for a specific type must extend this class and register in the parser list.
* (Right now registration is hardcoded in the WireFeedParser constructor).
* <p>
* @author Alejandro Abdelnur
*
*/
public class FeedParsers extends PluginManager {
/**
* WireFeedParser.classes= [className] ...
*
*/
public static final String FEED_PARSERS_KEY = "WireFeedParser.classes";
/**
* Creates a parser instance.
* <p>
*
*/
public FeedParsers() {
super(FEED_PARSERS_KEY);
}
public List getSupportedFeedTypes() {
return getKeys();
}
/**
* Finds the real parser type for the given document feed.
* <p>
* @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.
*
*/
public WireFeedParser getParserFor(Document document) {
List parsers = getPlugins();
WireFeedParser parser = null;
for (int i=0;parser==null && i<parsers.size();i++) {
parser = (WireFeedParser) parsers.get(i);
if (!parser.isMyType(document)) {
parser = null;
}
}
return parser;
}
protected String getKey(Object obj) {
return ((WireFeedParser)obj).getType();
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleGenerator;
import org.jdom.Element;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*/
public class ModuleGenerators extends PluginManager {
private Set _allNamespaces;
public ModuleGenerators(String propertyKey, BaseWireFeedGenerator parentGenerator) {
super(propertyKey, null, parentGenerator);
}
public ModuleGenerator getGenerator(String uri) {
return (ModuleGenerator) getPlugin(uri);
}
protected String getKey(Object obj) {
return ((ModuleGenerator)obj).getNamespaceUri();
}
public List getModuleNamespaces() {
return getKeys();
}
public void generateModules(List modules, Element element) {
Map generators = getPluginMap();
for (int i = 0; i < modules.size(); i++) {
Module module = (Module) modules.get(i);
String namespaceUri = module.getUri();
ModuleGenerator generator = (ModuleGenerator)generators.get(namespaceUri);
if (generator != null) {
generator.generate(module, element);
}
}
}
public Set getAllNamespaces() {
if (_allNamespaces==null) {
_allNamespaces = new HashSet();
List mUris = getModuleNamespaces();
for (int i=0;i<mUris.size();i++) {
ModuleGenerator mGen = getGenerator((String)mUris.get(i));
_allNamespaces.addAll(mGen.getNamespaces());
}
}
return _allNamespaces;
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleParser;
import com.sun.syndication.io.WireFeedParser;
import org.jdom.Element;
import org.jdom.Namespace;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class ModuleParsers extends PluginManager {
public ModuleParsers(String propertyKey, WireFeedParser parentParser) {
super(propertyKey, parentParser, null);
}
public String getKey(Object obj) {
return ((ModuleParser)obj).getNamespaceUri();
}
public List getModuleNamespaces() {
return getKeys();
}
public List parseModules(Element root) {
List parsers = getPlugins();
List modules = null;
for (int i=0;i<parsers.size();i++) {
ModuleParser parser = (ModuleParser) parsers.get(i);
String namespaceUri = parser.getNamespaceUri();
Namespace namespace = Namespace.getNamespace(namespaceUri);
if (hasElementsFrom(root, namespace)) {
Module module = parser.parse(root);
if (module != null) {
if (modules == null) {
modules = new ArrayList();
}
modules.add(module);
}
}
}
return modules;
}
private boolean hasElementsFrom(Element root, Namespace namespace) {
boolean hasElements = false;
// boolean hasElements = namespace.equals(root.getNamespace());
if (!hasElements) {
List children = root.getChildren();
for (int i=0;!hasElements && i < children.size();i++) {
Element child = (Element) children.get(i);
hasElements = namespace.equals(child.getNamespace());
}
}
return hasElements;
}
}

View file

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

View file

@ -0,0 +1,144 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.io.DelegatingModuleGenerator;
import com.sun.syndication.io.DelegatingModuleParser;
import com.sun.syndication.io.WireFeedGenerator;
import com.sun.syndication.io.WireFeedParser;
import java.util.*;
/**
* <p>
* @author Alejandro Abdelnur
*
*/
public abstract class PluginManager {
private String[] _propertyValues;
private Map _pluginsMap;
private List _pluginsList;
private List _keys;
private WireFeedParser _parentParser;
private WireFeedGenerator _parentGenerator;
/**
* Creates a PluginManager
* <p>
* @param propertyKey property key defining the plugins classes
*
*/
protected PluginManager(String propertyKey) {
this(propertyKey, null, null);
}
protected PluginManager(String propertyKey, WireFeedParser parentParser,
WireFeedGenerator parentGenerator)
{
_parentParser = parentParser;
_parentGenerator = parentGenerator;
_propertyValues = PropertiesLoader.getPropertiesLoader().getTokenizedProperty(propertyKey,", ");
loadPlugins();
_pluginsMap = Collections.unmodifiableMap(_pluginsMap);
_pluginsList = Collections.unmodifiableList(_pluginsList);
_keys = Collections.unmodifiableList(new ArrayList(_pluginsMap.keySet()));
}
protected abstract String getKey(Object obj);
protected List getKeys() {
return _keys;
}
protected List getPlugins() {
return _pluginsList;
}
protected Map getPluginMap() {
return _pluginsMap;
}
protected Object getPlugin(String key) {
return _pluginsMap.get(key);
}
// PRIVATE - LOADER PART
private void loadPlugins() {
List finalPluginsList = new ArrayList();
_pluginsList = new ArrayList();
_pluginsMap = new HashMap();
String className = null;
try {
Class[] classes = getClasses();
for (int i=0;i<classes.length;i++) {
className = classes[i].getName();
Object plugin = classes[i].newInstance();
if (plugin instanceof DelegatingModuleParser) {
((DelegatingModuleParser) plugin).setFeedParser(_parentParser);
}
if (plugin instanceof DelegatingModuleGenerator) {
((DelegatingModuleGenerator) plugin).setFeedGenerator(_parentGenerator);
}
_pluginsMap.put(getKey(plugin), plugin);
_pluginsList.add(plugin); // to preserve the order of definition in the rome.properties files
}
Iterator i = _pluginsMap.values().iterator();
while (i.hasNext()) {
finalPluginsList.add(i.next()); // to remove overridden plugin impls
}
i = _pluginsList.iterator();
while (i.hasNext()) {
Object plugin = i.next();
if (!finalPluginsList.contains(plugin)) {
i.remove();
}
}
}
catch (Exception ex) {
throw new RuntimeException("could not instantiate plugin "+className,ex);
}catch (ExceptionInInitializerError 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
* set to true then 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>
* @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
* and hard failure is ON.
*
*/
private Class[] getClasses() throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
List classes = new ArrayList();
boolean useLoadClass = Boolean.valueOf(System.getProperty("rome.pluginmanager.useloadclass", "false")).booleanValue();
for (int i = 0; i <_propertyValues.length; i++) {
Class mClass = (useLoadClass ? classLoader.loadClass(_propertyValues[i]) : Class.forName(_propertyValues[i], true, classLoader));
classes.add(mClass);
}
Class[] array = new Class[classes.size()];
classes.toArray(array);
return array;
}
}

View file

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

View file

@ -0,0 +1,271 @@
/*
* Copyright 2004 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.rss.*;
import com.sun.syndication.io.FeedException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import java.util.List;
/**
* Feed Generator for RSS 0.90
* <p/>
*
* @author Elaine Chien
*/
public class RSS090Generator extends BaseWireFeedGenerator {
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 CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI);
private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
private static final Namespace CONTENT_NS = Namespace.getNamespace("content", CONTENT_URI);
public RSS090Generator() {
this("rss_0.9");
}
protected RSS090Generator(String type) {
super(type);
}
public Document generate(WireFeed feed) throws FeedException {
Channel channel = (Channel)feed;
Element root = createRootElement(channel);
populateFeed(channel,root);
purgeUnusedNamespaceDeclarations(root);
return createDocument(root);
}
protected Namespace getFeedNamespace() {
return RSS_NS;
}
protected Namespace getRDFNamespace() {
return RDF_NS;
}
protected Namespace getContentNamespace() {
return CONTENT_NS;
}
protected Document createDocument(Element root) {
return new Document(root);
}
protected Element createRootElement(Channel channel) {
Element root = new Element("RDF",getRDFNamespace());
root.addNamespaceDeclaration(getFeedNamespace());
root.addNamespaceDeclaration(getRDFNamespace());
root.addNamespaceDeclaration(getContentNamespace());
generateModuleNamespaceDefs(root);
return root;
}
protected void populateFeed(Channel channel, Element parent) throws FeedException {
addChannel(channel,parent);
addImage(channel,parent);
addTextInput(channel,parent);
addItems(channel,parent);
generateForeignMarkup(parent, (List)channel.getForeignMarkup());
}
protected void addChannel(Channel channel,Element parent) throws FeedException {
Element eChannel = new Element("channel", getFeedNamespace());
populateChannel(channel,eChannel);
checkChannelConstraints(eChannel);
parent.addContent(eChannel);
generateFeedModules(channel.getModules(),eChannel);
}
/**
* Populates the given channel with parsed data from the ROME element that holds the
* channel data.
*
* @param channel the channel into which parsed data will be added.
* @param eChannel the XML element that holds the data for the channel.
*/
protected void populateChannel(Channel channel,Element eChannel) {
String title = channel.getTitle();
if (title!=null) {
eChannel.addContent(generateSimpleElement("title",title));
}
String link = channel.getLink();
if (link!=null) {
eChannel.addContent(generateSimpleElement("link",link));
}
String description = channel.getDescription();
if (description!=null) {
eChannel.addContent(generateSimpleElement("description",description));
}
}
// maxLen == -1 means unlimited.
protected void checkNotNullAndLength(Element parent, String childName, int minLen, int maxLen) throws FeedException {
Element child = parent.getChild(childName,getFeedNamespace());
if (child == null) {
throw new FeedException("Invalid "+getType()+" feed, missing "+parent.getName()+" "+childName);
}
checkLength(parent,childName,minLen,maxLen);
}
// maxLen == -1 means unlimited.
protected void checkLength(Element parent, String childName, int minLen, int maxLen) throws FeedException {
Element child = parent.getChild(childName,getFeedNamespace());
if (child != null) {
if (minLen>0 && child.getText().length()<minLen) {
throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "short of "+minLen+" length");
}
if (maxLen>-1 && child.getText().length()>maxLen) {
throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "exceeds "+maxLen+" length");
}
}
}
protected void addImage(Channel channel,Element parent) throws FeedException {
Image image = channel.getImage();
if (image!=null) {
Element eImage = new Element("image", getFeedNamespace());
populateImage(image,eImage);
checkImageConstraints(eImage);
parent.addContent(eImage);
}
}
protected void populateImage(Image image,Element eImage) {
String title = image.getTitle();
if (title!=null) {
eImage.addContent(generateSimpleElement("title",title));
}
String url = image.getUrl();
if (url!=null) {
eImage.addContent(generateSimpleElement("url",url));
}
String link = image.getLink();
if (link!=null) {
eImage.addContent(generateSimpleElement("link",link));
}
}
// Thxs DW for this one
protected String getTextInputLabel() {
return "textInput";
}
protected void addTextInput(Channel channel,Element parent) throws FeedException {
TextInput textInput = channel.getTextInput();
if (textInput!=null) {
Element eTextInput = new Element(getTextInputLabel(), getFeedNamespace());
populateTextInput(textInput,eTextInput);
checkTextInputConstraints(eTextInput);
parent.addContent(eTextInput);
}
}
protected void populateTextInput(TextInput textInput,Element eTextInput) {
String title = textInput.getTitle();
if (title!=null) {
eTextInput.addContent(generateSimpleElement("title",title));
}
String description = textInput.getDescription();
if (description!=null) {
eTextInput.addContent(generateSimpleElement("description",description));
}
String name = textInput.getName();
if (name!=null) {
eTextInput.addContent(generateSimpleElement("name",name));
}
String link = textInput.getLink();
if (link!=null) {
eTextInput.addContent(generateSimpleElement("link",link));
}
}
protected void addItems(Channel channel,Element parent) throws FeedException {
List items = channel.getItems();
for (int i=0;i<items.size();i++) {
addItem((Item)items.get(i),parent, i);
}
checkItemsConstraints(parent);
}
protected void addItem(Item item, Element parent, int index) throws FeedException {
Element eItem = new Element("item", getFeedNamespace());
populateItem(item,eItem, index);
checkItemConstraints(eItem);
generateItemModules(item.getModules(),eItem);
parent.addContent(eItem);
}
protected void populateItem(Item item, Element eItem, int index) {
String title = item.getTitle();
if (title!=null) {
eItem.addContent(generateSimpleElement("title",title));
}
String link = item.getLink();
if (link!=null) {
eItem.addContent(generateSimpleElement("link",link));
}
generateForeignMarkup(eItem, (List)item.getForeignMarkup());
}
protected Element generateSimpleElement(String name, String value) {
Element element = new Element(name, getFeedNamespace());
element.addContent(value);
return element;
}
protected void checkChannelConstraints(Element eChannel) throws FeedException {
checkNotNullAndLength(eChannel,"title", 0, 40);
checkNotNullAndLength(eChannel,"description", 0, 500);
checkNotNullAndLength(eChannel,"link", 0, 500);
}
protected void checkImageConstraints(Element eImage) throws FeedException {
checkNotNullAndLength(eImage,"title", 0, 40);
checkNotNullAndLength(eImage,"url", 0, 500);
checkNotNullAndLength(eImage,"link", 0, 500);
}
protected void checkTextInputConstraints(Element eTextInput) throws FeedException {
checkNotNullAndLength(eTextInput,"title", 0, 40);
checkNotNullAndLength(eTextInput,"description", 0, 100);
checkNotNullAndLength(eTextInput,"name", 0, 500);
checkNotNullAndLength(eTextInput,"link", 0, 500);
}
protected void checkItemsConstraints(Element parent) throws FeedException {
int count = parent.getChildren("item",getFeedNamespace()).size();
if (count<1 || count>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 {
checkNotNullAndLength(eItem,"title", 0, 100);
checkNotNullAndLength(eItem,"link", 0, 500);
}
}

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