package fitnesse.revisioncontrol.responders;
import fitnesse.FitNesseContext;
import fitnesse.html.HtmlPage;
import fitnesse.html.HtmlTag;
import fitnesse.html.HtmlUtil;
import fitnesse.html.TagGroup;
import fitnesse.http.Request;
import fitnesse.http.Response;
import fitnesse.http.SimpleResponse;
import fitnesse.responders.BasicResponder;
import fitnesse.responders.NotFoundResponder;
import fitnesse.revisioncontrol.RevisionControlException;
import fitnesse.revisioncontrol.RevisionControlOperation;
import fitnesse.revisioncontrol.wiki.RevisionControlledFileSystemPage;
import fitnesse.wiki.*;
import java.io.File;
import java.util.List;
public abstract class RevisionControlResponder extends BasicResponder {
private final RevisionControlOperation operation;
protected String rootPagePath;
protected RevisionControlResponder(RevisionControlOperation operation) {
this.operation = operation;
}
public Response makeResponse(FitNesseContext context, Request request) throws Exception {
rootPagePath = new File(context.rootPagePath).getAbsolutePath();
WikiPage root = context.root;
PageCrawler crawler = root.getPageCrawler();
String resource = request.getResource();
WikiPagePath path = PathParser.parse(resource);
WikiPage page = crawler.getPage(root, path);
if (page == null)
return new NotFoundResponder().makeResponse(context, request);
page = resolveSymbolicLinks(page);
SimpleResponse response = new SimpleResponse();
response.setMaxAge(0);
if (!(page instanceof RevisionControlledFileSystemPage)) {
response.setContent(makeHtml(resource, context, invalidWikiPageContent(resource)));
return response;
}
String returnMsg = executeRevisionControlOperation((RevisionControlledFileSystemPage) page);
response.setContent(makeHtml(resource, context, content(resource, returnMsg)));
return response;
}
private WikiPage resolveSymbolicLinks(WikiPage page) throws Exception {
while (page instanceof SymbolicPage)
page = ((SymbolicPage) page).getRealPage();
return page;
}
protected String executeRevisionControlOperation(RevisionControlledFileSystemPage page) {
String returnMsg;
try {
beforeOperation(page);
TagGroup group = new TagGroup();
performOperation(page, group);
if (group.childTags.size() == 0)
returnMsg = operation.getName() + " was successful.";
else
returnMsg = group.html();
} catch (RevisionControlException e) {
returnMsg = operation.getName() + " failed. Following exception occurred:<pre>\n";
returnMsg += buildExceptionMessage(e);
if (e.getCause() != null)
returnMsg += ":\n" + buildExceptionMessage(e.getCause());
returnMsg += "</pre>";
}
return returnMsg;
}
private String buildExceptionMessage(Throwable e) {
return e.getClass().getName() + ": " + e.getMessage();
}
protected void beforeOperation(FileSystemPage page) {
}
protected abstract void performOperation(RevisionControlledFileSystemPage page, HtmlTag tag);
protected String createPageLink(String resource) throws Exception {
return "View the " + HtmlUtil.makeLink(resource, "page").html() + ".";
}
private String makeHtml(String resource, FitNesseContext context, String content) throws Exception {
HtmlPage html = context.htmlPageFactory.newPage();
html.title.use(operation.getName() + " " + resource);
html.header.use(HtmlUtil.makeBreadCrumbsWithPageType(resource, operation.getName() + " Page"));
html.main.use(content);
return html.html();
}
private String content(String resource, String result) throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("Attempted to '").append(operation.getName()).append("' the page '").
append(resource).append("'.<br/><hr><br/>");
buffer.append(result);
buffer.append("<br/><hr><br/>");
buffer.append(createPageLink(resource));
return buffer.toString();
}
private String invalidWikiPageContent(String resource) {
return "The page " + resource + " doesn't support '" + operation.getName() + "' operation.";
}
protected List<WikiPage> getChildren(FileSystemPage page) {
try {
return page.getChildren();
} catch (Exception e) {
throw new RevisionControlException(e);
}
}
}