Package fitnesse.responders

Source Code of fitnesse.responders.RssResponder$RecentChangesPage

// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.responders;

import java.io.ByteArrayOutputStream;
import java.net.UnknownHostException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fitnesse.FitNesseContext;
import fitnesse.authentication.SecureOperation;
import fitnesse.authentication.SecureReadOperation;
import fitnesse.authentication.SecureResponder;
import fitnesse.wiki.*;
import fitnesse.http.Request;
import fitnesse.http.Response;
import fitnesse.http.SimpleResponse;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import fitnesse.util.XmlUtil;
import fitnesse.util.XmlWriter;

public class RssResponder implements SecureResponder {
  private RssFeed feed;

  public Response makeResponse(FitNesseContext context, Request request) throws Exception {
    WikiPage contextPage = getContextPage(context, request.getResource());
    WikiPage recentChangesPage = context.root.getChildPage(RecentChanges.RECENT_CHANGES);

    feed = new RssFeed(getConfiguredRssLinkPrefixFrom(contextPage));

    buildItemReportIfRecentChangesExists(recentChangesPage, request.getResource());

    return feed.asResponse();
  }

  private WikiPage getContextPage(FitNesseContext context, String resource) throws Exception {
    PageCrawler pageCrawler = context.root.getPageCrawler();
    WikiPagePath resourcePath = PathParser.parse(resource);
    return pageCrawler.getPage(resourcePath);
  }

  protected void buildItemReportIfRecentChangesExists(WikiPage recentChangesPage, String resource)
      throws Exception {
    if (recentChangesPage != null)
      buildItemReport(resource, new RecentChangesPage(recentChangesPage));
  }

  private void buildItemReport(String resource, RecentChangesPage recentChangesPage)
      throws Exception {
    for (RecentChangesPageEntry line : recentChangesPage.getLinesApplicableTo(resource)) {
      feed.addItem(line);
    }
  }

  private String getConfiguredRssLinkPrefixFrom(WikiPage contextPage) throws Exception {
    if (contextPage == null) {
      return null;
    }
    return contextPage.getVariable("RSS_PREFIX");
  }

  protected static boolean isNeitherNullNorBlank(String string) {
    return string != null && string.length() > 0;
  }

  public SecureOperation getSecureOperation() {
    return new SecureReadOperation();
  }

  static class RssFeed {
    private Element channelElement;
    private final Document document;
    private final LinkPrefixBuilder linkPrefixBuilder;

    public RssFeed(String configuredLinkPrefix) throws Exception {
      document = buildDocumentWithRssHeader();
      linkPrefixBuilder = new LinkPrefixBuilder(configuredLinkPrefix);
    }

    public void addItem(RecentChangesPageEntry line) throws Exception {
      Map<String, String> itemProperties = line.getItemProperties();
      Element itemElement = document.createElement("item");
      makeNodes(itemElement, itemProperties);
      linkPrefixBuilder.buildLink(itemElement, itemProperties.get("path"));

      String description = makeDescription(itemProperties);
      XmlUtil.addTextNode(itemElement, "description", description);
      channelElement.appendChild(itemElement);
    }

    public SimpleResponse asResponse() throws Exception {
      byte[] bytes = toByteArray(document);
      SimpleResponse response = new SimpleResponse();
      response.setContent(bytes);
      response.setContentType("text/xml");
      return response;
    }

    private static String makeDescription(Map<String, String> itemProperties) {
      String description;
      String authoredBy = "";
      if (isNeitherNullNorBlank(itemProperties.get("author")))
        authoredBy = itemProperties.get("author") + ":";
      description = authoredBy + itemProperties.get("pubDate");
      return description;
    }

    private static void makeNodes(Element itemElement, Map<String, String> itemProperties) {
      XmlUtil.addTextNode(itemElement, "title", itemProperties.get("path"));
      XmlUtil.addTextNode(itemElement, "author", itemProperties.get("author"));
      XmlUtil.addTextNode(itemElement, "pubDate", itemProperties.get("pubDate"));
    }

