@Test public void savePageRange() throws IOException { Page page = Page.fromText("title", "x\ny\nz\n"); when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, "commit", true)).thenReturn(page); when(pageRenderer.getHtml(PROJECT, BRANCH, PAGE_PATH, authenticatedAuthentication, Locale.US, CONTEXT)) .thenReturn("html"); when(markdownProcessor.processNonCacheableMacros("html", PROJECT, BRANCH, PAGE_PATH, authenticatedAuthentication, Locale.US, CONTEXT)).thenReturn("htmlWithMacros"); when(request.getContextPath()).thenReturn(CONTEXT); when(pageMetadata.getCommit()).thenReturn("newCommit"); when(pageStore.getPageMetadata(PROJECT, BRANCH, PAGE_PATH)).thenReturn(pageMetadata); Map<String, Object> result = pageController.savePageRange(PROJECT, BRANCH, PAGE_PATH_URL, "a\nb\nc\n", "2,4", "commit", authenticatedAuthentication, Locale.US, request); assertEquals("htmlWithMacros", result.get("html")); assertEquals("newCommit", result.get("commit")); verify(pageStore).savePage(eq(PROJECT), eq(BRANCH), eq(PAGE_PATH), argPage("title", "x\na\nb\nc\nz\n"), eq("commit"), same(USER)); }
@RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") public Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName, @PathVariable String path, @RequestParam String markdown, @RequestParam String range, @RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request) throws IOException { path = Util.toRealPagePath(path); markdown = markdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); int rangeStart = Integer.parseInt(StringUtils.substringBefore(range, ",")); int rangeEnd = Integer.parseInt(StringUtils.substringAfter(range, ",")); Page page = pageStore.getPage(projectName, branchName, path, commit, true); String text = ((PageTextData) page.getData()).getText(); rangeEnd = Math.min(rangeEnd, text.length()); String oldMarkdown = text.substring(rangeStart, rangeEnd); String cleanedOldMarkdown = oldMarkdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); rangeEnd -= oldMarkdown.length() - cleanedOldMarkdown.length(); String newText = text.substring(0, rangeStart) + markdown + text.substring(Math.min(rangeEnd, text.length())); page.setData(new PageTextData(newText)); User user = userStore.getUser(authentication.getName()); MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, commit, user); Map<String, Object> result = Maps.newHashMap(); if (conflict != null) { result.put("conflict", Boolean.TRUE); HttpSession session = request.getSession(); session.setAttribute("conflict", conflict); session.setAttribute("conflict.projectName", projectName); session.setAttribute("conflict.branchName", branchName); session.setAttribute("conflict.path", path); } else { String newCommit = pageStore.getPageMetadata(projectName, branchName, path).getCommit(); String contextPath = request.getContextPath(); String html = pageRenderer.getHtml(projectName, branchName, path, authentication, locale, contextPath); html = markdownProcessor.processNonCacheableMacros(html, projectName, branchName, path, authentication, locale, contextPath); result.put("html", html); result.put("commit", newCommit); } return result; }
PageController { @RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") public Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName, @PathVariable String path, @RequestParam String markdown, @RequestParam String range, @RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request) throws IOException { path = Util.toRealPagePath(path); markdown = markdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); int rangeStart = Integer.parseInt(StringUtils.substringBefore(range, ",")); int rangeEnd = Integer.parseInt(StringUtils.substringAfter(range, ",")); Page page = pageStore.getPage(projectName, branchName, path, commit, true); String text = ((PageTextData) page.getData()).getText(); rangeEnd = Math.min(rangeEnd, text.length()); String oldMarkdown = text.substring(rangeStart, rangeEnd); String cleanedOldMarkdown = oldMarkdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); rangeEnd -= oldMarkdown.length() - cleanedOldMarkdown.length(); String newText = text.substring(0, rangeStart) + markdown + text.substring(Math.min(rangeEnd, text.length())); page.setData(new PageTextData(newText)); User user = userStore.getUser(authentication.getName()); MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, commit, user); Map<String, Object> result = Maps.newHashMap(); if (conflict != null) { result.put("conflict", Boolean.TRUE); HttpSession session = request.getSession(); session.setAttribute("conflict", conflict); session.setAttribute("conflict.projectName", projectName); session.setAttribute("conflict.branchName", branchName); session.setAttribute("conflict.path", path); } else { String newCommit = pageStore.getPageMetadata(projectName, branchName, path).getCommit(); String contextPath = request.getContextPath(); String html = pageRenderer.getHtml(projectName, branchName, path, authentication, locale, contextPath); html = markdownProcessor.processNonCacheableMacros(html, projectName, branchName, path, authentication, locale, contextPath); result.put("html", html); result.put("commit", newCommit); } return result; } }
PageController { @RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") public Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName, @PathVariable String path, @RequestParam String markdown, @RequestParam String range, @RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request) throws IOException { path = Util.toRealPagePath(path); markdown = markdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); int rangeStart = Integer.parseInt(StringUtils.substringBefore(range, ",")); int rangeEnd = Integer.parseInt(StringUtils.substringAfter(range, ",")); Page page = pageStore.getPage(projectName, branchName, path, commit, true); String text = ((PageTextData) page.getData()).getText(); rangeEnd = Math.min(rangeEnd, text.length()); String oldMarkdown = text.substring(rangeStart, rangeEnd); String cleanedOldMarkdown = oldMarkdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); rangeEnd -= oldMarkdown.length() - cleanedOldMarkdown.length(); String newText = text.substring(0, rangeStart) + markdown + text.substring(Math.min(rangeEnd, text.length())); page.setData(new PageTextData(newText)); User user = userStore.getUser(authentication.getName()); MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, commit, user); Map<String, Object> result = Maps.newHashMap(); if (conflict != null) { result.put("conflict", Boolean.TRUE); HttpSession session = request.getSession(); session.setAttribute("conflict", conflict); session.setAttribute("conflict.projectName", projectName); session.setAttribute("conflict.branchName", branchName); session.setAttribute("conflict.path", path); } else { String newCommit = pageStore.getPageMetadata(projectName, branchName, path).getCommit(); String contextPath = request.getContextPath(); String html = pageRenderer.getHtml(projectName, branchName, path, authentication, locale, contextPath); html = markdownProcessor.processNonCacheableMacros(html, projectName, branchName, path, authentication, locale, contextPath); result.put("html", html); result.put("commit", newCommit); } return result; }  }
PageController { @RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") public Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName, @PathVariable String path, @RequestParam String markdown, @RequestParam String range, @RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request) throws IOException { path = Util.toRealPagePath(path); markdown = markdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); int rangeStart = Integer.parseInt(StringUtils.substringBefore(range, ",")); int rangeEnd = Integer.parseInt(StringUtils.substringAfter(range, ",")); Page page = pageStore.getPage(projectName, branchName, path, commit, true); String text = ((PageTextData) page.getData()).getText(); rangeEnd = Math.min(rangeEnd, text.length()); String oldMarkdown = text.substring(rangeStart, rangeEnd); String cleanedOldMarkdown = oldMarkdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); rangeEnd -= oldMarkdown.length() - cleanedOldMarkdown.length(); String newText = text.substring(0, rangeStart) + markdown + text.substring(Math.min(rangeEnd, text.length())); page.setData(new PageTextData(newText)); User user = userStore.getUser(authentication.getName()); MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, commit, user); Map<String, Object> result = Maps.newHashMap(); if (conflict != null) { result.put("conflict", Boolean.TRUE); HttpSession session = request.getSession(); session.setAttribute("conflict", conflict); session.setAttribute("conflict.projectName", projectName); session.setAttribute("conflict.branchName", branchName); session.setAttribute("conflict.path", path); } else { String newCommit = pageStore.getPageMetadata(projectName, branchName, path).getCommit(); String contextPath = request.getContextPath(); String html = pageRenderer.getHtml(projectName, branchName, path, authentication, locale, contextPath); html = markdownProcessor.processNonCacheableMacros(html, projectName, branchName, path, authentication, locale, contextPath); result.put("html", html); result.put("commit", newCommit); } return result; }  @RequestMapping(value="/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method={ RequestMethod.GET, RequestMethod.HEAD }) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") String getPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Model model, HttpServletRequest request, HttpServletResponse response); @RequestMapping(value="/create/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{parentPagePath:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String createPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String parentPagePath, Model model); @RequestMapping(value="/edit/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") String editPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Model model, HttpSession session); @RequestMapping(value="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult,
			Model model, Authentication authentication); @ModelAttribute PageForm createPageForm(@PathVariable String projectName, @PathVariable String branchName,
			@RequestParam(required=false) String path, @RequestParam(required=false) String parentPagePath,
			@RequestParam(required=false) String title, @RequestParam(required=false) String text,
			@RequestParam(required=false) String viewRestrictionRole,
			@RequestParam(required=false) String commit,
			@RequestParam(required=false) String[] tags,
			@RequestParam(required=false) Integer orderIndex); @RequestMapping(value="/generateName/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{parentPagePath:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST, produces="application/json") @ResponseBody @PreAuthorize("hasBranchPermission(#projectName, #branchName, VIEW)") Map<String, Object> generateName(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String parentPagePath, @RequestParam String title); @RequestMapping(value="/markdownToHtml/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/json", method=RequestMethod.POST, produces="application/json") @ResponseBody @PreAuthorize("isAuthenticated()") Map<String, String> markdownToHtml(@PathVariable String projectName, @PathVariable String branchName,
			@RequestParam String markdown, @RequestParam(required=false) String pagePath, Authentication authentication,
			Locale locale, HttpServletRequest request); @RequestMapping(value="/copyToBranch/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW) and " + "hasBranchPermission(#projectName, #targetBranchName, EDIT_PAGE)") String copyToBranch(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String targetBranchName, Authentication authentication); @RequestMapping(value="/delete/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String deletePage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Authentication authentication); @RequestMapping(value="/relocate/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String relocatePage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String newParentPagePath, Authentication authentication); @RequestMapping(value="/markdown/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.GET) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") Map<String, String> getPageMarkdown(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam Set<String> versions); @RequestMapping(value="/markdownInRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/" + "{rangeStart:[0-9]+},{rangeEnd:[0-9]+}/{commit:[0-9a-fA-F]+}/json", method=RequestMethod.GET) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") Map<String, String> getPageMarkdownInRange(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @PathVariable int rangeStart, @PathVariable int rangeEnd,
			@PathVariable String commit); @RequestMapping(value="/changes/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("isAuthenticated() and hasPagePermission(#projectName, #branchName, #path, VIEW)") String getPageChanges(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Model model); @RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String markdown, @RequestParam String range,
			@RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request); @RequestMapping(value="/restoreVersion/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") Map<String, Object> restoreVersion(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String version, Authentication authentication); @RequestMapping(value="/cherryPick/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") String cherryPick(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String version1, @RequestParam String version2,
			@RequestParam("branch") Set<String> targetBranches, @RequestParam boolean dryRun,
			WebRequest request, Model model, Authentication authentication, Locale locale); @RequestMapping(value="/split/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/" + "{rangeStart:[0-9]+},{rangeEnd:[0-9]+}", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String splitPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @PathVariable int rangeStart, @PathVariable int rangeEnd,
			Model model); @RequestMapping(value="/saveChildrenOrder/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") @ResponseBody Map<String, Object> saveChildrenOrder(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam(value="childrenOrder[]", required=false) List<String> childrenOrder,
			Authentication authentication); @RequestMapping(value="/resetChildrenOrder/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") @ResponseBody Map<String, Object> resetChildrenOrder(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Authentication authentication); }
PageController { @RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") public Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName, @PathVariable String path, @RequestParam String markdown, @RequestParam String range, @RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request) throws IOException { path = Util.toRealPagePath(path); markdown = markdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); int rangeStart = Integer.parseInt(StringUtils.substringBefore(range, ",")); int rangeEnd = Integer.parseInt(StringUtils.substringAfter(range, ",")); Page page = pageStore.getPage(projectName, branchName, path, commit, true); String text = ((PageTextData) page.getData()).getText(); rangeEnd = Math.min(rangeEnd, text.length()); String oldMarkdown = text.substring(rangeStart, rangeEnd); String cleanedOldMarkdown = oldMarkdown.replaceAll("[\\r\\n]+$", StringUtils.EMPTY); rangeEnd -= oldMarkdown.length() - cleanedOldMarkdown.length(); String newText = text.substring(0, rangeStart) + markdown + text.substring(Math.min(rangeEnd, text.length())); page.setData(new PageTextData(newText)); User user = userStore.getUser(authentication.getName()); MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, commit, user); Map<String, Object> result = Maps.newHashMap(); if (conflict != null) { result.put("conflict", Boolean.TRUE); HttpSession session = request.getSession(); session.setAttribute("conflict", conflict); session.setAttribute("conflict.projectName", projectName); session.setAttribute("conflict.branchName", branchName); session.setAttribute("conflict.path", path); } else { String newCommit = pageStore.getPageMetadata(projectName, branchName, path).getCommit(); String contextPath = request.getContextPath(); String html = pageRenderer.getHtml(projectName, branchName, path, authentication, locale, contextPath); html = markdownProcessor.processNonCacheableMacros(html, projectName, branchName, path, authentication, locale, contextPath); result.put("html", html); result.put("commit", newCommit); } return result; }  @RequestMapping(value="/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method={ RequestMethod.GET, RequestMethod.HEAD }) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") String getPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Model model, HttpServletRequest request, HttpServletResponse response); @RequestMapping(value="/create/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{parentPagePath:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String createPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String parentPagePath, Model model); @RequestMapping(value="/edit/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") String editPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Model model, HttpSession session); @RequestMapping(value="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult,
			Model model, Authentication authentication); @ModelAttribute PageForm createPageForm(@PathVariable String projectName, @PathVariable String branchName,
			@RequestParam(required=false) String path, @RequestParam(required=false) String parentPagePath,
			@RequestParam(required=false) String title, @RequestParam(required=false) String text,
			@RequestParam(required=false) String viewRestrictionRole,
			@RequestParam(required=false) String commit,
			@RequestParam(required=false) String[] tags,
			@RequestParam(required=false) Integer orderIndex); @RequestMapping(value="/generateName/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{parentPagePath:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST, produces="application/json") @ResponseBody @PreAuthorize("hasBranchPermission(#projectName, #branchName, VIEW)") Map<String, Object> generateName(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String parentPagePath, @RequestParam String title); @RequestMapping(value="/markdownToHtml/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/json", method=RequestMethod.POST, produces="application/json") @ResponseBody @PreAuthorize("isAuthenticated()") Map<String, String> markdownToHtml(@PathVariable String projectName, @PathVariable String branchName,
			@RequestParam String markdown, @RequestParam(required=false) String pagePath, Authentication authentication,
			Locale locale, HttpServletRequest request); @RequestMapping(value="/copyToBranch/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW) and " + "hasBranchPermission(#projectName, #targetBranchName, EDIT_PAGE)") String copyToBranch(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String targetBranchName, Authentication authentication); @RequestMapping(value="/delete/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String deletePage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Authentication authentication); @RequestMapping(value="/relocate/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String relocatePage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String newParentPagePath, Authentication authentication); @RequestMapping(value="/markdown/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.GET) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") Map<String, String> getPageMarkdown(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam Set<String> versions); @RequestMapping(value="/markdownInRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/" + "{rangeStart:[0-9]+},{rangeEnd:[0-9]+}/{commit:[0-9a-fA-F]+}/json", method=RequestMethod.GET) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") Map<String, String> getPageMarkdownInRange(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @PathVariable int rangeStart, @PathVariable int rangeEnd,
			@PathVariable String commit); @RequestMapping(value="/changes/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.GET) @PreAuthorize("isAuthenticated() and hasPagePermission(#projectName, #branchName, #path, VIEW)") String getPageChanges(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Model model); @RequestMapping(value="/saveRange/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") Map<String, Object> savePageRange(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String markdown, @RequestParam String range,
			@RequestParam String commit, Authentication authentication, Locale locale, HttpServletRequest request); @RequestMapping(value="/restoreVersion/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @ResponseBody @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, EDIT_PAGE)") Map<String, Object> restoreVersion(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String version, Authentication authentication); @RequestMapping(value="/cherryPick/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasPagePermission(#projectName, #branchName, #path, VIEW)") String cherryPick(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam String version1, @RequestParam String version2,
			@RequestParam("branch") Set<String> targetBranches, @RequestParam boolean dryRun,
			WebRequest request, Model model, Authentication authentication, Locale locale); @RequestMapping(value="/split/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/" + "{rangeStart:[0-9]+},{rangeEnd:[0-9]+}", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") String splitPage(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @PathVariable int rangeStart, @PathVariable int rangeEnd,
			Model model); @RequestMapping(value="/saveChildrenOrder/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") @ResponseBody Map<String, Object> saveChildrenOrder(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, @RequestParam(value="childrenOrder[]", required=false) List<String> childrenOrder,
			Authentication authentication); @RequestMapping(value="/resetChildrenOrder/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{path:" + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method=RequestMethod.GET) @PreAuthorize("hasBranchPermission(#projectName, #branchName, EDIT_PAGE)") @ResponseBody Map<String, Object> resetChildrenOrder(@PathVariable String projectName, @PathVariable String branchName,
			@PathVariable String path, Authentication authentication);  }