searchindex.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,046 行 · 第 1/3 页

JAVA
1,046
字号
     * @throws RepositoryException if an error occurs while indexing a node.     * @throws IOException         if an error occurs while updating the index.     */    public void updateNodes(NodeIdIterator remove, NodeStateIterator add)            throws RepositoryException, IOException {        checkOpen();        index.update(new AbstractIteratorDecorator(remove) {            public Object next() {                return ((NodeId) super.next()).getUUID();            }        }, new AbstractIteratorDecorator(add) {            public Object next() {                NodeState state = (NodeState) super.next();                if (state == null) {                    return null;                }                Document doc = null;                try {                    doc = createDocument(state, getNamespaceMappings());                } catch (RepositoryException e) {                    log.warn("Exception while creating document for node: "                            + state.getNodeId() + ": " + e.toString());                }                return doc;            }        });    }    /**     * Creates a new query by specifying the query statement itself and the     * language in which the query is stated.  If the query statement is     * syntactically invalid, given the language specified, an     * InvalidQueryException is thrown. <code>language</code> must specify a query language     * string from among those returned by QueryManager.getSupportedQueryLanguages(); if it is not     * then an <code>InvalidQueryException</code> is thrown.     *     * @param session the session of the current user creating the query object.     * @param itemMgr the item manager of the current user.     * @param statement the query statement.     * @param language the syntax of the query statement.     * @throws InvalidQueryException if statement is invalid or language is unsupported.     * @return A <code>Query</code> object.     */    public ExecutableQuery createExecutableQuery(SessionImpl session,                                             ItemManager itemMgr,                                             String statement,                                             String language)            throws InvalidQueryException {        QueryImpl query = new QueryImpl(session, itemMgr, this,                getContext().getPropertyTypeRegistry(), statement, language);        query.setRespectDocumentOrder(documentOrder);        return query;    }    /**     * Closes this <code>QueryHandler</code> and frees resources attached     * to this handler.     */    public void close() {        // shutdown extractor        if (extractor instanceof PooledTextExtractor) {            ((PooledTextExtractor) extractor).shutdown();        }        index.close();        getContext().destroy();        closed = true;        log.info("Index closed: " + path);    }    /**     * Executes the query on the search index.     * @param queryImpl the query impl.     * @param query the lucene query.     * @param orderProps name of the properties for sort order.     * @param orderSpecs the order specs for the sort order properties.     * <code>true</code> indicates ascending order, <code>false</code> indicates     * descending.     * @return the lucene Hits object.     * @throws IOException if an error occurs while searching the index.     */    public QueryHits executeQuery(QueryImpl queryImpl,                                  Query query,                                  QName[] orderProps,                                  boolean[] orderSpecs) throws IOException {        checkOpen();        SortField[] sortFields = createSortFields(orderProps, orderSpecs);        IndexReader reader = getIndexReader();        IndexSearcher searcher = new IndexSearcher(reader);        Hits hits;        if (sortFields.length > 0) {            hits = searcher.search(query, new Sort(sortFields));        } else {            hits = searcher.search(query);        }        return new QueryHits(hits, reader);    }    /**     * Creates an excerpt provider for the given <code>query</code>.     *     * @param query the query.     * @return an excerpt provider for the given <code>query</code>.     * @throws IOException if the provider cannot be created.     */    public ExcerptProvider createExcerptProvider(Query query)            throws IOException {        ExcerptProvider ep;        try {            ep = (ExcerptProvider) excerptProviderClass.newInstance();        } catch (Exception e) {            IOException ex = new IOException();            ex.initCause(e);            throw ex;        }        ep.init(query, this);        return ep;    }    /**     * Returns the analyzer in use for indexing.     * @return the analyzer in use for indexing.     */    public Analyzer getTextAnalyzer() {        return analyzer;    }    /**     * Returns the text extractor in use for indexing.     *     * @return the text extractor in use for indexing.     */    public TextExtractor getTextExtractor() {        return extractor;    }    /**     * Returns the namespace mappings for the internal representation.     * @return the namespace mappings for the internal representation.     */    public NamespaceMappings getNamespaceMappings() {        return index.getNamespaceMappings();    }    /**     * Returns an index reader for this search index. The caller of this method     * is responsible for closing the index reader when he is finished using     * it.     *     * @return an index reader for this search index.     * @throws IOException the index reader cannot be obtained.     */    public IndexReader getIndexReader() throws IOException {        QueryHandler parentHandler = getContext().getParentHandler();        IndexReader parentReader = null;        if (parentHandler instanceof SearchIndex) {            parentReader = ((SearchIndex) parentHandler).index.getIndexReader();        }        IndexReader reader = index.getIndexReader();        if (parentReader != null) {            // todo FIXME not type safe            CachingMultiReader[] readers = {(CachingMultiReader) reader,                                            (CachingMultiReader) parentReader};            reader = new CombinedIndexReader(readers);        }        return reader;    }    /**     * Creates the SortFields for the order properties.     *     * @param orderProps the order properties.     * @param orderSpecs the order specs for the properties.     * @return an array of sort fields     */    protected SortField[] createSortFields(QName[] orderProps,                                           boolean[] orderSpecs) {        List sortFields = new ArrayList();        for (int i = 0; i < orderProps.length; i++) {            String prop = null;            if (QName.JCR_SCORE.equals(orderProps[i])) {                // order on jcr:score does not use the natural order as                // implemented in lucene. score ascending in lucene means that                // higher scores are first. JCR specs that lower score values                // are first.                sortFields.add(new SortField(null, SortField.SCORE, orderSpecs[i]));            } else {                try {                    prop = NameFormat.format(orderProps[i], getNamespaceMappings());                } catch (NoPrefixDeclaredException e) {                    // will never happen                }                sortFields.add(new SortField(prop, SharedFieldSortComparator.PROPERTIES, !orderSpecs[i]));            }        }        return (SortField[]) sortFields.toArray(new SortField[sortFields.size()]);    }    /**     * Creates a lucene <code>Document</code> for a node state using the     * namespace mappings <code>nsMappings</code>.     *     * @param node       the node state to index.     * @param nsMappings the namespace mappings of the search index.     * @return a lucene <code>Document</code> that contains all properties of     *         <code>node</code>.     * @throws RepositoryException if an error occurs while indexing the     *                             <code>node</code>.     */    protected Document createDocument(NodeState node,                                      NamespaceMappings nsMappings)            throws RepositoryException {        NodeIndexer indexer = new NodeIndexer(node,                getContext().getItemStateManager(), nsMappings, extractor);        indexer.setSupportHighlighting(supportHighlighting);        return indexer.createDoc();    }    /**     * Returns the actual index.     *     * @return the actual index.     */    protected MultiIndex getIndex() {        return index;    }    /**     * Factory method to create the <code>TextExtractor</code> instance.     *     * @return the <code>TextExtractor</code> instance this index should use.     */    protected TextExtractor createTextExtractor() {        TextExtractor txtExtr = new JackrabbitTextExtractor(textFilterClasses);        if (extractorPoolSize > 0) {            // wrap with pool            txtExtr = new PooledTextExtractor(txtExtr, extractorPoolSize,                    extractorBackLog, extractorTimeout);        }        return txtExtr;    }    //----------------------------< internal >----------------------------------    /**     * Combines multiple {@link CachingMultiReader} into a <code>MultiReader</code>     * with {@link HierarchyResolver} support.     */    protected static final class CombinedIndexReader            extends MultiReader            implements HierarchyResolver, MultiIndexReader {        /**         * The sub readers.         */        final private CachingMultiReader[] subReaders;        /**         * Doc number starts for each sub reader         */        private int[] starts;        public CombinedIndexReader(CachingMultiReader[] indexReaders) throws IOException {            super(indexReaders);            this.subReaders = indexReaders;            this.starts = new int[subReaders.length + 1];            int maxDoc = 0;            for (int i = 0; i < subReaders.length; i++) {                starts[i] = maxDoc;                maxDoc += subReaders[i].maxDoc();            }            starts[subReaders.length] = maxDoc;        }        /**         * @inheritDoc         */        public int getParent(int n) throws IOException {            int i = readerIndex(n);            DocId id = subReaders[i].getParentDocId(n - starts[i]);            id = id.applyOffset(starts[i]);            return id.getDocumentNumber(this);        }        //-------------------------< MultiIndexReader >-------------------------        /**         * {@inheritDoc}         */        public IndexReader[] getIndexReaders() {            IndexReader readers[] = new IndexReader[subReaders.length];            System.arraycopy(subReaders, 0, readers, 0, subReaders.length);            return readers;        }        //---------------------------< internal >-------------------------------        /**         * Returns the reader index for document <code>n</code>.         * Implementation copied from lucene MultiReader class.         *         * @param n document number.         * @return the reader index.         */        private int readerIndex(int n) {            int lo = 0;                                      // search starts array            int hi = subReaders.length - 1;                  // for first element less            while (hi >= lo) {                int mid = (lo + hi) >> 1;                int midValue = starts[mid];                if (n < midValue) {                    hi = mid - 1;                } else if (n > midValue) {                    lo = mid + 1;                } else {                                      // found a match                    while (mid + 1 < subReaders.length && starts[mid + 1] == midValue) {                        mid++;                                  // scan to last match                    }                    return mid;                }            }            return hi;        }        public boolean equals(Object obj) {            if (obj instanceof CombinedIndexReader) {                CombinedIndexReader other = (CombinedIndexReader) obj;                return Arrays.equals(subReaders, other.subReaders);            }            return false;        }        public int hashCode() {            int hash = 0;            for (int i = 0; i < subReaders.length; i++) {                hash = 31 * hash + subReaders[i].hashCode();            }            return hash;        }    }    //--------------------------< properties >----------------------------------    /**     * Sets the analyzer in use for indexing. The given analyzer class name     * must satisfy the following conditions:

⌨️ 快捷键说明

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