📄 rssmacro.java
字号:
/**
* ===================================================================
*
* Copyright (c) 2003 Ludovic Dubost, All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details, published at
* http://www.gnu.org/copyleft/gpl.html or in gpl.txt in the
* root folder of this distribution.
*
* User: ludovic
* Date: 17 mars 2004
* Time: 15:10:09
*/
package com.xpn.xwiki.render.macro.rss;
import java.io.Writer;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.radeox.macro.BaseLocaleMacro;
import org.radeox.macro.parameter.MacroParameter;
import org.radeox.util.Encoder;
import org.radeox.util.logging.Logger;
import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.TextInput;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndImage;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
/**
* A Radeox MacroFilter for rendering an RSS feed.
* @author Joe Germuska
* @version 0.2d
*/
public class RSSMacro extends BaseLocaleMacro {
private static final String NAME = "rss";
private static final String DESCRIPTION = "Use to aggregate RSS feeds";
private static final String[] PARAM_DESCRIPTION = new String[] {
"feed: url of an RSS feed",
"?img: if 'true' and if feed has an image, image will be included",
"?align: if an image will be included, use this alignment",
"?css: if 'true', elements will be created with CSS styles; otherwise, static formatting methods will be used",
"?count: an integer, the maximum number of feed items to display",
"?full: if 'true', descriptions for each item will be included. Otherwise, just titles.",
"?search: if 'true' and if feed has a search field, field will be included"
};
private static final String[] PARAM_NAMES = new String[] {
"img", "align", "css", "count", "full", "search"
};
private static final char NEWLINE = '\n';
public String getLocaleKey() {
return "macro.rss";
}
public String getName() {
return NAME;
}
/**
* Process the macro.
* @param writer the output writer
* @param parameter the input parameters of the macro.
* @throws java.lang.IllegalArgumentException
* @throws java.io.IOException from calls to <code>writer.write()</code>
* TODO Make commons-digester understand more different RSS feeds, or switch
* to a better RSS library.
*/
public void execute(Writer writer, MacroParameter parameter) throws java.lang.IllegalArgumentException, java.io.IOException {
RSSMacroParameters paramObj = processParameters(parameter);
java.net.URL feedURL = paramObj.getFeedURL();
SyndFeedInput input = new SyndFeedInput();
SyndFeed feed = null;
try {
feed = input.build(new XmlReader(feedURL));
}
catch (Exception ex) {
throw new java.io.IOException("Error processing " + feedURL + ": " + ex.getMessage());
}
if (feed == null) throw new IllegalArgumentException("No feed found at " + feedURL);
if (paramObj.isCss())
{
writer.write(NEWLINE);
writer.write("<div class='rssfeed'>");
}
renderImage(feed, writer, paramObj);
renderTitle(feed, writer, paramObj);
renderEntries(feed, writer, paramObj);
renderSearch(feed, writer, paramObj);
writer.write(NEWLINE);
writer.write(NEWLINE);
if (paramObj.isCss())
{
writer.write("</div>");
}
}
/**
* Render as many of the given <code>Channel</code>'s items as needed,
* according to the value of the optional <code>count</code> parameter
* and the number of items in the feed.
* @param writer the output writer
* @param paramObj our parameter helper object
* @throws java.io.IOException
*/
private void renderEntries(SyndFeed feed, Writer writer, RSSMacroParameters paramObj) throws java.io.IOException
{
List listEntries = feed.getEntries();
int max = paramObj.evalCount(listEntries.size());
for (int i = 0; i < max; i++) {
renderEntry((SyndEntry)listEntries.get(i), writer, paramObj);
}
}
/**
* Render the given RSS <code>Item</code> according to whether or not the
* parameters call for CSS processing.
* @param writer the output writer
* @param paramObj our parameter helper object
* @throws java.io.IOException from calls to <code>writer.write()</code>
*/
private void renderEntry(SyndEntry entry, Writer writer, RSSMacroParameters paramObj) throws java.io.IOException
{
StringBuffer buf = new StringBuffer();
if (paramObj.isCss()){
renderEntryCSS(entry, buf, paramObj);
} else {
renderEntryDefault(entry, buf, paramObj);
}
writer.write(buf.toString());
}
/**
* Render the given <code>Item</code> using Radeox macros.
* <ul>
* <li>The item title is wrapped in <code>__bold__</code></li>
* <li>The link is rendered using the <code>{link}</code> macro.</li>
* <li>If present, the item description is wrapped in <code>{quote}</code> macro tags.</li>
* </ul>
* @param buf the StringBuffer we're using to prepare the output
* @param paramObj our parameter helper object
*/
private void renderEntryDefault(SyndEntry entry, StringBuffer buf, RSSMacroParameters paramObj) {
buf.append(NEWLINE).append("* ");
if (entry.getLink() != null) { buf.append("{link:"); }
buf.append(entry.getTitle());
if (entry.getLink() != null) {
buf.append("|")
.append(entry.getLink())
.append("}");
}
if (paramObj.isFull() && entry.getDescription() != null)
{
buf.append(NEWLINE).append("{quote}")
.append(NEWLINE).append(entry.getDescription())
.append(NEWLINE).append("{quote}");
}
}
/**
* Render the given <code>Item</code> using <code><div></code> tags
* with CSS class attributes.
* <ul>
* <li>The whole item is wrapped in <code><div class='rss.item'></li>
* <li>The item title is wrapped in <code><div class='rss.item.title'></li>
* <li>The item title link is wrapped in <code><a class='rss.item.title'></code></li>
* <li>If present, the item description is wrapped in <code><div class='rss.item.description'></li>
* </ul>
* @param buf the StringBuffer we're using to prepare the output
* @param paramObj our parameter helper object
* TODO Figure out how to stop Radeox from filtering the URLs
*/
private void renderEntryCSS(SyndEntry entry, StringBuffer buf, RSSMacroParameters paramObj) {
buf.append(NEWLINE).append("<div class='rssitem'>");
buf.append(NEWLINE).append("<div class='rssitemtitle'>").append(NEWLINE);
if (entry.getLink() != null)
{
buf.append("<a class='rssitemtitle' href=\"")
.append(Encoder.escape(entry.getLink()))
.append("\">");
}
buf.append(entry.getTitle());
if (entry.getLink() != null) { buf.append("</a>"); }
buf.append(NEWLINE).append("</div>"); // close rss.item.title
if (paramObj.isFull() && entry.getDescription() != null)
{
buf.append(NEWLINE).append("<div class='rssitemdescription'>")
.append(NEWLINE).append(entry.getDescription())
.append(NEWLINE).append("</div>"); // close rss.item.description
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -