blob: c2328df433ae9549ae28a255b60ae5c656fbb36d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.stanbol.enhancer.engines.lucenefstlinking;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.index.IndexReader;
import org.apache.solr.core.SolrCore;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.RefCounted;
import org.opensextant.solrtexttagger.TaggerFstCorpus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Runtime creation of FST corpora is done as {@link Callable}. This allows
* users to decide by the configuration of the {@link ExecutorService} to
* control how Corpora are build (e.g. how many can be built at a time.
* @author Rupert Westenthaler
*
*/
public class CorpusCreationTask implements Callable<TaggerFstCorpus>{
private final Logger log = LoggerFactory.getLogger(CorpusCreationTask.class);
private final CorpusInfo fstInfo;
private final IndexConfiguration indexConfig;
public CorpusCreationTask(IndexConfiguration indexConfig, CorpusInfo fstInfo){
if(indexConfig == null || fstInfo == null){
throw new IllegalArgumentException("Pared parameters MUST NOT be NULL!");
}
this.indexConfig = indexConfig;
this.fstInfo = fstInfo;
}
@Override
public TaggerFstCorpus call() {
if(!indexConfig.isActive()){
String msg = "Index Configuration already deactivated";
fstInfo.setError(msg);
throw new IllegalStateException(msg);
}
SolrCore core = indexConfig.getIndex();
if(core.isClosed()){
String msg = "Unable to build " + fstInfo + " becuase SolrCore " + core.getName() + " is closed!";
fstInfo.setError(msg);
throw new IllegalStateException(msg);
}
final TaggerFstCorpus corpus;
RefCounted<SolrIndexSearcher> searcherRef = core.getSearcher();
try { //STANBOL-1177: create FST models in AccessController.doPrivileged(..)
final SolrIndexSearcher searcher = searcherRef.get();
//we do get the AtomicReader, because TaggerFstCorpus will need it
//anyways. This prevents to create another SlowCompositeReaderWrapper.
final IndexReader reader = searcher.getAtomicReader();
log.info(" ... build FST corpus for {}",fstInfo);
corpus = AccessController.doPrivileged(new PrivilegedExceptionAction<TaggerFstCorpus>() {
public TaggerFstCorpus run() throws IOException {
return new TaggerFstCorpus(reader, searcher.getIndexReader().getVersion(),
null, fstInfo.indexedField, fstInfo.storedField, fstInfo.analyzer,
fstInfo.partialMatches,1,100);
}
});
if(indexConfig.isActive()){
//set the created corpus to the FST Info
fstInfo.setCorpus(corpus);
} else { //index configuration no longer active ... ignore the built FST
log.warn("Index Config for "+ fstInfo + "was deactivated while building FST. "
+ "Built FST will be ignored.");
}
return corpus;
} catch (PrivilegedActionException pae) {
Exception e = pae.getException();
if(e instanceof IOException){ //IO Exception while loading the file
throw new IllegalStateException("Unable to read Information to build "
+ fstInfo + " from SolrIndex '" + core.getName() + "'!", e);
} else { //Runtime exception
throw RuntimeException.class.cast(e);
}
} finally {
searcherRef.decref(); //ensure that we dereference the searcher
}
}
@Override
public String toString() {
return new StringBuilder("Task: building ").append(fstInfo)
.append(" for SolrCore ").append(indexConfig.getIndex().getName()).toString();
}
}