Package org.jamwiki.servlets

Source Code of org.jamwiki.servlets.RecentChangesFeedServlet

/**
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the latest version of the GNU Lesser General
* Public License as published by the Free Software Foundation;
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program (LICENSE.txt); if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package org.jamwiki.servlets;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.io.SyndFeedOutput;
import org.apache.commons.lang.StringUtils;
import org.jamwiki.Environment;
import org.jamwiki.WikiBase;
import org.jamwiki.model.RecentChange;
import org.jamwiki.utils.Pagination;
import org.jamwiki.utils.Utilities;
import org.jamwiki.utils.WikiLogger;
import org.jamwiki.utils.WikiUtil;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
* Provides an RSS or Atom feed for recent changes.
*
* Feed generation can be influenced through following request parameters:
* <ul>
* <li><code>feedType</code>: RSS or Atom (see
* {@link #setDefaultFeedType(String)}) </li>
* <li><code>minorEdits</code>: set to 'true' to include minor edits </li>
* <li><code>num</code>: number of entries to return (see
* {@link WikiUtil#buildPagination(HttpServletRequest)})</li>
* </ul>
*
* @author Rainer Schmitz
* @since 22.12.2006
*/
public class RecentChangesFeedServlet extends AbstractController {

  private static final WikiLogger logger = WikiLogger.getLogger(RecentChangesFeedServlet.class.getName());
  private static final String MIME_TYPE = "application/xml";
  private static final String FEED_ENCODING = "UTF-8";
  private static final String DEFAULT_FEED_TYPE = "rss_2.0";
  private static final String FEED_TYPE = "feedType";
  private static final String MINOR_EDITS = "minorEdits";
  private static final String LINK_TO_VERSION = "linkToVersion";
  private String defaultFeedType = DEFAULT_FEED_TYPE;
  private boolean defaultIncludeMinorEdits = false;
  private boolean defaultLinkToVersion = false;
  private String feedUrlPrefix = "";

  /**
   * Sets the default feed type.
   *
   * Valid values are rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0,
   * atom_0.3, and atom_1.0.
   *
   * This value is used if no feed type is given in the request (parameter
   * 'feedType'). Default is rss_2.0.
   *
   * @param defaultFeedType
   *            The defaultFeedType to set.
   */
  public void setDefaultFeedType(String defaultFeedType) {
    this.defaultFeedType = defaultFeedType;
  }

  /**
   * Sets whether minor edits are included in generated feed.
   *
   * This value can be overriden by the request parameter 'minorEdits'.
   * Default is false.
   *
   * @param includeMinorEdits
   *            <code>true</code> if minor edits shall be included in feed.
   */
  public void setDefaultIncludeMinorEdits(boolean includeMinorEdits) {
    this.defaultIncludeMinorEdits = includeMinorEdits;
  }

  /**
   * Sets whether feed entry link should link to the changed or to the current
   * version of the changed entry.
   *
   * This value can be overriden by the request parameter 'linkToVersion'.
   * Default is false.
   *
   * @param feedUrlPrefix feed URL prefix to set; may not be null.
   */
  public void setFeedUrlPrefix(String feedUrlPrefix) {
    if (feedUrlPrefix == null) {
      throw new IllegalArgumentException("Feed URL prefix may not be null");
    }
    this.feedUrlPrefix = feedUrlPrefix;
  }

  /**
   * Prefix to use in feed and feed entry links.
   *
   * This is useful in portal environments to prefix the feed URL with the portal URL.
   *
   * @param linkToVersion
   *            <code>true</code> if link should point to edited version.
   */
  public void setDefaultLinkToVersion(boolean linkToVersion) {
    this.defaultLinkToVersion = linkToVersion;
  }

