/**
   * Index a forum in a group.
   *
   * @param parentResourceContext
   * @param businessGroup
   * @param indexWriter
   * @throws IOException
   */
  @Override
  public void doIndex(
      final SearchResourceContext parentResourceContext,
      final Object businessObj,
      final OlatFullIndexer indexWriter)
      throws IOException, InterruptedException {
    if (!(businessObj instanceof BusinessGroup)) {
      throw new AssertException("businessObj must be BusinessGroup");
    }
    final BusinessGroup businessGroup = (BusinessGroup) businessObj;

    final NarrowedPropertyManager npm = NarrowedPropertyManager.getInstance(businessGroup);
    final ForumManager fom = ForumManager.getInstance();

    final Property forumKeyProperty =
        npm.findProperty(
            null, null, CollaborationTools.PROP_CAT_BG_COLLABTOOLS, CollaborationTools.KEY_FORUM);
    // Check if forum-property exist
    if (forumKeyProperty != null) {
      final Long forumKey = forumKeyProperty.getLongValue();
      final Forum forum = fom.loadForum(forumKey);
      final SearchResourceContext forumSearchResourceContext =
          new SearchResourceContext(parentResourceContext);
      forumSearchResourceContext.setBusinessControlFor(
          BusinessGroupMainRunController.ORES_TOOLFORUM);
      forumSearchResourceContext.setDocumentType(TYPE);
      forumSearchResourceContext.setDocumentContext(businessGroup.getKey() + " " + forumKey);
      forumSearchResourceContext.setParentContextType(GroupDocument.TYPE);
      forumSearchResourceContext.setParentContextName(businessGroup.getName());
      doIndexAllMessages(forumSearchResourceContext, forum, indexWriter);
    }
  }
  /**
   * If the forumCallback is null no filtering is executed, else if a thread is hidden and the user
   * doesn't have moderator rights the hidden thread is not included into the archive.
   *
   * @param forumId
   * @param metaInfo
   * @return all top message nodes together with their children in a list
   */
  private List convertToThreadTrees(final long forumId, final ForumCallback forumCallback) {
    List messages;
    final List topNodeList = new ArrayList();
    final ForumManager fm = ForumManager.getInstance();
    final Long l = new Long(forumId);
    final Forum f = fm.loadForum(l);
    messages = fm.getMessagesByForum(f);

    for (final Iterator iterTop = messages.iterator(); iterTop.hasNext(); ) {
      final Message msg = (Message) iterTop.next();
      if (msg.getParent() == null) {
        iterTop.remove();
        final MessageNode topNode = new MessageNode(msg);
        if (topNode.isHidden()
            && (forumCallback == null
                || (forumCallback != null && forumCallback.mayEditMessageAsModerator()))) {
          addChildren(messages, topNode);
          topNodeList.add(topNode);
        } else if (!topNode.isHidden()) {
          addChildren(messages, topNode);
          topNodeList.add(topNode);
        }
      }
    }
    return getMessagesSorted(topNodeList);
  }
 /**
  * @see org.olat.search.service.indexer.Indexer#checkAccess(org.olat.core.id.context.ContextEntry,
  *     org.olat.core.id.context.BusinessControl, org.olat.core.id.Identity,
  *     org.olat.core.id.Roles)
  */
 @Override
 public boolean checkAccess(
     final ContextEntry contextEntry,
     final BusinessControl businessControl,
     final Identity identity,
     final Roles roles) {
   // TODO:chg: check with collabTools if forum is enabled
   final ContextEntry ce = businessControl.popLauncherContextEntry();
   final Long resourceableId = ce.getOLATResourceable().getResourceableId();
   final Message message = ForumManager.getInstance().loadMessage(resourceableId);
   Message threadtop = message.getThreadtop();
   if (threadtop == null) {
     threadtop = message;
   }
   final boolean isMessageHidden = Status.getStatus(threadtop.getStatusCode()).isHidden();
   // assumes that if is owner then is moderator so it is allowed to see the hidden forum threads
   // TODO: (LD) fix this!!!
   // here it is checked if the identity is owner of the forum tool but it has no way to find out
   // whether is owner of the group that owns the forum tool
   final boolean isOwner =
       BaseSecurityManager.getInstance()
           .isIdentityPermittedOnResourceable(
               identity, Constants.PERMISSION_ACCESS, contextEntry.getOLATResourceable());
   if (isMessageHidden && !isOwner) {
     return false;
   }
   return true;
 }
 /**
  * @param messageId
  * @param metaInfo
  * @return the top message node with all its children
  */
 private MessageNode convertToThreadTree(final long topMessageId) {
   List messages;
   MessageNode topNode = null;
   final ForumManager fm = ForumManager.getInstance();
   final Long l = new Long(topMessageId);
   messages = fm.getThread(l);
   for (final Iterator iterTop = messages.iterator(); iterTop.hasNext(); ) {
     final Message msg = (Message) iterTop.next();
     if (msg.getParent() == null) {
       iterTop.remove();
       topNode = new MessageNode(msg);
       addChildren(messages, topNode);
     }
   }
   return topNode;
 }
  /**
   * Index a forum in a group.
   *
   * @param parentResourceContext
   * @param businessGroup
   * @param indexWriter
   * @throws IOException
   */
  public void doIndex(
      SearchResourceContext parentResourceContext, Object businessObj, OlatFullIndexer indexWriter)
      throws IOException, InterruptedException {
    if (!(businessObj instanceof BusinessGroup))
      throw new AssertException("businessObj must be BusinessGroup");
    BusinessGroup businessGroup = (BusinessGroup) businessObj;

    NarrowedPropertyManager npm = NarrowedPropertyManager.getInstance(businessGroup);
    ForumManager fom = ForumManager.getInstance();

    Property forumKeyProperty =
        npm.findProperty(
            null, null, CollaborationTools.PROP_CAT_BG_COLLABTOOLS, CollaborationTools.KEY_FORUM);
    // Check if forum-property exist
    if (forumKeyProperty != null) {
      Long forumKey = forumKeyProperty.getLongValue();
      Forum forum = fom.loadForum(forumKey);
      SearchResourceContext forumSearchResourceContext =
          new SearchResourceContext(parentResourceContext);
      forumSearchResourceContext.setBusinessControlFor(
          BusinessGroupMainRunController.ORES_TOOLFORUM);
      forumSearchResourceContext.setDocumentType(TYPE);
      forumSearchResourceContext.setParentContextType(GroupDocument.TYPE);
      forumSearchResourceContext.setParentContextName(businessGroup.getName());
      if (forum == null) { // fxdiff: FXOLAT-104 warn about missing forums
        logError(
            "found a forum-key "
                + forumKey
                + " for businessgroup "
                + businessGroup.getName()
                + " ["
                + businessGroup.getKey()
                + "] to index a forum that could not be "
                + "found by key! skip indexing, check if forum should still be enabled. context: "
                + forumSearchResourceContext.getResourceUrl(),
            null);
        return;
      }
      doIndexAllMessages(forumSearchResourceContext, forum, indexWriter);
    }
  }