/*
* <p><b>License and Copyright: </b>The contents of this file is subject to the
* same open source license as the Fedora Repository System at www.fedora-commons.org
* Copyright © 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 by The Technical University of Denmark.
* All rights reserved.</p>
*/
package dk.defxws.fgssolr;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import javax.xml.transform.stream.StreamSource;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Version;
import dk.defxws.fedoragsearch.server.GTransformer;
import dk.defxws.fedoragsearch.server.GenericOperationsImpl;
import dk.defxws.fedoragsearch.server.errors.ConfigException;
import dk.defxws.fedoragsearch.server.errors.GenericSearchException;
/**
* performs the Solr specific parts of the operations
*
* @author gsp@dtv.dk
* @version
*/
public class OperationsImpl extends GenericOperationsImpl {
private static final Logger logger = Logger.getLogger(OperationsImpl.class);
public String gfindObjects(
String query,
int hitPageStart,
int hitPageSize,
int snippetsMax,
int fieldMaxLength,
String indexName,
String sortFields,
String resultPageXslt)
throws java.rmi.RemoteException {
super.gfindObjects(query, hitPageStart, hitPageSize, snippetsMax, fieldMaxLength, indexName, sortFields, resultPageXslt);
if ("".equals(usingQuery)) {
return embeddedResult.toString();
}
String usingIndexName = config.getIndexName(indexName);
if (srf != null && config.isSearchResultFilteringActive("presearch")) {
usingIndexName = srf.selectIndexNameForPresearch(fgsUserName, usingIndexName, fgsUserAttributes, config);
if (logger.isDebugEnabled())
logger.debug("gfindObjects presearch" +
" fgsUserName="+fgsUserName+
" usingIndexName="+usingIndexName);
}
if (srf != null && config.isSearchResultFilteringActive("insearch")) {
usingQuery = srf.rewriteQueryForInsearch(fgsUserName, usingIndexName, usingQuery, fgsUserAttributes, config);
if (logger.isDebugEnabled())
logger.debug("gfindObjects insearch" +
" fgsUserName="+fgsUserName+
" usingQuery="+usingQuery);
}
ResultSet resultSet = null;
try {
getIndexReaderAndSearcher(usingIndexName);
resultSet = (new Connection()).createStatement().executeQuery(
searcher,
usingQuery,
hitPageStart,
hitPageSize,
snippetsMax,
fieldMaxLength,
getQueryAnalyzer(usingIndexName),
config.getDefaultQueryFields(usingIndexName),
config.getIndexDir(usingIndexName),
usingIndexName,
config.getSnippetBegin(usingIndexName),
config.getSnippetEnd(usingIndexName),
config.getSortFields(usingIndexName, sortFields));
} catch (Exception e) {
throw new GenericSearchException("gfindObjects executeQuery error:\n" + e.toString());
} finally {
closeIndexReaderAndSearcher(usingIndexName);
}
params[12] = "RESULTPAGEXSLT";
params[13] = resultPageXslt;
String xsltPath = null;
try {
xsltPath = config.getConfigName()+"/index/"+usingIndexName+"/"+config.getGfindObjectsResultXslt(usingIndexName, resultPageXslt);
} catch (Exception e) {
throw new GenericSearchException("gfindObjects xsltPath error:\n" + e.toString());
}
if (logger.isDebugEnabled())
logger.debug("gfindObjects xsltPath=\n"+xsltPath+" resultSet="+resultSet);
StringBuffer resultXml = null;
try {
resultXml = (new GTransformer()).transform(
xsltPath,
resultSet.getResultXml(),
params);
} catch (Exception e) {
throw new GenericSearchException("gfindObjects transform error:\n" + e.toString());
}
if (srf != null && config.isSearchResultFilteringActive("postsearch")) {
resultXml = srf.filterResultsetForPostsearch(fgsUserName, resultXml, fgsUserAttributes, config);
if (logger.isDebugEnabled())
logger.debug("gfindObjects postsearch" +
" fgsUserName="+fgsUserName+
" resultXml=\n"+resultXml);
}
return resultXml.toString();
}
public String browseIndex(
String startTerm,
int termPageSize,
String fieldName,
String indexName,
String resultPageXslt)
throws java.rmi.RemoteException {
super.browseIndex(startTerm, termPageSize, fieldName, indexName, resultPageXslt);
StringBuffer resultXml = new StringBuffer();
optimize(indexName, resultXml);
int termNo = 0;
try {
getIndexReaderAndSearcher(indexName);
Fields fields;
try {
fields = MultiFields.getFields(ir);
} catch (Exception e) {
throw new GenericSearchException("MultiFields.getFields error:\n" + e.toString());
}
resultXml.append("<fields>");
if (fields != null) {
for(String field : fields) {
resultXml.append("<field>"+field+"</field>");
}
}
resultXml.append("</fields>");
resultXml.append("<terms>");
if (fields != null && fieldName != null && fieldName.length()>0) {
int pageSize = 0;
Terms terms;
try {
terms = fields.terms(fieldName);
} catch (Exception e) {
throw new GenericSearchException("fields.terms error:\n" + e.toString());
}
TermsEnum termsEnum;
try {
termsEnum = terms.iterator(null);
} catch (Exception e) {
throw new GenericSearchException("terms.iterator error:\n" + e.toString());
}
BytesRef text;
try {
while((text = termsEnum.next()) != null) {
termNo++;
String termString = text.utf8ToString();
if (startTerm.compareTo(termString) <= 0 && pageSize < termPageSize) {
pageSize++;
resultXml.append("<term no=\""+termNo+"\""
+" fieldtermhittotal=\""+termsEnum.docFreq()
+"\">"+encode(termString)+"</term>");
}
}
} catch (Exception e) {
throw new GenericSearchException("termsEnum.next error:\n" + e.toString());
}
}
resultXml.append("</terms>");
} catch (IOException e) {
throw new GenericSearchException("IndexReader open error:\n" + e.toString());
} finally {
closeIndexReaderAndSearcher(indexName);
}
resultXml.insert(0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<solrbrowseindex "+
" xmlns:dc=\"http://purl.org/dc/elements/1.1/"+
"\" startTerm=\""+encode(startTerm)+
"\" termPageSize=\""+termPageSize+
"\" fieldName=\""+fieldName+
"\" indexName=\""+indexName+
"\" termTotal=\""+termNo+"\">");
resultXml.append("</solrbrowseindex>");
if (logger.isDebugEnabled())
logger.debug("resultXml="+resultXml);
params[10] = "RESULTPAGEXSLT";
params[11] = resultPageXslt;
String xsltPath = config.getConfigName()+"/index/"+config.getIndexName(indexName)+"/"+config.getBrowseIndexResultXslt(indexName, resultPageXslt);
StringBuffer sb = (new GTransformer()).transform(
xsltPath,
resultXml,
params);
return sb.toString();
}
public String getIndexInfo(
String indexName,
String resultPageXslt)
throws java.rmi.RemoteException {
super.getIndexInfo(indexName, resultPageXslt);
InputStream infoStream = null;
String indexInfoPath = "/"+config.getConfigName()+"/index/"+config.getIndexName(indexName)+"/indexInfo.xml";
try {
infoStream = OperationsImpl.class.getResourceAsStream(indexInfoPath);
if (infoStream == null) {
throw new GenericSearchException("Error "+indexInfoPath+" not found in classpath");
}
} catch (IOException e) {
throw new GenericSearchException("Error "+indexInfoPath+" not found in classpath", e);
}
String xsltPath = config.getConfigName()+"/index/"+config.getIndexName(indexName)+"/"+config.getIndexInfoResultXslt(indexName, resultPageXslt);
StringBuffer sb = (new GTransformer()).transform(
xsltPath,
new StreamSource(infoStream),
new String[] {});
return sb.toString();
}
public String updateIndex(
String action,
String value,
String repositoryName,
String indexName,
String indexDocXslt,
String resultPageXslt)
throws java.rmi.RemoteException {
insertTotal = 0;
updateTotal = 0;
deleteTotal = 0;
emptyTotal = 0;
int initDocCount = 0;
StringBuffer resultXml = new StringBuffer();
resultXml.append("<solrUpdateIndex");
resultXml.append(" indexName=\""+indexName+"\"");
resultXml.append(">\n");
try {
getIndexReaderAndSearcher(indexName);
initDocCount = docCount;
if ("createEmpty".equals(action)) {
createEmpty(indexName, resultXml);
initDocCount = 0;
}
else {
if ("deletePid".equals(action))
deletePid(value, indexName, resultXml);
else {
if ("fromPid".equals(action))
fromPid(value, repositoryName, indexName, resultXml, indexDocXslt);
else {
if ("fromFoxmlFiles".equals(action))
fromFoxmlFiles(value, repositoryName, indexName, resultXml, indexDocXslt);
else
if ("optimize".equals(action))
optimize(indexName, resultXml);
}
}
}
} finally {
closeIndexReaderAndSearcher(indexName);
docCount = initDocCount + insertTotal - deleteTotal;
}
logger.info("updateIndex "+action+" indexName="+indexName
+" indexDirSpace="+indexDirSpace(new File(config.getIndexDir(indexName)))
+" docCount="+docCount);
resultXml.append("<counts");
resultXml.append(" insertTotal=\""+insertTotal+"\"");
resultXml.append(" updateTotal=\""+updateTotal+"\"");
resultXml.append(" deleteTotal=\""+deleteTotal+"\"");
resultXml.append(" emptyTotal=\""+emptyTotal+"\"");
resultXml.append(" docCount=\""+docCount+"\"");
resultXml.append(" warnCount=\""+warnCount+"\"");
resultXml.append("/>\n");
resultXml.append("</solrUpdateIndex>\n");
if (logger.isDebugEnabled())
logger.debug("resultXml =\n"+resultXml.toString());
params = new String[12];
params[0] = "OPERATION";
params[1] = "updateIndex";
params[2] = "ACTION";
params[3] = action;
params[4] = "VALUE";
params[5] = value;
params[6] = "REPOSITORYNAME";
params[7] = repositoryName;
params[8] = "INDEXNAME";
params[9] = indexName;
params[10] = "RESULTPAGEXSLT";
params[11] = resultPageXslt;
String xsltPath = config.getConfigName()+"/index/"+config.getIndexName(indexName)+"/"+config.getUpdateIndexResultXslt(indexName, resultPageXslt);
StringBuffer sb = (new GTransformer()).transform(
xsltPath,
resultXml,
params);
return sb.toString();
}
private void createEmpty(
String indexName,
StringBuffer resultXml)
throws java.rmi.RemoteException {
throw new GenericSearchException("createEmpty: Stop solr, remove the index dir, restart solr");
}
private void deletePid(
String pid,
String indexName,
StringBuffer resultXml)
throws java.rmi.RemoteException {
if (logger.isDebugEnabled())
logger.debug("deletePid indexName="+indexName+" pid="+pid);
if (pid.length()>0) {
boolean existed = indexDocExists(pid);
StringBuffer sb = new StringBuffer("<delete><id>"+pid+"</id></delete>");
postData(config.getIndexBase(indexName)+"/update", new StringReader(sb.toString()), resultXml);
if (existed) {
deleteTotal++;
docCount--;
}
resultXml.append("<deletePid pid=\""+pid+"\"/>\n");
}
}
private void optimize(
String indexName,
StringBuffer resultXml)
throws java.rmi.RemoteException {
StringBuffer sb = new StringBuffer("<optimize/>");
postData(config.getIndexBase(indexName)+"/update", new StringReader(sb.toString()), resultXml);
if (logger.isDebugEnabled())
logger.debug("optimize indexName="+indexName);
resultXml.append("<optimize/>\n");
}
private void fromFoxmlFiles(
String filePath,
String repositoryName,
String indexName,
StringBuffer resultXml,
String indexDocXslt)
throws java.rmi.RemoteException {
if (logger.isDebugEnabled())
logger.debug("fromFoxmlFiles filePath="+filePath+" repositoryName="+repositoryName+" indexName="+indexName);
File objectDir = null;
if (filePath==null || filePath.equals(""))
objectDir = config.getFedoraObjectDir(repositoryName);
else objectDir = new File(filePath);
indexDocs(objectDir, repositoryName, indexName, resultXml, indexDocXslt);
}
private void indexDocs(
File file,
String repositoryName,
String indexName,
StringBuffer resultXml,
String indexDocXslt)
throws java.rmi.RemoteException
{
if (file.isHidden()) return;
if (file.isDirectory())
{
String[] files = file.list();
for (int i = 0; i < files.length; i++) {
if (i % 100 == 0)
logger.info("updateIndex fromFoxmlFiles "+file.getAbsolutePath()
+" indexDirSpace="+indexDirSpace(new File(config.getIndexDir(indexName)))
+" docCount="+docCount);
indexDocs(new File(file, files[i]), repositoryName, indexName, resultXml, indexDocXslt);
}
}
else
{
try {
indexDoc(getPidFromObjectFilename(file.getName()), repositoryName, indexName, new FileInputStream(file), resultXml, indexDocXslt);
} catch (RemoteException e) {
resultXml.append("<warning no=\""+(++warnCount)+"\">file="+file.getAbsolutePath()+" exception="+e.toString()+"</warning>\n");
logger.warn("<warning no=\""+(warnCount)+"\">file="+file.getAbsolutePath()+" exception="+e.toString()+"</warning>");
} catch (FileNotFoundException e) {
resultXml.append("<warning no=\""+(++warnCount)+"\">file="+file.getAbsolutePath()+" exception="+e.toString()+"</warning>\n");
logger.warn("<warning no=\""+(warnCount)+"\">file="+file.getAbsolutePath()+" exception="+e.toString()+"</warning>");
}
}
}
private void fromPid(
String pid,
String repositoryName,
String indexName,
StringBuffer resultXml,
String indexDocXslt)
throws java.rmi.RemoteException {
if (pid==null || pid.length()<1) return;
getFoxmlFromPid(pid, repositoryName);
indexDoc(pid, repositoryName, indexName, new ByteArrayInputStream(foxmlRecord), resultXml, indexDocXslt);
}
private void indexDoc(
String pid,
String repositoryName,
String indexName,
InputStream foxmlStream,
StringBuffer resultXml,
String indexDocXslt)
throws java.rmi.RemoteException {
String xsltName = indexDocXslt;
String[] params = new String[12];
int beginParams = indexDocXslt.indexOf("(");
if (beginParams > -1) {
xsltName = indexDocXslt.substring(0, beginParams).trim();
int endParams = indexDocXslt.indexOf(")");
if (endParams < beginParams)
throw new GenericSearchException("Format error (no ending ')') in indexDocXslt="+indexDocXslt+": ");
StringTokenizer st = new StringTokenizer(indexDocXslt.substring(beginParams+1, endParams), ",");
params = new String[12+2*st.countTokens()];
int i=1;
while (st.hasMoreTokens()) {
String param = st.nextToken().trim();
if (param==null || param.length()<1)
throw new GenericSearchException("Format error (empty param) in indexDocXslt="+indexDocXslt+" params["+i+"]="+param);
int eq = param.indexOf("=");
if (eq < 0)
throw new GenericSearchException("Format error (no '=') in indexDocXslt="+indexDocXslt+" params["+i+"]="+param);
String pname = param.substring(0, eq).trim();
String pvalue = param.substring(eq+1).trim();
if (pname==null || pname.length()<1)
throw new GenericSearchException("Format error (no param name) in indexDocXslt="+indexDocXslt+" params["+i+"]="+param);
if (pvalue==null || pvalue.length()<1)
throw new GenericSearchException("Format error (no param value) in indexDocXslt="+indexDocXslt+" params["+i+"]="+param);
params[10+2*i] = pname;
params[11+2*i++] = pvalue;
}
}
params[0] = "REPOSITORYNAME";
params[1] = repositoryName;
params[2] = "FEDORASOAP";
params[3] = config.getFedoraSoap(repositoryName);
params[4] = "FEDORAUSER";
params[5] = config.getFedoraUser(repositoryName);
params[6] = "FEDORAPASS";
params[7] = config.getFedoraPass(repositoryName);
params[8] = "TRUSTSTOREPATH";
params[9] = config.getTrustStorePath(repositoryName);
params[10] = "TRUSTSTOREPASS";
params[11] = config.getTrustStorePass(repositoryName);
String xsltPath = config.getConfigName()+"/index/"+indexName+"/"+config.getUpdateIndexDocXslt(indexName, xsltName);
StringBuffer sb = (new GTransformer()).transform(
xsltPath,
new StreamSource(foxmlStream),
config.getURIResolver(indexName),
params);
if (logger.isDebugEnabled())
logger.debug("indexDoc=\n"+sb.toString());
if (sb.indexOf("</field>") > 0) { // skip if no fields
postData(config.getIndexBase(indexName)+"/update", new StringReader(sb.toString()), resultXml);
if (indexDocExists(pid)) {
updateTotal++;
resultXml.append("<updated>"+pid+"</updated>\n");
} else {
insertTotal++;
docCount++;
resultXml.append("<inserted>"+pid+"</inserted>\n");
}
logger.info("IndexDocument="+pid+" insertTotal="+insertTotal+" updateTotal="+updateTotal+" deleteTotal="+deleteTotal+" emptyTotal="+emptyTotal+" warnCount="+warnCount+" docCount="+docCount);
}
else {
deletePid(pid, indexName, resultXml);
logger.warn("IndexDocument "+pid+" does not contain any IndexFields!!! RepositoryName="+repositoryName+" IndexName="+indexName);
emptyTotal++;
}
}
public Analyzer getAnalyzer(String indexName)
throws GenericSearchException {
return getAnalyzer(indexName, "");
}
public Analyzer getAnalyzer(String indexName, String className)
throws GenericSearchException {
String analyzerClassName = className;
if (analyzerClassName.length()==0) {
analyzerClassName= config.getAnalyzer(indexName);
}
String stopwordsLocation = config.getStopwordsLocation(indexName);
if (logger.isDebugEnabled())
logger.debug("getAnalyzer analyzerClassName=" + analyzerClassName+ " stopwordsLocation="+stopwordsLocation);
Analyzer analyzer = null;
if ("org.apache.lucene.analysis.KeywordAnalyzer".equals(analyzerClassName)) {
analyzer = new KeywordAnalyzer();
} else {
try {
Version version = Version.LUCENE_42;
Class analyzerClass = Class.forName(analyzerClassName);
if (logger.isDebugEnabled())
logger.debug("getAnalyzer analyzerClass=" + analyzerClass.toString());
if (stopwordsLocation == null || stopwordsLocation.equals("")) {
analyzer = (Analyzer) analyzerClass.getConstructor(new Class[] { Version.class})
.newInstance(new Object[] { version });
} else {
analyzer = (Analyzer) analyzerClass.getConstructor(new Class[] { Version.class, File.class})
.newInstance(new Object[] { version, new File(stopwordsLocation) });
}
} catch (Exception e) {
throw new GenericSearchException(analyzerClassName
+ ": instantiation error.\n", e);
}
}
if (logger.isDebugEnabled())
logger.debug("getAnalyzer analyzer=" + analyzer.toString());
return analyzer;
}
public Analyzer getQueryAnalyzer(String indexName)
throws GenericSearchException {
if (logger.isDebugEnabled())
logger.debug("getQueryAnalyzer indexName=" + indexName);
Analyzer analyzer = getAnalyzer(indexName);
Map<String,Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
String configFieldAnalyzers = "";
try {
configFieldAnalyzers = config.getFieldAnalyzers(indexName);
} catch (Exception e) {
throw new ConfigException("getQueryAnalyzer config.getFieldAnalyzers "+" :\n", e);
}
if (logger.isDebugEnabled())
logger.debug("getQueryAnalyzer configFieldAnalyzers=" + configFieldAnalyzers);
if (configFieldAnalyzers != null && configFieldAnalyzers.length()>0) {
StringTokenizer stConfigFieldAnalyzers = new StringTokenizer(configFieldAnalyzers);
while (stConfigFieldAnalyzers.hasMoreElements()) {
String fieldAnalyzer = stConfigFieldAnalyzers.nextToken();
if (logger.isDebugEnabled())
logger.debug("getQueryAnalyzer fieldAnalyzer=" + fieldAnalyzer);
int i = fieldAnalyzer.indexOf("::");
if (i<0) {
throw new ConfigException("getQueryAnalyzer fgsindex.fieldAnalyzer="+fieldAnalyzer+ " missing '::'");
}
String fieldName = "-";
String analyzerClassName = "-";
try {
fieldName = fieldAnalyzer.substring(0, i);
analyzerClassName = fieldAnalyzer.substring(i+2);
fieldAnalyzers.put(fieldName, getAnalyzer(indexName, analyzerClassName));
} catch (Exception e) {
throw new ConfigException("getQueryAnalyzer getAnalyzer fieldName="+fieldName+" analyzerClassName="+analyzerClassName+" :\n", e);
}
}
}
StringTokenizer untokenizedFields = new StringTokenizer(config.getUntokenizedFields(indexName));
while (untokenizedFields.hasMoreElements()) {
String fieldName = untokenizedFields.nextToken();
if (!fieldAnalyzers.containsKey(fieldName)) {
fieldAnalyzers.put(fieldName, new KeywordAnalyzer());
}
}
PerFieldAnalyzerWrapper pfanalyzer = new PerFieldAnalyzerWrapper(analyzer, fieldAnalyzers);
if (logger.isDebugEnabled())
logger.debug("getQueryAnalyzer indexName=" + indexName+ " untokenizedFields="+untokenizedFields);
return pfanalyzer;
}
/**
* Reads data from the data reader and posts it to solr,
* writes the response to output
*/
private void postData(String solrUrlString, Reader data, StringBuffer output)
throws GenericSearchException {
URL solrUrl = null;
try {
solrUrl = new URL(solrUrlString);
} catch (MalformedURLException e) {
throw new GenericSearchException("solrUrl="+solrUrlString+": ", e);
}
HttpURLConnection urlc = null;
String POST_ENCODING = "UTF-8";
try {
urlc = (HttpURLConnection) solrUrl.openConnection();
try {
urlc.setRequestMethod("POST");
} catch (ProtocolException e) {
throw new GenericSearchException("Shouldn't happen: HttpURLConnection doesn't support POST??", e);
}
urlc.setDoOutput(true);
urlc.setDoInput(true);
urlc.setUseCaches(false);
urlc.setAllowUserInteraction(false);
urlc.setRequestProperty("Content-type", "text/xml; charset=" + POST_ENCODING);
OutputStream out = urlc.getOutputStream();
try {
Writer writer = new OutputStreamWriter(out, POST_ENCODING);
pipe(data, writer);
writer.close();
} catch (IOException e) {
throw new GenericSearchException("IOException while posting data", e);
} finally {
if(out!=null) out.close();
}
InputStream in = urlc.getInputStream();
int status = urlc.getResponseCode();
StringBuffer errorStream = new StringBuffer();
try {
if (status!=HttpURLConnection.HTTP_OK) {
errorStream.append("postData URL="+solrUrlString+" HTTP response code="+status+" ");
throw new GenericSearchException("URL="+solrUrlString+" HTTP response code="+status);
}
Reader reader = new InputStreamReader(in);
pipeString(reader, output);
reader.close();
} catch (IOException e) {
throw new GenericSearchException("IOException while reading response", e);
} finally {
if(in!=null) in.close();
}
InputStream es = urlc.getErrorStream();
if (es != null) {
try {
Reader reader = new InputStreamReader(es);
pipeString(reader, errorStream);
reader.close();
} catch (IOException e) {
throw new GenericSearchException("IOException while reading response", e);
} finally {
if(es!=null) es.close();
}
}
if (errorStream.length()>0) {
throw new GenericSearchException("postData error: " + errorStream.toString());
}
} catch (IOException e) {
throw new GenericSearchException("Connection error (is Solr running at " + solrUrl + " ?): " + e);
} finally {
if(urlc!=null) urlc.disconnect();
}
}
/**
* Pipes everything from the reader to the writer via a buffer
*/
private static void pipe(Reader reader, Writer writer) throws IOException {
char[] buf = new char[1024];
int read = 0;
while ( (read = reader.read(buf) ) >= 0) {
writer.write(buf, 0, read);
}
writer.flush();
}
/**
* Pipes everything from the reader to the writer via a buffer
* except lines starting with '<?'
*/
private static void pipeString(Reader reader, StringBuffer writer) throws IOException {
char[] buf = new char[1024];
int read = 0;
while ( (read = reader.read(buf) ) >= 0) {
if (!(buf[0]=='<' && buf[1]=='?'))
writer.append(buf, 0, read);
}
}
private void getIndexReaderAndSearcher(String indexName)
throws GenericSearchException {
DirectoryReader irreopened = null;
if (ir != null) {
try {
irreopened = DirectoryReader.openIfChanged(ir);
} catch (Exception e) {
throw new GenericSearchException("IndexReader reopen error indexName=" + indexName+ " :\n", e);
}
if (null != irreopened){
try {
ir.close();
} catch (Exception e) {
ir = null;
try {
irreopened.close();
} catch (Exception e1) {
}
throw new GenericSearchException("IndexReader close after reopen error indexName=" + indexName+ " :\n", e);
}
ir = irreopened;
}
} else {
try {
closeIndexReaderAndSearcher(indexName);
Directory dir = new SimpleFSDirectory(new File(config.getIndexDir(indexName)));
ir = DirectoryReader.open(dir);
} catch (Exception e) {
throw new GenericSearchException("IndexReader open error indexName=" + indexName+ " :\n", e);
}
searcher = new IndexSearcher(ir);
}
docCount = ir.numDocs();
if (logger.isDebugEnabled())
logger.debug("getIndexReaderAndSearcher indexName=" + indexName+ " docCount=" + docCount);
}
private void closeIndexReaderAndSearcher(String indexName)
throws GenericSearchException {
searcher = null;
if (ir != null) {
docCount = ir.numDocs();
try {
ir.close();
} catch (Exception e) {
throw new GenericSearchException("IndexReader close error indexName=" + indexName+ " :\n", e);
} finally {
ir = null;
if (logger.isDebugEnabled())
logger.debug("closeIndexReader indexName=" + indexName+ " docCount=" + docCount);
}
}
}
private long indexDirSpace(File dir) {
long ids = 0;
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
File f = files[i];
if (f.isDirectory()) {
ids += indexDirSpace(f);
} else {
ids += f.length();
}
}
return ids;
}
}