public void testSymbolicLinkListing() throws Exception {
    WikiPage page = root.addChildPage("SomePage");
    page.addChildPage("SomeChild");
    WikiPage pageOne = root.addChildPage("PageOne"); // ...page must exist!
    pageOne.addChildPage("ChildOne"); // ...page must exist!

    PageData data = page.getData();
    WikiPageProperties props = data.getProperties();
    WikiPageProperty symProp = props.set(SymbolicPage.PROPERTY_NAME);
    symProp.set("InternalAbsPage", ".PageOne.ChildOne");
    symProp.set("InternalRelPage", "PageOne.ChildOne");
    symProp.set("InternalSubPage", ">SomeChild");
    symProp.set("ExternalPage", "file://some/page");
    page.commit(data);

    getPropertiesContentFromPage(page);

    assertSubString("<td>InternalAbsPage</td>", content);
    assertSubString("<input type=\"text\" name=\"InternalAbsPage\"", content);
    assertSubString("<a href=\".PageOne.ChildOne\">.PageOne.ChildOne</a>", content);
    assertMatches("<a href=\".*\">&nbsp;Rename:</a>", content);

    assertSubString("<td>InternalRelPage</td>", content);
    assertSubString("<input type=\"text\" name=\"InternalRelPage\"", content);
    assertSubString("<a href=\".PageOne.ChildOne\">PageOne.ChildOne</a>", content);

    assertSubString("<td>InternalSubPage</td>", content);
    assertSubString("<input type=\"text\" name=\"InternalSubPage\"", content);
    assertSubString("<a href=\".SomePage.SomeChild\">&gt;SomeChild</a>", content);

    assertSubString("<td>file://some/page</td>", content);
  }
  private void prepareSymlinkOnPageOne() {
    PageData data = pageOne.getData();
    WikiPageProperty symLinks = data.getProperties().set(SymbolicPage.PROPERTY_NAME);
    symLinks.set("SymLink", "PageTwo");
    pageOne.commit(data);
    assertNotNull(pageOne.getChildPage("SymLink"));

    request.addInput("rename", "SymLink");
  }
    private WikiPage createSymbolicPage(WikiPage page, String linkName) {
      WikiPageProperty symLinkProperty =
          page.getData().getProperties().getProperty(SymbolicPage.PROPERTY_NAME);
      if (symLinkProperty == null) return null;
      String linkPath = symLinkProperty.get(linkName);
      if (linkPath == null) return null;

      if (linkPath.startsWith("file:")) return createExternalSymbolicLink(linkPath, linkName, page);
      else return createInternalSymbolicPage(linkPath, linkName, page);
    }
  private void removeSymbolicLink(Request request, WikiPage page) {
    String linkToRemove = request.getInput("removal");

    PageData data = page.getData();
    WikiPageProperty properties = data.getProperties();
    WikiPageProperty symLinks = getSymLinkProperty(properties);
    symLinks.remove(linkToRemove);
    if (symLinks.keySet().isEmpty()) properties.remove(SymbolicPage.PROPERTY_NAME);
    page.commit(data);
    setRedirect(resource);
  }
 protected List<WikiPage> getSymlinkChildren(WikiPage page) {
   List<WikiPage> children = new LinkedList<>();
   WikiPageProperties props = page.getData().getProperties();
   WikiPageProperty symLinksProperty = props.getProperty(SymbolicPage.PROPERTY_NAME);
   if (symLinksProperty != null) {
     for (String linkName : symLinksProperty.keySet()) {
       WikiPage linkedPage = createSymbolicPage(page, linkName);
       if (linkedPage != null && !children.contains(linkedPage)) children.add(linkedPage);
     }
   }
   return children;
 }
  private void addSymbolicLink(Request request, WikiPage page) throws Exception {
    String linkName = StringUtils.trim(request.getInput("linkName"));
    String linkPath = StringUtils.trim(request.getInput("linkPath"));

    PageData data = page.getData();
    WikiPageProperty properties = data.getProperties();
    WikiPageProperty symLinks = getSymLinkProperty(properties);
    if (isValidLinkPathName(linkPath) && isValidWikiPageName(linkName, symLinks)) {
      symLinks.set(linkName, linkPath);
      page.commit(data);
      setRedirect(resource);
    }
  }
  private void makeSymbolicLinkSection() {
    WikiPageProperty symLinksProperty =
        pageData.getProperties().getProperty(SymbolicPage.PROPERTY_NAME);
    if (symLinksProperty == null) return;
    List<Symlink> symlinks = new ArrayList<Symlink>();
    Set<String> symbolicLinkNames = symLinksProperty.keySet();
    for (String name : symbolicLinkNames) {
      String link = symLinksProperty.get(name);

      String path = makePathForSymbolicLink(link);
      symlinks.add(new Symlink(name, Utils.escapeHTML(link), path));
    }
    html.put("symlinks", symlinks);
  }
  @Test
  public void testRemoval() throws Exception {
    PageData data = pageOne.getData();
    WikiPageProperty symLinks = data.getProperties().set(SymbolicPage.PROPERTY_NAME);
    symLinks.set("SymLink", "PageTwo");
    pageOne.commit(data);
    assertNotNull(pageOne.getChildPage("SymLink"));

    request.addInput("removal", "SymLink");
    Response response = invokeResponder();
    checkPageOneRedirectToProperties(response);

    assertNull(pageOne.getChildPage("SymLink"));
  }
  public void testSymbolicLinkListingForBackwardPath() throws Exception {
    WikiPage page = root.addChildPage("SomePage");
    WikiPage child = page.addChildPage("SomeChild");
    page.addChildPage("OtherChild");

    PageData data = child.getData();
    WikiPageProperties props = data.getProperties();
    WikiPageProperty symProp = props.set(SymbolicPage.PROPERTY_NAME);
    symProp.set("InternalBackPage", "<SomePage.OtherChild");
    page.commit(data);

    getPropertiesContentFromPage(page);

    assertSubString("InternalBackPage", content);
    assertSubString("<a href=\".SomePage.OtherChild\">&lt;SomePage.OtherChild</a>", content);
  }
  private void renameSymbolicLink(Request request, WikiPage page) throws Exception {
    String linkToRename = (String) request.getInput("rename"),
        newName = (String) request.getInput("newname");

    PageData data = page.getData();
    WikiPageProperty properties = data.getProperties();
    WikiPageProperty symLinks = getSymLinkProperty(properties);

    if (isValidWikiPageName(newName, symLinks)) {
      String currentPath = symLinks.get(linkToRename);
      symLinks.remove(linkToRename);
      symLinks.set(newName, currentPath);
      page.commit(data);
      setRedirect(resource);
    }
  }
  public HtmlTag makeInputField(
      String label, String propertyName, String fieldId, int size, PageData pageData)
      throws Exception {
    HtmlTag div = new HtmlTag("div");
    div.addAttribute("style", "float: left;");
    div.add(label);

    String textValue = "";
    WikiPageProperty theProp = pageData.getProperties().getProperty(propertyName);
    if (theProp != null) {
      String propValue = theProp.getValue();
      if (propValue != null) textValue = propValue;
    }

    div.add(HtmlUtil.BR);
    HtmlTag input = HtmlUtil.makeInputTag("text", fieldId, textValue);
    input.addAttribute("size", Integer.toString(size));
    div.add(input);
    return div;
  }
 private boolean isValidWikiPageName(String linkName, WikiPageProperty symLinks) throws Exception {
   if (page.hasChildPage(linkName) && !symLinks.has(linkName)) {
     response =
         new ErrorResponder(resource + " already has a child named " + linkName + ".")
             .makeResponse(context, null);
     response.setStatus(412);
     return false;
   } else if (!PathParser.isSingleWikiWord(linkName)) {
     response =
         new ErrorResponder(linkName + " is not a valid WikiWord.").makeResponse(context, null);
     response.setStatus(412);
     return false;
   }
   return true;
 }
 private WikiPageProperty getSymLinkProperty(WikiPageProperty properties) {
   WikiPageProperty symLinks = properties.getProperty(SymbolicPage.PROPERTY_NAME);
   if (symLinks == null) symLinks = properties.set(SymbolicPage.PROPERTY_NAME);
   return symLinks;
 }