001: /*---------------------------------------------------------------------------*\
002: $Id: RSSElement.java 7041 2007-09-09 01:04:47Z bmc $
003: ---------------------------------------------------------------------------
004: This software is released under a BSD-style license:
005:
006: Copyright (c) 2004-2007 Brian M. Clapper. All rights reserved.
007:
008: Redistribution and use in source and binary forms, with or without
009: modification, are permitted provided that the following conditions are
010: met:
011:
012: 1. Redistributions of source code must retain the above copyright notice,
013: this list of conditions and the following disclaimer.
014:
015: 2. The end-user documentation included with the redistribution, if any,
016: must include the following acknowlegement:
017:
018: "This product includes software developed by Brian M. Clapper
019: (bmc@clapper.org, http://www.clapper.org/bmc/). That software is
020: copyright (c) 2004-2007 Brian M. Clapper."
021:
022: Alternately, this acknowlegement may appear in the software itself,
023: if wherever such third-party acknowlegements normally appear.
024:
025: 3. Neither the names "clapper.org", "curn", nor any of the names of the
026: project contributors may be used to endorse or promote products
027: derived from this software without prior written permission. For
028: written permission, please contact bmc@clapper.org.
029:
030: 4. Products derived from this software may not be called "curn", nor may
031: "clapper.org" appear in their names without prior written permission
032: of Brian M. Clapper.
033:
034: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
036: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
037: NO EVENT SHALL BRIAN M. CLAPPER BE LIABLE FOR ANY DIRECT, INDIRECT,
038: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
039: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
040: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
041: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
042: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
043: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044: \*---------------------------------------------------------------------------*/
045:
046: package org.clapper.curn.parser;
047:
048: import java.net.URL;
049: import org.clapper.util.text.TextUtil;
050:
051: import java.util.Collection;
052:
053: /**
054: * Abstract parent class of {@link RSSItem} and {@link RSSChannel},
055: * containing various shared methods.
056: *
057: * @see RSSParser
058: * @see RSSChannel
059: * @see RSSItem
060: *
061: * @version <tt>$Revision: 7041 $</tt>
062: */
063: public abstract class RSSElement {
064: /*----------------------------------------------------------------------*\
065: Constructor
066: \*----------------------------------------------------------------------*/
067:
068: /**
069: * Default constructor
070: */
071: protected RSSElement() {
072: // Nothing to do
073: }
074:
075: /*----------------------------------------------------------------------*\
076: Public Methods
077: \*----------------------------------------------------------------------*/
078:
079: /**
080: * Get the item's author. This method simply calls the {@link
081: * #getAuthors} method and combines the results into a comma-delimited
082: * string.
083: *
084: * @return the author string, or null if not available
085: *
086: * @see #setAuthor
087: * @see #getAuthors
088: */
089: public final String getAuthor() {
090: Collection<String> authors = getAuthors();
091: String result = null;
092:
093: if ((authors != null) && (authors.size() > 0))
094: result = TextUtil.join(authors, ", ");
095:
096: return result;
097: }
098:
099: /**
100: * Set the item's author. This method clears the existing authors
101: * field, then calls {@link #addAuthor}. You're better off calling
102: * {@link #addAuthor} directly, since some sites support multiple
103: * authors for a feed item.
104: *
105: * @param newAuthor the author, or null if not available
106: *
107: * @see #setAuthors
108: */
109: public final void setAuthor(String newAuthor) {
110: clearAuthors();
111: addAuthor(newAuthor);
112: }
113:
114: /**
115: * Set the item's list of authors to the specified <tt>Collection</tt>.
116: * This method clears the existing authors field, then calls
117: * {@link #addAuthor} for every string in the <tt>Collection</tt>.
118: *
119: * @param newAuthors the author, or null if not available
120: *
121: * @see #addAuthor
122: * @see #getAuthor
123: * @see #clearAuthors
124: */
125: public final void setAuthors(Collection<String> newAuthors) {
126: clearAuthors();
127: for (String author : newAuthors)
128: addAuthor(author);
129: }
130:
131: /**
132: * Get a unique ID for the item. The default implementation of this
133: * method simply returns the URL, if any.
134: *
135: * @return the ID, or null if there isn't one.
136: */
137: public String getID() {
138: String id = null;
139: RSSLink link = getURL();
140:
141: if (link != null) {
142: URL url = link.getURL();
143: if (url != null)
144: id = url.toExternalForm();
145: }
146:
147: return id;
148: }
149:
150: /**
151: * Get the link with a specific MIME type and one of a set of
152: * link types.
153: *
154: * @param mimeType the desired MIME type
155: * @param linkTypes one or more link types that are acceptable
156: *
157: * @return the link, or null no matches were found
158: */
159: public final RSSLink getLink(String mimeType,
160: RSSLink.Type... linkTypes) {
161: return ParserUtil.findMatchingLink(getLinks(), mimeType,
162: linkTypes);
163: }
164:
165: /**
166: * Get the first link with the specified link type.
167: *
168: * @param linkType the link type
169: *
170: * @return the link, or null if no match was found
171: */
172: public final RSSLink getLink(RSSLink.Type linkType) {
173: return ParserUtil.findMatchingLink(getLinks(), linkType);
174: }
175:
176: /**
177: * Get the first link with the specified MIME type.
178: *
179: * @param mimeType the MIME type
180: *
181: * @return the link, or null if no match was found
182: */
183: public final RSSLink getLink(String mimeType) {
184: return ParserUtil.findMatchingLink(getLinks(), mimeType);
185: }
186:
187: /**
188: * Get the first link with the specified MIME type. Fall back to the
189: * {@link RSSLink.Type#SELF SELF} link if not found. Fall back to the
190: * first available link if the <tt>SELF</tt> link is not found.
191: *
192: * @param mimeType the MIME type
193: *
194: * @return the link, or null if no links are available
195: */
196: public final RSSLink getLinkWithFallback(String mimeType) {
197: RSSLink link = null;
198: Collection<RSSLink> links = getLinks();
199:
200: if (links.size() > 0) {
201: link = ParserUtil.findMatchingLink(links, mimeType);
202: if (link == null) {
203: link = getLink(RSSLink.Type.SELF);
204: if (link == null)
205: link = links.iterator().next();
206: }
207: }
208:
209: return link;
210: }
211:
212: /**
213: * Get the URL associated with this item. This method first attempts to
214: * get the {@link RSSLink.Type#SELF SELF} link. If that fails, it looks
215: * for the first {@link RSSLink.Type#ALTERNATE ALTERNATE} link.
216: *
217: * @return the {@link RSSLink} for the URL, or null if it can't be found
218: */
219: public final RSSLink getURL() {
220: // First, try to find the SELF link. If that's not available, use the
221: // first ALTERNATE link.
222:
223: RSSLink link = getLink(RSSLink.Type.SELF);
224:
225: if (link == null) {
226: link = getLink(RSSLink.Type.ALTERNATE);
227: if (link == null)
228: link = getLinkWithFallback("text/html");
229: }
230:
231: return link;
232: }
233:
234: /*----------------------------------------------------------------------*\
235: Public Abstract Methods
236: \*----------------------------------------------------------------------*/
237:
238: /**
239: * Get the element's list of published links (its URLs). Each
240: * element in the returned <tt>Collection</tt> is an
241: * {@link RSSLink} object.
242: *
243: * @return the collection of links, or an empty list if there are none.
244: * The result will never be null.
245: */
246: public abstract Collection<RSSLink> getLinks();
247:
248: /**
249: * Get the item's author list.
250: *
251: * @return the authors, or null (or an empty <tt>Collection</tt>) if
252: * not available
253: *
254: * @see #addAuthor
255: * @see #clearAuthors
256: * @see #setAuthor
257: * @see #getAuthor
258: */
259: public abstract Collection<String> getAuthors();
260:
261: /**
262: * Add to the element's author list.
263: *
264: * @param author another author string to add
265: *
266: * @see #getAuthors
267: * @see #clearAuthors
268: * @see #setAuthor
269: * @see #getAuthor
270: */
271: public abstract void addAuthor(String author);
272:
273: /**
274: * Clear the authors list.
275: *
276: * @see #getAuthors
277: * @see #addAuthor
278: * @see #setAuthor
279: * @see #getAuthor
280: */
281: public abstract void clearAuthors();
282:
283: /*----------------------------------------------------------------------*\
284: Private Methods
285: \*----------------------------------------------------------------------*/
286: }
|