@Override
  protected Document doGetDocument(Object obj) throws Exception {
    BookmarksEntry entry = (BookmarksEntry) obj;

    Document document = getBaseModelDocument(PORTLET_ID, entry);

    document.addText(Field.DESCRIPTION, entry.getDescription());
    document.addKeyword(Field.FOLDER_ID, entry.getFolderId());
    document.addText(Field.TITLE, entry.getName());
    document.addText(Field.URL, entry.getUrl());

    if (!entry.isInTrash() && entry.isInTrashContainer()) {
      BookmarksFolder folder = entry.getTrashContainer();

      addTrashFields(
          document,
          BookmarksFolder.class.getName(),
          folder.getFolderId(),
          null,
          null,
          BookmarksEntryAssetRendererFactory.TYPE);

      document.addKeyword(Field.ROOT_ENTRY_CLASS_NAME, BookmarksFolder.class.getName());
      document.addKeyword(Field.ROOT_ENTRY_CLASS_PK, folder.getFolderId());
      document.addKeyword(Field.STATUS, WorkflowConstants.STATUS_IN_TRASH);
    }

    return document;
  }
  @Override
  public void getSubfolderIds(List<Long> folderIds, long groupId, long folderId, boolean recurse)
      throws SystemException {

    List<BookmarksFolder> folders =
        bookmarksFolderPersistence.filterFindByG_P_S(
            groupId, folderId, WorkflowConstants.STATUS_APPROVED);

    for (BookmarksFolder folder : folders) {
      folderIds.add(folder.getFolderId());

      if (recurse) {
        getSubfolderIds(folderIds, folder.getGroupId(), folder.getFolderId(), recurse);
      }
    }
  }
  @Test
  public void testGetFolder() throws Exception {
    BookmarksFolder folder =
        BookmarksTestUtil.addFolder(_group.getGroupId(), RandomTestUtil.randomString());

    BookmarksFolderServiceUtil.getFolder(folder.getFolderId());
  }
  @Test
  public void testSearchAndVerifyDocs() throws Exception {
    ServiceContext serviceContext = ServiceContextTestUtil.getServiceContext(_group.getGroupId());

    BookmarksFolder folder =
        BookmarksTestUtil.addFolder(_group.getGroupId(), RandomTestUtil.randomString());

    BookmarksEntry entry = BookmarksTestUtil.addEntry(folder.getFolderId(), true, serviceContext);

    SearchContext searchContext =
        BookmarksTestUtil.getSearchContext(
            entry.getCompanyId(), entry.getGroupId(), entry.getFolderId(), "test");

    Indexer indexer = IndexerRegistryUtil.getIndexer(BookmarksEntry.class);

    Hits hits = indexer.search(searchContext);

    Assert.assertEquals(1, hits.getLength());

    List<Document> results = hits.toList();

    for (Document doc : results) {
      Assert.assertEquals(entry.getCompanyId(), GetterUtil.getLong(doc.get(Field.COMPANY_ID)));
      Assert.assertEquals(BookmarksEntry.class.getName(), doc.get(Field.ENTRY_CLASS_NAME));
      Assert.assertEquals(entry.getEntryId(), GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK)));
      AssertUtils.assertEqualsIgnoreCase(entry.getName(), doc.get(Field.TITLE));
      Assert.assertEquals(entry.getUrl(), doc.get(Field.URL));
    }
  }
  @Test
  public void testSearchAndDeleteFolderAndSearch() throws Exception {
    ServiceContext serviceContext = ServiceContextTestUtil.getServiceContext(_group.getGroupId());

    BookmarksFolder folder =
        BookmarksTestUtil.addFolder(_group.getGroupId(), RandomTestUtil.randomString());

    BookmarksEntry entry = BookmarksTestUtil.addEntry(folder.getFolderId(), true, serviceContext);

    long companyId = entry.getCompanyId();
    long groupId = entry.getFolder().getGroupId();
    long folderId = entry.getFolderId();
    String keywords = "test";

    SearchContext searchContext =
        BookmarksTestUtil.getSearchContext(companyId, groupId, folderId, keywords);

    Indexer indexer = IndexerRegistryUtil.getIndexer(BookmarksEntry.class);

    Hits hits = indexer.search(searchContext);

    Assert.assertEquals(1, hits.getLength());

    BookmarksFolderLocalServiceUtil.deleteFolder(folderId);

    hits = indexer.search(searchContext);

    Query query = hits.getQuery();

    Assert.assertEquals(query.toString(), 0, hits.getLength());
  }
  public void testUpdateExisting() throws Exception {
    long pk = nextLong();

    BookmarksFolder newBookmarksFolder = _persistence.create(pk);

    newBookmarksFolder.setUuid(randomString());

    newBookmarksFolder.setGroupId(nextLong());

    newBookmarksFolder.setCompanyId(nextLong());

    newBookmarksFolder.setUserId(nextLong());

    newBookmarksFolder.setUserName(randomString());

    newBookmarksFolder.setCreateDate(nextDate());

    newBookmarksFolder.setModifiedDate(nextDate());

    newBookmarksFolder.setParentFolderId(nextLong());

    newBookmarksFolder.setName(randomString());

    newBookmarksFolder.setDescription(randomString());

    _persistence.update(newBookmarksFolder, false);

    BookmarksFolder existingBookmarksFolder =
        _persistence.findByPrimaryKey(newBookmarksFolder.getPrimaryKey());

    assertEquals(existingBookmarksFolder.getUuid(), newBookmarksFolder.getUuid());
    assertEquals(existingBookmarksFolder.getFolderId(), newBookmarksFolder.getFolderId());
    assertEquals(existingBookmarksFolder.getGroupId(), newBookmarksFolder.getGroupId());
    assertEquals(existingBookmarksFolder.getCompanyId(), newBookmarksFolder.getCompanyId());
    assertEquals(existingBookmarksFolder.getUserId(), newBookmarksFolder.getUserId());
    assertEquals(existingBookmarksFolder.getUserName(), newBookmarksFolder.getUserName());
    assertEquals(
        Time.getShortTimestamp(existingBookmarksFolder.getCreateDate()),
        Time.getShortTimestamp(newBookmarksFolder.getCreateDate()));
    assertEquals(
        Time.getShortTimestamp(existingBookmarksFolder.getModifiedDate()),
        Time.getShortTimestamp(newBookmarksFolder.getModifiedDate()));
    assertEquals(
        existingBookmarksFolder.getParentFolderId(), newBookmarksFolder.getParentFolderId());
    assertEquals(existingBookmarksFolder.getName(), newBookmarksFolder.getName());
    assertEquals(existingBookmarksFolder.getDescription(), newBookmarksFolder.getDescription());
  }
  public static boolean contains(
      PermissionChecker permissionChecker, BookmarksFolder folder, String actionId)
      throws PortalException {

    if (actionId.equals(ActionKeys.ADD_FOLDER)) {
      actionId = ActionKeys.ADD_SUBFOLDER;
    }

    Boolean hasPermission =
        StagingPermissionUtil.hasPermission(
            permissionChecker,
            folder.getGroupId(),
            BookmarksFolder.class.getName(),
            folder.getFolderId(),
            PortletKeys.BOOKMARKS,
            actionId);

    if (hasPermission != null) {
      return hasPermission.booleanValue();
    }

    if (actionId.equals(ActionKeys.VIEW) && PropsValues.PERMISSIONS_VIEW_DYNAMIC_INHERITANCE) {

      try {
        long folderId = folder.getFolderId();

        while (folderId != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

          folder = BookmarksFolderLocalServiceUtil.getFolder(folderId);

          if (!_hasPermission(permissionChecker, folder, actionId)) {
            return false;
          }

          folderId = folder.getParentFolderId();
        }
      } catch (NoSuchFolderException nsfe) {
        if (!folder.isInTrash()) {
          throw nsfe;
        }
      }

      return BookmarksPermission.contains(permissionChecker, folder.getGroupId(), actionId);
    }

    return _hasPermission(permissionChecker, folder, actionId);
  }
  private static boolean _hasPermission(
      PermissionChecker permissionChecker, BookmarksFolder folder, String actionId) {

    if (permissionChecker.hasOwnerPermission(
            folder.getCompanyId(),
            BookmarksFolder.class.getName(),
            folder.getFolderId(),
            folder.getUserId(),
            actionId)
        || permissionChecker.hasPermission(
            folder.getGroupId(), BookmarksFolder.class.getName(), folder.getFolderId(), actionId)) {

      return true;
    }

    return false;
  }
  @Override
  protected long addContainerModel(long containerModelId) throws Exception {
    ServiceContext serviceContext = ServiceTestUtil.getServiceContext(group.getGroupId());

    BookmarksFolder folder =
        BookmarksTestUtil.addFolder(
            containerModelId, ServiceTestUtil.randomString(), serviceContext);

    return folder.getFolderId();
  }
  public static void addPortletBreadcrumbEntries(
      BookmarksFolder folder, HttpServletRequest request, RenderResponse renderResponse)
      throws Exception {

    String strutsAction = ParamUtil.getString(request, "struts_action");

    PortletURL portletURL = renderResponse.createRenderURL();

    if (strutsAction.equals("/bookmarks/select_folder")) {
      ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);

      portletURL.setWindowState(LiferayWindowState.POP_UP);

      portletURL.setParameter("struts_action", "/bookmarks/select_folder");

      PortalUtil.addPortletBreadcrumbEntry(
          request, themeDisplay.translate("home"), portletURL.toString());
    } else {
      portletURL.setParameter("struts_action", "/bookmarks/view");
    }

    List<BookmarksFolder> ancestorFolders = folder.getAncestors();

    Collections.reverse(ancestorFolders);

    for (BookmarksFolder ancestorFolder : ancestorFolders) {
      portletURL.setParameter("folderId", String.valueOf(ancestorFolder.getFolderId()));

      PortalUtil.addPortletBreadcrumbEntry(
          request, ancestorFolder.getName(), portletURL.toString());
    }

    portletURL.setParameter("folderId", String.valueOf(folder.getFolderId()));

    if (folder.getFolderId() != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

      PortalUtil.addPortletBreadcrumbEntry(request, folder.getName(), portletURL.toString());
    }
  }
  @Override
  protected BaseModel<?> addBaseModelWithWorkflow(
      BaseModel<?> parentBaseModel,
      boolean approved,
      String keywords,
      ServiceContext serviceContext)
      throws Exception {

    BookmarksFolder parentFolder = (BookmarksFolder) parentBaseModel;

    return BookmarksTestUtil.addFolder(
        parentFolder.getGroupId(), parentFolder.getFolderId(), keywords);
  }
  public void testDynamicQueryByPrimaryKeyExisting() throws Exception {
    BookmarksFolder newBookmarksFolder = addBookmarksFolder();

    DynamicQuery dynamicQuery =
        DynamicQueryFactoryUtil.forClass(
            BookmarksFolder.class, BookmarksFolder.class.getClassLoader());

    dynamicQuery.add(RestrictionsFactoryUtil.eq("folderId", newBookmarksFolder.getFolderId()));

    List<BookmarksFolder> result = _persistence.findWithDynamicQuery(dynamicQuery);

    assertEquals(1, result.size());

    BookmarksFolder existingBookmarksFolder = result.get(0);

    assertEquals(existingBookmarksFolder, newBookmarksFolder);
  }
  public static void addPortletBreadcrumbEntries(
      BookmarksEntry entry, HttpServletRequest request, RenderResponse renderResponse)
      throws Exception {

    BookmarksFolder folder = entry.getFolder();

    if (folder.getFolderId() != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

      addPortletBreadcrumbEntries(folder, request, renderResponse);
    }

    PortletURL portletURL = renderResponse.createRenderURL();

    portletURL.setParameter("struts_action", "/bookmarks/view_entry");
    portletURL.setParameter("entryId", String.valueOf(entry.getEntryId()));

    PortalUtil.addPortletBreadcrumbEntry(request, entry.getName(), portletURL.toString());
  }
  @Test
  public void testSearch() throws Exception {
    ServiceContext serviceContext = ServiceContextTestUtil.getServiceContext(_group.getGroupId());

    BookmarksFolder folder =
        BookmarksTestUtil.addFolder(_group.getGroupId(), RandomTestUtil.randomString());

    BookmarksEntry entry = BookmarksTestUtil.addEntry(folder.getFolderId(), true, serviceContext);

    SearchContext searchContext =
        BookmarksTestUtil.getSearchContext(
            entry.getCompanyId(), entry.getGroupId(), entry.getFolderId(), "test");

    Indexer indexer = IndexerRegistryUtil.getIndexer(BookmarksEntry.class);

    Hits hits = indexer.search(searchContext);

    Assert.assertEquals(1, hits.getLength());
  }
  public void testDynamicQueryByProjectionExisting() throws Exception {
    BookmarksFolder newBookmarksFolder = addBookmarksFolder();

    DynamicQuery dynamicQuery =
        DynamicQueryFactoryUtil.forClass(
            BookmarksFolder.class, BookmarksFolder.class.getClassLoader());

    dynamicQuery.setProjection(ProjectionFactoryUtil.property("folderId"));

    Object newFolderId = newBookmarksFolder.getFolderId();

    dynamicQuery.add(RestrictionsFactoryUtil.in("folderId", new Object[] {newFolderId}));

    List<Object> result = _persistence.findWithDynamicQuery(dynamicQuery);

    assertEquals(1, result.size());

    Object existingFolderId = result.get(0);

    assertEquals(existingFolderId, newFolderId);
  }
  protected void reindexFolders(long companyId, long startFolderId, long endFolderId)
      throws Exception {

    DynamicQuery dynamicQuery =
        DynamicQueryFactoryUtil.forClass(
            BookmarksFolder.class, PortalClassLoaderUtil.getClassLoader());

    Property property = PropertyFactoryUtil.forName("folderId");

    dynamicQuery.add(property.ge(startFolderId));
    dynamicQuery.add(property.lt(endFolderId));

    addReindexCriteria(dynamicQuery, companyId);

    List<BookmarksFolder> folders = BookmarksFolderLocalServiceUtil.dynamicQuery(dynamicQuery);

    for (BookmarksFolder folder : folders) {
      long groupId = folder.getGroupId();
      long folderId = folder.getFolderId();

      reindexEntries(companyId, groupId, folderId);
    }
  }
  @Override
  protected void doImportStagedModel(
      PortletDataContext portletDataContext, Element element, String path, BookmarksFolder folder)
      throws Exception {

    long userId = portletDataContext.getUserId(folder.getUserUuid());

    Map<Long, Long> folderIds =
        (Map<Long, Long>) portletDataContext.getNewPrimaryKeysMap(BookmarksFolder.class);

    long parentFolderId =
        MapUtil.getLong(folderIds, folder.getParentFolderId(), folder.getParentFolderId());

    if ((parentFolderId != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID)
        && (parentFolderId == folder.getParentFolderId())) {

      String parentFolderPath =
          StagedModelPathUtil.getPath(
              portletDataContext, BookmarksFolder.class.getName(), parentFolderId);

      BookmarksFolder parentFolder =
          (BookmarksFolder) portletDataContext.getZipEntryAsObject(parentFolderPath);

      importStagedModel(portletDataContext, element, parentFolderPath, parentFolder);

      parentFolderId =
          MapUtil.getLong(folderIds, folder.getParentFolderId(), folder.getParentFolderId());
    }

    ServiceContext serviceContext =
        portletDataContext.createServiceContext(
            path, folder, BookmarksPortletDataHandler.NAMESPACE);

    BookmarksFolder importedFolder = null;

    if (portletDataContext.isDataStrategyMirror()) {
      BookmarksFolder existingFolder =
          BookmarksFolderUtil.fetchByUUID_G(folder.getUuid(), portletDataContext.getScopeGroupId());

      if (existingFolder == null) {
        serviceContext.setUuid(folder.getUuid());

        importedFolder =
            BookmarksFolderLocalServiceUtil.addFolder(
                userId, parentFolderId, folder.getName(), folder.getDescription(), serviceContext);
      } else {
        importedFolder =
            BookmarksFolderLocalServiceUtil.updateFolder(
                userId,
                existingFolder.getFolderId(),
                parentFolderId,
                folder.getName(),
                folder.getDescription(),
                false,
                serviceContext);
      }
    } else {
      importedFolder =
          BookmarksFolderLocalServiceUtil.addFolder(
              userId, parentFolderId, folder.getName(), folder.getDescription(), serviceContext);
    }

    portletDataContext.importClassedModel(
        folder, importedFolder, BookmarksPortletDataHandler.NAMESPACE);
  }