diff --git a/Core/src/org/sleuthkit/autopsy/guicomponentutils/AutoCompletion.java b/Core/src/org/sleuthkit/autopsy/guicomponentutils/AutoCompletion.java
new file mode 100755
index 0000000000..4a5c195d7e
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/guicomponentutils/AutoCompletion.java
@@ -0,0 +1,228 @@
+package org.sleuthkit.autopsy.guicomponentutils;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.ComboBoxEditor;
+import javax.swing.ComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+
+
+/*
+ * This code is taken from http://www.orbital-computer.de/JComboBox/source/AutoCompletion.java
+ * Author: Thomas Bierhance
+ * This work is hereby released into the Public Domain. To view a copy of the
+ * public domain dedication, visit
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+public class AutoCompletion extends PlainDocument {
+
+ private static final long serialVersionUID = 1L;
+
+ private JComboBox> comboBox;
+ private ComboBoxModel> model;
+ private JTextComponent editor;
+// flag to indicate if setSelectedItem has been called
+// subsequent calls to remove/insertString should be ignored
+ private boolean selecting = false;
+ private boolean hidePopupOnFocusLoss;
+ private boolean hitBackspace = false;
+ private boolean hitBackspaceOnSelection;
+
+ private KeyListener editorKeyListener;
+ private FocusListener editorFocusListener;
+
+ public AutoCompletion(final JComboBox> comboBox) {
+ this.comboBox = comboBox;
+ model = comboBox.getModel();
+ comboBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (!selecting) {
+ highlightCompletedText(0);
+ }
+ }
+ });
+ comboBox.addPropertyChangeListener(new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent e) {
+ if (e.getPropertyName().equals("editor")) {
+ configureEditor((ComboBoxEditor) e.getNewValue());
+ }
+ if (e.getPropertyName().equals("model")) {
+ model = (ComboBoxModel) e.getNewValue();
+ }
+ }
+ });
+ editorKeyListener = new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (comboBox.isDisplayable()) {
+ comboBox.setPopupVisible(true);
+ }
+ hitBackspace = false;
+ switch (e.getKeyCode()) {
+ // determine if the pressed key is backspace (needed by the remove method)
+ case KeyEvent.VK_BACK_SPACE:
+ hitBackspace = true;
+ hitBackspaceOnSelection = editor.getSelectionStart() != editor.getSelectionEnd();
+ break;
+ // ignore delete key
+ case KeyEvent.VK_DELETE:
+ e.consume();
+ comboBox.getToolkit().beep();
+ break;
+ }
+ }
+ };
+ // Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out
+ hidePopupOnFocusLoss = System.getProperty("java.version").startsWith("1.5");
+ // Highlight whole text when gaining focus
+ editorFocusListener = new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ highlightCompletedText(0);
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ // Workaround for Bug 5100422 - Hide Popup on focus loss
+ if (hidePopupOnFocusLoss) {
+ comboBox.setPopupVisible(false);
+ }
+ }
+ };
+ configureEditor(comboBox.getEditor());
+ // Handle initially selected object
+ Object selected = comboBox.getSelectedItem();
+ if (selected != null) {
+ setText(selected.toString());
+ }
+ highlightCompletedText(0);
+ }
+
+ public static void enable(JComboBox> comboBox) {
+ // has to be editable
+ comboBox.setEditable(true);
+ // change the editor's document
+ new AutoCompletion(comboBox);
+ }
+
+ void configureEditor(ComboBoxEditor newEditor) {
+ if (editor != null) {
+ editor.removeKeyListener(editorKeyListener);
+ editor.removeFocusListener(editorFocusListener);
+ }
+
+ if (newEditor != null) {
+ editor = (JTextComponent) newEditor.getEditorComponent();
+ editor.addKeyListener(editorKeyListener);
+ editor.addFocusListener(editorFocusListener);
+ editor.setDocument(this);
+ }
+ }
+
+ public void remove(int offs, int len) throws BadLocationException {
+ // return immediately when selecting an item
+ if (selecting) {
+ return;
+ }
+ if (hitBackspace) {
+ // user hit backspace => move the selection backwards
+ // old item keeps being selected
+ if (offs > 0) {
+ if (hitBackspaceOnSelection) {
+ offs--;
+ }
+ } else {
+ // User hit backspace with the cursor positioned on the start => beep
+ comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
+ }
+ highlightCompletedText(offs);
+ } else {
+ super.remove(offs, len);
+ }
+ }
+
+ @Override
+ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+ // return immediately when selecting an item
+ if (selecting) {
+ return;
+ }
+ // insert the string into the document
+ super.insertString(offs, str, a);
+ // lookup and select a matching item
+ Object item = lookupItem(getText(0, getLength()));
+ if (item != null) {
+ setSelectedItem(item);
+ } else {
+ // keep old item selected if there is no match
+ item = comboBox.getSelectedItem();
+ // imitate no insert (later on offs will be incremented by str.length(): selection won't move forward)
+ offs = offs - str.length();
+ // provide feedback to the user that his input has been received but can not be accepted
+ comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
+ }
+ setText(item.toString());
+ // select the completed part
+ highlightCompletedText(offs + str.length());
+ }
+
+ private void setText(String text) {
+ try {
+ // remove all text and insert the completed string
+ super.remove(0, getLength());
+ super.insertString(0, text, null);
+ } catch (BadLocationException e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ private void highlightCompletedText(int start) {
+ editor.setCaretPosition(getLength());
+ editor.moveCaretPosition(start);
+ }
+
+ private void setSelectedItem(Object item) {
+ selecting = true;
+ model.setSelectedItem(item);
+ selecting = false;
+ }
+
+ private Object lookupItem(String pattern) {
+ Object selectedItem = model.getSelectedItem();
+ // only search for a different item if the currently selected does not match
+ if (selectedItem != null && startsWithIgnoreCase(selectedItem.toString(), pattern)) {
+ return selectedItem;
+ } else {
+ // iterate over all items
+ for (int i = 0, n = model.getSize(); i < n; i++) {
+ Object currentItem = model.getElementAt(i);
+ // current item starts with the pattern?
+ if (currentItem != null && startsWithIgnoreCase(currentItem.toString(), pattern)) {
+ return currentItem;
+ }
+ }
+ }
+ // no item starts with the pattern => return null
+ return null;
+ }
+
+// checks if str1 starts with str2 - ignores case
+ private boolean startsWithIgnoreCase(String str1, String str2) {
+ return str1.toUpperCase().startsWith(str2.toUpperCase());
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java
index a6b5f897dd..a89d0ec680 100644
--- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java
+++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettings.java
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -402,7 +403,7 @@ public final class IngestJobSettings {
}
for (String moduleName : disabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
- missingModuleNames.add(moduleName);
+ logger.log(Level.WARNING, MessageFormat.format("A module marked as disabled in the ingest job settings, ''{0}'', could not be found.", moduleName));
}
}
for (String moduleName : missingModuleNames) {
diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java
index f341176820..ee7a69aee2 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java
@@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.modules.interestingitems;
+import org.sleuthkit.autopsy.guicomponentutils.AutoCompletion;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.util.Arrays;
@@ -76,6 +77,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
*/
FilesSetRulePanel(JButton okButton, JButton cancelButton, PANEL_TYPE panelType) {
initComponents();
+ AutoCompletion.enable(mimeTypeComboBox);
if (panelType == FilesSetDefsPanel.PANEL_TYPE.FILE_INGEST_FILTERS) { //Hide the mimetype settings when this is displaying a FileSet rule instead of a interesting item rule
mimeTypeComboBox.setVisible(false);
mimeCheck.setVisible(false);
@@ -102,6 +104,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
*/
FilesSetRulePanel(FilesSet.Rule rule, JButton okButton, JButton cancelButton, PANEL_TYPE panelType) {
initComponents();
+ AutoCompletion.enable(mimeTypeComboBox);
if (panelType == FilesSetDefsPanel.PANEL_TYPE.FILE_INGEST_FILTERS) { //Hide the mimetype settings when this is displaying a FileSet rule instead of a interesting item rule
mimeTypeComboBox.setVisible(false);
mimeCheck.setVisible(false);
diff --git a/KeywordSearch/ivy.xml b/KeywordSearch/ivy.xml
index 7b417a99c7..174c2e22fd 100644
--- a/KeywordSearch/ivy.xml
+++ b/KeywordSearch/ivy.xml
@@ -18,7 +18,8 @@
-
+
+
diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties
index bc6da03ae3..639894fee3 100644
--- a/KeywordSearch/nbproject/project.properties
+++ b/KeywordSearch/nbproject/project.properties
@@ -48,6 +48,7 @@ file.reference.stax2-api-4.2.1.jar=release/modules/ext/stax2-api-4.2.1.jar
file.reference.woodstox-core-6.2.4.jar=release/modules/ext/woodstox-core-6.2.4.jar
file.reference.zookeeper-3.8.0.jar=release/modules/ext/zookeeper-3.8.0.jar
file.reference.zookeeper-jute-3.8.0.jar=release/modules/ext/zookeeper-jute-3.8.0.jar
+file.reference.lucene-core-8.11.2.jar=release/modules/ext/lucene-core-8.11.2.jar
javac.source=17
javac.compilerargs=-Xlint -Xlint:-serial
license.file=../LICENSE-2.0.txt
diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml
index 9e170fac12..b1ec158a2a 100644
--- a/KeywordSearch/nbproject/project.xml
+++ b/KeywordSearch/nbproject/project.xml
@@ -434,6 +434,10 @@
ext/zookeeper-jute-3.8.0.jar
release/modules/ext/zookeeper-jute-3.8.0.jar
+
+ ext/lucene-core-8.11.2.jar
+ release/modules/ext/lucene-core-8.11.2.jar
+
diff --git a/KeywordSearch/solr/server/solr/configsets/AutopsyConfig/conf/solrconfig.xml b/KeywordSearch/solr/server/solr/configsets/AutopsyConfig/conf/solrconfig.xml
index 9fde79cd36..92ce238a46 100755
--- a/KeywordSearch/solr/server/solr/configsets/AutopsyConfig/conf/solrconfig.xml
+++ b/KeywordSearch/solr/server/solr/configsets/AutopsyConfig/conf/solrconfig.xml
@@ -301,7 +301,7 @@
300000
- true
+ false