  /**
   * Handle the servlet request, generating appropriate output.
   *
   * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
    try {
      String feedType = ServletRequestUtils.getStringParameter(request, FEED_TYPE, defaultFeedType);
      logger.finer("Serving xml feed of type " + feedType);
      SyndFeed feed = getFeed(request);
      feed.setFeedType(feedType);
      response.setContentType(MIME_TYPE);
      response.setCharacterEncoding(FEED_ENCODING);
      SyndFeedOutput output = new SyndFeedOutput();
      output.output(feed, response.getWriter());
    } catch (Exception e) {
      logger.severe("Could not generate feed: " + e.getMessage(), e);
      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not generate feed: "
          + e.getMessage());
    }
    return null;
  }

  /**
   * TODO cache feed to avoid high load caused by RSS aggregators
   *
   * @throws Exception
   */
  private SyndFeed getFeed(HttpServletRequest request) throws Exception {
    List<RecentChange> changes = getChanges(request);
    SyndFeed feed = new SyndFeedImpl();
    feed.setEncoding(FEED_ENCODING);
    feed.setTitle(Environment.getValue(Environment.PROP_RSS_TITLE));
    StringBuffer requestURL = request.getRequestURL();
    String feedURL = feedUrlPrefix + requestURL.substring(0, requestURL.length() - WikiUtil.getTopicFromURI(request).length());
    feed.setLink(feedURL);
    feed.setDescription("List of the last " + changes.size() + " changed wiki pages.");
    boolean includeMinorEdits = ServletRequestUtils.getBooleanParameter(request, MINOR_EDITS,
        defaultIncludeMinorEdits);
    boolean linkToVersion = ServletRequestUtils.getBooleanParameter(request, LINK_TO_VERSION, defaultLinkToVersion);
    feed.setEntries(getFeedEntries(changes, includeMinorEdits, linkToVersion, feedURL));
    return feed;
  }

  /**
   *
   */
  private List<SyndEntry> getFeedEntries(List<RecentChange> changes, boolean includeMinorEdits, boolean linkToVersion, String feedURL) {
    List<SyndEntry> entries = new ArrayList<SyndEntry>();
    for (RecentChange change : changes) {
      // FIXME - add support for log item changes
      if (!StringUtils.isBlank(change.getTopicName()) && (includeMinorEdits || !change.getMinor())) {
        entries.add(getFeedEntry(change, linkToVersion, feedURL));
      }
    }
    return entries;
  }

  /**
   *
   */
  private SyndEntry getFeedEntry(RecentChange change, boolean linkToVersion, String feedURL) {
    SyndContent description;
    SyndEntry entry = new SyndEntryImpl();
    entry.setTitle(change.getTopicName());
    entry.setAuthor(change.getAuthorName());
    entry.setPublishedDate(change.getChangeDate());
    description = new SyndContentImpl();
    description.setType("text/plain");
    StringBuffer descr = new StringBuffer();
    if (!StringUtils.isBlank(change.getChangeComment())) {
      descr.append(change.getChangeComment());
    }
    if (change.isDelete()) {
      descr.append(" (deleted)");
    } else {
      if (linkToVersion) {
        try {
        String url = feedURL + URLEncoder.encode("Special:History?topicVersionId=" + change.getTopicVersionId() + "&topic="
            + Utilities.encodeAndEscapeTopicName(change.getTopicName()), "UTF-8");
          entry.setLink(url);
        } catch (UnsupportedEncodingException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      } else {
        entry.setLink(feedURL + Utilities.encodeAndEscapeTopicName(change.getTopicName()));
      }
    }
    if (change.isUndelete()) {
      descr.append(" (undeleted)");
    }
    if (change.getMinor()) {
      descr.append(" (minor)");
    }
    description.setValue(descr.toString());
    entry.setDescription(description);
    // URI is used as GUID in RSS 2.0 and should therefore contain the
    // version id
    entry.setUri(feedURL + Utilities.encodeAndEscapeTopicName(change.getTopicName()) + "#" + change.getTopicVersionId());
    return entry;
  }

  /**
   *
   */
  private List<RecentChange> getChanges(HttpServletRequest request) throws Exception {
    String virtualWiki = WikiUtil.getVirtualWikiFromURI(request);
    Pagination pagination = WikiUtil.buildPagination(request);
    return WikiBase.getDataHandler().getRecentChanges(virtualWiki, pagination, true);
  }
}
TOP

Related Classes of org.jamwiki.servlets.RecentChangesFeedServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.