001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.search.lucene;
016    
017    import java.io.IOException;
018    
019    import org.apache.lucene.index.IndexReader;
020    import org.apache.lucene.index.IndexWriter;
021    import org.apache.lucene.search.IndexSearcher;
022    import org.apache.lucene.store.AlreadyClosedException;
023    import org.apache.lucene.store.Directory;
024    
025    /**
026     * @author Tina Tian
027     * @author Shuyang Zhou
028     */
029    public class IndexSearcherManager {
030    
031            public IndexSearcherManager(Directory directory) throws IOException {
032                    _indexSearcher = _createIndexSearcher(
033                            IndexReader.open(directory, true));
034            }
035    
036            public IndexSearcherManager(IndexWriter writer) throws IOException {
037                    _indexSearcher = _createIndexSearcher(IndexReader.open(writer, true));
038            }
039    
040            public IndexSearcher acquire() throws IOException {
041                    if (_invalid) {
042                            synchronized (this) {
043                                    if (_invalid) {
044                                            IndexSearcher indexSearcher = _indexSearcher;
045    
046                                            if (indexSearcher == null) {
047                                                    throw new AlreadyClosedException(
048                                                            "Index searcher manager is closed");
049                                            }
050    
051                                            IndexReader newIndexReader = IndexReader.openIfChanged(
052                                                    indexSearcher.getIndexReader());
053    
054                                            if (newIndexReader != null) {
055                                                    _indexSearcher = _createIndexSearcher(newIndexReader);
056    
057                                                    release(indexSearcher);
058                                            }
059    
060                                            _invalid = false;
061                                    }
062                            }
063                    }
064    
065                    IndexSearcher indexSearcher = null;
066    
067                    while ((indexSearcher = _indexSearcher) != null) {
068                            IndexReader indexReader = indexSearcher.getIndexReader();
069    
070                            if (indexReader.tryIncRef()) {
071                                    return indexSearcher;
072                            }
073    
074                            if (indexSearcher == _indexSearcher) {
075                                    throw new IllegalStateException(
076                                            "Index reader was closed externally");
077                            }
078                    }
079    
080                    throw new AlreadyClosedException("Index searcher manager is closed");
081            }
082    
083            public synchronized void close() throws IOException {
084                    IndexSearcher indexSearcher = _indexSearcher;
085    
086                    _indexSearcher = null;
087    
088                    release(indexSearcher);
089            }
090    
091            public synchronized void invalidate() {
092                    _invalid = true;
093            }
094    
095            public void release(IndexSearcher indexSearcher) throws IOException {
096                    if (indexSearcher == null) {
097                            return;
098                    }
099    
100                    IndexReader indexReader = indexSearcher.getIndexReader();
101    
102                    indexReader.decRef();
103            }
104    
105            private IndexSearcher _createIndexSearcher(IndexReader indexReader) {
106                    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
107    
108                    indexSearcher.setDefaultFieldSortScoring(true, false);
109                    indexSearcher.setSimilarity(new FieldWeightSimilarity());
110    
111                    return indexSearcher;
112            }
113    
114            private volatile IndexSearcher _indexSearcher;
115            private volatile boolean _invalid;
116    
117    }