public static Page createPage(
      ObjectFactory objectFactory,
      URI baseUri,
      URI self,
      Document doc,
      boolean useVersion,
      XWiki xwikiApi,
      Boolean withPrettyNames)
      throws XWikiException {
    Page page = objectFactory.createPage();
    fillPageSummary(page, objectFactory, baseUri, doc, useVersion, xwikiApi, withPrettyNames);

    page.setMajorVersion(doc.getRCSVersion().at(0));
    page.setMinorVersion(doc.getRCSVersion().at(1));
    page.setLanguage(doc.getLanguage());
    page.setCreator(doc.getCreator());
    if (withPrettyNames) {
      page.setCreatorName(xwikiApi.getUserName(doc.getCreator(), false));
    }

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(doc.getCreationDate());
    page.setCreated(calendar);

    page.setModifier(doc.getContentAuthor());
    if (withPrettyNames) {
      page.setModifierName(xwikiApi.getUserName(doc.getContentAuthor(), false));
    }

    calendar = Calendar.getInstance();
    calendar.setTime(doc.getContentUpdateDate());
    page.setModified(calendar);

    page.setComment(doc.getComment());
    page.setContent(doc.getContent());

    if (self != null) {
      Link pageLink = objectFactory.createLink();
      pageLink.setHref(self.toString());
      pageLink.setRel(Relations.SELF);
      page.getLinks().add(pageLink);
    }

    com.xpn.xwiki.api.Class xwikiClass = doc.getxWikiClass();
    if (xwikiClass != null) {
      String classUri = uri(baseUri, ClassResource.class, doc.getWiki(), xwikiClass.getName());
      Link classLink = objectFactory.createLink();
      classLink.setHref(classUri);
      classLink.setRel(Relations.CLASS);
      page.getLinks().add(classLink);
    }

    return page;
  }
  private static void fillObjectSummary(
      ObjectSummary objectSummary,
      ObjectFactory objectFactory,
      URI baseUri,
      Document doc,
      BaseObject xwikiObject,
      XWiki xwikiApi,
      Boolean withPrettyNames)
      throws XWikiException {

    objectSummary.setId(String.format("%s:%s", doc.getPrefixedFullName(), xwikiObject.getGuid()));
    objectSummary.setGuid(xwikiObject.getGuid());
    objectSummary.setPageId(doc.getPrefixedFullName());
    objectSummary.setPageVersion(doc.getVersion());
    objectSummary.setPageAuthor(doc.getAuthor());
    if (withPrettyNames) {
      objectSummary.setPageAuthorName(xwikiApi.getUserName(doc.getAuthor(), false));
    }
    objectSummary.setWiki(doc.getWiki());
    objectSummary.setSpace(doc.getSpace());
    objectSummary.setPageName(doc.getName());
    objectSummary.setClassName(xwikiObject.getClassName());
    objectSummary.setNumber(xwikiObject.getNumber());

    String[] propertyNames = xwikiObject.getPropertyNames();
    if (propertyNames.length > 0) {
      objectSummary.setHeadline(xwikiObject.get(propertyNames[0]).toFormString());
    }
  }
  @GET
  public Spaces getSpaces(
      @PathParam("wikiName") String wikiName,
      @QueryParam("start") @DefaultValue("0") Integer start,
      @QueryParam("number") @DefaultValue("-1") Integer number)
      throws XWikiException, QueryException, ComponentLookupException {
    String database = Utils.getXWikiContext(componentManager).getDatabase();

    Spaces spaces = objectFactory.createSpaces();

    /* This try is just needed for executing the finally clause. */
    try {
      Utils.getXWikiContext(componentManager).setDatabase(wikiName);

      List<String> spaceNames =
          queryManager
              .getNamedQuery("getSpaces")
              .addFilter(componentManager.<QueryFilter>getInstance(QueryFilter.class, "hidden"))
              .setOffset(start)
              .setLimit(number)
              .execute();

      for (String spaceName : spaceNames) {
        String homeId = Utils.getPageId(wikiName, spaceName, "WebHome");
        Document home = null;

        XWiki xwikiApi = Utils.getXWikiApi(componentManager);
        if (xwikiApi.hasAccessLevel("view", homeId)) {
          if (xwikiApi.exists(homeId)) {
            home = Utils.getXWikiApi(componentManager).getDocument(homeId);
          }
          spaces
              .getSpaces()
              .add(
                  DomainObjectFactory.createSpace(
                      objectFactory, uriInfo.getBaseUri(), wikiName, spaceName, home));
        }
      }
    } finally {
      Utils.getXWikiContext(componentManager).setDatabase(database);
    }

    return spaces;
  }
  public static Comment createComment(
      ObjectFactory objectFactory,
      URI baseUri,
      Document doc,
      com.xpn.xwiki.api.Object xwikiComment,
      XWiki xwikiApi,
      Boolean withPrettyNames) {
    Comment comment = objectFactory.createComment();
    comment.setId(xwikiComment.getNumber());

    com.xpn.xwiki.api.Property property = xwikiComment.getProperty("author");
    if (property != null) {
      comment.setAuthor((String) property.getValue());
      if (withPrettyNames) {
        comment.setAuthorName(xwikiApi.getUserName((String) property.getValue(), false));
      }
    }

    property = xwikiComment.getProperty("date");
    if (property != null) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime((Date) property.getValue());
      comment.setDate(calendar);
    }

    property = xwikiComment.getProperty("highlight");
    if (property != null) {
      comment.setHighlight((String) property.getValue());
    }

    property = xwikiComment.getProperty("comment");
    if (property != null) {
      comment.setText((String) property.getValue());
    }

    property = xwikiComment.getProperty("replyto");
    if (property != null) {
      comment.setReplyTo((Integer) property.getValue());
    }

    String pageUri = uri(baseUri, PageResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
    Link pageLink = objectFactory.createLink();
    pageLink.setHref(pageUri);
    pageLink.setRel(Relations.PAGE);
    comment.getLinks().add(pageLink);

    return comment;
  }
  private static void fillAttachment(
      Attachment attachment,
      ObjectFactory objectFactory,
      URI baseUri,
      com.xpn.xwiki.api.Attachment xwikiAttachment,
      String xwikiRelativeUrl,
      String xwikiAbsoluteUrl,
      XWiki xwikiApi,
      Boolean withPrettyNames) {
    Document doc = xwikiAttachment.getDocument();

    attachment.setId(
        String.format("%s@%s", doc.getPrefixedFullName(), xwikiAttachment.getFilename()));
    attachment.setName(xwikiAttachment.getFilename());
    attachment.setSize(xwikiAttachment.getFilesize());
    attachment.setVersion(xwikiAttachment.getVersion());
    attachment.setPageId(doc.getPrefixedFullName());
    attachment.setPageVersion(doc.getVersion());
    attachment.setMimeType(xwikiAttachment.getMimeType());
    attachment.setAuthor(xwikiAttachment.getAuthor());
    if (withPrettyNames) {
      attachment.setAuthorName(xwikiApi.getUserName(xwikiAttachment.getAuthor(), false));
    }

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(xwikiAttachment.getDate());
    attachment.setDate(calendar);

    attachment.setXwikiRelativeUrl(xwikiRelativeUrl);
    attachment.setXwikiAbsoluteUrl(xwikiAbsoluteUrl);

    String pageUri = uri(baseUri, PageResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
    Link pageLink = objectFactory.createLink();
    pageLink.setHref(pageUri);
    pageLink.setRel(Relations.PAGE);
    attachment.getLinks().add(pageLink);
  }
  public static HistorySummary createHistorySummary(
      ObjectFactory objectFactory,
      URI baseUri,
      String wikiName,
      String spaceName,
      String pageName,
      String language,
      Version version,
      String modifier,
      Date modified,
      String comment,
      XWiki xwikiApi,
      Boolean withPrettyNames) {
    HistorySummary historySummary = objectFactory.createHistorySummary();

    String pageId = Utils.getPageId(wikiName, spaceName, pageName);

    historySummary.setPageId(pageId);
    historySummary.setWiki(wikiName);
    historySummary.setSpace(spaceName);
    historySummary.setName(pageName);
    historySummary.setVersion(version.toString());
    historySummary.setMajorVersion(version.at(0));
    historySummary.setMinorVersion(version.at(1));
    historySummary.setComment(comment);
    historySummary.setModifier(modifier);
    if (withPrettyNames) {
      historySummary.setModifierName(xwikiApi.getUserName(modifier, false));
    }

    historySummary.setLanguage(language);

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(modified);
    historySummary.setModified(calendar);

    if (language == null) {
      String pageUri =
          uri(baseUri, PageVersionResource.class, wikiName, spaceName, pageName, version);
      Link pageLink = objectFactory.createLink();
      pageLink.setHref(pageUri);
      pageLink.setRel(Relations.PAGE);
      historySummary.getLinks().add(pageLink);
    } else {
      String pageUri =
          uri(
              baseUri,
              PageTranslationVersionResource.class,
              wikiName,
              spaceName,
              pageName,
              language,
              version);
      Link pageLink = objectFactory.createLink();
      pageLink.setHref(pageUri);
      pageLink.setRel(Relations.PAGE);
      historySummary.getLinks().add(pageLink);
    }

    return historySummary;
  }
  /* This method is used to fill the "common part" of a Page and a PageSummary */
  private static void fillPageSummary(
      PageSummary pageSummary,
      ObjectFactory objectFactory,
      URI baseUri,
      Document doc,
      boolean useVersion,
      XWiki xwikiApi,
      Boolean withPrettyNames)
      throws XWikiException {
    pageSummary.setWiki(doc.getWiki());
    pageSummary.setFullName(doc.getFullName());
    pageSummary.setId(doc.getPrefixedFullName());
    pageSummary.setSpace(doc.getSpace());
    pageSummary.setName(doc.getName());
    pageSummary.setTitle(doc.getDisplayTitle());
    pageSummary.setXwikiRelativeUrl(doc.getURL("view"));
    pageSummary.setXwikiAbsoluteUrl(doc.getExternalURL("view"));
    pageSummary.setTranslations(createTranslations(objectFactory, baseUri, doc));
    pageSummary.setSyntax(doc.getSyntaxId());
    pageSummary.setVersion(doc.getVersion());
    pageSummary.setAuthor(doc.getAuthor());
    if (withPrettyNames) {
      pageSummary.setAuthorName(xwikiApi.getUserName(doc.getAuthor(), false));
    }

    Document parent = Utils.getParentDocument(doc, xwikiApi);
    pageSummary.setParent(doc.getParent());
    // parentId must not be set if the parent document does not exist.
    if (parent != null && !parent.isNew()) {
      pageSummary.setParentId(parent.getPrefixedFullName());
    } else {
      pageSummary.setParentId("");
    }

    String spaceUri = uri(baseUri, SpaceResource.class, doc.getWiki(), doc.getSpace());
    Link spaceLink = objectFactory.createLink();
    spaceLink.setHref(spaceUri);
    spaceLink.setRel(Relations.SPACE);
    pageSummary.getLinks().add(spaceLink);

    if (parent != null) {
      String parentUri =
          uri(baseUri, PageResource.class, parent.getWiki(), parent.getSpace(), parent.getName());
      Link parentLink = objectFactory.createLink();
      parentLink.setHref(parentUri);
      parentLink.setRel(Relations.PARENT);
      pageSummary.getLinks().add(parentLink);
    }

    String historyUri =
        uri(baseUri, PageHistoryResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
    Link historyLink = objectFactory.createLink();
    historyLink.setHref(historyUri);
    historyLink.setRel(Relations.HISTORY);
    pageSummary.getLinks().add(historyLink);

    if (!doc.getChildren().isEmpty()) {
      String pageChildrenUri =
          uri(baseUri, PageChildrenResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
      Link pageChildrenLink = objectFactory.createLink();
      pageChildrenLink.setHref(pageChildrenUri);
      pageChildrenLink.setRel(Relations.CHILDREN);
      pageSummary.getLinks().add(pageChildrenLink);
    }

    if (!doc.getComments().isEmpty()) {
      String commentsUri;
      if (useVersion) {
        commentsUri =
            uri(
                baseUri,
                CommentsVersionResource.class,
                doc.getWiki(),
                doc.getSpace(),
                doc.getName(),
                doc.getVersion());
      } else {
        commentsUri =
            uri(baseUri, CommentsResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
      }

      Link commentsLink = objectFactory.createLink();
      commentsLink.setHref(commentsUri);
      commentsLink.setRel(Relations.COMMENTS);
      pageSummary.getLinks().add(commentsLink);
    }

    if (!doc.getAttachmentList().isEmpty()) {
      String attachmentsUri;
      if (useVersion) {
        attachmentsUri =
            uri(
                baseUri,
                AttachmentsAtPageVersionResource.class,
                doc.getWiki(),
                doc.getSpace(),
                doc.getName(),
                doc.getVersion());
      } else {
        attachmentsUri =
            uri(baseUri, AttachmentsResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
      }

      Link attachmentsLink = objectFactory.createLink();
      attachmentsLink.setHref(attachmentsUri);
      attachmentsLink.setRel(Relations.ATTACHMENTS);
      pageSummary.getLinks().add(attachmentsLink);
    }

    if (!doc.getxWikiObjects().keySet().isEmpty()) {
      String objectsUri;

      if (useVersion) {
        objectsUri =
            uri(
                baseUri,
                ObjectsAtPageVersionResource.class,
                doc.getWiki(),
                doc.getSpace(),
                doc.getName(),
                doc.getVersion());
      } else {
        objectsUri =
            uri(baseUri, ObjectsResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
      }
      Link objectsLink = objectFactory.createLink();
      objectsLink.setHref(objectsUri);
      objectsLink.setRel(Relations.OBJECTS);
      pageSummary.getLinks().add(objectsLink);
    }

    com.xpn.xwiki.api.Object tagsObject = doc.getObject("XWiki.TagClass", 0);
    if (tagsObject != null) {
      if (tagsObject.getProperty("tags") != null) {
        String tagsUri =
            uri(baseUri, PageTagsResource.class, doc.getWiki(), doc.getSpace(), doc.getName());
        Link tagsLink = objectFactory.createLink();
        tagsLink.setHref(tagsUri);
        tagsLink.setRel(Relations.TAGS);
        pageSummary.getLinks().add(tagsLink);
      }
    }

    String syntaxesUri = uri(baseUri, SyntaxesResource.class);
    Link syntaxesLink = objectFactory.createLink();
    syntaxesLink.setHref(syntaxesUri);
    syntaxesLink.setRel(Relations.SYNTAXES);
    pageSummary.getLinks().add(syntaxesLink);
  }