org.modeshape.jcr.query.lucene.LuceneProcessingContext Maven / Gradle / Ivy
/*
* ModeShape (http://www.modeshape.org)
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
* See the AUTHORS.txt file in the distribution for a full listing of
* individual contributors.
*
* ModeShape is free software. Unless otherwise indicated, all code in ModeShape
* is licensed to you under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* ModeShape is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.modeshape.jcr.query.lucene;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.hibernate.search.SearchFactory;
import org.modeshape.common.annotation.ThreadSafe;
import org.modeshape.common.logging.Logger;
import org.modeshape.jcr.JcrI18n;
import org.modeshape.jcr.query.QueryContext;
@ThreadSafe
public class LuceneProcessingContext {
private final String repositoryName;
private final SearchFactory searchFactory;
private final Map readerByIndexName = new HashMap();
private final Map searcherByIndexName = new HashMap();
private final Lock lock = new ReentrantLock();
private final QueryContext queryContext;
private final LuceneQueryFactory queryFactory;
protected LuceneProcessingContext( QueryContext queryContext,
String repositoryName,
SearchFactory searchFactory,
LuceneSchema schema ) {
assert queryContext != null;
assert searchFactory != null;
assert repositoryName != null;
this.queryContext = queryContext;
this.searchFactory = searchFactory;
this.repositoryName = repositoryName;
this.queryFactory = schema.createLuceneQueryFactory(queryContext, searchFactory);
}
/**
* @return queryContext
*/
public QueryContext getQueryContext() {
return queryContext;
}
/**
* @return queryFactory
*/
public LuceneQueryFactory getQueryFactory() {
return queryFactory;
}
/**
* Return the name of each workspace to be queried, or an empty set if all the workspaces should be queried.
*
* @return workspaceNames the workspace names; never null
*/
public Set getWorkspaceNames() {
return queryContext.getWorkspaceNames();
}
/**
* @return repositoryName
*/
public String getRepositoryName() {
return repositoryName;
}
/**
* Get an IndexReader for the Lucene index with the supplied name. Note that this method is thread-safe such that there will
* only be one IndexReader instance for a given named index.
*
* @param indexName the name of the index; may not be null
* @return the IndexReader; never null
* @throws LuceneException if the index manager to which the named index belongs failed to start
*/
public IndexReader getReader( String indexName ) throws LuceneException {
assert indexName != null;
IndexReader reader = readerByIndexName.get(indexName);
if (reader == null) {
try {
lock.lock();
reader = readerByIndexName.get(indexName);
if (reader == null) {
try {
reader = searchFactory.getIndexReaderAccessor().open(indexName);
} catch (org.hibernate.search.SearchException e) {
throw new LuceneException(e);
}
readerByIndexName.put(indexName, reader);
}
} finally {
lock.unlock();
}
}
return reader;
}
/**
* Get an IndexSearcher for the Lucene index with the supplied name. Note that this method is thread-safe such that there will
* only be one IndexSearcher instance (and underlying IndexSearcher instance) for a given named index.
*
* @param indexName the name of the index; may not be null
* @return the IndexSearcher; never null
* @throws LuceneException if the index manager to which the named index belongs failed to start
*/
public IndexSearcher getSearcher( String indexName ) throws LuceneException {
IndexSearcher searcher = searcherByIndexName.get(indexName);
if (searcher == null) {
try {
lock.lock();
searcher = searcherByIndexName.get(indexName);
if (searcher == null) {
searcher = new IndexSearcher(getReader(indexName));
searcherByIndexName.put(indexName, searcher);
}
} finally {
lock.unlock();
}
}
return searcher;
}
/**
* Close all of the readers and searchers that are associated with this processing context.
*/
public void close() {
// Make sure we always attempt to close all readers even if there is a problem with one of them ...
RuntimeException firstError = null;
try {
lock.lock();
for (Map.Entry entry : readerByIndexName.entrySet()) {
String indexName = entry.getKey();
IndexReader reader = entry.getValue();
assert reader != null;
try {
searchFactory.getIndexReaderAccessor().close(reader);
} catch (RuntimeException e) {
if (firstError == null) firstError = e;
Logger.getLogger(getClass()).error(firstError,
JcrI18n.errorClosingLuceneReaderForIndex,
repositoryName,
indexName);
}
}
readerByIndexName.clear();
searcherByIndexName.clear();
} finally {
lock.unlock();
}
if (firstError != null) throw firstError;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy