⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmssearchindex.java

📁 一个cms内容管理平台
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            }
            // add the calculated phrase query for the root path
            query.add(pathQuery, BooleanClause.Occur.MUST);

            if ((params.getCategories() != null) && (params.getCategories().size() > 0)) {
                // add query categories (if required)
                BooleanQuery categoryQuery = new BooleanQuery();
                for (int i = 0; i < params.getCategories().size(); i++) {
                    Term term = new Term(I_CmsDocumentFactory.DOC_CATEGORY, (String)params.getCategories().get(i));
                    TermQuery termQuery = new TermQuery(term);
                    categoryQuery.add(termQuery, BooleanClause.Occur.SHOULD);
                }
                query.add(categoryQuery, BooleanClause.Occur.MUST);
            }

            if ((params.getFields() != null) && (params.getFields().size() > 0)) {
                // this is a "regular" query over one or more fields
                BooleanQuery fieldsQuery = new BooleanQuery();
                // add one sub-query for each of the selected fields, e.g. "content", "title" etc.
                for (int i = 0; i < params.getFields().size(); i++) {
                    QueryParser p = new QueryParser((String)params.getFields().get(i), languageAnalyzer);
                    fieldsQuery.add(p.parse(params.getQuery()), BooleanClause.Occur.SHOULD);
                }
                // finally add the field queries to the main query
                query.add(fieldsQuery, BooleanClause.Occur.MUST);
            } else {
                // if no fields are provided, just use the "content" field by default
                QueryParser p = new QueryParser(I_CmsDocumentFactory.DOC_CONTENT, languageAnalyzer);
                query.add(p.parse(params.getQuery()), BooleanClause.Occur.MUST);
            }

            // create the index searcher
            searcher = new IndexSearcher(m_path);
            Query finalQuery;

            if (m_createExcerpt || LOG.isDebugEnabled()) {
                // we re-write the query because this enables highlighting of wildcard terms in excerpts 
                finalQuery = searcher.rewrite(query);
            } else {
                finalQuery = query;
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug(Messages.get().getBundle().key(Messages.LOG_BASE_QUERY_1, query));
                LOG.debug(Messages.get().getBundle().key(Messages.LOG_REWRITTEN_QUERY_1, finalQuery));

            }

            // collect the categories
            CmsSearchCategoryCollector categoryCollector;
            if (params.isCalculateCategories()) {
                // USE THIS OPTION WITH CAUTION
                // this may slow down searched by an order of magnitude
                categoryCollector = new CmsSearchCategoryCollector(searcher);
                // perform a first search to collect the categories
                searcher.search(finalQuery, categoryCollector);
                // store the result
                searchResults.setCategories(categoryCollector.getCategoryCountResult());
            }

            // perform the search operation          
            hits = searcher.search(finalQuery, params.getSort());

            int hitCount = hits.length();

            timeLucene += System.currentTimeMillis();
            timeResultProcessing = -System.currentTimeMillis();

            Document doc;
            CmsSearchResult searchResult;
            String excerpt = null;

            if (hits != null) {
                int page = params.getSearchPage();
                int start = -1, end = -1;
                if (matchesPerPage > 0 && page > 0 && hitCount > 0) {
                    // calculate the final size of the search result
                    start = matchesPerPage * (page - 1);
                    end = start + matchesPerPage;
                    // ensure that both i and n are inside the range of foundDocuments.size()
                    start = (start > hitCount) ? hitCount : start;
                    end = (end > hitCount) ? hitCount : end;
                } else {
                    // return all found documents in the search result
                    start = 0;
                    end = hitCount;
                }

                int visibleHitCount = hitCount;
                for (int i = 0, cnt = 0; i < hitCount && cnt < end; i++) {
                    try {
                        doc = hits.doc(i);
                        if (hasReadPermission(cms, doc)) {
                            // user has read permission
                            if (cnt >= start) {
                                // do not use the resource to obtain the raw content, read it from the lucene document !
                                // documents must not have content (i.e. images), so check if the content field exists
                                if (m_createExcerpt && doc.getField(I_CmsDocumentFactory.DOC_CONTENT) != null) {
                                    excerpt = getExcerpt(
                                        doc.getField(I_CmsDocumentFactory.DOC_CONTENT).stringValue(),
                                        finalQuery,
                                        languageAnalyzer);
                                }
                                searchResult = new CmsSearchResult(Math.round(hits.score(i) * 100f), doc, excerpt);
                                searchResults.add(searchResult);
                            }
                            cnt++;
                        } else {
                            visibleHitCount--;
                        }
                    } catch (Exception e) {
                        // should not happen, but if it does we want to go on with the next result nevertheless                        
                        if (LOG.isWarnEnabled()) {
                            LOG.warn(Messages.get().getBundle().key(Messages.LOG_RESULT_ITERATION_FAILED_0), e);
                        }
                    }
                }

                // save the total count of search results at the last index of the search result 
                searchResults.setHitCount(visibleHitCount);
            } else {
                searchResults.setHitCount(0);
            }

            timeResultProcessing += System.currentTimeMillis();

        } catch (Exception exc) {
            throw new CmsSearchException(Messages.get().container(Messages.ERR_SEARCH_PARAMS_1, params), exc);
        } finally {

            // re-set thread to previous priority
            Thread.currentThread().setPriority(previousPriority);

            if (searcher != null) {
                try {
                    searcher.close();
                } catch (IOException exc) {
                    // noop
                }
            }

            // switch back to the original project
            context.setCurrentProject(currentProject);
        }

        timeTotal += System.currentTimeMillis();

        Object[] logParams = new Object[] {
            new Integer(hits.length()),
            new Long(timeTotal),
            new Long(timeLucene),
            new Long(timeResultProcessing)};
        if (LOG.isDebugEnabled()) {
            LOG.debug(Messages.get().getBundle().key(Messages.LOG_STAT_RESULTS_TIME_4, logParams));
        }

        return searchResults;
    }

    /**
     * Can be used to enable / disable this index.<p>
     * 
     * @param enabled the state of the index to set
     */
    public void setEnabled(boolean enabled) {

        m_enabled = enabled;
    }

    /**
     * Sets the locale to index resources.<p>
     * 
     * @param locale the locale to index resources
     */
    public void setLocale(String locale) {

        m_locale = locale;
    }

    /**
     * Sets the logical key/name of this search index.<p>
     * 
     * @param name the logical key/name of this search index 
     * 
     * @throws org.opencms.main.CmsIllegalArgumentException 
     *   if the given name is null, empty or already taken 
     *   by another search index. 
     */
    public void setName(String name) throws CmsIllegalArgumentException {

        if (CmsStringUtil.isEmptyOrWhitespaceOnly(name)) {
            throw new CmsIllegalArgumentException(Messages.get().container(
                Messages.ERR_SEARCHINDEX_CREATE_MISSING_NAME_0));
        } else {

            // check if already used, but only if the name was modified: 
            // this is important as unmodifiable DisplayWidgets will also invoke this...
            if (!name.equals(m_name)) {
                // don't mess with xml-configuration
                if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_2_INITIALIZING) {
                    // Not needed at startup and additionally getSearchManager may return null
                    Iterator itIdxNames = OpenCms.getSearchManager().getIndexNames().iterator();
                    while (itIdxNames.hasNext()) {
                        if (itIdxNames.next().equals(name)) {
                            throw new CmsIllegalArgumentException(Messages.get().container(
                                Messages.ERR_SEARCHINDEX_CREATE_INVALID_NAME_1,
                                name));
                        }
                    }
                }
            }
        }

        m_name = name;

    }

    /**
     * Sets the name of the project used to index resources.<p>
     * 
     * A duplicate method of <code>{@link #setProjectName(String)}</code> that allows 
     * to use instances of this class as a widget object (bean convention, 
     * cp.: <code>{@link #getProject()}</code>.<p> 
     * 
     * @param projectName the name of the project used to index resources
     */
    public void setProject(String projectName) {

        setProjectName(projectName);
    }

    /**
     * Sets the name of the project used to index resources.<p>
     * 
     * @param projectName the name of the project used to index resources
     */
    public void setProjectName(String projectName) {

        m_project = projectName;
    }

    /**
     * Sets the rebuild mode of this search index.<p>
     * 
     * @param rebuildMode the rebuild mode of this search index {auto|manual}
     */
    public void setRebuildMode(String rebuildMode) {

        m_rebuild = rebuildMode;
    }

    /**
     * Returns the name (<code>{@link #getName()}</code>) of this search index.<p>
     *  
     * @return the name (<code>{@link #getName()}</code>) of this search index
     * 
     * @see java.lang.Object#toString()
     */
    public String toString() {

        return getName();
    }

    /**
     * Returns an excerpt of the given content related to the given search query.<p>
     * 
     * @param content the content
     * @param searchQuery the search query
     * @param analyzer the analyzer used 
     * 
     * @return an excerpt of the content
     * 
     * @throws IOException if something goes wrong
     */
    protected String getExcerpt(String content, Query searchQuery, Analyzer analyzer) throws IOException {

        if (content == null) {
            return null;
        }

        CmsHighlightFinder highlighter = new CmsHighlightFinder(
            OpenCms.getSearchManager().getHighlighter(),
            searchQuery,
            analyzer);

        String excerpt = highlighter.getBestFragments(
            content,
            EXCERPT_FRAGMENT_SIZE,
            EXCERPT_REQUIRED_FRAGMENTS,
            EXCERPT_FRAGMENT_SEPARATOR);

        // kill all unwanted chars in the excerpt
        excerpt = excerpt.replace('\t', ' ');
        excerpt = excerpt.replace('\n', ' ');
        excerpt = excerpt.replace('\r', ' ');
        excerpt = excerpt.replace('\f', ' ');

        int maxLength = OpenCms.getSearchManager().getMaxExcerptLength();
        if (excerpt != null && excerpt.length() > maxLength) {
            excerpt = excerpt.substring(0, maxLength);
        }

        return excerpt;
    }

    /**
     * Checks if the OpenCms resource referenced by the result document can be read 
     * be the user of the given OpenCms context.<p>
     * 
     * @param cms the OpenCms user context to use for permission testing
     * @param doc the search result document to check
     * @return <code>true</code> if the user has read permissions to the resource
     */
    protected boolean hasReadPermission(CmsObject cms, Document doc) {

        if (m_dontCheckPermissions) {
            // no permission check is performed at all
            return true;
        }

        Field typeField = doc.getField(I_CmsDocumentFactory.DOC_TYPE);
        Field pathField = doc.getField(I_CmsDocumentFactory.DOC_PATH);
        if ((typeField == null) || (pathField == null)) {
            // permission check needs only to be performed for VFS documents that contain both fields
            return true;
        }

        String rootPath = cms.getRequestContext().removeSiteRoot(pathField.stringValue());

        // check if the resource "exits", this will implicitly check read permission and if the resource was deleted
        return cms.existsResource(rootPath);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -