// 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.wiki;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import fitnesse.util.Clock;
import fitnesse.FitNesseContext;
public class RecentChangesWikiPage implements RecentChanges {
private static final Logger LOG = Logger.getLogger(RecentChangesWikiPage.class.getName());
private static SimpleDateFormat makeDateFormat() {
//SimpleDateFormat is not thread safe, so we need to create each instance independently.
return new SimpleDateFormat(FitNesseContext.recentChangesDateFormat);
}
@Override
public void updateRecentChanges(WikiPage page) {
createRecentChangesIfNecessary(page);
addCurrentPageToRecentChanges(page);
}
@Override
public WikiPage toWikiPage(WikiPage root) {
return root.getPageCrawler().getRoot().getChildPage(RECENT_CHANGES);
}
public List<String> getRecentChangesLines(PageData recentChangesdata) {
String content = recentChangesdata.getContent();
BufferedReader reader = null;
List<String> lines = new ArrayList<>();
try {
reader = new BufferedReader(new StringReader(content));
String line = null;
while ((line = reader.readLine()) != null)
lines.add(line);
} catch (IOException e) {
LOG.log(Level.WARNING, "Unable to read recent changes", e);
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
LOG.log(Level.FINE, "Unable to close recent changes file for reading", e);
}
}
return lines;
}
private void addCurrentPageToRecentChanges(WikiPage page) {
WikiPage recentChanges = page.getPageCrawler().getRoot().getChildPage(RECENT_CHANGES);
String resource = resource(page);
PageData recentChangesData = recentChanges.getData();
List<String> lines = getRecentChangesLines(recentChangesData);
removeDuplicate(lines, resource);
lines.add(0, makeRecentChangesLine(page));
trimExtraLines(lines);
String content = convertLinesToWikiText(lines);
recentChangesData.setContent(content);
recentChanges.commit(recentChangesData);
}
private String resource(WikiPage page) {
WikiPagePath fullPath = page.getPageCrawler().getFullPath();
String resource = PathParser.render(fullPath);
return resource;
}
private void createRecentChangesIfNecessary(WikiPage page) {
PageCrawler crawler = page.getPageCrawler();
WikiPage root = crawler.getRoot();
if (!root.hasChildPage(RECENT_CHANGES))
WikiPageUtil.addPage(root, PathParser.parse(RECENT_CHANGES), "");
}
private String makeRecentChangesLine(WikiPage page) {
String user = page.getData().getAttribute(PageData.LAST_MODIFYING_USER);
if (user == null)
user = "";
return "|" + resource(page) + "|" + user + "|" + makeDateFormat().format(Clock.currentDate()) + "|";
}
private void removeDuplicate(List<String> lines, String resource) {
for (ListIterator<String> iterator = lines.listIterator(); iterator.hasNext();) {
String s = iterator.next();
if (s.startsWith("|" + resource + "|"))
iterator.remove();
}
}
private String convertLinesToWikiText(List<String> lines) {
StringBuilder buffer = new StringBuilder();
for (String line : lines) {
buffer.append(line).append("\n");
}
return buffer.toString();
}
private void trimExtraLines(List<String> lines) {
while (lines.size() > 100)
lines.remove(100);
}
}