001: /*---------------------------------------------------------------------------*\
002: $Id: TitleOverridePlugIn.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.plugins;
047:
048: import org.clapper.curn.CurnConfig;
049: import org.clapper.curn.CurnException;
050: import org.clapper.curn.FeedInfo;
051: import org.clapper.curn.FeedConfigItemPlugIn;
052: import org.clapper.curn.PostFeedParsePlugIn;
053: import org.clapper.curn.parser.RSSChannel;
054:
055: import org.clapper.util.classutil.ClassUtil;
056: import org.clapper.util.config.ConfigurationException;
057: import org.clapper.util.logging.Logger;
058:
059: import java.util.HashMap;
060: import java.util.Map;
061: import org.clapper.curn.FeedCache;
062:
063: /**
064: * The <tt>TitleOverridePlugIn</tt> handles overriding the title of a feed.
065: * It intercepts the following per-feed configuration parameters:
066: *
067: * <table border="1">
068: * <tr valign="top" align="left">
069: * <th>Parameter</th>
070: * <th>Meaning</th>
071: * </tr>
072: * <tr valign="top">
073: * <td><tt>TitleOverride</tt></td>
074: * <td>The string to use instead of the feed title from the downloaded
075: * RSS data.</td>
076: * </tr>
077: * </table>
078: *
079: * @version <tt>$Revision: 7041 $</tt>
080: */
081: public class TitleOverridePlugIn implements FeedConfigItemPlugIn,
082: PostFeedParsePlugIn {
083: /*----------------------------------------------------------------------*\
084: Private Constants
085: \*----------------------------------------------------------------------*/
086:
087: private static final String VAR_TITLE_OVERRIDE = "TitleOverride";
088:
089: /*----------------------------------------------------------------------*\
090: Private Data Items
091: \*----------------------------------------------------------------------*/
092:
093: /**
094: * Feed title data, by feed
095: */
096: private Map<FeedInfo, String> perFeedTitleMap = new HashMap<FeedInfo, String>();
097:
098: /**
099: * For log messages
100: */
101: private static final Logger log = new Logger(
102: TitleOverridePlugIn.class);
103:
104: /*----------------------------------------------------------------------*\
105: Constructor
106: \*----------------------------------------------------------------------*/
107:
108: /**
109: * Default constructor (required).
110: */
111: public TitleOverridePlugIn() {
112: // Nothing to do
113: }
114:
115: /*----------------------------------------------------------------------*\
116: Public Methods Required by *PlugIn Interfaces
117: \*----------------------------------------------------------------------*/
118:
119: /**
120: * Get a displayable name for the plug-in.
121: *
122: * @return the name
123: */
124: public String getPlugInName() {
125: return "Override Feed Title";
126: }
127:
128: /**
129: * Get the sort key for this plug-in.
130: *
131: * @return the sort key string.
132: */
133: public String getPlugInSortKey() {
134: return ClassUtil.getShortClassName(getClass().getName());
135: }
136:
137: /**
138: * Initialize the plug-in. This method is called before any of the
139: * plug-in methods are called.
140: *
141: * @throws CurnException on error
142: */
143: public void initPlugIn() throws CurnException {
144: }
145:
146: /**
147: * Called immediately after <i>curn</i> has read and processed a
148: * configuration item in a "feed" configuration section. All
149: * configuration items are passed, one by one, to each loaded plug-in.
150: * If a plug-in class is not interested in a particular configuration
151: * item, this method should simply return without doing anything. Note
152: * that some configuration items may simply be variable assignment;
153: * there's no real way to distinguish a variable assignment from a
154: * blessed configuration item.
155: *
156: * @param sectionName the name of the configuration section where
157: * the item was found
158: * @param paramName the name of the parameter
159: * @param config the active configuration
160: * @param feedInfo partially complete <tt>FeedInfo</tt> object
161: * for the feed. The URL is guaranteed to be
162: * present, but no other fields are.
163: *
164: * @return <tt>true</tt> to continue processing the feed,
165: * <tt>false</tt> to skip it
166: *
167: * @throws CurnException on error
168: *
169: * @see CurnConfig
170: * @see FeedInfo
171: * @see FeedInfo#getURL
172: */
173: public boolean runFeedConfigItemPlugIn(String sectionName,
174: String paramName, CurnConfig config, FeedInfo feedInfo)
175: throws CurnException {
176: try {
177: if (paramName.equals(VAR_TITLE_OVERRIDE)) {
178: String title = config.getConfigurationValue(
179: sectionName, paramName);
180: perFeedTitleMap.put(feedInfo, title);
181: log.debug("[" + sectionName + "]: " + paramName + "="
182: + title);
183: }
184:
185: return true;
186: }
187:
188: catch (ConfigurationException ex) {
189: throw new CurnException(ex);
190: }
191: }
192:
193: /**
194: * Called immediately after a feed is parsed, but before it is
195: * otherwise processed. This method can return <tt>false</tt> to signal
196: * <i>curn</i> that the feed should be skipped. For instance, a plug-in
197: * that filters on the parsed feed data could use this method to weed
198: * out non-matching feeds before they are downloaded. Similarly, a
199: * plug-in that edits the parsed data (removing or editing individual
200: * items, for instance) could use method to do so.
201: *
202: * @param feedInfo the {@link FeedInfo} object for the feed that
203: * has been downloaded and parsed.
204: * @param feedCache the feed cache
205: * @param channel the parsed channel data
206: *
207: * @return <tt>true</tt> if <i>curn</i> should continue to process the
208: * feed, <tt>false</tt> to skip the feed. A return value of
209: * <tt>false</tt> aborts all further processing on the feed.
210: * In particular, <i>curn</i> will not pass the feed along to
211: * other plug-ins that have yet to be notified of this event.
212: *
213: * @throws CurnException on error
214: *
215: * @see RSSChannel
216: * @see FeedInfo
217: */
218: public boolean runPostFeedParsePlugIn(FeedInfo feedInfo,
219: FeedCache feedCache, RSSChannel channel)
220: throws CurnException {
221: String title = perFeedTitleMap.get(feedInfo);
222: if (title != null) {
223: log.debug("Overriding title for feed \""
224: + feedInfo.getURL().toString() + "\" to \"" + title
225: + "\"");
226: channel.setTitle(title);
227: }
228:
229: return true;
230: }
231: }
|