diff --git a/KeywordSearch/build.xml b/KeywordSearch/build.xml index 3e4314aec72c2790bd8f8e236bf212a459897320..dfd91b6f0762bc283ef5c364a8644240e026a4f0 100644 --- a/KeywordSearch/build.xml +++ b/KeywordSearch/build.xml @@ -2,7 +2,41 @@ <!-- You may freely edit this file. See harness/README in the NetBeans platform --> <!-- for some information on what you could do (e.g. targets to override). --> <!-- If you delete this file and reopen the project it will be recreated. --> -<project name="org.sleuthkit.autopsy.keywordsearch" default="netbeans" basedir="."> +<project name="org.sleuthkit.autopsy.keywordsearch" default="netbeans" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant"> <description>Builds, tests, and runs the project org.sleuthkit.autopsy.keywordsearch.</description> <import file="nbproject/build-impl.xml"/> + + <!-- + <property name="ivy.install.version" value="2.1.0-rc2" /> + <condition property="ivy.home" value="${env.IVY_HOME}"> + <isset property="env.IVY_HOME" /> + </condition> + <property name="ivy.home" value="${user.home}/.ant" /> + <property name="ivy.jar.dir" value="${ivy.home}/lib" /> + <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" /> + + <target name="download-ivy" unless="offline"> + <mkdir dir="${ivy.jar.dir}"/> + <get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" + dest="${ivy.jar.file}" usetimestamp="true"/> + </target> + + <target name="init-ivy" depends="download-ivy"> + + <path id="ivy.lib.path"> + <fileset dir="${ivy.jar.dir}" includes="*.jar"/> + </path> + <taskdef resource="org/apache/ivy/ant/antlib.xml" + uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/> + </target> + + --> + + + <target name="init" depends="basic-init,files-init,build-init,-javac-init"> + + <ivy:resolve/> + <ivy:retrieve sync="true" pattern="/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" /> + </target> + </project> diff --git a/KeywordSearch/ivy.xml b/KeywordSearch/ivy.xml new file mode 100644 index 0000000000000000000000000000000000000000..ced1e81c6793e05e95f86950dab6a8bd09a696a6 --- /dev/null +++ b/KeywordSearch/ivy.xml @@ -0,0 +1,12 @@ + +<ivy-module version="2.0"> + <info organisation="org.sleuthkit.autopsy" module="keywordsearch"/> + <dependencies> + <dependency org="org.apache.solr" name="solr-cell" rev="3.5.0"/> + <dependency org="org.apache.solr" name="solr-solrj" rev="3.5.0"/> + <dependency org="org.apache.solr" name="solr" rev="3.5.0"/> + <dependency org="org.apache.solr" name="solr" rev="3.5.0"/> + <dependency org="org.mortbay.jetty" name="start" rev="6.1.26"/> + <dependency org="commons-lang" name="commons-lang" rev="2.4"/> + </dependencies> +</ivy-module> diff --git a/KeywordSearch/manifest.mf b/KeywordSearch/manifest.mf index cc92feb905b134ce289c40bd718d510d020ddc1e..2a5aa19d6b2fecdb6d1406f3276e75987e740250 100644 --- a/KeywordSearch/manifest.mf +++ b/KeywordSearch/manifest.mf @@ -1,6 +1,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.keywordsearch/0 OpenIDE-Module-Implementation-Version: 1 +OpenIDE-Module-Install: org/sleuthkit/autopsy/keywordsearch/Installer.class OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties diff --git a/KeywordSearch/nbproject/genfiles.properties b/KeywordSearch/nbproject/genfiles.properties index 02e215031a457cb35ce6b2b933aa1a6447860d41..77a13dda5094edd977d60b0f026fec52f7ee3e1f 100644 --- a/KeywordSearch/nbproject/genfiles.properties +++ b/KeywordSearch/nbproject/genfiles.properties @@ -3,6 +3,6 @@ build.xml.script.CRC32=87b97b04 build.xml.stylesheet.CRC32=a56c6a5b@1.46.2 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=eaa84b46 +nbproject/build-impl.xml.data.CRC32=ecf316f0 nbproject/build-impl.xml.script.CRC32=fe1f48d2 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.2 diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties index 18e9c3a2759d0dda3577fd250615dab847c0dc2c..63041f6f7a3fb7a007d176fd5898bd4c5059749b 100644 --- a/KeywordSearch/nbproject/project.properties +++ b/KeywordSearch/nbproject/project.properties @@ -1,4 +1,12 @@ -file.reference.apache-solr-solrj-3.4.0.jar=release/modules/ext/apache-solr-solrj-3.4.0.jar +file.reference.commons-codec-1.5.jar=release/modules/ext/commons-codec-1.5.jar +file.reference.commons-httpclient-3.1.jar=release/modules/ext/commons-httpclient-3.1.jar +file.reference.commons-io-1.4.jar=release/modules/ext/commons-io-1.4.jar +file.reference.jcl-over-slf4j-1.6.1.jar=release/modules/ext/jcl-over-slf4j-1.6.1.jar +file.reference.slf4j-api-1.6.1.jar=release/modules/ext/slf4j-api-1.6.1.jar +file.reference.slf4j-jdk14-1.6.1.jar=release/modules/ext/slf4j-jdk14-1.6.1.jar +file.reference.solr-solrj-3.5.0.jar=release/modules/ext/solr-solrj-3.5.0.jar javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial +javadoc.reference.solr-solrj-3.5.0.jar=release/modules/ext/solr-solrj-3.5.0-javadoc.jar +source.reference.solr-solrj-3.5.0.jar=release/modules/ext/solr-solrj-3.5.0-sources.jar spec.version.base=0.0 diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index cd9043e97e8c3ba1e333e06319b33c86af08eee1..f82e7afeebaac0d163c5f6ce8146eb9c5260ce41 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -14,6 +14,14 @@ <specification-version>7.31.1</specification-version> </run-dependency> </dependency> + <dependency> + <code-name-base>org.openide.modules</code-name-base> + <build-prerequisite/> + <compile-dependency/> + <run-dependency> + <specification-version>7.23.1</specification-version> + </run-dependency> + </dependency> <dependency> <code-name-base>org.openide.nodes</code-name-base> <build-prerequisite/> @@ -99,24 +107,24 @@ <binary-origin>release/modules/ext/commons-httpclient-3.1.jar</binary-origin> </class-path-extension> <class-path-extension> - <runtime-relative-path>ext/apache-solr-solrj-3.4.0.jar</runtime-relative-path> - <binary-origin>release/modules/ext/apache-solr-solrj-3.4.0.jar</binary-origin> - </class-path-extension> - <class-path-extension> - <runtime-relative-path>ext/commons-codec-1.4.jar</runtime-relative-path> - <binary-origin>release/modules/ext/commons-codec-1.4.jar</binary-origin> + <runtime-relative-path>ext/commons-codec-1.5.jar</runtime-relative-path> + <binary-origin>release/modules/ext/commons-codec-1.5.jar</binary-origin> </class-path-extension> <class-path-extension> - <runtime-relative-path>ext/wstx-asl-3.2.7.jar</runtime-relative-path> - <binary-origin>release/modules/ext/wstx-asl-3.2.7.jar</binary-origin> + <runtime-relative-path>ext/commons-lang-2.4.jar</runtime-relative-path> + <binary-origin>release/modules/ext/commons-lang-2.4.jar</binary-origin> </class-path-extension> <class-path-extension> <runtime-relative-path>ext/jcl-over-slf4j-1.6.1.jar</runtime-relative-path> <binary-origin>release/modules/ext/jcl-over-slf4j-1.6.1.jar</binary-origin> </class-path-extension> <class-path-extension> - <runtime-relative-path>ext/geronimo-stax-api_1.0_spec-1.0.1.jar</runtime-relative-path> - <binary-origin>release/modules/ext/geronimo-stax-api_1.0_spec-1.0.1.jar</binary-origin> + <runtime-relative-path>ext/slf4j-jdk14-1.6.1.jar</runtime-relative-path> + <binary-origin>release/modules/ext/slf4j-jdk14-1.6.1.jar</binary-origin> + </class-path-extension> + <class-path-extension> + <runtime-relative-path>ext/solr-solrj-3.5.0.jar</runtime-relative-path> + <binary-origin>release/modules/ext/solr-solrj-3.5.0.jar</binary-origin> </class-path-extension> </data> </configuration> diff --git a/KeywordSearch/release/modules/ext/apache-solr-solrj-3.4.0.jar b/KeywordSearch/release/modules/ext/apache-solr-solrj-3.4.0.jar deleted file mode 100644 index f615d94370ecb02720a55e71c330d3bd855de726..0000000000000000000000000000000000000000 Binary files a/KeywordSearch/release/modules/ext/apache-solr-solrj-3.4.0.jar and /dev/null differ diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java index 839f3910bc7064c3be0aa078ada263992ecf7872..b398a081de0c92a8b0bcc35a41b5bca1ba768750 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java @@ -26,12 +26,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.openide.nodes.Node; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.datamodel.ContentNode; +import org.apache.commons.lang.StringEscapeUtils; + @ServiceProvider(service = DataContentViewer.class) public class ExtractedContentViewer implements DataContentViewer { @@ -62,8 +63,8 @@ public void setNode(final ContentNode selectedNode) { @Override public String getMarkup() { try { - String content = getSolrContent(selectedNode); - return "<pre>" + content + "</pre>"; + String content = StringEscapeUtils.escapeHtml(getSolrContent(selectedNode)); + return "<pre>" + content.trim() + "</pre>"; } catch (SolrServerException ex) { logger.log(Level.WARNING, "Couldn't get extracted content.", ex); return ""; @@ -115,14 +116,14 @@ public boolean isSupported(ContentNode node) { return true; } - SolrServer solr = Server.getServer().getSolr(); + Server.Core solrCore = KeywordSearch.getServer().getCore(); SolrQuery q = new SolrQuery(); q.setQuery("*:*"); q.addFilterQuery("id:" + node.getContent().getId()); q.setFields("id"); try { - return !solr.query(q).getResults().isEmpty(); + return !solrCore.query(q).getResults().isEmpty(); } catch (SolrServerException ex) { logger.log(Level.WARNING, "Couldn't determine whether content is supported.", ex); return false; @@ -136,14 +137,15 @@ private void setPanel(List<MarkupSource> sources) { } private String getSolrContent(ContentNode cNode) throws SolrServerException { - SolrServer solr = Server.getServer().getSolr(); + Server.Core solrCore = KeywordSearch.getServer().getCore(); SolrQuery q = new SolrQuery(); q.setQuery("*:*"); q.addFilterQuery("id:" + cNode.getContent().getId()); q.setFields("content"); + //TODO: for debugging, remove String queryURL = q.toString(); - String content = (String) solr.query(q).getResults().get(0).getFieldValue("content"); + String content = (String) solrCore.query(q).getResults().get(0).getFieldValue("content"); return content; } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedMatchesSource.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedMatchesSource.java index 0b096b9035a134537d482792d1b48f48048053b3..faed12ab6adc41fd04190841ddc914edd0135480 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedMatchesSource.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedMatchesSource.java @@ -23,6 +23,7 @@ import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.QueryResponse; +import org.sleuthkit.autopsy.keywordsearch.Server.Core; import org.sleuthkit.datamodel.Content; class HighlightedMatchesSource implements MarkupSource { @@ -30,11 +31,19 @@ class HighlightedMatchesSource implements MarkupSource { private static final Logger logger = Logger.getLogger(HighlightedMatchesSource.class.getName()); Content content; String solrQuery; - + Core solrCore; + HighlightedMatchesSource(Content content, String solrQuery) { + this(content, solrQuery, KeywordSearch.getServer().getCore()); + } + + HighlightedMatchesSource(Content content, String solrQuery, Core solrCore) { this.content = content; this.solrQuery = solrQuery; + this.solrCore = solrCore; } + + @Override public String getMarkup() { @@ -46,15 +55,19 @@ public String getMarkup() { q.setHighlightSimplePre("<span style=\"background:yellow\">"); q.setHighlightSimplePost("</span>"); q.setHighlightFragsize(0); // don't fragment the highlight + + + //TODO: remove (only for debugging) + String queryString = q.toString(); try { - QueryResponse response = Server.getServer().getSolr().query(q); + QueryResponse response = solrCore.query(q); List<String> contentHighlights = response.getHighlighting().get(Long.toString(content.getId())).get("content"); if (contentHighlights == null) { return "<span style=\"background:red\">No matches in content.</span>"; } else { - return "<pre>" + contentHighlights.get(0) + "</pre>"; + return "<pre>" + contentHighlights.get(0).trim() + "</pre>"; } } catch (SolrServerException ex) { throw new RuntimeException(ex); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexContentFilesAction.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexContentFilesAction.java index e5ff41d1d12e1132cfa8b0c094452e9d5a880474..2c78fbf79126f7846a38cd3950abb3297d066837 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexContentFilesAction.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexContentFilesAction.java @@ -34,22 +34,28 @@ import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.FsContent; public class IndexContentFilesAction extends AbstractAction { - + + private static final Logger logger = Logger.getLogger(IndexContentFilesAction.class.getName()); + private Content c; private String name; - private static final Logger logger = Logger.getLogger(IndexContentFilesAction.class.getName()); - + private Server.Core solrCore; + public IndexContentFilesAction(Content c, String name) { + this(c, name, KeywordSearch.getServer().getCore()); + } + + IndexContentFilesAction(Content c, String name, Server.Core solrCore) { super("Index files..."); this.c = c; this.name = name; + this.solrCore = solrCore; } @Override @@ -69,7 +75,7 @@ public void actionPerformed(ActionEvent e) { @Override protected Integer doInBackground() throws Exception { - Ingester ingester = new Ingester("http://localhost:8983/solr"); + Ingester ingester = solrCore.getIngester(); Collection<FsContent> files = c.accept(new GetIngestableFilesContentVisitor()); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java index fdd97a699a98903a8a405f1c5f2bd1d769505212..b7502ebb38716d240974993fb11d793bb7107c86 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java @@ -21,14 +21,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Logger; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest; import org.apache.solr.common.SolrException; @@ -42,23 +40,11 @@ class Ingester { private static final Logger logger = Logger.getLogger(Ingester.class.getName()); - private SolrServer solr; + private SolrServer solrCore; private boolean uncommitedIngests = false; - /** - * New Ingester connected to the server at given url - * @param url Should be something like "http://localhost:8983/solr" - */ - Ingester(String url) { - try { - this.solr = new CommonsHttpSolrServer(url); - } catch (MalformedURLException ex) { - throw new RuntimeException(ex); - } - } - - Ingester(SolrServer solr) { - this.solr = solr; + Ingester(SolrServer solrCore) { + this.solrCore = solrCore; } @Override @@ -67,7 +53,7 @@ protected void finalize() throws Throwable { // Warn if files might have been left uncommited. if (uncommitedIngests) { - logger.warning("Ingester was used to add files that it never committed!"); + logger.warning("Ingester was used to add files that it never committed."); } } @@ -97,7 +83,7 @@ void ingest(FsContent f) throws IngesterException { up.setParam("commit", "false"); try { - solr.request(up); + solrCore.request(up); // should't get any checked exceptions, } catch (IOException ex) { // It's possible that we will have IO errors @@ -126,7 +112,7 @@ void ingest(FsContent f) throws IngesterException { void commit() { uncommitedIngests = false; try { - solr.commit(); + solrCore.commit(); // if commit doesn't work, something's broken } catch (IOException ex) { throw new RuntimeException(ex); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java new file mode 100644 index 0000000000000000000000000000000000000000..8bb8b39128915690ab36bb10649db264f7bb4ee9 --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java @@ -0,0 +1,35 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier <at> sleuthkit <dot> org + * + * Licensed 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.sleuthkit.autopsy.keywordsearch; + +import org.openide.modules.ModuleInstall; +import org.sleuthkit.autopsy.casemodule.Case; + +public class Installer extends ModuleInstall{ + + @Override + public void restored() { + Case.addPropertyChangeListener(new KeywordSearch.CaseChangeListener()); + } + + // TODO: need logic for starting & shutting down the server. + // startup should be robust enough to deal with a still running server + // from a previous crash. + +} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java new file mode 100644 index 0000000000000000000000000000000000000000..41746e1515458abb9b25dfad399ef68aafa44aef --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -0,0 +1,61 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier <at> sleuthkit <dot> org + * + * Licensed 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.sleuthkit.autopsy.keywordsearch; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.sleuthkit.autopsy.casemodule.Case; + +class KeywordSearch { + + private static final String BASE_URL = "http://localhost:8983/solr/"; + private static final Server SERVER = new Server(BASE_URL); + + static Server getServer() { + return SERVER; + } + + // don't instantiate + private KeywordSearch() { + throw new AssertionError(); + } + + static class CaseChangeListener implements PropertyChangeListener { + + CaseChangeListener() { + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String changed = evt.getPropertyName(); + Object oldValue = evt.getOldValue(); + Object newValue = evt.getNewValue(); + + if (changed.equals(Case.CASE_CURRENT_CASE)) { + if (newValue != null) { + // new case is open + SERVER.openCore(); + } else if (oldValue != null) { + // a case was closed + SERVER.closeCore(); + } + } + } + } +} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchDataExplorer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchDataExplorer.java index 8570f01e4f1139f54891dbc68f110219c85106dc..b5bf4f7dd946f498bf61d34f0746a7d7e164a63b 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchDataExplorer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchDataExplorer.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; @@ -75,7 +74,7 @@ private void search(String solrQuery) { - SolrServer solr = Server.getServer().getSolr(); + Server.Core solrCore = KeywordSearch.getServer().getCore(); SolrQuery q = new SolrQuery(); q.setQuery(solrQuery); @@ -84,12 +83,10 @@ private void search(String solrQuery) { for (int start = 0; !allMatchesFetched; start = start + ROWS_PER_FETCH) { - - q.setStart(start); try { - QueryResponse response = solr.query(q); + QueryResponse response = solrCore.query(q); SolrDocumentList resultList = response.getResults(); long results = resultList.getNumFound(); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java index 6b30998aa8a7b663829dc5df546b9e08b3e6796d..b3a90fce727b549b69f5dc615490dcbcb4d23a38 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java @@ -18,19 +18,25 @@ */ package org.sleuthkit.autopsy.keywordsearch; +import java.io.File; +import java.io.IOException; import java.net.MalformedURLException; +import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer; +import org.apache.solr.client.solrj.request.CoreAdminRequest; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.sleuthkit.autopsy.casemodule.Case; class Server { - private static final String url = "http://localhost:8983/solr"; - private static final Server S = new Server(url); + private static final String DEFAULT_CORE_NAME = "coreCase"; + // TODO: DEFAULT_CORE_NAME needs to be replaced with unique names to support multiple open cases + - static Server getServer() { - return S; - } - private SolrServer solr; + private CommonsHttpSolrServer solr; + private String instanceDir = "C:/Users/pmartel/solr-test/maytag/solr"; Server(String url) { try { @@ -40,11 +46,105 @@ static Server getServer() { } } - Ingester getIngester() { - return new Ingester(this.solr); + void start() { + } + + void stop() { + } + + + + /**** Convenience methods for use while we only open one case at a time ****/ + + private Core currentCore = null; + + void openCore() { + if (currentCore != null) { + throw new RuntimeException("Already an open Core!"); + } + currentCore = openCore(Case.getCurrentCase()); + } + + void closeCore() { + if (currentCore == null) { + throw new RuntimeException("No currently open Core!"); + } + currentCore.close(); + currentCore = null; + } + + Core getCore() { + if (currentCore == null) { + throw new RuntimeException("No currently open Core!"); + } + return currentCore; + } + + + /**** end single-case specific methods ****/ + + + + Core openCore(Case c) { + String sep = File.separator; + String dataDir = c.getCaseDirectory() + sep + "keywordsearch" + sep + "data"; + return this.openCore(DEFAULT_CORE_NAME, new File(dataDir)); } - SolrServer getSolr() { - return this.solr; + Core openCore(String coreName, File dataDir) { + try { + if (!dataDir.exists()) { + dataDir.mkdirs(); + } + + CoreAdminRequest.Create createCore = new CoreAdminRequest.Create(); + createCore.setDataDir(dataDir.getAbsolutePath()); + createCore.setInstanceDir(instanceDir); + createCore.setCoreName(coreName); + + this.solr.request(createCore); + + return new Core(coreName); + + } catch (SolrServerException ex) { + throw new RuntimeException(ex); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + class Core { + + private String name; + // server to access a core needs to be built from a URL with the + // core in it, and is only good for core-specific operations + private SolrServer solrCore; + + private Core(String name) { + this.name = name; + try { + this.solrCore = new CommonsHttpSolrServer(solr.getBaseURL() + "/" + name); + } catch (MalformedURLException ex) { + throw new RuntimeException(ex); + } + } + + Ingester getIngester() { + return new Ingester(this.solrCore); + } + + QueryResponse query(SolrQuery sq) throws SolrServerException { + return solrCore.query(sq); + } + + void close () { + try { + CoreAdminRequest.unloadCore(this.name, solr); + } catch (SolrServerException ex) { + throw new RuntimeException(ex); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } } }