19 package org.sleuthkit.autopsy.keywordsearch;
 
   21 import java.awt.event.ActionEvent;
 
   22 import java.beans.PropertyChangeListener;
 
   23 import java.io.BufferedReader;
 
   24 import java.io.BufferedWriter;
 
   26 import java.io.FileOutputStream;
 
   27 import java.io.IOException;
 
   28 import java.io.InputStream;
 
   29 import java.io.InputStreamReader;
 
   30 import java.io.OutputStream;
 
   31 import java.io.OutputStreamWriter;
 
   32 import java.net.ConnectException;
 
   33 import java.net.ServerSocket;
 
   34 import java.net.SocketException;
 
   35 import java.nio.charset.Charset;
 
   36 import java.nio.file.Files;
 
   37 import java.nio.file.Path;
 
   38 import java.nio.file.Paths;
 
   39 import java.util.ArrayList;
 
   40 import java.util.Arrays;
 
   41 import java.util.Collection;
 
   42 import java.util.List;
 
   43 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
   44 import java.util.logging.Level;
 
   45 import javax.swing.AbstractAction;
 
   46 import org.apache.solr.client.solrj.SolrQuery;
 
   47 import org.apache.solr.client.solrj.SolrRequest;
 
   48 import org.apache.solr.client.solrj.SolrServerException;
 
   49 import org.apache.solr.client.solrj.impl.HttpSolrServer;
 
   50 import org.apache.solr.client.solrj.impl.XMLResponseParser;
 
   51 import org.apache.solr.client.solrj.request.CoreAdminRequest;
 
   52 import org.apache.solr.client.solrj.response.CoreAdminResponse;
 
   53 import org.apache.solr.client.solrj.response.QueryResponse;
 
   54 import org.apache.solr.client.solrj.response.TermsResponse;
 
   55 import org.apache.solr.common.SolrDocument;
 
   56 import org.apache.solr.common.SolrDocumentList;
 
   57 import org.apache.solr.common.SolrException;
 
   58 import org.apache.solr.common.SolrInputDocument;
 
   59 import org.apache.solr.common.util.NamedList;
 
   60 import org.openide.modules.InstalledFileLocator;
 
   61 import org.openide.modules.Places;
 
   62 import org.openide.util.NbBundle;
 
   85             public String toString() {
 
   91             public String toString() {
 
   98             public String toString() {
 
  104             public String toString() {
 
  105                 return "content_str"; 
 
  110             public String toString() {
 
  116             public String toString() {
 
  122             public String toString() {
 
  129             public String toString() {
 
  136             public String toString() {
 
  143             public String toString() {
 
  150             public String toString() {
 
  156             public String toString() {
 
  162             public String toString() {
 
  180     static final String PROPERTIES_FILE = KeywordSearchSettings.MODULE_NAME;
 
  181     static final String PROPERTIES_CURRENT_SERVER_PORT = 
"IndexingServerPort"; 
 
  182     static final String PROPERTIES_CURRENT_STOP_PORT = 
"IndexingServerStopPort"; 
 
  183     private static final String 
KEY = 
"jjk#09s"; 
 
  184     static final String DEFAULT_SOLR_SERVER_HOST = 
"localhost"; 
 
  185     static final int DEFAULT_SOLR_SERVER_PORT = 23232;
 
  186     static final int DEFAULT_SOLR_STOP_PORT = 34343;
 
  189     private static final boolean DEBUG = 
false;
 
  190    private static final String 
SOLR = 
"solr";
 
  220         this.localSolrServer = 
new HttpSolrServer(
"http://localhost:" + currentSolrServerPort + 
"/solr"); 
 
  221         serverAction = 
new ServerAction();
 
  222         solrFolder = InstalledFileLocator.getDefault().locate(
"solr", 
Server.class.getPackage().getName(), 
false); 
 
  226         if (!solrHome.toFile().exists()) {
 
  228                 Files.createDirectory(solrHome);
 
  229                 Files.copy(Paths.get(solrFolder.getAbsolutePath(), 
"solr", 
"solr.xml"), solrHome.resolve(
"solr.xml")); 
 
  230                 Files.copy(Paths.get(solrFolder.getAbsolutePath(), 
"solr", 
"zoo.cfg"), solrHome.resolve(
"zoo.cfg")); 
 
  231             } 
catch (IOException ex) {
 
  232                 logger.log(Level.SEVERE, 
"Failed to create Solr home folder:", ex); 
 
  235         currentCoreLock = 
new ReentrantReadWriteLock(
true);
 
  237         logger.log(Level.INFO, 
"Created Server instance using Java at {0}", javaPath); 
 
  245             } 
catch (NumberFormatException nfe) {
 
  246                 logger.log(Level.WARNING, 
"Could not decode indexing server port, value was not a valid port number, using the default. ", nfe); 
 
  247                 currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
 
  250             currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
 
  257             } 
catch (NumberFormatException nfe) {
 
  258                 logger.log(Level.WARNING, 
"Could not decode indexing server stop port, value was not a valid port number, using default", nfe); 
 
  259                 currentSolrStopPort = DEFAULT_SOLR_STOP_PORT;
 
  262             currentSolrStopPort = DEFAULT_SOLR_STOP_PORT;
 
  268     public void finalize() throws java.lang.Throwable {
 
  274         serverAction.addPropertyChangeListener(l);
 
  277     int getCurrentSolrServerPort() {
 
  281     int getCurrentSolrStopPort() {
 
  292         volatile boolean doRun = 
true;
 
  295             this.stream = stream;
 
  297                 final String log = Places.getUserDirectory().getAbsolutePath()
 
  298                         + 
File.separator + 
"var" + 
File.separator + 
"log"  
  299                         + 
File.separator + 
"solr.log." + type; 
 
  300                 File outputFile = 
new File(log.concat(
".0"));
 
  301                 File first = 
new File(log.concat(
".1"));
 
  302                 File second = 
new File(log.concat(
".2"));
 
  303                 if (second.exists()) {
 
  306                 if (first.exists()) {
 
  307                     first.renameTo(second);
 
  309                 if (outputFile.
exists()) {
 
  310                     outputFile.renameTo(first);
 
  312                     outputFile.createNewFile();
 
  314                 out = 
new FileOutputStream(outputFile);
 
  316             } 
catch (Exception ex) {
 
  317                 logger.log(Level.WARNING, 
"Failed to create solr log file", ex); 
 
  328             try (InputStreamReader isr = 
new InputStreamReader(stream);
 
  329                     BufferedReader br = 
new BufferedReader(isr);
 
  331                     BufferedWriter bw = 
new BufferedWriter(osw);) {
 
  334                 while (doRun && (line = br.readLine()) != null) {
 
  343             } 
catch (IOException ex) {
 
  344                 logger.log(Level.SEVERE, 
"Error redirecting Solr output stream", ex); 
 
  359         final String MAX_SOLR_MEM_MB_PAR = 
"-Xmx" + Integer.toString(MAX_SOLR_MEM_MB) + 
"m"; 
 
  360         List<String> commandLine = 
new ArrayList<>();
 
  361         commandLine.add(javaPath);
 
  362         commandLine.add(MAX_SOLR_MEM_MB_PAR);
 
  363         commandLine.add(
"-DSTOP.PORT=" + currentSolrStopPort); 
 
  364         commandLine.add(
"-Djetty.port=" + currentSolrServerPort); 
 
  365         commandLine.add(
"-DSTOP.KEY=" + KEY); 
 
  366         commandLine.add(
"-jar"); 
 
  367         commandLine.add(
"start.jar"); 
 
  369         commandLine.addAll(solrArguments);
 
  371         ProcessBuilder solrProcessBuilder = 
new ProcessBuilder(commandLine);
 
  372         solrProcessBuilder.directory(solrFolder);
 
  375         Path solrStdoutPath = Paths.get(Places.getUserDirectory().getAbsolutePath(), 
"var", 
"log", 
"solr.log.stdout"); 
 
  376         solrProcessBuilder.redirectOutput(solrStdoutPath.toFile());
 
  378         Path solrStderrPath = Paths.get(Places.getUserDirectory().getAbsolutePath(), 
"var", 
"log", 
"solr.log.stderr"); 
 
  379         solrProcessBuilder.redirectError(solrStderrPath.toFile());
 
  381         logger.log(Level.INFO, 
"Running Solr command: {0}", solrProcessBuilder.command()); 
 
  382         Process process = solrProcessBuilder.start();
 
  383         logger.log(Level.INFO, 
"Finished running Solr command"); 
 
  392     List<Long> getSolrPIDs() {
 
  393         List<Long> pids = 
new ArrayList<>();
 
  396         final String pidsQuery = 
"Args.*.eq=-DSTOP.KEY=" + KEY + 
",Args.*.eq=start.jar"; 
 
  399         if (pidsArr != null) {
 
  400             for (
int i = 0; i < pidsArr.length; ++i) {
 
  401                 pids.add(pidsArr[i]);
 
  413         List<Long> solrPids = getSolrPIDs();
 
  414         for (
long pid : solrPids) {
 
  415             logger.log(Level.INFO, 
"Trying to kill old Solr process, PID: {0}", pid); 
 
  416             PlatformUtil.killProcess(pid);
 
  425     void start() throws KeywordSearchModuleException, SolrServerNoPortException {
 
  431         if (!isPortAvailable(currentSolrServerPort)) {
 
  435             final List<Long> pids = this.getSolrPIDs();
 
  439             if (pids.isEmpty()) {
 
  440                 throw new SolrServerNoPortException(currentSolrServerPort);
 
  449             if (!isPortAvailable(currentSolrServerPort)) {
 
  450                 throw new SolrServerNoPortException(currentSolrServerPort);
 
  452             if (!isPortAvailable(currentSolrStopPort)) {
 
  453                 throw new SolrServerNoPortException(currentSolrStopPort);
 
  457         logger.log(Level.INFO, 
"Starting Solr server from: {0}", solrFolder.getAbsolutePath()); 
 
  459         if (isPortAvailable(currentSolrServerPort)) {
 
  460             logger.log(Level.INFO, 
"Port [{0}] available, starting Solr", currentSolrServerPort); 
 
  463                         Arrays.asList(
"-Dbootstrap_confdir=../solr/configsets/AutopsyConfig/conf", 
 
  464                                 "-Dcollection.configName=AutopsyConfig"))); 
 
  469                     Thread.sleep(10 * 1000);
 
  470                 } 
catch (InterruptedException ex) {
 
  471                     logger.log(Level.WARNING, 
"Timer interrupted"); 
 
  474                 final List<Long> pids = this.getSolrPIDs();
 
  475                 logger.log(Level.INFO, 
"New Solr process PID: {0}", pids); 
 
  476             } 
catch (SecurityException ex) {
 
  477                 logger.log(Level.SEVERE, 
"Could not start Solr process!", ex); 
 
  478                 throw new KeywordSearchModuleException(
 
  479                         NbBundle.getMessage(
this.getClass(), 
"Server.start.exception.cantStartSolr.msg"), ex);
 
  480             } 
catch (IOException ex) {
 
  481                 logger.log(Level.SEVERE, 
"Could not start Solr server process!", ex); 
 
  482                 throw new KeywordSearchModuleException(
 
  483                         NbBundle.getMessage(
this.getClass(), 
"Server.start.exception.cantStartSolr.msg2"), ex);
 
  493     static boolean isPortAvailable(
int port) {
 
  494         ServerSocket ss = null;
 
  497             ss = 
new ServerSocket(port, 0, java.net.Inet4Address.getByName(
"localhost")); 
 
  499                 ss.setReuseAddress(
true);
 
  504         } 
catch (IOException e) {
 
  509                 } 
catch (IOException e) {
 
  524     void changeSolrServerPort(
int port) {
 
  525         currentSolrServerPort = port;
 
  526         ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT, String.valueOf(port));
 
  534     void changeSolrStopPort(
int port) {
 
  535         currentSolrStopPort = port;
 
  536         ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT, String.valueOf(port));
 
  544     synchronized void stop() {
 
  549         } 
catch (KeywordSearchModuleException e) {
 
  550             logger.log(Level.WARNING, 
"Failed to close core: ", e); 
 
  554             logger.log(Level.INFO, 
"Stopping Solr server from: {0}", solrFolder.getAbsolutePath()); 
 
  557             Process process = 
runSolrCommand(
new ArrayList<>(Arrays.asList(
"--stop"))); 
 
  559             logger.log(Level.INFO, 
"Waiting for Solr server to stop"); 
 
  563             if (curSolrProcess != null) {
 
  564                 curSolrProcess.destroy();
 
  565                 curSolrProcess = null;
 
  568         } 
catch (IOException | InterruptedException ex) {
 
  569             logger.log(Level.WARNING, 
"Error while attempting to stop Solr server", ex);
 
  573                 if (errorRedirectThread != null) {
 
  574                     errorRedirectThread.stopRun();
 
  575                     errorRedirectThread = null;
 
  582             logger.log(Level.INFO, 
"Finished stopping Solr server"); 
 
  593     synchronized boolean isRunning() throws KeywordSearchModuleException {
 
  596             if (isPortAvailable(currentSolrServerPort)) {
 
  603             CoreAdminRequest.getStatus(null, localSolrServer);
 
  605             logger.log(Level.INFO, 
"Solr server is running"); 
 
  606         } 
catch (SolrServerException ex) {
 
  608             Throwable cause = ex.getRootCause();
 
  613             if (cause instanceof ConnectException || cause instanceof SocketException) { 
 
  614                 logger.log(Level.INFO, 
"Solr server is not running, cause: {0}", cause.getMessage()); 
 
  617                 throw new KeywordSearchModuleException(
 
  618                         NbBundle.getMessage(
this.getClass(), 
"Server.isRunning.exception.errCheckSolrRunning.msg"), ex);
 
  620         } 
catch (SolrException ex) {
 
  622             logger.log(Level.INFO, 
"Solr server is not running", ex); 
 
  624         } 
catch (IOException ex) {
 
  625             throw new KeywordSearchModuleException(
 
  626                     NbBundle.getMessage(
this.getClass(), 
"Server.isRunning.exception.errCheckSolrRunning.msg2"), ex);
 
  644     void openCoreForCase(Case theCase, Index index) 
throws KeywordSearchModuleException {
 
  645         currentCoreLock.writeLock().lock();
 
  647             currentCore = 
openCore(theCase, index);
 
  652             } 
catch (NoOpenCoreException ex) {
 
  653                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.openCore.exception.cantOpen.msg"), ex);
 
  656             serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STARTED);
 
  658             currentCoreLock.writeLock().unlock();
 
  667     boolean coreIsOpen() {
 
  668         currentCoreLock.readLock().lock();
 
  670             return (null != currentCore);
 
  672             currentCoreLock.readLock().unlock();
 
  676     Index getIndexInfo() throws NoOpenCoreException {
 
  677         currentCoreLock.readLock().lock();
 
  679             if (null == currentCore) {
 
  680                 throw new NoOpenCoreException();
 
  682             return currentCore.getIndexInfo();
 
  684             currentCoreLock.readLock().unlock();
 
  688     void closeCore() throws KeywordSearchModuleException {
 
  689         currentCoreLock.writeLock().lock();
 
  691             if (null != currentCore) {
 
  694                 serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED);
 
  697             currentCoreLock.writeLock().unlock();
 
  701     void addDocument(SolrInputDocument doc) 
throws KeywordSearchModuleException, NoOpenCoreException {
 
  702         currentCoreLock.readLock().lock();
 
  704             if (null == currentCore) {
 
  705                 throw new NoOpenCoreException();
 
  707             currentCore.addDocument(doc);
 
  709             currentCoreLock.readLock().unlock();
 
  723         "# {0} - core name", 
"Server.deleteCore.exception.msg=Failed to delete Solr core {0}",})
 
  724     void deleteCore(String coreName) 
throws KeywordSearchServiceException {
 
  735         currentCoreLock.readLock().lock();
 
  737             if (null != currentCore) {
 
  738                 if (currentCore.getName().equals(coreName)) {
 
  743         } 
catch (KeywordSearchModuleException ex) {
 
  744             throw new KeywordSearchServiceException(NbBundle.getMessage(Server.class, 
"Server.close.exception.msg"), ex);
 
  746             currentCoreLock.readLock().unlock();
 
  750             HttpSolrServer solrServer = 
new HttpSolrServer(
"http://" + UserPreferences.getIndexingServerHost() + 
":" + UserPreferences.getIndexingServerPort() + 
"/solr"); 
 
  751             connectToSolrServer(solrServer);
 
  752             org.apache.solr.client.solrj.request.CoreAdminRequest.unloadCore(coreName, 
true, 
true, solrServer); 
 
  753         } 
catch (SolrServerException | IOException ex) {
 
  754             throw new KeywordSearchServiceException(Bundle.Server_deleteCore_exception_msg(coreName), ex);
 
  770     private Core 
openCore(
Case theCase, Index index) 
throws KeywordSearchModuleException {
 
  778                 currentSolrServer = 
new HttpSolrServer(
"http://" + host + 
":" + port + 
"/solr"); 
 
  780             connectToSolrServer(currentSolrServer);
 
  782         } 
catch (SolrServerException | IOException ex) {
 
  783             throw new KeywordSearchModuleException(NbBundle.getMessage(
Server.class, 
"Server.connect.exception.msg"), ex);
 
  787             File dataDir = 
new File(
new File(index.getIndexPath()).getParent()); 
 
  792             if (!this.isRunning()) {
 
  793                 logger.log(Level.SEVERE, 
"Core create/open requested, but server not yet running"); 
 
  794                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.openCore.exception.msg"));
 
  797             String coreName = index.getIndexName();
 
  809                     if (corePropertiesFile.toFile().exists()) {
 
  811                             corePropertiesFile.toFile().delete();
 
  812                         } 
catch (Exception ex) {
 
  813                             logger.log(Level.INFO, 
"Could not delete pre-existing core.properties prior to opening the core."); 
 
  818                 CoreAdminRequest.Create createCoreRequest = 
new CoreAdminRequest.Create();
 
  819                 createCoreRequest.setDataDir(dataDir.getAbsolutePath());
 
  820                 createCoreRequest.setCoreName(coreName);
 
  821                 createCoreRequest.setConfigSet(
"AutopsyConfig"); 
 
  822                 createCoreRequest.setIsLoadOnStartup(
false);
 
  823                 createCoreRequest.setIsTransient(
true);
 
  824                 currentSolrServer.request(createCoreRequest);
 
  828                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.openCore.exception.noIndexDir.msg"));
 
  831             return new Core(coreName, theCase.getCaseType(), index);
 
  833         } 
catch (SolrServerException | SolrException | IOException ex) {
 
  834             throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.openCore.exception.cantOpen.msg"), ex);
 
  843     void commit() throws SolrServerException, NoOpenCoreException {
 
  844         currentCoreLock.readLock().lock();
 
  846             if (null == currentCore) {
 
  847                 throw new NoOpenCoreException();
 
  849             currentCore.commit();
 
  851             currentCoreLock.readLock().unlock();
 
  855     NamedList<Object> request(SolrRequest request) 
throws SolrServerException, NoOpenCoreException {
 
  856         currentCoreLock.readLock().lock();
 
  858             if (null == currentCore) {
 
  859                 throw new NoOpenCoreException();
 
  861             return currentCore.request(request);
 
  863             currentCoreLock.readLock().unlock();
 
  878         currentCoreLock.readLock().lock();
 
  880             if (null == currentCore) {
 
  881                 throw new NoOpenCoreException();
 
  884                 return currentCore.queryNumIndexedFiles();
 
  885             } 
catch (SolrServerException | IOException ex) {
 
  886                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.queryNumIdxFiles.exception.msg"), ex);
 
  889             currentCoreLock.readLock().unlock();
 
  903         currentCoreLock.readLock().lock();
 
  905             if (null == currentCore) {
 
  906                 throw new NoOpenCoreException();
 
  909                 return currentCore.queryNumIndexedChunks();
 
  910             } 
catch (SolrServerException | IOException ex) {
 
  911                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.queryNumIdxChunks.exception.msg"), ex);
 
  914             currentCoreLock.readLock().unlock();
 
  928         currentCoreLock.readLock().lock();
 
  930             if (null == currentCore) {
 
  931                 throw new NoOpenCoreException();
 
  934                 return currentCore.queryNumIndexedDocuments();
 
  935             } 
catch (SolrServerException | IOException ex) {
 
  936                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.queryNumIdxDocs.exception.msg"), ex);
 
  939             currentCoreLock.readLock().unlock();
 
  953     public boolean queryIsIndexed(
long contentID) 
throws KeywordSearchModuleException, NoOpenCoreException {
 
  954         currentCoreLock.readLock().lock();
 
  956             if (null == currentCore) {
 
  957                 throw new NoOpenCoreException();
 
  960                 return currentCore.queryIsIndexed(contentID);
 
  961             } 
catch (SolrServerException | IOException ex) {
 
  962                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.queryIsIdxd.exception.msg"), ex);
 
  966             currentCoreLock.readLock().unlock();
 
  982     public int queryNumFileChunks(
long fileID) 
throws KeywordSearchModuleException, NoOpenCoreException {
 
  983         currentCoreLock.readLock().lock();
 
  985             if (null == currentCore) {
 
  986                 throw new NoOpenCoreException();
 
  989                 return currentCore.queryNumFileChunks(fileID);
 
  990             } 
catch (SolrServerException | IOException ex) {
 
  991                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.queryNumFileChunks.exception.msg"), ex);
 
  994             currentCoreLock.readLock().unlock();
 
 1008     public QueryResponse 
query(SolrQuery sq) 
throws KeywordSearchModuleException, NoOpenCoreException, IOException {
 
 1009         currentCoreLock.readLock().lock();
 
 1011             if (null == currentCore) {
 
 1012                 throw new NoOpenCoreException();
 
 1015                 return currentCore.query(sq);
 
 1016             } 
catch (SolrServerException ex) {
 
 1017                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.query.exception.msg", sq.getQuery()), ex);
 
 1020             currentCoreLock.readLock().unlock();
 
 1035     public QueryResponse 
query(SolrQuery sq, SolrRequest.METHOD method) throws KeywordSearchModuleException, NoOpenCoreException {
 
 1036         currentCoreLock.readLock().lock();
 
 1038             if (null == currentCore) {
 
 1039                 throw new NoOpenCoreException();
 
 1042                 return currentCore.query(sq, method);
 
 1043             } 
catch (SolrServerException | IOException ex) {
 
 1044                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.query2.exception.msg", sq.getQuery()), ex);
 
 1047             currentCoreLock.readLock().unlock();
 
 1061     public TermsResponse 
queryTerms(SolrQuery sq) 
throws KeywordSearchModuleException, NoOpenCoreException {
 
 1062         currentCoreLock.readLock().lock();
 
 1064             if (null == currentCore) {
 
 1065                 throw new NoOpenCoreException();
 
 1068                 return currentCore.queryTerms(sq);
 
 1069             } 
catch (SolrServerException | IOException ex) {
 
 1070                 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(), 
"Server.queryTerms.exception.msg", sq.getQuery()), ex);
 
 1073             currentCoreLock.readLock().unlock();
 
 1087         currentCoreLock.readLock().lock();
 
 1089             if (null == currentCore) {
 
 1090                 throw new NoOpenCoreException();
 
 1092             return currentCore.getSolrContent(content.getId(), 0);
 
 1094             currentCoreLock.readLock().unlock();
 
 1111         currentCoreLock.readLock().lock();
 
 1113             if (null == currentCore) {
 
 1114                 throw new NoOpenCoreException();
 
 1116             return currentCore.getSolrContent(content.getId(), chunkID);
 
 1118             currentCoreLock.readLock().unlock();
 
 1132         currentCoreLock.readLock().lock();
 
 1134             if (null == currentCore) {
 
 1135                 throw new NoOpenCoreException();
 
 1137             return currentCore.getSolrContent(objectID, 0);
 
 1139             currentCoreLock.readLock().unlock();
 
 1153     public String 
getSolrContent(
final long objectID, 
final int chunkID) 
throws NoOpenCoreException {
 
 1154         currentCoreLock.readLock().lock();
 
 1156             if (null == currentCore) {
 
 1157                 throw new NoOpenCoreException();
 
 1159             return currentCore.getSolrContent(objectID, chunkID);
 
 1161             currentCoreLock.readLock().unlock();
 
 1186     void connectToSolrServer(HttpSolrServer solrServer) 
throws SolrServerException, IOException {
 
 1187         CoreAdminRequest.getStatus(null, solrServer);
 
 1203     private boolean coreIsLoaded(String coreName) 
throws SolrServerException, IOException {
 
 1204         CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, currentSolrServer);
 
 1205         return response.getCoreStatus(coreName).get(
"instanceDir") != null; 
 
 1220         CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, currentSolrServer);
 
 1221         Object dataDirPath = response.getCoreStatus(coreName).get(
"dataDir"); 
 
 1222         if (null != dataDirPath) {
 
 1223             File indexDir = Paths.get((String) dataDirPath, 
"index").toFile();  
 
 1224             return indexDir.
exists();
 
 1233         private final String name;
 
 1237         private final Index textIndex;
 
 1241         private final HttpSolrServer solrCore;
 
 1243         private Core(String name, 
CaseType caseType, Index index) {
 
 1245             this.caseType = caseType;
 
 1246             this.textIndex = index;
 
 1248             this.solrCore = 
new HttpSolrServer(currentSolrServer.getBaseURL() + 
"/" + name); 
 
 1253             solrCore.setDefaultMaxConnectionsPerHost(2);
 
 1254             solrCore.setMaxTotalConnections(5);
 
 1255             solrCore.setFollowRedirects(
false);  
 
 1258             solrCore.setAllowCompression(
true);
 
 1259             solrCore.setParser(
new XMLResponseParser()); 
 
 1272         private Index getIndexInfo() {
 
 1273             return this.textIndex;
 
 1276         private QueryResponse 
query(SolrQuery sq) 
throws SolrServerException, IOException {
 
 1277             return solrCore.query(sq);
 
 1280         private NamedList<Object> request(SolrRequest request) 
throws SolrServerException {
 
 1282                 return solrCore.request(request);
 
 1283             } 
catch (IOException e) {
 
 1284                 logger.log(Level.WARNING, 
"Could not issue Solr request. ", e); 
 
 1285                 throw new SolrServerException(
 
 1286                         NbBundle.getMessage(
this.getClass(), 
"Server.request.exception.exception.msg"), e);
 
 1291         private QueryResponse 
query(SolrQuery sq, SolrRequest.METHOD method) throws SolrServerException, IOException {
 
 1292             return solrCore.query(sq, method);
 
 1295         private TermsResponse 
queryTerms(SolrQuery sq) 
throws SolrServerException, IOException {
 
 1296             QueryResponse qres = solrCore.query(sq);
 
 1297             return qres.getTermsResponse();
 
 1300         private void commit() throws SolrServerException {
 
 1303                 solrCore.commit(
true, 
true);
 
 1304             } 
catch (IOException e) {
 
 1305                 logger.log(Level.WARNING, 
"Could not commit index. ", e); 
 
 1306                 throw new SolrServerException(NbBundle.getMessage(
this.getClass(), 
"Server.commit.exception.msg"), e);
 
 1310         void addDocument(SolrInputDocument doc) 
throws KeywordSearchModuleException {
 
 1313             } 
catch (SolrServerException ex) {
 
 1314                 logger.log(Level.SEVERE, 
"Could not add document to index via update handler: " + doc.getField(
"id"), ex); 
 
 1315                 throw new KeywordSearchModuleException(
 
 1316                         NbBundle.getMessage(
this.getClass(), 
"Server.addDoc.exception.msg", doc.getField(
"id")), ex); 
 
 1317             } 
catch (IOException ex) {
 
 1318                 logger.log(Level.SEVERE, 
"Could not add document to index via update handler: " + doc.getField(
"id"), ex); 
 
 1319                 throw new KeywordSearchModuleException(
 
 1320                         NbBundle.getMessage(
this.getClass(), 
"Server.addDoc.exception.msg2", doc.getField(
"id")), ex); 
 
 1333             final SolrQuery q = 
new SolrQuery();
 
 1335             String filterQuery = Schema.ID.toString() + 
":" + KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
 
 1337                 filterQuery = filterQuery + Server.CHUNK_ID_SEPARATOR + chunkID;
 
 1339             q.addFilterQuery(filterQuery);
 
 1340             q.setFields(Schema.TEXT.toString());
 
 1343                 SolrDocumentList solrDocuments = solrCore.query(q).getResults();
 
 1345                 if (!solrDocuments.isEmpty()) {
 
 1346                     SolrDocument solrDocument = solrDocuments.get(0);
 
 1347                     if (solrDocument != null) {
 
 1348                         Collection<Object> fieldValues = solrDocument.getFieldValues(Schema.TEXT.toString());
 
 1349                         if (fieldValues.size() == 1) 
 
 1351                             return fieldValues.toArray(
new String[0])[0];
 
 1355                             return fieldValues.toArray(
new String[0])[1];
 
 1359             } 
catch (SolrServerException ex) {
 
 1360                 logger.log(Level.WARNING, 
"Error getting content from Solr", ex); 
 
 1367         synchronized void close() throws KeywordSearchModuleException {
 
 1374                 CoreAdminRequest.unloadCore(this.name, currentSolrServer);
 
 1375             } 
catch (SolrServerException ex) {
 
 1376                 throw new KeywordSearchModuleException(
 
 1377                         NbBundle.getMessage(
this.getClass(), 
"Server.close.exception.msg"), ex);
 
 1378             } 
catch (IOException ex) {
 
 1379                 throw new KeywordSearchModuleException(
 
 1380                         NbBundle.getMessage(
this.getClass(), 
"Server.close.exception.msg2"), ex);
 
 1407             SolrQuery q = 
new SolrQuery(Server.Schema.ID + 
":*" + Server.CHUNK_ID_SEPARATOR + 
"*");
 
 1409             int numChunks = (int) 
query(q).getResults().getNumFound();
 
 1424             SolrQuery q = 
new SolrQuery(
"*:*");
 
 1426             return (
int) 
query(q).getResults().getNumFound();
 
 1438         private boolean queryIsIndexed(
long contentID) 
throws SolrServerException, IOException {
 
 1439             String 
id = KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
 
 1440             SolrQuery q = 
new SolrQuery(
"*:*");
 
 1441             q.addFilterQuery(Server.Schema.ID.toString() + 
":" + id);
 
 1444             return (
int) 
query(q).getResults().getNumFound() != 0;
 
 1458         private int queryNumFileChunks(
long contentID) 
throws SolrServerException, IOException {
 
 1459             String 
id = KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
 
 1461                     = 
new SolrQuery(Server.Schema.ID + 
":" + 
id + Server.CHUNK_ID_SEPARATOR + 
"*");
 
 1463             return (
int) 
query(q).getResults().getNumFound();
 
 1467     class ServerAction 
extends AbstractAction {
 
 1469         private static final long serialVersionUID = 1L;
 
 1472         public void actionPerformed(ActionEvent e) {
 
 1473             logger.log(Level.INFO, e.paramString().trim());
 
 1480     class SolrServerNoPortException 
extends SocketException {
 
 1482         private static final long serialVersionUID = 1L;
 
 1487         private final int port;
 
 1489         SolrServerNoPortException(
int port) {
 
 1490             super(NbBundle.getMessage(Server.class, 
"Server.solrServerNoPortException.msg", port,
 
 1491                     Server.PROPERTIES_CURRENT_SERVER_PORT));
 
 1495         int getPortNumber() {
 
int queryNumIndexedFiles()
 
String getSolrContent(final long objectID)
 
final ReentrantReadWriteLock currentCoreLock
 
int queryNumIndexedChunks()
 
static final char ID_CHUNK_SEP
 
final ServerAction serverAction
 
static String getIndexingServerPort()
 
static final String CORE_PROPERTIES
 
boolean coreIsLoaded(String coreName)
 
final HttpSolrServer localSolrServer
 
static final Logger logger
 
void addServerActionListener(PropertyChangeListener l)
 
static final String HL_ANALYZE_CHARS_UNLIMITED
 
Process runSolrCommand(List< String > solrArguments)
 
String getSolrContent(final Content content)
 
static final long MAX_CONTENT_SIZE
 
boolean coreIndexFolderExists(String coreName)
 
HttpSolrServer currentSolrServer
 
int queryNumIndexedDocuments()
 
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
 
static final String CHUNK_ID_SEPARATOR
 
static final String CORE_EVT
 
static final Charset DEFAULT_INDEXED_TEXT_CHARSET
default Charset to index text as 
 
InputStreamPrinterThread errorRedirectThread
 
QueryResponse query(SolrQuery sq)
 
static String getConfigSetting(String moduleName, String settingName)
 
int currentSolrServerPort
 
TermsResponse queryTerms(SolrQuery sq)
 
boolean queryIsIndexed(long contentID)
 
String getSolrContent(final Content content, int chunkID)
 
String getSolrContent(final long objectID, final int chunkID)
 
synchronized static Logger getLogger(String name)
 
Core openCore(Case theCase, Index index)
 
static final int MAX_SOLR_MEM_MB
 
static String getChunkIdString(long parentID, int childID)
 
static String getIndexingServerHost()
 
static boolean settingExists(String moduleName, String settingName)
 
int queryNumFileChunks(long fileID)
 
String toString(boolean preserveState)
 
static final boolean DEBUG
 
QueryResponse query(SolrQuery sq, SolrRequest.METHOD method)