@Test public void savePageButNonexistentBranch() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); PageForm pageForm = new PageForm(PROJECT, "nonexistent", PAGE_PATH, PARENT_PAGE, "title", "text", null, null, ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); String view = pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); assertEquals("/project/branch/page/edit", view); assertTrue(bindingResult.hasErrors()); assertTrue(bindingResult.hasFieldErrors("branchName")); }
@RequestMapping(value="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") public String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult, Model model, Authentication authentication) throws IOException { String projectName = form.getProjectName(); String branchName = form.getBranchName(); User user = userStore.getUser(authentication.getName()); if (!globalRepositoryManager.listProjectBranches(projectName).contains(branchName)) { bindingResult.rejectValue("branchName", "page.branch.nonexistent"); } if (bindingResult.hasErrors()) { return "/project/branch/page/edit"; } String parentPagePath = form.getParentPagePath(); if (StringUtils.isBlank(parentPagePath)) { parentPagePath = null; } parentPagePath = Util.toRealPagePath(parentPagePath); Page page = Page.fromText(form.getTitle(), form.getText()); String path = form.getPath(); if (StringUtils.isBlank(path)) { path = parentPagePath + "/" + Util.simplifyForUrl(form.getTitle()); } page.setTags(Sets.newHashSet(form.getTags())); page.setViewRestrictionRole(StringUtils.isNotBlank(form.getViewRestrictionRole()) ? form.getViewRestrictionRole() : null); page.setOrderIndex(form.getOrderIndex()); Page oldPage = null; try { oldPage = pageStore.getPage(projectName, branchName, path, true); } catch (PageNotFoundException e) { } if ((oldPage == null) || !page.equals(oldPage)) { MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, Strings.emptyToNull(form.getCommit()), user); if (conflict != null) { form.setText(conflict.getText()); form.setCommit(conflict.getNewBaseCommit()); model.addAttribute("mergeConflict", Boolean.TRUE); return "/project/branch/page/edit"; } } Integer start = form.getParentPageSplitRangeStart(); Integer end = form.getParentPageSplitRangeEnd(); if (StringUtils.isNotBlank(parentPagePath) && (start != null) && (end != null) && permissionEvaluator.hasBranchPermission(authentication, projectName, branchName, Permission.EDIT_PAGE)) { log.info("splitting off {}-{} of {}/{}/{}", start, end, projectName, branchName, parentPagePath); Page parentPage = pageStore.getPage(projectName, branchName, parentPagePath, true); String text = ((PageTextData) parentPage.getData()).getText(); end = Math.min(end, text.length()); text = text.substring(0, start) + text.substring(end); parentPage.setData(new PageTextData(text)); pageStore.savePage(projectName, branchName, parentPagePath, parentPage, null, user); } return "redirect:/page/" + projectName + "/" + branchName + "/" + Util.toUrlPagePath(path); }
PageController { @RequestMapping(value="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") public String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult, Model model, Authentication authentication) throws IOException { String projectName = form.getProjectName(); String branchName = form.getBranchName(); User user = userStore.getUser(authentication.getName()); if (!globalRepositoryManager.listProjectBranches(projectName).contains(branchName)) { bindingResult.rejectValue("branchName", "page.branch.nonexistent"); } if (bindingResult.hasErrors()) { return "/project/branch/page/edit"; } String parentPagePath = form.getParentPagePath(); if (StringUtils.isBlank(parentPagePath)) { parentPagePath = null; } parentPagePath = Util.toRealPagePath(parentPagePath); Page page = Page.fromText(form.getTitle(), form.getText()); String path = form.getPath(); if (StringUtils.isBlank(path)) { path = parentPagePath + "/" + Util.simplifyForUrl(form.getTitle()); } page.setTags(Sets.newHashSet(form.getTags())); page.setViewRestrictionRole(StringUtils.isNotBlank(form.getViewRestrictionRole()) ? form.getViewRestrictionRole() : null); page.setOrderIndex(form.getOrderIndex()); Page oldPage = null; try { oldPage = pageStore.getPage(projectName, branchName, path, true); } catch (PageNotFoundException e) { } if ((oldPage == null) || !page.equals(oldPage)) { MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, Strings.emptyToNull(form.getCommit()), user); if (conflict != null) { form.setText(conflict.getText()); form.setCommit(conflict.getNewBaseCommit()); model.addAttribute("mergeConflict", Boolean.TRUE); return "/project/branch/page/edit"; } } Integer start = form.getParentPageSplitRangeStart(); Integer end = form.getParentPageSplitRangeEnd(); if (StringUtils.isNotBlank(parentPagePath) && (start != null) && (end != null) && permissionEvaluator.hasBranchPermission(authentication, projectName, branchName, Permission.EDIT_PAGE)) { log.info("splitting off {}-{} of {}/{}/{}", start, end, projectName, branchName, parentPagePath); Page parentPage = pageStore.getPage(projectName, branchName, parentPagePath, true); String text = ((PageTextData) parentPage.getData()).getText(); end = Math.min(end, text.length()); text = text.substring(0, start) + text.substring(end); parentPage.setData(new PageTextData(text)); pageStore.savePage(projectName, branchName, parentPagePath, parentPage, null, user); } return "redirect:/page/" + projectName + "/" + branchName + "/" + Util.toUrlPagePath(path); } }
PageController { @RequestMapping(value="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") public String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult, Model model, Authentication authentication) throws IOException { String projectName = form.getProjectName(); String branchName = form.getBranchName(); User user = userStore.getUser(authentication.getName()); if (!globalRepositoryManager.listProjectBranches(projectName).contains(branchName)) { bindingResult.rejectValue("branchName", "page.branch.nonexistent"); } if (bindingResult.hasErrors()) { return "/project/branch/page/edit"; } String parentPagePath = form.getParentPagePath(); if (StringUtils.isBlank(parentPagePath)) { parentPagePath = null; } parentPagePath = Util.toRealPagePath(parentPagePath); Page page = Page.fromText(form.getTitle(), form.getText()); String path = form.getPath(); if (StringUtils.isBlank(path)) { path = parentPagePath + "/" + Util.simplifyForUrl(form.getTitle()); } page.setTags(Sets.newHashSet(form.getTags())); page.setViewRestrictionRole(StringUtils.isNotBlank(form.getViewRestrictionRole()) ? form.getViewRestrictionRole() : null); page.setOrderIndex(form.getOrderIndex()); Page oldPage = null; try { oldPage = pageStore.getPage(projectName, branchName, path, true); } catch (PageNotFoundException e) { } if ((oldPage == null) || !page.equals(oldPage)) { MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, Strings.emptyToNull(form.getCommit()), user); if (conflict != null) { form.setText(conflict.getText()); form.setCommit(conflict.getNewBaseCommit()); model.addAttribute("mergeConflict", Boolean.TRUE); return "/project/branch/page/edit"; } } Integer start = form.getParentPageSplitRangeStart(); Integer end = form.getParentPageSplitRangeEnd(); if (StringUtils.isNotBlank(parentPagePath) && (start != null) && (end != null) && permissionEvaluator.hasBranchPermission(authentication, projectName, branchName, Permission.EDIT_PAGE)) { log.info("splitting off {}-{} of {}/{}/{}", start, end, projectName, branchName, parentPagePath); Page parentPage = pageStore.getPage(projectName, branchName, parentPagePath, true); String text = ((PageTextData) parentPage.getData()).getText(); end = Math.min(end, text.length()); text = text.substring(0, start) + text.substring(end); parentPage.setData(new PageTextData(text)); pageStore.savePage(projectName, branchName, parentPagePath, parentPage, null, user); } return "redirect:/page/" + projectName + "/" + branchName + "/" + Util.toUrlPagePath(path); }  }
PageController { @RequestMapping(value="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") public String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult, Model model, Authentication authentication) throws IOException { String projectName = form.getProjectName(); String branchName = form.getBranchName(); User user = userStore.getUser(authentication.getName()); if (!globalRepositoryManager.listProjectBranches(projectName).contains(branchName)) { bindingResult.rejectValue("branchName", "page.branch.nonexistent"); } if (bindingResult.hasErrors()) { return "/project/branch/page/edit"; } String parentPagePath = form.getParentPagePath(); if (StringUtils.isBlank(parentPagePath)) { parentPagePath = null; } parentPagePath = Util.toRealPagePath(parentPagePath); Page page = Page.fromText(form.getTitle(), form.getText()); String path = form.getPath(); if (StringUtils.isBlank(path)) { path = parentPagePath + "/" + Util.simplifyForUrl(form.getTitle()); } page.setTags(Sets.newHashSet(form.getTags())); page.setViewRestrictionRole(StringUtils.isNotBlank(form.getViewRestrictionRole()) ? form.getViewRestrictionRole() : null); page.setOrderIndex(form.getOrderIndex()); Page oldPage = null; try { oldPage = pageStore.getPage(projectName, branchName, path, true); } catch (PageNotFoundException e) { } if ((oldPage == null) || !page.equals(oldPage)) { MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, Strings.emptyToNull(form.getCommit()), user); if (conflict != null) { form.setText(conflict.getText()); form.setCommit(conflict.getNewBaseCommit()); model.addAttribute("mergeConflict", Boolean.TRUE); return "/project/branch/page/edit"; } } Integer start = form.getParentPageSplitRangeStart(); Integer end = form.getParentPageSplitRangeEnd(); if (StringUtils.isNotBlank(parentPagePath) && (start != null) && (end != null) && permissionEvaluator.hasBranchPermission(authentication, projectName, branchName, Permission.EDIT_PAGE)) { log.info("splitting off {}-{} of {}/{}/{}", start, end, projectName, branchName, parentPagePath); Page parentPage = pageStore.getPage(projectName, branchName, parentPagePath, true); String text = ((PageTextData) parentPage.getData()).getText(); end = Math.min(end, text.length()); text = text.substring(0, start) + text.substring(end); parentPage.setData(new PageTextData(text)); pageStore.savePage(projectName, branchName, parentPagePath, parentPage, null, user); } return "redirect:/page/" + projectName + "/" + branchName + "/" + Util.toUrlPagePath(path); }  @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="/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}", method=RequestMethod.POST) @PreAuthorize("hasBranchPermission(#form.projectName, #form.branchName, EDIT_PAGE)") public String savePage(@ModelAttribute @Valid PageForm form, BindingResult bindingResult, Model model, Authentication authentication) throws IOException { String projectName = form.getProjectName(); String branchName = form.getBranchName(); User user = userStore.getUser(authentication.getName()); if (!globalRepositoryManager.listProjectBranches(projectName).contains(branchName)) { bindingResult.rejectValue("branchName", "page.branch.nonexistent"); } if (bindingResult.hasErrors()) { return "/project/branch/page/edit"; } String parentPagePath = form.getParentPagePath(); if (StringUtils.isBlank(parentPagePath)) { parentPagePath = null; } parentPagePath = Util.toRealPagePath(parentPagePath); Page page = Page.fromText(form.getTitle(), form.getText()); String path = form.getPath(); if (StringUtils.isBlank(path)) { path = parentPagePath + "/" + Util.simplifyForUrl(form.getTitle()); } page.setTags(Sets.newHashSet(form.getTags())); page.setViewRestrictionRole(StringUtils.isNotBlank(form.getViewRestrictionRole()) ? form.getViewRestrictionRole() : null); page.setOrderIndex(form.getOrderIndex()); Page oldPage = null; try { oldPage = pageStore.getPage(projectName, branchName, path, true); } catch (PageNotFoundException e) { } if ((oldPage == null) || !page.equals(oldPage)) { MergeConflict conflict = pageStore.savePage(projectName, branchName, path, page, Strings.emptyToNull(form.getCommit()), user); if (conflict != null) { form.setText(conflict.getText()); form.setCommit(conflict.getNewBaseCommit()); model.addAttribute("mergeConflict", Boolean.TRUE); return "/project/branch/page/edit"; } } Integer start = form.getParentPageSplitRangeStart(); Integer end = form.getParentPageSplitRangeEnd(); if (StringUtils.isNotBlank(parentPagePath) && (start != null) && (end != null) && permissionEvaluator.hasBranchPermission(authentication, projectName, branchName, Permission.EDIT_PAGE)) { log.info("splitting off {}-{} of {}/{}/{}", start, end, projectName, branchName, parentPagePath); Page parentPage = pageStore.getPage(projectName, branchName, parentPagePath, true); String text = ((PageTextData) parentPage.getData()).getText(); end = Math.min(end, text.length()); text = text.substring(0, start) + text.substring(end); parentPage.setData(new PageTextData(text)); pageStore.savePage(projectName, branchName, parentPagePath, parentPage, null, user); } return "redirect:/page/" + projectName + "/" + branchName + "/" + Util.toUrlPagePath(path); }  @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);  }