@Override
  public void addDocuments(
      String searchEngineId,
      long companyId,
      Collection<Document> documents,
      boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
      return;
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    for (Document document : documents) {
      if (_log.isDebugEnabled()) {
        _log.debug("Add document " + document.toString());
      }

      _searchPermissionChecker.addPermissionFields(companyId, document);
    }

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately);

    indexWriter.addDocuments(searchContext, documents);
  }
  protected SearchContext buildSearchContext(
      long companyId,
      long[] groupIds,
      String title,
      long[] parentCategoryIds,
      long[] vocabularyIds,
      int start,
      int end,
      Sort sort) {

    SearchContext searchContext = new SearchContext();

    Map<String, Serializable> attributes = new HashMap<>();

    attributes.put(Field.ASSET_PARENT_CATEGORY_IDS, parentCategoryIds);
    attributes.put(Field.ASSET_VOCABULARY_IDS, vocabularyIds);
    attributes.put(Field.TITLE, title);

    searchContext.setAttributes(attributes);

    searchContext.setCompanyId(companyId);
    searchContext.setEnd(end);
    searchContext.setGroupIds(groupIds);
    searchContext.setKeywords(title);
    searchContext.setSorts(sort);
    searchContext.setStart(start);

    QueryConfig queryConfig = searchContext.getQueryConfig();

    queryConfig.setHighlightEnabled(false);
    queryConfig.setScoreEnabled(false);

    return searchContext;
  }
  @Override
  public void updateDocument(
      String searchEngineId, long companyId, Document document, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (document == null)) {
      return;
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Document " + document.toString());
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    _searchPermissionChecker.addPermissionFields(companyId, document);

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately || ProxyModeThreadLocal.isForceSync());

    indexWriter.updateDocument(searchContext, document);
  }
  @Override
  public void deleteEntityDocuments(
      String searchEngineId, long companyId, String className, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly()) {
      return;
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    if (searchEngine == null) {
      return;
    }

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately);

    indexWriter.deleteEntityDocuments(searchContext, className);
  }
  protected void search(
      FileEntry fileEntry, boolean rootFolder, String keywords, boolean assertTrue)
      throws Exception {

    SearchContext searchContext = new SearchContext();

    searchContext.setAttribute("paginationType", "regular");
    searchContext.setCompanyId(fileEntry.getCompanyId());
    searchContext.setFolderIds(new long[] {fileEntry.getFolderId()});
    searchContext.setGroupIds(new long[] {fileEntry.getRepositoryId()});
    searchContext.setKeywords(keywords);

    QueryConfig queryConfig = new QueryConfig();

    queryConfig.setHighlightEnabled(false);
    queryConfig.setScoreEnabled(false);

    searchContext.setQueryConfig(queryConfig);

    Indexer indexer = IndexerRegistryUtil.getIndexer(DLFileEntryConstants.getClassName());

    Hits hits = indexer.search(searchContext);

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

    boolean found = false;

    for (Document document : documents) {
      long fileEntryId = GetterUtil.getLong(document.get(Field.ENTRY_CLASS_PK));

      if (fileEntryId == fileEntry.getFileEntryId()) {
        found = true;

        break;
      }
    }

    String message = "Search engine could not find ";

    if (rootFolder) {
      message += "root file entry by " + keywords;
    } else {
      message += "file entry by " + keywords;
    }

    message += " using query " + hits.getQuery();

    if (assertTrue) {
      Assert.assertTrue(message, found);
    } else {
      Assert.assertFalse(message, found);
    }
  }
  @Test
  public void testMatchNotOnlyCompanyIdButAlsoQueryTerms() throws Exception {
    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(TestPropsValues.getCompanyId());

    BooleanQuery query = new BooleanQueryImpl();

    query.addTerm("title", RandomTestUtil.randomString());

    assertEquals(0, query, searchContext);
  }
  public Hits search(
      long companyId,
      long[] groupIds,
      long userId,
      String className,
      String keywords,
      int status,
      int start,
      int end)
      throws SystemException {

    try {
      SearchContext searchContext = new SearchContext();

      Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);

      assetEntriesFacet.setStatic(true);

      searchContext.addFacet(assetEntriesFacet);

      Facet scopeFacet = new ScopeFacet(searchContext);

      scopeFacet.setStatic(true);

      searchContext.addFacet(scopeFacet);

      searchContext.setAttribute("paginationType", "regular");
      searchContext.setAttribute("status", status);
      searchContext.setCompanyId(companyId);
      searchContext.setEnd(end);
      searchContext.setEntryClassNames(getClassNames(className));
      searchContext.setGroupIds(groupIds);
      searchContext.setKeywords(keywords);

      QueryConfig queryConfig = new QueryConfig();

      queryConfig.setHighlightEnabled(false);
      queryConfig.setScoreEnabled(false);

      searchContext.setQueryConfig(queryConfig);

      searchContext.setStart(start);
      searchContext.setUserId(userId);

      Indexer indexer = FacetedSearcher.getInstance();

      return indexer.search(searchContext);
    } catch (Exception e) {
      throw new SystemException(e);
    }
  }
  @Override
  public void commit(String searchEngineId, long companyId) throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    indexWriter.commit(searchContext);
  }
  @Override
  public void indexSpellCheckerDictionaries(String searchEngineId, long companyId)
      throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    indexWriter.indexSpellCheckerDictionaries(searchContext);
  }
  @Override
  public void indexQuerySuggestionDictionary(String searchEngineId, long companyId, Locale locale)
      throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);
    searchContext.setLocale(locale);

    indexWriter.indexQuerySuggestionDictionary(searchContext);
  }
  protected SearchContext buildSearchContext(
      long companyId,
      String name,
      String description,
      LinkedHashMap<String, Object> params,
      boolean andSearch,
      int start,
      int end,
      Sort sort) {

    SearchContext searchContext = new SearchContext();

    searchContext.setAndSearch(andSearch);

    Map<String, Serializable> attributes = new HashMap<>();

    attributes.put("description", description);
    attributes.put("name", name);

    searchContext.setAttributes(attributes);

    searchContext.setCompanyId(companyId);
    searchContext.setEnd(end);

    if (params != null) {
      String keywords = (String) params.remove("keywords");

      if (Validator.isNotNull(keywords)) {
        searchContext.setKeywords(keywords);
      }
    }

    if (sort != null) {
      searchContext.setSorts(sort);
    }

    searchContext.setStart(start);

    QueryConfig queryConfig = searchContext.getQueryConfig();

    queryConfig.setHighlightEnabled(false);
    queryConfig.setScoreEnabled(false);

    return searchContext;
  }
  @Override
  public Hits search(
      long groupId,
      long userId,
      long creatorUserId,
      long startDate,
      long endDate,
      int status,
      int start,
      int end)
      throws PortalException {

    Indexer<MBThread> indexer = IndexerRegistryUtil.getIndexer(MBThread.class.getName());

    SearchContext searchContext = new SearchContext();

    searchContext.setAttribute(Field.STATUS, status);

    if (endDate > 0) {
      searchContext.setAttribute("endDate", endDate);
    }

    searchContext.setAttribute("paginationType", "none");

    if (creatorUserId > 0) {
      searchContext.setAttribute("participantUserId", String.valueOf(creatorUserId));
    }

    if (startDate > 0) {
      searchContext.setAttribute("startDate", startDate);
    }

    Group group = groupLocalService.getGroup(groupId);

    searchContext.setCompanyId(group.getCompanyId());

    searchContext.setEnd(end);
    searchContext.setGroupIds(new long[] {groupId});
    searchContext.setSorts(new Sort("lastPostDate", true));
    searchContext.setStart(start);
    searchContext.setUserId(userId);

    return indexer.search(searchContext);
  }
  protected SearchContext buildSearchContext(
      long companyId, long groupId, String title, int start, int end) {

    SearchContext searchContext = new SearchContext();

    searchContext.setAttribute(Field.TITLE, title);
    searchContext.setCompanyId(companyId);
    searchContext.setEnd(end);
    searchContext.setGroupIds(new long[] {groupId});
    searchContext.setKeywords(title);
    searchContext.setStart(start);

    QueryConfig queryConfig = searchContext.getQueryConfig();

    queryConfig.setHighlightEnabled(false);
    queryConfig.setScoreEnabled(false);

    return searchContext;
  }
  protected void search(boolean rootFolder, String keywords) throws Exception {

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(_fileEntry.getCompanyId());
    searchContext.setFolderIds(new long[] {_fileEntry.getFolderId()});
    searchContext.setGroupIds(new long[] {_fileEntry.getRepositoryId()});
    searchContext.setKeywords(keywords);

    QueryConfig queryConfig = new QueryConfig();

    queryConfig.setHighlightEnabled(false);
    queryConfig.setScoreEnabled(false);

    searchContext.setQueryConfig(queryConfig);

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

    List<Document> documents = indexer.search(searchContext).toList();

    boolean found = false;

    for (Document document : documents) {
      long fileEntryId = GetterUtil.getLong(document.get(Field.ENTRY_CLASS_PK));

      if (fileEntryId == _fileEntry.getFileEntryId()) {
        found = true;

        break;
      }
    }

    String message = "Search engine could not find ";

    if (rootFolder) {
      message += "root file entry by " + keywords;
    } else {
      message += "file entry by " + keywords;
    }

    assertTrue(message, found);
  }
  @Override
  public void deleteDocuments(
      String searchEngineId, long companyId, Collection<String> uids, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (uids == null) || uids.isEmpty()) {
      return;
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately);

    indexWriter.deleteDocuments(searchContext, uids);
  }
  @Override
  public void indexKeyword(
      String searchEngineId,
      long companyId,
      String querySuggestion,
      float weight,
      String keywordType,
      Locale locale)
      throws SearchException {

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);
    searchContext.setKeywords(querySuggestion);
    searchContext.setLocale(locale);

    indexWriter.indexKeyword(searchContext, weight, keywordType);
  }
  public Hits search(
      long companyId,
      long userId,
      String portletId,
      long groupId,
      long[] repositoryIds,
      String keywords,
      int start,
      int end) {

    try {
      SearchContext searchContext = new SearchContext();

      searchContext.setCompanyId(companyId);
      searchContext.setEnd(end);
      searchContext.setEntryClassNames(new String[] {DLFileEntryConstants.getClassName()});
      searchContext.setGroupIds(new long[] {groupId});

      Indexer indexer = IndexerRegistryUtil.getIndexer(DLFileEntryConstants.getClassName());

      searchContext.setSearchEngineId(indexer.getSearchEngineId());

      searchContext.setStart(start);
      searchContext.setUserId(userId);

      BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(searchContext);

      contextQuery.addRequiredTerm(Field.PORTLET_ID, portletId);

      if (groupId > 0) {
        Group group = groupLocalService.getGroup(groupId);

        if (group.isLayout()) {
          contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);

          groupId = group.getParentGroupId();
        }

        contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
      }

      if (ArrayUtil.isNotEmpty(repositoryIds)) {
        BooleanQuery repositoryIdsQuery = BooleanQueryFactoryUtil.create(searchContext);

        for (long repositoryId : repositoryIds) {
          try {
            if (userId > 0) {
              PermissionChecker permissionChecker = PermissionThreadLocal.getPermissionChecker();

              DLFolderPermission.check(permissionChecker, groupId, repositoryId, ActionKeys.VIEW);
            }

            if (repositoryId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

              repositoryId = groupId;
            }

            TermQuery termQuery =
                TermQueryFactoryUtil.create(searchContext, "repositoryId", repositoryId);

            repositoryIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
          } catch (Exception e) {
          }
        }

        contextQuery.add(repositoryIdsQuery, BooleanClauseOccur.MUST);
      }

      BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(searchContext);

      searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);

      BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);

      fullQuery.add(contextQuery, BooleanClauseOccur.MUST);

      List<BooleanClause> clauses = searchQuery.clauses();

      if (!clauses.isEmpty()) {
        fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
      }

      return SearchEngineUtil.search(searchContext, fullQuery);
    } catch (Exception e) {
      throw new SystemException(e);
    }
  }
  public Hits search(
      long companyId,
      long[] groupIds,
      long userId,
      String className,
      String userName,
      String title,
      String description,
      String assetCategoryIds,
      String assetTagNames,
      int status,
      boolean andSearch,
      int start,
      int end)
      throws SystemException {

    try {
      SearchContext searchContext = new SearchContext();

      Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);

      assetEntriesFacet.setStatic(true);

      searchContext.addFacet(assetEntriesFacet);

      Facet scopeFacet = new ScopeFacet(searchContext);

      scopeFacet.setStatic(true);

      searchContext.addFacet(scopeFacet);

      searchContext.setAndSearch(andSearch);
      searchContext.setAssetCategoryIds(StringUtil.split(assetCategoryIds, 0L));
      searchContext.setAssetTagNames(StringUtil.split(assetTagNames));
      searchContext.setAttribute(Field.DESCRIPTION, description);
      searchContext.setAttribute(Field.TITLE, title);
      searchContext.setAttribute(Field.USER_NAME, userName);
      searchContext.setAttribute("paginationType", "regular");
      searchContext.setAttribute("status", status);
      searchContext.setCompanyId(companyId);
      searchContext.setEnd(end);
      searchContext.setEntryClassNames(getClassNames(className));
      searchContext.setGroupIds(groupIds);

      QueryConfig queryConfig = new QueryConfig();

      queryConfig.setHighlightEnabled(false);
      queryConfig.setScoreEnabled(false);

      searchContext.setQueryConfig(queryConfig);

      searchContext.setStart(start);
      searchContext.setUserId(userId);

      Indexer indexer = FacetedSearcher.getInstance();

      return indexer.search(searchContext);
    } catch (Exception e) {
      throw new SystemException(e);
    }
  }