// 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.components; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import util.Clock; import fitnesse.FitNesseContext; import fitnesse.wiki.PageCrawler; import fitnesse.wiki.PageData; import fitnesse.wiki.PathParser; import fitnesse.wiki.WikiPage; import fitnesse.wiki.WikiPagePath; public class RecentChanges { private static final String RECENT_CHANGES = "RecentChanges"; private static SimpleDateFormat makeDateFormat() { //SimpleDateFormat is not thread safe, so we need to create each instance independently. return new SimpleDateFormat(FitNesseContext.recentChangesDateFormat); } public static void updateRecentChanges(PageData pageData) { createRecentChangesIfNecessary(pageData); addCurrentPageToRecentChanges(pageData); } public static List<String> getRecentChangesLines(PageData recentChangesdata) { String content = recentChangesdata.getContent(); BufferedReader reader = new BufferedReader(new StringReader(content)); List<String> lines = new ArrayList<String>(); String line = null; try { while ((line = reader.readLine()) != null) lines.add(line); } catch (IOException e) { // TODO: -AJM- It's only the recent changes file. Should we throw an error or just log to the console? throw new RuntimeException("Unable to read recent changes", e); } return lines; } private static void addCurrentPageToRecentChanges(PageData data) { WikiPage recentChanges = data.getWikiPage().getPageCrawler().getRoot(data.getWikiPage()).getChildPage(RECENT_CHANGES); String resource = resource(data); PageData recentChangesdata = recentChanges.getData(); List<String> lines = getRecentChangesLines(recentChangesdata); removeDuplicate(lines, resource); lines.add(0, makeRecentChangesLine(data)); trimExtraLines(lines); String content = convertLinesToWikiText(lines); recentChangesdata.setContent(content); recentChanges.commit(recentChangesdata); } private static String resource(PageData data) { WikiPagePath fullPath = data.getWikiPage().getPageCrawler().getFullPath(data.getWikiPage()); String resource = PathParser.render(fullPath); return resource; } private static void createRecentChangesIfNecessary(PageData data) { PageCrawler crawler = data.getWikiPage().getPageCrawler(); WikiPage root = crawler.getRoot(data.getWikiPage()); if (!root.hasChildPage(RECENT_CHANGES)) crawler.addPage(root, PathParser.parse(RECENT_CHANGES), ""); } private static String makeRecentChangesLine(PageData data) { String user = data.getAttribute(PageData.LAST_MODIFYING_USER); if (user == null) user = ""; return "|" + resource(data) + "|" + user + "|" + makeDateFormat().format(Clock.currentDate()) + "|"; } private static 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 static String convertLinesToWikiText(List<String> lines) { StringBuffer buffer = new StringBuffer(); for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) { String s = iterator.next(); buffer.append(s).append("\n"); } return buffer.toString(); } private static void trimExtraLines(List<String> lines) { while (lines.size() > 100) lines.remove(100); } }