⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rssmacro.java

📁 xwiki 源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * ===================================================================
 *
 * 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>&lt;div&gt;</code> tags
     * with CSS class attributes.
     * <ul>
     * <li>The whole item is wrapped in <code>&lt;div class='rss.item'&gt;</li>
     * <li>The item title is wrapped in <code>&lt;div class='rss.item.title'&gt;</li>
     * <li>The item title link is wrapped in <code>&lt;a class='rss.item.title'&gt;</code></li>
     * <li>If present, the item description is wrapped in <code>&lt;div class='rss.item.description'&gt;</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 + -