    private Document buildDocumentWithRssHeader() throws Exception {
      Document rssDocument = XmlUtil.newDocument();
      Element rssDocumentElement = rssDocument.createElement("rss");
      rssDocument.appendChild(rssDocumentElement);
      channelElement = rssDocument.createElement("channel");
      rssDocumentElement.setAttribute("version", "2.0");
      rssDocumentElement.appendChild(channelElement);
      XmlUtil.addTextNode(channelElement, "title", "FitNesse:");

      return rssDocument;
    }

    private static byte[] toByteArray(Document rssDocument) throws Exception {
      ByteArrayOutputStream os = new ByteArrayOutputStream();
      XmlWriter writer = new XmlWriter(os);
      writer.write(rssDocument);
      writer.close();
      return os.toByteArray();
    }

    private Document buildRssHeader() {
      Document rssDocument = XmlUtil.newDocument();
      Element rssDocumentElement = rssDocument.createElement("rss");
      rssDocument.appendChild(rssDocumentElement);
      channelElement = rssDocument.createElement("channel");
      rssDocumentElement.setAttribute("version", "2.0");
      rssDocumentElement.appendChild(channelElement);
      return rssDocument;
    }
  }

  static class RecentChangesPage {
    private WikiPage page;

    RecentChangesPage(WikiPage page) {
      this.page = page;
    }

    public List<RecentChangesPageEntry> getLinesApplicableTo(String resource) throws Exception {
      List<RecentChangesPageEntry> filteredLines = new ArrayList<RecentChangesPageEntry>();
      for (RecentChangesPageEntry line : getLines()) {
        if (line.relatesTo(resource))
          filteredLines.add(line);
      }
      return filteredLines;
    }

    private List<RecentChangesPageEntry> getLines() throws Exception {
      List<RecentChangesPageEntry> lines = new ArrayList<RecentChangesPageEntry>();
      for (String lineString : getPageContentLines()) {
        lines.add(new RecentChangesPageEntry(lineString));
      }
      return lines;
    }

    private String[] getPageContentLines() throws Exception {
      PageData data = page.getData();
      String content = data.getContent();
      return content.split("\n");
    }
  }

  static class RecentChangesPageEntry {
    private String line;

    RecentChangesPageEntry(String line) {
      this.line = line;
    }

    public Map<String, String> getItemProperties() {
      String[] fields = convertTableLineToStrings();
      Map<String, String> itemProperties = new HashMap<String, String>();
      itemProperties.put("path", fields[1]);
      itemProperties.put("author", fields[2]);
      itemProperties.put("pubDate", convertDateFormat(fields[3]));
      return itemProperties;
    }

    protected boolean relatesTo(String resource) {
      String path = getItemProperties().get("path");
      boolean blank = isNeitherNullNorBlank(resource);
      return !blank || path.startsWith(resource);
    }

    private String[] convertTableLineToStrings() {
      return line.split("\\|");
    }

    static String convertDateFormat(String dateIn) {
      // format matched kk:mm:ss EEE, MMM dd, yyyy
      Pattern timePattern = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");
      Matcher m = timePattern.matcher(dateIn);
      if (m.matches())
        return (new SimpleDateFormat(FitNesseContext.rfcCompliantDateFormat))
            .format((new SimpleDateFormat(FitNesseContext.recentChangesDateFormat)).parse(dateIn,
                new ParsePosition(0)));
      else
        return dateIn;
    }
  }

  static class LinkPrefixBuilder {
    private String preconfiguredPrefix;

    LinkPrefixBuilder(String preconfiguredPrefix) {
      this.preconfiguredPrefix = preconfiguredPrefix;
    }

    public void buildLink(Element itemElement, String pageName)
        throws Exception {
      String prefix = getRssLinkPrefix();
      String link = prefix + pageName;

      XmlUtil.addTextNode(itemElement, "link", link);
    }

    private static String hostnameRssLinkPrefix() throws UnknownHostException {
      String hostName = java.net.InetAddress.getLocalHost().getHostName();
      return "http://" + hostName + "/";
    }

    private String getRssLinkPrefix() throws Exception {
      return preconfiguredPrefix == null ? hostnameRssLinkPrefix() : preconfiguredPrefix;
    }
  }
}
TOP

Related Classes of fitnesse.responders.RssResponder$RecentChangesPage

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.