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