// 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.editing; import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.json.JSONArray; import org.json.JSONObject; import fitnesse.FitNesseContext; import fitnesse.authentication.SecureOperation; import fitnesse.authentication.SecureReadOperation; import fitnesse.authentication.SecureResponder; import fitnesse.html.HtmlUtil; import fitnesse.html.template.HtmlPage; import fitnesse.html.template.PageTitle; import fitnesse.http.Request; import fitnesse.http.Response; import fitnesse.http.SimpleResponse; import fitnesse.responders.NotFoundResponder; import fitnesse.wiki.*; import static fitnesse.wiki.PageData.ACTION_ATTRIBUTES; import static fitnesse.wiki.PageData.NAVIGATION_ATTRIBUTES; import static fitnesse.wiki.PageData.PAGE_TYPE_ATTRIBUTES; import static fitnesse.wiki.PageData.SECURITY_ATTRIBUTES; import static fitnesse.wiki.PageType.SUITE; import static fitnesse.wiki.PageType.TEST; import static fitnesse.wiki.WikiPageProperty.EDIT; import static fitnesse.wiki.WikiPageProperty.FILES; import static fitnesse.wiki.WikiPageProperty.HELP; import static fitnesse.wiki.WikiPageProperty.LAST_MODIFIED; import static fitnesse.wiki.WikiPageProperty.LAST_MODIFYING_USER; import static fitnesse.wiki.WikiPageProperty.PROPERTIES; import static fitnesse.wiki.WikiPageProperty.PRUNE; import static fitnesse.wiki.WikiPageProperty.RECENT_CHANGES; import static fitnesse.wiki.WikiPageProperty.REFACTOR; import static fitnesse.wiki.WikiPageProperty.SEARCH; import static fitnesse.wiki.WikiPageProperty.SECURE_READ; import static fitnesse.wiki.WikiPageProperty.SECURE_TEST; import static fitnesse.wiki.WikiPageProperty.SECURE_WRITE; import static fitnesse.wiki.WikiPageProperty.SUITES; import static fitnesse.wiki.WikiPageProperty.VERSIONS; import static fitnesse.wiki.WikiPageProperty.WHERE_USED; public class PropertiesResponder implements SecureResponder { private WikiPage page; public PageData pageData; private String resource; private WikiPagePath path; private SimpleResponse response; private HtmlPage html; @Override public Response makeResponse(FitNesseContext context, Request request) throws Exception { response = new SimpleResponse(); resource = request.getResource(); path = PathParser.parse(resource); PageCrawler crawler = context.getRootPage().getPageCrawler(); page = crawler.getPage(path, new MockingPageCrawler()); if (page == null) return new NotFoundResponder().makeResponse(context, request); pageData = page.getData(); makeContent(context, request); response.setMaxAge(0); return response; } private void makeContent(FitNesseContext context, Request request) throws UnsupportedEncodingException { if ("json".equals(request.getInput("format"))) { JSONObject jsonObject = makeJson(); response.setContent(jsonObject.toString(1)); } else { String html = makeHtml(context, request); response.setContent(html); } } private JSONObject makeJson() { response.setContentType(Response.Format.JSON); JSONObject jsonObject = new JSONObject(); String[] attributes = { TEST.toString(), SEARCH, EDIT, PROPERTIES, VERSIONS, REFACTOR, WHERE_USED, RECENT_CHANGES, SUITE.toString(), PRUNE, SECURE_READ, SECURE_WRITE, SECURE_TEST, FILES }; for (String attribute : attributes) addJsonAttribute(jsonObject, attribute); if (pageData.hasAttribute(HELP)) { jsonObject.put(HELP, pageData.getAttribute(HELP)); } if (pageData.hasAttribute(SUITES)) { JSONArray tags = new JSONArray(); for(String tag : pageData.getAttribute(SUITES).split(",")) { if (StringUtils.isNotBlank(tag)) { tags.put(tag.trim()); } } jsonObject.put(SUITES, tags); } return jsonObject; } private void addJsonAttribute(JSONObject jsonObject, String attribute) { jsonObject.put(attribute, pageData.hasAttribute(attribute)); } private String makeHtml(FitNesseContext context, Request request) { html = context.pageFactory.newPage(); html.setNavTemplate("viewNav"); html.put("viewLocation", request.getResource()); html.setTitle("Properties: " + resource); String tags = ""; if(pageData != null) { tags = pageData.getAttribute(SUITES); } html.setPageTitle(new PageTitle("Page Properties", path, tags)); html.put("pageData", pageData); html.setMainTemplate("propertiesPage"); makeLastModifiedTag(); makeFormSections(); return html.html(); } private void makeLastModifiedTag() { String username = pageData.getAttribute(LAST_MODIFYING_USER); String dateString = pageData.getAttribute(LAST_MODIFIED); if (dateString == null) dateString =""; if (!dateString.isEmpty()){ try { Date date = WikiPageProperty.getTimeFormat().parse(dateString); dateString = " on " + new SimpleDateFormat("MMM dd, yyyy").format(date) + " at " + new SimpleDateFormat("hh:mm:ss a").format(date); } catch (ParseException e) { dateString = " on " + dateString; } } if (username == null || "".equals(username)) html.put("lastModified", "Last modified anonymously" + dateString); else html.put("lastModified", "Last modified by " + username + dateString) ; } private void makeFormSections() { makePropertiesForm(); WikiImportProperty importProperty = WikiImportProperty.createFrom(pageData .getProperties()); if (importProperty != null) makeImportUpdateForm(importProperty); else makeImportForm(); makeSymbolicLinkSection(); } private void makePropertiesForm() { makePageTypeRadiosHtml(pageData); makeTestActionCheckboxesHtml(); makeNavigationCheckboxesHtml(); makeSecurityCheckboxesHtml(); } public void makePageTypeRadiosHtml(PageData pageData) { html.put("pageTypes", PAGE_TYPE_ATTRIBUTES); html.put("selectedPageType", getCheckedAttribute(pageData, PAGE_TYPE_ATTRIBUTES)); } private String getCheckedAttribute(PageData pageData, String[] attributes) { for (int i = attributes.length - 1; i > 0; i--) { if (pageData.hasAttribute(attributes[i])) return attributes[i]; } return attributes[0]; } private void makeImportForm() { html.put("makeImportForm", true); html.put("autoUpdate", true); } private void makeImportUpdateForm(WikiImportProperty importProps) { if (importProps.isRoot()) { html.put("makeImportRootForm", true); } else { html.put("makeImportSubpageForm", true); } if (importProps.isAutoUpdate()) html.put("autoUpdate", true); html.put("sourceUrl", importProps.getSourceUrl()); } private void makeSymbolicLinkSection() { WikiPageProperty symLinksProperty = pageData.getProperties().getProperty( SymbolicPage.PROPERTY_NAME); if (symLinksProperty == null) return; List<Symlink> symlinks = new ArrayList<>(); Set<String> symbolicLinkNames = symLinksProperty.keySet(); for (String name : symbolicLinkNames) { String link = symLinksProperty.get(name); String path = makePathForSymbolicLink(link); symlinks.add(new Symlink(name, HtmlUtil.escapeHTML(link), path)); } html.put("symlinks", symlinks); } private String makePathForSymbolicLink(String linkPath) { WikiPagePath wikiPagePath = PathParser.parse(linkPath); if (wikiPagePath != null) { WikiPage parent = wikiPagePath.isRelativePath() ? page.getParent() : page; PageCrawler crawler = parent.getPageCrawler(); WikiPage target = crawler.getPage(wikiPagePath); WikiPagePath fullPath; if (target != null) { fullPath = target.getPageCrawler().getFullPath(); fullPath.makeAbsolute(); } else fullPath = new WikiPagePath(); return fullPath.toString(); } return null; } @Override public SecureOperation getSecureOperation() { return new SecureReadOperation(); } public void makeTestActionCheckboxesHtml() { html.put("actionTypes", ACTION_ATTRIBUTES); } public void makeNavigationCheckboxesHtml() { html.put("navigationTypes", NAVIGATION_ATTRIBUTES); } public void makeSecurityCheckboxesHtml() { html.put("securityTypes", SECURITY_ATTRIBUTES); } public static class Symlink { private String name, link, path; Symlink(String name, String link, String path) { this.name = name; this.link = link; this.path = path; } public String getName() { return name; } public String getLink() { return link; } public String getPath() { return path; } } }