Merge pull request #4229 from millmanorama/timeline-event-mgr
1093 Timeline event mgr
@ -26,7 +26,6 @@
|
||||
|
||||
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.1.1"/>
|
||||
<dependency conf="core->default" org="org.apache.commons" name="commons-pool2" rev="2.4.2"/>
|
||||
<dependency org="com.monitorjbl" name="xlsx-streamer" rev="1.2.1"/>
|
||||
|
||||
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
|
||||
<dependency conf="core->default" org="com.googlecode.plist" name="dd-plist" rev="1.20"/>
|
||||
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.core/10
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
|
||||
OpenIDE-Module-Implementation-Version: 24
|
||||
OpenIDE-Module-Implementation-Version: 25
|
||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||
AutoUpdate-Show-In-Client: true
|
||||
AutoUpdate-Essential-Module: true
|
||||
|
@ -29,13 +29,12 @@ file.reference.cxf-rt-transports-http-3.0.16.jar=release/modules/ext/cxf-rt-tran
|
||||
file.reference.fontbox-2.0.8.jar=release/modules/ext/fontbox-2.0.8.jar
|
||||
file.reference.pdfbox-2.0.8.jar=release/modules/ext/pdfbox-2.0.8.jar
|
||||
file.reference.pdfbox-tools-2.0.8.jar=release/modules/ext/pdfbox-tools-2.0.8.jar
|
||||
file.reference.sleuthkit-postgresql-4.6.2.jar=release/modules/ext/sleuthkit-postgresql-4.6.2.jar
|
||||
file.reference.sleuthkit-postgresql-4.6.3.jar=release/modules/ext/sleuthkit-postgresql-4.6.3.jar
|
||||
file.reference.tika-core-1.17.jar=release/modules/ext/tika-core-1.17.jar
|
||||
file.reference.tika-parsers-1.17.jar=release/modules/ext/tika-parsers-1.17.jar
|
||||
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
|
||||
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
|
||||
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
|
||||
file.reference.xlsx-streamer-1.2.1.jar=release/modules/ext/xlsx-streamer-1.2.1.jar
|
||||
file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
|
||||
file.reference.xz-1.6.jar=release/modules/ext/xz-1.6.jar
|
||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||
@ -48,5 +47,5 @@ nbm.homepage=http://www.sleuthkit.org/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
|
||||
spec.version.base=10.12
|
||||
spec.version.base=10.13
|
||||
|
||||
|
@ -394,8 +394,8 @@
|
||||
<binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-postgresql-4.6.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-postgresql-4.6.2.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-postgresql-4.6.3.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-postgresql-4.6.3.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>
|
||||
@ -497,10 +497,6 @@
|
||||
<runtime-relative-path>ext/SparseBitSet-1.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/SparseBitSet-1.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xlsx-streamer-1.2.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xlsx-streamer-1.2.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/pdfbox-2.0.8.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/pdfbox-2.0.8.jar</binary-origin>
|
||||
|
147
Core/src/org/sleuthkit/autopsy/casemodule/CasePreferences.java
Executable file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 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.casemodule;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||
|
||||
/**
|
||||
* Read and update case preference file values.
|
||||
*/
|
||||
public final class CasePreferences {
|
||||
|
||||
private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS
|
||||
private static final String KEY_GROUP_BY_DATA_SOURCE = "groupByDataSource"; //NON-NLS
|
||||
private static final String VALUE_TRUE = "true"; //NON-NLS
|
||||
private static final String VALUE_FALSE = "false"; //NON-NLS
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CasePreferences.class.getName());
|
||||
|
||||
private static Boolean groupItemsInTreeByDataSource = null;
|
||||
|
||||
/**
|
||||
* Prevent instantiation.
|
||||
*/
|
||||
private CasePreferences() {
|
||||
}
|
||||
|
||||
static {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
if (evt.getNewValue() != null) {
|
||||
loadFromStorage((Case) evt.getNewValue());
|
||||
} else {
|
||||
saveToStorage((Case) evt.getOldValue());
|
||||
clear();
|
||||
}
|
||||
});
|
||||
try {
|
||||
loadFromStorage(Case.getCurrentCaseThrows());
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "No current case open.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the 'groupItemsInTreeByDataSource' value. This can be true, false, or
|
||||
* null.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
public static Boolean getGroupItemsInTreeByDataSource() {
|
||||
return groupItemsInTreeByDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'groupItemsInTreeByDataSource' value to true or false.
|
||||
*
|
||||
* @param value The value to use for the value change.
|
||||
*/
|
||||
public static void setGroupItemsInTreeByDataSource(boolean value) {
|
||||
groupItemsInTreeByDataSource = value;
|
||||
DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load case preferences from the settings file.
|
||||
*/
|
||||
private static void loadFromStorage(Case currentCase) {
|
||||
Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS
|
||||
if (settingsFile.toFile().exists()) {
|
||||
// Read the settings
|
||||
try (InputStream inputStream = Files.newInputStream(settingsFile)) {
|
||||
Properties props = new Properties();
|
||||
props.load(inputStream);
|
||||
String groupByDataSourceValue = props.getProperty(KEY_GROUP_BY_DATA_SOURCE);
|
||||
if (groupByDataSourceValue != null) {
|
||||
switch (groupByDataSourceValue) {
|
||||
case VALUE_TRUE:
|
||||
groupItemsInTreeByDataSource = true;
|
||||
break;
|
||||
case VALUE_FALSE:
|
||||
groupItemsInTreeByDataSource = false;
|
||||
break;
|
||||
default:
|
||||
logger.log(Level.WARNING, String.format("Unexpected value '%s' for key '%s'. Using 'null' instead.",
|
||||
groupByDataSourceValue, KEY_GROUP_BY_DATA_SOURCE));
|
||||
groupItemsInTreeByDataSource = null;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
groupItemsInTreeByDataSource = null;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error reading settings file", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all values to their default states.
|
||||
*/
|
||||
private static void clear() {
|
||||
groupItemsInTreeByDataSource = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store case preferences in the settings file.
|
||||
*/
|
||||
private static void saveToStorage(Case currentCase) {
|
||||
Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS
|
||||
Properties props = new Properties();
|
||||
if (groupItemsInTreeByDataSource != null) {
|
||||
props.setProperty(KEY_GROUP_BY_DATA_SOURCE, (groupItemsInTreeByDataSource ? VALUE_TRUE : VALUE_FALSE));
|
||||
}
|
||||
|
||||
try (OutputStream fos = Files.newOutputStream(settingsFile)) {
|
||||
props.store(fos, ""); //NON-NLS
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error writing settings file", ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -203,11 +203,11 @@ public class SingleUserCaseConverter {
|
||||
icd.getCaseOutputFolder().toString(),
|
||||
icd.getNewCaseName(),
|
||||
new CaseDetails(icd.getNewCaseName(),
|
||||
oldCaseMetadata.getCaseNumber(),
|
||||
oldCaseMetadata.getExaminer(),
|
||||
oldCaseMetadata.getExaminerPhone(),
|
||||
oldCaseMetadata.getExaminerEmail(),
|
||||
oldCaseMetadata.getCaseNotes()));
|
||||
oldCaseMetadata.getCaseNumber(),
|
||||
oldCaseMetadata.getExaminer(),
|
||||
oldCaseMetadata.getExaminerPhone(),
|
||||
oldCaseMetadata.getExaminerEmail(),
|
||||
oldCaseMetadata.getCaseNotes()));
|
||||
newCaseMetadata.setCaseDatabaseName(dbName);
|
||||
// Set created date. This calls writefile, no need to call it again
|
||||
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
|
||||
@ -850,7 +850,7 @@ public class SingleUserCaseConverter {
|
||||
// content_tags
|
||||
biggestPK = 0;
|
||||
inputStatement = sqliteConnection.createStatement();
|
||||
inputResultSet = inputStatement.executeQuery("SELECT * FROM content_tags"); //NON-NLS
|
||||
inputResultSet = inputStatement.executeQuery("SELECT * FROM content_tags LEFT OUTER JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id"); //NON-NLS
|
||||
|
||||
while (inputResultSet.next()) {
|
||||
outputStatement = postgreSQLConnection.createStatement();
|
||||
@ -859,14 +859,14 @@ public class SingleUserCaseConverter {
|
||||
if (value > biggestPK) {
|
||||
biggestPK = value;
|
||||
}
|
||||
outputStatement.executeUpdate("INSERT INTO content_tags (tag_id, obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset, user_name) VALUES (" //NON-NLS
|
||||
outputStatement.executeUpdate("INSERT INTO content_tags (tag_id, obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset, examiner_id) VALUES (" //NON-NLS
|
||||
+ value + ","
|
||||
+ inputResultSet.getLong(2) + ","
|
||||
+ inputResultSet.getLong(3) + ",'"
|
||||
+ inputResultSet.getString(4) + "',"
|
||||
+ inputResultSet.getLong(5) + ","
|
||||
+ inputResultSet.getLong(6) + ",'"
|
||||
+ inputResultSet.getString(7)+ "')"); //NON-NLS
|
||||
+ inputResultSet.getLong(6) + ","
|
||||
+ inputResultSet.getInt(7) + ")"); //NON-NLS
|
||||
|
||||
} catch (SQLException ex) {
|
||||
if (ex.getErrorCode() != 0) { // 0 if the entry already exists
|
||||
|
@ -31,7 +31,7 @@ import org.openide.util.Lookup;
|
||||
iconBase = "org/sleuthkit/autopsy/casemodule/services/tag-options-panel-icon.png",
|
||||
keywords = "#OptionsCategory_TagNames",
|
||||
keywordsCategory = "CustomTagNames",
|
||||
position = 11
|
||||
position = 12
|
||||
)
|
||||
|
||||
public final class TagsOptionsPanelController extends OptionsPanelController {
|
||||
|
@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.centralrepository;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
@ -37,9 +39,9 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
* An AbstractAction to manage adding and modifying a Central Repository file
|
||||
* instance comment.
|
||||
*/
|
||||
|
||||
|
||||
@Messages({"AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoComment=Add/Edit Central Repository Comment"})
|
||||
@Messages({"AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentEmptyFile=Add/Edit Central Repository Comment (Empty File)",
|
||||
"AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentNoMD5=Add/Edit Central Repository Comment (No MD5 Hash)",
|
||||
"AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoComment=Add/Edit Central Repository Comment"})
|
||||
public final class AddEditCentralRepoCommentAction extends AbstractAction {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AddEditCentralRepoCommentAction.class.getName());
|
||||
@ -58,14 +60,19 @@ public final class AddEditCentralRepoCommentAction extends AbstractAction {
|
||||
*
|
||||
*/
|
||||
public AddEditCentralRepoCommentAction(AbstractFile file) {
|
||||
super(Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoComment());
|
||||
fileId = file.getId();
|
||||
correlationAttributeInstance = EamArtifactUtil.getInstanceFromContent(file);
|
||||
if (correlationAttributeInstance == null) {
|
||||
addToDatabase = true;
|
||||
correlationAttributeInstance = EamArtifactUtil.makeInstanceFromContent(file);
|
||||
}
|
||||
|
||||
if (file.getSize() == 0) {
|
||||
putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoCommentEmptyFile());
|
||||
} else if (StringUtils.isBlank(file.getMd5Hash())) {
|
||||
putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoCommentNoMD5());
|
||||
} else {
|
||||
putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoComment());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,6 +35,7 @@
|
||||
<EmptySpace min="0" pref="451" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="remainingCharactersLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="okButton" min="-2" pref="75" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
@ -53,9 +54,12 @@
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="remainingCharactersLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -104,9 +108,10 @@
|
||||
<Component class="javax.swing.JLabel" name="commentLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/Bundle.properties" key="CentralRepoCommentDialog.commentLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/Bundle.properties" key="CentralRepoCommentDialog.commentLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="remainingCharactersLabel"></Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -18,8 +18,12 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository;
|
||||
|
||||
import javax.swing.text.AbstractDocument;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DocumentFilter;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
|
||||
/**
|
||||
@ -37,20 +41,24 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
/**
|
||||
* Create an instance.
|
||||
*
|
||||
* @param correlationAttributeInstance The correlation attribute to be modified.
|
||||
* @param correlationAttributeInstance The correlation attribute to be
|
||||
* modified.
|
||||
*/
|
||||
CentralRepoCommentDialog(CorrelationAttributeInstance correlationAttributeInstance) {
|
||||
super(WindowManager.getDefault().getMainWindow(), Bundle.CentralRepoCommentDialog_title_addEditCentralRepoComment());
|
||||
|
||||
|
||||
initComponents();
|
||||
|
||||
CorrelationAttributeInstance instance = correlationAttributeInstance;
|
||||
|
||||
|
||||
// Store the original comment
|
||||
if (instance.getComment() != null) {
|
||||
currentComment = instance.getComment();
|
||||
}
|
||||
|
||||
//Truncate legacy comments to be MAX_CHARACTERS characters, pressing 'okay'
|
||||
//once the editted comment is loaded in will truncate it in the database as
|
||||
//well.
|
||||
commentTextArea.setText(instance.getComment());
|
||||
|
||||
this.correlationAttributeInstance = correlationAttributeInstance;
|
||||
@ -76,18 +84,118 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
boolean isCommentUpdated() {
|
||||
return commentUpdated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current comment.
|
||||
* If the user hit OK, this will be the new comment.
|
||||
* If the user canceled, this will be the original comment.
|
||||
*
|
||||
* Get the current comment. If the user hit OK, this will be the new
|
||||
* comment. If the user canceled, this will be the original comment.
|
||||
*
|
||||
* @return the comment
|
||||
*/
|
||||
String getComment() {
|
||||
return currentComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits the number of characters that can go into the Comment JTextArea of
|
||||
* this Dialog box.
|
||||
*/
|
||||
private class CentralRepoCommentLengthFilter extends DocumentFilter {
|
||||
|
||||
private final Integer MAX_CHARACTERS = 500;
|
||||
private Integer remainingCharacters = MAX_CHARACTERS;
|
||||
|
||||
public CentralRepoCommentLengthFilter() {
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the insert string if its addition in the Comment dialog box
|
||||
* will cause it to go past MAX_CHARACTERS in length.
|
||||
*
|
||||
* @param filter FilterBypass that can be used to mutate Document
|
||||
* @param offset the offset into the document to insert the content >=
|
||||
* 0. All positions that track change at or after the
|
||||
* given location will move.
|
||||
* @param input the string to insert
|
||||
* @param attrSet the attributes to associate with the inserted content.
|
||||
* This may be null if there are no attributes.
|
||||
*
|
||||
* @throws BadLocationException the given insert position is not a valid
|
||||
* position within the document
|
||||
*/
|
||||
public void insertString(FilterBypass filter, int offset, String input,
|
||||
AttributeSet attrSet) throws BadLocationException {
|
||||
//Truncate the insert if its too long
|
||||
this.replace(filter, offset, 0, input, attrSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the number of characters from the Comment Text box and add
|
||||
* back to our remaining count.
|
||||
*
|
||||
* @param filter FilterBypass that can be used to mutate Document
|
||||
* @param offset the offset from the beginning >= 0
|
||||
* @param length the number of characters to remove >= 0
|
||||
*
|
||||
* @throws BadLocationException some portion of the removal range was
|
||||
* not a valid part of the document. The
|
||||
* location in the exception is the first
|
||||
* bad position encountered.
|
||||
*/
|
||||
public void remove(FilterBypass filter, int offset, int length)
|
||||
throws BadLocationException {
|
||||
super.remove(filter, offset, length);
|
||||
remainingCharacters += length;
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the current text at the offset position with the inputted
|
||||
* text. If the offset is the end of the text box, then this functions
|
||||
* like an append. Truncate this input if its addition will cause the
|
||||
* Comment text box to be > MAX_CHARACTERS in length.
|
||||
*
|
||||
* @param filter FilterBypass that can be used to mutate Document
|
||||
* @param offset Location in Document
|
||||
* @param length Length of text to delete
|
||||
* @param input Text to insert, null indicates no text to insert
|
||||
* @param attrSet AttributeSet indicating attributes of inserted text,
|
||||
* null is legal.
|
||||
*
|
||||
* @throws BadLocationException the given insert position is not a valid
|
||||
* position within the document
|
||||
*/
|
||||
public void replace(FilterBypass filter, int offset, int length, String input,
|
||||
AttributeSet attrSet) throws BadLocationException {
|
||||
//Truncate the replace if its too long
|
||||
String truncatedText = input;
|
||||
if ((filter.getDocument().getLength() + input.length() - length) > MAX_CHARACTERS) {
|
||||
truncatedText = input.substring(0, MAX_CHARACTERS -
|
||||
filter.getDocument().getLength() - length);
|
||||
}
|
||||
super.replace(filter, offset, length, truncatedText, attrSet);
|
||||
remainingCharacters -= truncatedText.length() - length;
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the remainingCharactersLabel to reflect the current state.
|
||||
* If there are no more characters left, a red 0 is displayed in the
|
||||
* UI.
|
||||
*/
|
||||
private void updateLabel() {
|
||||
if (remainingCharacters == 0) {
|
||||
remainingCharactersLabel.setText(String.format(
|
||||
"<html><font color=\"red\">%d</font> %s</html>",
|
||||
remainingCharacters, "characters remaining"));
|
||||
} else {
|
||||
remainingCharactersLabel.setText(String.format(
|
||||
"<html><font color=\"black\">%d</font> %s</html>",
|
||||
remainingCharacters, "characters remaining"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
@ -102,6 +210,7 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
okButton = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
commentLabel = new javax.swing.JLabel();
|
||||
remainingCharactersLabel = new javax.swing.JLabel();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setSize(getPreferredSize());
|
||||
@ -111,6 +220,8 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
commentTextArea.setRows(5);
|
||||
commentTextArea.setTabSize(4);
|
||||
commentTextArea.setWrapStyleWord(true);
|
||||
((AbstractDocument)commentTextArea.getDocument())
|
||||
.setDocumentFilter(new CentralRepoCommentLengthFilter());
|
||||
jScrollPane1.setViewportView(commentTextArea);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(CentralRepoCommentDialog.class, "CentralRepoCommentDialog.okButton.text")); // NOI18N
|
||||
@ -141,7 +252,8 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
.addComponent(commentLabel)
|
||||
.addGap(0, 451, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(remainingCharactersLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
@ -155,9 +267,11 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cancelButton)
|
||||
.addComponent(okButton))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cancelButton)
|
||||
.addComponent(okButton))
|
||||
.addComponent(remainingCharactersLabel))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
@ -180,6 +294,7 @@ final class CentralRepoCommentDialog extends javax.swing.JDialog {
|
||||
private javax.swing.JButton cancelButton;
|
||||
private javax.swing.JLabel commentLabel;
|
||||
private javax.swing.JTextArea commentTextArea;
|
||||
private javax.swing.JLabel remainingCharactersLabel;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JButton okButton;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
@ -18,6 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -34,6 +37,8 @@ import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil.updateSchemaVersion;
|
||||
@ -57,7 +62,21 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
private int bulkArtifactsCount;
|
||||
protected int bulkArtifactsThreshold;
|
||||
private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
|
||||
|
||||
private static final int CASE_CACHE_TIMEOUT = 5;
|
||||
private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
|
||||
private static final Cache<Integer, CorrelationAttributeInstance.Type> typeCache = CacheBuilder.newBuilder().build();
|
||||
private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
|
||||
build();
|
||||
private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
|
||||
build();
|
||||
private static final Cache<String, CorrelationDataSource> dataSourceCacheByDeviceId = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
|
||||
build();
|
||||
private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
|
||||
build();
|
||||
// Maximum length for the value column in the instance tables
|
||||
static final int MAX_VALUE_LENGTH = 256;
|
||||
|
||||
@ -88,7 +107,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
/**
|
||||
* Add a new name/value pair in the db_info table.
|
||||
*
|
||||
* @param name Key to set
|
||||
* @param name Key to set
|
||||
* @param value Value to set
|
||||
*
|
||||
* @throws EamDbException
|
||||
@ -149,10 +168,21 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the contents of the caches associated with EamDb results.
|
||||
*/
|
||||
protected final void clearCaches() {
|
||||
typeCache.invalidateAll();
|
||||
caseCacheByUUID.invalidateAll();
|
||||
caseCacheById.invalidateAll();
|
||||
dataSourceCacheByDeviceId.invalidateAll();
|
||||
dataSourceCacheById.invalidateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the value for a name in the name/value db_info table.
|
||||
*
|
||||
* @param name Name to find
|
||||
* @param name Name to find
|
||||
* @param value Value to assign to name.
|
||||
*
|
||||
* @throws EamDbException
|
||||
@ -201,9 +231,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
+ "examiner_name, examiner_email, examiner_phone, notes) "
|
||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
|
||||
+ getConflictClause();
|
||||
|
||||
ResultSet resultSet = null;
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(sql);
|
||||
preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
preparedStatement.setString(1, eamCase.getCaseUUID());
|
||||
if (null == eamCase.getOrg()) {
|
||||
@ -240,9 +270,21 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
}
|
||||
|
||||
preparedStatement.executeUpdate();
|
||||
//update the case in the caches
|
||||
resultSet = preparedStatement.getGeneratedKeys();
|
||||
if (!resultSet.next()) {
|
||||
throw new EamDbException(String.format("Failed to INSERT case %s in central repo", eamCase.getCaseUUID()));
|
||||
}
|
||||
int caseID = resultSet.getInt(1); //last_insert_rowid()
|
||||
CorrelationCase correlationCase = new CorrelationCase(caseID, eamCase.getCaseUUID(), eamCase.getOrg(),
|
||||
eamCase.getDisplayName(), eamCase.getCreationDate(), eamCase.getCaseNumber(), eamCase.getExaminerName(),
|
||||
eamCase.getExaminerEmail(), eamCase.getExaminerPhone(), eamCase.getNotes());
|
||||
caseCacheByUUID.put(eamCase.getCaseUUID(), correlationCase);
|
||||
caseCacheById.put(caseID, correlationCase);
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error inserting new case.", ex); // NON-NLS
|
||||
} finally {
|
||||
EamDbUtil.closeResultSet(resultSet);
|
||||
EamDbUtil.closeStatement(preparedStatement);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
@ -339,6 +381,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
preparedStatement.setString(9, eamCase.getCaseUUID());
|
||||
|
||||
preparedStatement.executeUpdate();
|
||||
//update the case in the cache
|
||||
caseCacheById.put(eamCase.getID(), eamCase);
|
||||
caseCacheByUUID.put(eamCase.getCaseUUID(), eamCase);
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error updating case.", ex); // NON-NLS
|
||||
} finally {
|
||||
@ -347,6 +392,25 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Case details based on Case UUID from the central repo
|
||||
*
|
||||
* @param caseUUID unique identifier for a case
|
||||
*
|
||||
* @return The retrieved case
|
||||
*/
|
||||
@Override
|
||||
public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
|
||||
try {
|
||||
return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
|
||||
} catch (CacheLoader.InvalidCacheLoadException ignored) {
|
||||
//lambda valueloader returned a null value and cache can not store null values this is normal if the case does not exist in the central repo yet
|
||||
return null;
|
||||
} catch (ExecutionException ex) {
|
||||
throw new EamDbException("Error getting autopsy case from Central repo", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Case details based on Case UUID
|
||||
*
|
||||
@ -354,10 +418,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
*
|
||||
* @return The retrieved case
|
||||
*/
|
||||
@Override
|
||||
public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
|
||||
// @@@ We should have a cache here...
|
||||
|
||||
private CorrelationCase getCaseByUUIDFromCr(String caseUUID) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
CorrelationCase eamCaseResult = null;
|
||||
@ -377,6 +438,10 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
if (resultSet.next()) {
|
||||
eamCaseResult = getEamCaseFromResultSet(resultSet);
|
||||
}
|
||||
if (eamCaseResult != null) {
|
||||
//Update the version in the other cache
|
||||
caseCacheById.put(eamCaseResult.getID(), eamCaseResult);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error getting case details.", ex); // NON-NLS
|
||||
} finally {
|
||||
@ -397,8 +462,24 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
*/
|
||||
@Override
|
||||
public CorrelationCase getCaseById(int caseId) throws EamDbException {
|
||||
// @@@ We should have a cache here...
|
||||
try {
|
||||
return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
|
||||
} catch (CacheLoader.InvalidCacheLoadException ignored) {
|
||||
//lambda valueloader returned a null value and cache can not store null values this is normal if the case does not exist in the central repo yet
|
||||
return null;
|
||||
} catch (ExecutionException ex) {
|
||||
throw new EamDbException("Error getting autopsy case from Central repo", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Case details based on Case ID
|
||||
*
|
||||
* @param caseID unique identifier for a case
|
||||
*
|
||||
* @return The retrieved case
|
||||
*/
|
||||
private CorrelationCase getCaseByIdFromCr(int caseId) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
CorrelationCase eamCaseResult = null;
|
||||
@ -410,7 +491,6 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
+ "FROM cases "
|
||||
+ "LEFT JOIN organizations ON cases.org_id=organizations.id "
|
||||
+ "WHERE cases.id=?";
|
||||
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(sql);
|
||||
preparedStatement.setInt(1, caseId);
|
||||
@ -418,6 +498,10 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
if (resultSet.next()) {
|
||||
eamCaseResult = getEamCaseFromResultSet(resultSet);
|
||||
}
|
||||
if (eamCaseResult != null) {
|
||||
//Update the version in the other cache
|
||||
caseCacheByUUID.put(eamCaseResult.getCaseUUID(), eamCaseResult);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error getting case details.", ex); // NON-NLS
|
||||
} finally {
|
||||
@ -466,6 +550,32 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
return cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a key to the DataSourceCacheByDeviceId
|
||||
*
|
||||
* @param caseId - the id of the CorrelationCase in the Central
|
||||
* Repository
|
||||
* @param dataSourceDeviceId - the device Id of the data source
|
||||
*
|
||||
* @return a String to be used as a key for the dataSourceCacheByDeviceId
|
||||
*/
|
||||
private static String getDataSourceByDeviceIdCacheKey(int caseId, String dataSourceDeviceId) {
|
||||
return "Case" + caseId + "DeviceId" + dataSourceDeviceId; //NON-NLS
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a key to the DataSourceCacheById
|
||||
*
|
||||
* @param caseId - the id of the CorrelationCase in the Central
|
||||
* Repository
|
||||
* @param dataSourceId - the id of the datasource in the central repository
|
||||
*
|
||||
* @return a String to be used as a key for the dataSourceCacheById
|
||||
*/
|
||||
private static String getDataSourceByIdCacheKey(int caseId, int dataSourceId) {
|
||||
return "Case" + caseId + "Id" + dataSourceId; //NON-NLS
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Data Source in the database
|
||||
*
|
||||
@ -485,18 +595,27 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) "
|
||||
+ getConflictClause();
|
||||
|
||||
ResultSet resultSet = null;
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(sql);
|
||||
preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
preparedStatement.setString(1, eamDataSource.getDeviceID());
|
||||
preparedStatement.setInt(2, eamDataSource.getCaseID());
|
||||
preparedStatement.setString(3, eamDataSource.getName());
|
||||
|
||||
preparedStatement.executeUpdate();
|
||||
resultSet = preparedStatement.getGeneratedKeys();
|
||||
if (!resultSet.next()) {
|
||||
throw new EamDbException(String.format("Failed to INSERT data source %s in central repo", eamDataSource.getName()));
|
||||
}
|
||||
int dataSourceId = resultSet.getInt(1); //last_insert_rowid()
|
||||
CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName());
|
||||
dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(dataSource.getCaseID(), dataSource.getDeviceID()), dataSource);
|
||||
dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource);
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error inserting new data source.", ex); // NON-NLS
|
||||
} finally {
|
||||
EamDbUtil.closeResultSet(resultSet);
|
||||
EamDbUtil.closeStatement(preparedStatement);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
@ -505,18 +624,43 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
/**
|
||||
* Retrieves Data Source details based on data source device ID
|
||||
*
|
||||
* @param correlationCase the current CorrelationCase used for ensuring
|
||||
* uniqueness of DataSource
|
||||
* @param correlationCase the current CorrelationCase used for ensuring
|
||||
* uniqueness of DataSource
|
||||
* @param dataSourceDeviceId the data source device ID number
|
||||
*
|
||||
* @return The data source
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
|
||||
|
||||
if (correlationCase == null) {
|
||||
throw new EamDbException("Correlation case is null");
|
||||
}
|
||||
try {
|
||||
return dataSourceCacheByDeviceId.get(getDataSourceByDeviceIdCacheKey(correlationCase.getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId));
|
||||
} catch (CacheLoader.InvalidCacheLoadException ignored) {
|
||||
//lambda valueloader returned a null value and cache can not store null values this is normal if the dataSource does not exist in the central repo yet
|
||||
return null;
|
||||
} catch (ExecutionException ex) {
|
||||
throw new EamDbException("Error getting data source from central repository", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Data Source details based on data source device ID from the
|
||||
* central repository.
|
||||
*
|
||||
* @param correlationCase the current CorrelationCase used for ensuring
|
||||
* uniqueness of DataSource
|
||||
* @param dataSourceDeviceId the data source device ID number
|
||||
*
|
||||
* @return The data source
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
private CorrelationDataSource getDataSourceFromCr(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
CorrelationDataSource eamDataSourceResult = null;
|
||||
@ -533,6 +677,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
if (resultSet.next()) {
|
||||
eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
|
||||
}
|
||||
if (eamDataSourceResult != null) {
|
||||
dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCase.getID(), eamDataSourceResult.getID()), eamDataSourceResult);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error getting data source.", ex); // NON-NLS
|
||||
} finally {
|
||||
@ -548,8 +695,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Retrieves Data Source details based on data source ID
|
||||
*
|
||||
* @param correlationCase the current CorrelationCase used for ensuring
|
||||
* uniqueness of DataSource
|
||||
* @param dataSourceId the data source ID number
|
||||
* uniqueness of DataSource
|
||||
* @param dataSourceId the data source ID number
|
||||
*
|
||||
* @return The data source
|
||||
*/
|
||||
@ -558,7 +705,26 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
if (correlationCase == null) {
|
||||
throw new EamDbException("Correlation case is null");
|
||||
}
|
||||
try {
|
||||
return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
|
||||
} catch (CacheLoader.InvalidCacheLoadException ignored) {
|
||||
//lambda valueloader returned a null value and cache can not store null values this is normal if the dataSource does not exist in the central repo yet
|
||||
return null;
|
||||
} catch (ExecutionException ex) {
|
||||
throw new EamDbException("Error getting data source from central repository", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Data Source details based on data source ID
|
||||
*
|
||||
* @param correlationCase the current CorrelationCase used for ensuring
|
||||
* uniqueness of DataSource
|
||||
* @param dataSourceId the data source ID number
|
||||
*
|
||||
* @return The data source
|
||||
*/
|
||||
private CorrelationDataSource getDataSourceByIdFromCr(CorrelationCase correlationCase, int dataSourceId) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
CorrelationDataSource eamDataSourceResult = null;
|
||||
@ -575,6 +741,9 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
if (resultSet.next()) {
|
||||
eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
|
||||
}
|
||||
if (eamDataSourceResult != null) {
|
||||
dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDeviceID()), eamDataSourceResult);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error getting data source.", ex); // NON-NLS
|
||||
} finally {
|
||||
@ -715,7 +884,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
|
||||
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||
|
||||
|
||||
Connection conn = connect();
|
||||
|
||||
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
|
||||
@ -764,7 +933,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Retrieves eamArtifact instances from the database that are associated
|
||||
* with the aType and filePath
|
||||
*
|
||||
* @param aType EamArtifact.Type to search for
|
||||
* @param aType EamArtifact.Type to search for
|
||||
* @param filePath File path to search for
|
||||
*
|
||||
* @return List of 0 or more EamArtifactInstances
|
||||
@ -835,7 +1004,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param value The correlation value
|
||||
*
|
||||
* @return Number of artifact instances having ArtifactType and
|
||||
* ArtifactValue.
|
||||
* ArtifactValue.
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
@ -957,11 +1126,11 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* associated with the caseDisplayName and dataSource of the given
|
||||
* eamArtifact instance.
|
||||
*
|
||||
* @param caseUUID Case ID to search for
|
||||
* @param caseUUID Case ID to search for
|
||||
* @param dataSourceID Data source ID to search for
|
||||
*
|
||||
* @return Number of artifact instances having caseDisplayName and
|
||||
* dataSource
|
||||
* dataSource
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException {
|
||||
@ -1224,7 +1393,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* associated CorrelationAttribute object.
|
||||
*
|
||||
* @param eamArtifact The correlation attribute whose database instance will
|
||||
* be updated.
|
||||
* be updated.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@ -1274,11 +1443,11 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Find a correlation attribute in the Central Repository database given the
|
||||
* instance type, case, data source, value, and file path.
|
||||
*
|
||||
* @param type The type of instance.
|
||||
* @param correlationCase The case tied to the instance.
|
||||
* @param type The type of instance.
|
||||
* @param correlationCase The case tied to the instance.
|
||||
* @param correlationDataSource The data source tied to the instance.
|
||||
* @param value The value tied to the instance.
|
||||
* @param filePath The file path tied to the instance.
|
||||
* @param value The value tied to the instance.
|
||||
* @param filePath The file path tied to the instance.
|
||||
*
|
||||
* @return The correlation attribute if it exists; otherwise null.
|
||||
*
|
||||
@ -1287,7 +1456,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
@Override
|
||||
public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
|
||||
CorrelationDataSource correlationDataSource, String value, String filePath) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
|
||||
|
||||
if (correlationCase == null) {
|
||||
throw new EamDbException("Correlation case is null");
|
||||
}
|
||||
@ -1306,7 +1475,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
try {
|
||||
String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
|
||||
|
||||
|
||||
String tableName = EamDbUtil.correlationTypeToInstanceTableName(type);
|
||||
String sql
|
||||
= "SELECT id, known_status, comment FROM "
|
||||
@ -1349,7 +1518,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
*
|
||||
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
|
||||
* @param knownStatus The status to change the artifact to. Should never be
|
||||
* KNOWN
|
||||
* KNOWN
|
||||
*/
|
||||
@Override
|
||||
public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
@ -1548,7 +1717,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
artifactInstances.add(artifactInstance);
|
||||
} catch (CorrelationAttributeNormalizationException ex) {
|
||||
logger.log(Level.INFO, "Unable to get artifact instance from resultset.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error getting notable artifact instances.", ex); // NON-NLS
|
||||
@ -1571,7 +1740,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
|
||||
|
||||
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||
|
||||
Connection conn = connect();
|
||||
@ -1612,13 +1781,13 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param value Value to search for
|
||||
*
|
||||
* @return List of cases containing this artifact with instances marked as
|
||||
* bad
|
||||
* bad
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
|
||||
|
||||
String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||
|
||||
Connection conn = connect();
|
||||
@ -1778,7 +1947,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
|
||||
String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
|
||||
|
||||
|
||||
Connection conn = connect();
|
||||
|
||||
Long matchingInstances = 0L;
|
||||
@ -1816,10 +1985,10 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
*/
|
||||
@Override
|
||||
public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value) throws EamDbException, CorrelationAttributeNormalizationException {
|
||||
|
||||
|
||||
//this should be done here so that we can be certain that aType and value are valid before we proceed
|
||||
String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
|
||||
|
||||
|
||||
// TEMP: Only support file correlation type
|
||||
if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
|
||||
return false;
|
||||
@ -1832,7 +2001,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
ResultSet resultSet = null;
|
||||
String sql = "SELECT count(*) FROM %s WHERE value=? AND known_status=?";
|
||||
|
||||
try {
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(aType)));
|
||||
preparedStatement.setString(1, normalizeValued);
|
||||
preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
|
||||
@ -1853,7 +2022,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
/**
|
||||
* Process the Artifact instance in the EamDb
|
||||
*
|
||||
* @param type EamArtifact.Type to search for
|
||||
* @param type EamArtifact.Type to search for
|
||||
* @param instanceTableCallback callback to process the instance
|
||||
*
|
||||
* @throws EamDbException
|
||||
@ -1892,9 +2061,10 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
/**
|
||||
* Process the Artifact instance in the EamDb give a where clause
|
||||
*
|
||||
* @param type EamArtifact.Type to search for
|
||||
* @param type EamArtifact.Type to search for
|
||||
* @param instanceTableCallback callback to process the instance
|
||||
* @param whereClause query string to execute
|
||||
* @param whereClause query string to execute
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
@ -2076,7 +2246,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Update an existing organization.
|
||||
*
|
||||
* @param updatedOrganization the values the Organization with the same ID
|
||||
* will be updated to in the database.
|
||||
* will be updated to in the database.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@ -2279,7 +2449,8 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Add a new reference instance
|
||||
*
|
||||
* @param eamGlobalFileInstance The reference instance to add
|
||||
* @param correlationType Correlation Type that this Reference Instance is
|
||||
* @param correlationType Correlation Type that this Reference
|
||||
* Instance is
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@ -2407,7 +2578,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
/**
|
||||
* Get all reference entries having a given correlation type and value
|
||||
*
|
||||
* @param aType Type to use for matching
|
||||
* @param aType Type to use for matching
|
||||
* @param aValue Value to use for matching
|
||||
*
|
||||
* @return List of all global file instances with a type and value
|
||||
@ -2440,7 +2611,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
EamDbUtil.closeResultSet(resultSet);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
|
||||
|
||||
return globalFileInstances;
|
||||
}
|
||||
|
||||
@ -2607,7 +2778,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* artifacts.
|
||||
*
|
||||
* @return List of enabled EamArtifact.Type's. If none are defined in the
|
||||
* database, the default list will be returned.
|
||||
* database, the default list will be returned.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@ -2642,7 +2813,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* correlate artifacts.
|
||||
*
|
||||
* @return List of supported EamArtifact.Type's. If none are defined in the
|
||||
* database, the default list will be returned.
|
||||
* database, the default list will be returned.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@ -2694,7 +2865,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
|
||||
preparedStatement.setInt(5, aType.getId());
|
||||
preparedStatement.executeUpdate();
|
||||
|
||||
typeCache.put(aType.getId(), aType);
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error updating correlation type.", ex); // NON-NLS
|
||||
} finally {
|
||||
@ -2715,6 +2886,26 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
*/
|
||||
@Override
|
||||
public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws EamDbException {
|
||||
try {
|
||||
return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
|
||||
} catch (CacheLoader.InvalidCacheLoadException ignored) {
|
||||
//lambda valueloader returned a null value and cache can not store null values this is normal if the correlation type does not exist in the central repo yet
|
||||
return null;
|
||||
} catch (ExecutionException ex) {
|
||||
throw new EamDbException("Error getting correlation type", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the EamArtifact.Type that has the given Type.Id from the central repo
|
||||
*
|
||||
* @param typeId Type.Id of Correlation Type to get
|
||||
*
|
||||
* @return EamArtifact.Type or null if it doesn't exist.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(int typeId) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
CorrelationAttributeInstance.Type aType;
|
||||
@ -2746,7 +2937,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Convert a ResultSet to a EamCase object
|
||||
*
|
||||
* @param resultSet A resultSet with a set of values to create a EamCase
|
||||
* object.
|
||||
* object.
|
||||
*
|
||||
* @return fully populated EamCase object, or null
|
||||
*
|
||||
@ -2816,7 +3007,7 @@ abstract class AbstractSqlEamDb implements EamDb {
|
||||
* Convert a ResultSet to a EamArtifactInstance object
|
||||
*
|
||||
* @param resultSet A resultSet with a set of values to create a
|
||||
* EamArtifactInstance object.
|
||||
* EamArtifactInstance object.
|
||||
*
|
||||
* @return fully populated EamArtifactInstance, or null
|
||||
*
|
||||
|
@ -283,7 +283,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id Unique ID for this Correlation Type
|
||||
* @param typeId Unique ID for this Correlation Type
|
||||
* @param displayName Name of this type displayed in the UI.
|
||||
* @param dbTableName Central repository db table where data of this
|
||||
* type is stored. Must start with a lowercase letter and only contain
|
||||
@ -387,7 +387,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the typeId to set
|
||||
* @param typeId the typeId to set
|
||||
*/
|
||||
public void setId(int typeId) {
|
||||
this.typeId = typeId;
|
||||
|
@ -55,8 +55,6 @@ public class EamArtifactUtil {
|
||||
* null.
|
||||
*
|
||||
* @param bbArtifact BlackboardArtifact to examine
|
||||
* @param addInstanceDetails If true, add instance details from bbArtifact
|
||||
* into the returned structure
|
||||
* @param checkEnabled If true, only create a CorrelationAttribute if it is
|
||||
* enabled
|
||||
*
|
||||
@ -129,7 +127,10 @@ public class EamArtifactUtil {
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() == artifactTypeID)) {
|
||||
|
||||
// Lower-case this to normalize domains
|
||||
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN)).getValueString();
|
||||
BlackboardAttribute attribute = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN));
|
||||
if (attribute != null) {
|
||||
value = attribute.getValueString();
|
||||
}
|
||||
} else if (correlationType.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID
|
||||
&& (BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID() == artifactTypeID
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() == artifactTypeID
|
||||
@ -173,7 +174,7 @@ public class EamArtifactUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null != value) {
|
||||
if ((null != value) && (value.isEmpty() == false)) {
|
||||
return makeCorrelationAttributeInstanceUsingTypeValue(bbArtifact, correlationType, value);
|
||||
} else {
|
||||
return null;
|
||||
|
@ -178,7 +178,7 @@ public interface EamDb {
|
||||
/**
|
||||
* Retrieves Case details based on Case ID
|
||||
*
|
||||
* @param caseID unique identifier for a case
|
||||
* @param caseId unique identifier for a case
|
||||
*
|
||||
* @return The retrieved case
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2015-2017 Basis Technology Corp.
|
||||
* Copyright 2015-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -78,6 +78,7 @@ final class PostgresEamDb extends AbstractSqlEamDb {
|
||||
connectionPool.close();
|
||||
connectionPool = null; // force it to be re-created on next connect()
|
||||
}
|
||||
clearCaches();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2015-2017 Basis Technology Corp.
|
||||
* Copyright 2015-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -85,6 +85,7 @@ final class SqliteEamDb extends AbstractSqlEamDb {
|
||||
connectionPool.close();
|
||||
connectionPool = null; // force it to be re-created on next connect()
|
||||
}
|
||||
clearCaches();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS
|
||||
|
@ -42,7 +42,7 @@ public class IngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||
*
|
||||
* @return The module name.
|
||||
*/
|
||||
static String getModuleName() {
|
||||
public static String getModuleName() {
|
||||
return Bundle.IngestModuleFactory_ingestmodule_name();
|
||||
}
|
||||
|
||||
|
@ -75,3 +75,4 @@ ShowCasesDialog.title=Case Details
|
||||
GlobalSettingsPanel.Case\ Details.AccessibleContext.accessibleName=Cases Details
|
||||
ShowCasesDialog.caseDetailsTable.AccessibleContext.accessibleDescription=Click column name to sort.
|
||||
GlobalSettingsPanel.casesTextArea.text=Display table that lists central repository case details.
|
||||
GlobalSettingsPanel.ingestRunningWarningLabel.text=Cannot make changes to central repository settings when ingest is running!
|
||||
|
@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
*/
|
||||
@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Central_Repository_Options",
|
||||
iconBase = "org/sleuthkit/autopsy/centralrepository/images/options-icon.png",
|
||||
position = 14,
|
||||
position = 15,
|
||||
keywords = "#OptionsCategory_Keywords_Central_Repository_Options",
|
||||
keywordsCategory = "CentralRepository")
|
||||
public final class EamOptionsPanelController extends OptionsPanelController {
|
||||
|
@ -27,7 +27,7 @@
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="517" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="0" pref="512" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
@ -61,21 +61,20 @@
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="pnDatabaseConfiguration" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="pnCorrelationProperties" alignment="0" pref="1016" max="32767" attributes="0"/>
|
||||
<Component id="pnCorrelationProperties" alignment="0" pref="1012" max="32767" attributes="0"/>
|
||||
<Component id="organizationPanel" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="casesPanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cbUseCentralRepo" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="cbUseCentralRepo" min="-2" pref="162" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="ingestRunningWarningLabel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tbOops" min="-2" pref="974" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -84,7 +83,10 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lbCentralRepository" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbUseCentralRepo" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cbUseCentralRepo" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="ingestRunningWarningLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="pnDatabaseConfiguration" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
@ -512,6 +514,21 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="ingestRunningWarningLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="false" component="ingestRunningWarningLabel" property="font" relativeSize="false" size="11"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/modules/filetypeid/warning16.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.ingestRunningWarningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
@ -129,6 +129,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
casesScrollPane = new javax.swing.JScrollPane();
|
||||
casesTextArea = new javax.swing.JTextArea();
|
||||
tbOops = new javax.swing.JTextField();
|
||||
ingestRunningWarningLabel = new javax.swing.JLabel();
|
||||
|
||||
setName(""); // NOI18N
|
||||
setPreferredSize(new java.awt.Dimension(1022, 488));
|
||||
@ -347,6 +348,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
|
||||
tbOops.setBorder(null);
|
||||
|
||||
ingestRunningWarningLabel.setFont(ingestRunningWarningLabel.getFont().deriveFont(ingestRunningWarningLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||
ingestRunningWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/filetypeid/warning16.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ingestRunningWarningLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.ingestRunningWarningLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
@ -355,24 +360,26 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1016, Short.MAX_VALUE)
|
||||
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.DEFAULT_SIZE, 1012, Short.MAX_VALUE)
|
||||
.addComponent(organizationPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(casesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cbUseCentralRepo)
|
||||
.addComponent(casesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(cbUseCentralRepo, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 974, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(lbCentralRepository)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cbUseCentralRepo)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cbUseCentralRepo)
|
||||
.addComponent(ingestRunningWarningLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
@ -398,7 +405,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 517, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 512, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -555,6 +562,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
|
||||
if (IngestManager.getInstance().isIngestRunning()) {
|
||||
tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning());
|
||||
tbOops.setVisible(true);
|
||||
cbUseCentralRepo.setEnabled(false);
|
||||
enableAllSubComponents(false);
|
||||
} else if (!cbUseCentralRepo.isEnabled()) {
|
||||
@ -586,6 +594,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
*/
|
||||
private void enableDatabaseConfigureButton(Boolean enable) {
|
||||
boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
|
||||
ingestRunningWarningLabel.setVisible(ingestRunning);
|
||||
pnDatabaseConfiguration.setEnabled(enable && !ingestRunning);
|
||||
bnDbConfigure.setEnabled(enable && !ingestRunning);
|
||||
lbDbLocationLabel.setEnabled(enable && !ingestRunning);
|
||||
@ -628,6 +637,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
private javax.swing.JCheckBox cbUseCentralRepo;
|
||||
private javax.swing.JScrollPane correlationPropertiesScrollPane;
|
||||
private javax.swing.JTextArea correlationPropertiesTextArea;
|
||||
private javax.swing.JLabel ingestRunningWarningLabel;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JLabel lbCentralRepository;
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -33,62 +33,52 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
|
||||
/**
|
||||
* Prototype for an object which finds files with common attributes.
|
||||
* Subclass this and implement findMatches in order
|
||||
* Prototype for an object which finds files with common attributes. Subclass
|
||||
* this and implement findMatches in order
|
||||
*/
|
||||
public abstract class AbstractCommonAttributeSearcher {
|
||||
|
||||
private final Map<Long, String> dataSourceIdToNameMap;
|
||||
|
||||
private boolean filterByMedia;
|
||||
private boolean filterByDoc;
|
||||
final int frequencyPercentageThreshold;
|
||||
|
||||
AbstractCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMedia, boolean filterByDoc, int percentageThreshold){
|
||||
|
||||
AbstractCommonAttributeSearcher(boolean filterByMedia, boolean filterByDoc, int percentageThreshold) {
|
||||
this.filterByDoc = filterByDoc;
|
||||
this.filterByMedia = filterByMedia;
|
||||
this.dataSourceIdToNameMap = dataSourceIdMap;
|
||||
this.frequencyPercentageThreshold = percentageThreshold;
|
||||
}
|
||||
|
||||
Map<Long, String> getDataSourceIdToNameMap(){
|
||||
return Collections.unmodifiableMap(this.dataSourceIdToNameMap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implement this to search for files with common attributes. Creates an
|
||||
* object (CommonAttributeSearchResults) which contains all of the information
|
||||
* required to display a tree view in the UI. The view will contain 3 layers:
|
||||
* a top level node, indicating the number matches each of it's children possess,
|
||||
* a mid level node indicating the matched attribute,
|
||||
* Implement this to search for files with common attributes. Creates an
|
||||
* object (CommonAttributeSearchResults) which contains all of the
|
||||
* information required to display a tree view in the UI. The view will
|
||||
* contain 3 layers: a top level node, indicating the number matches each of
|
||||
* it's children possess, a mid level node indicating the matched attribute,
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws NoCurrentCaseException
|
||||
* @throws SQLException
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public abstract CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Implement this to create a descriptive string for the tab which will display
|
||||
* this data.
|
||||
* Implement this to create a descriptive string for the tab which will
|
||||
* display this data.
|
||||
*
|
||||
* @return an informative string
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Attributes (All Data Sources, %s)",
|
||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraSingle=Common Attributes (Data Source: %s, %s)",
|
||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterAll=Common Attributes (All Central Repository Cases, %s)",
|
||||
"AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterSingle=Common Attributes (Central Repository Case: %s, %s)",
|
||||
})
|
||||
abstract String buildTabTitle();
|
||||
|
||||
abstract String getTabTitle();
|
||||
|
||||
@NbBundle.Messages({
|
||||
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents",
|
||||
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media",
|
||||
"AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories"
|
||||
})
|
||||
|
||||
|
||||
String buildCategorySelectionString() {
|
||||
if (!this.isFilterByDoc() && !this.isFilterByMedia()) {
|
||||
return Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_all();
|
||||
@ -103,15 +93,33 @@ public abstract class AbstractCommonAttributeSearcher {
|
||||
return String.join(", ", filters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the portion of the title that will display the frequency percentage
|
||||
* threshold. Items that existed in over this percent of data sources were
|
||||
* ommited from the results.
|
||||
*
|
||||
* @return A string providing the frequency percentage threshold, or an empty string if no threshold was set
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"# {0} - threshold percent",
|
||||
"AbstractCommonFilesMetadataBuilder.getPercentFilter.thresholdPercent=, Threshold {0}%"})
|
||||
String getPercentThresholdString() {
|
||||
if (frequencyPercentageThreshold == 0) {
|
||||
return "";
|
||||
} else {
|
||||
return Bundle.AbstractCommonFilesMetadataBuilder_getPercentFilter_thresholdPercent(frequencyPercentageThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
static Map<Integer, CommonAttributeValueList> collateMatchesByNumberOfInstances(Map<String, CommonAttributeValue> commonFiles) {
|
||||
//collate matches by number of matching instances - doing this in sql doesnt seem efficient
|
||||
Map<Integer, CommonAttributeValueList> instanceCollatedCommonFiles = new TreeMap<>();
|
||||
|
||||
for(CommonAttributeValue md5Metadata : commonFiles.values()){
|
||||
|
||||
for (CommonAttributeValue md5Metadata : commonFiles.values()) {
|
||||
Integer size = md5Metadata.getInstanceCount();
|
||||
|
||||
if(instanceCollatedCommonFiles.containsKey(size)){
|
||||
|
||||
if (instanceCollatedCommonFiles.containsKey(size)) {
|
||||
instanceCollatedCommonFiles.get(size).addMetadataToList(md5Metadata);
|
||||
} else {
|
||||
CommonAttributeValueList value = new CommonAttributeValueList();
|
||||
@ -121,13 +129,13 @@ public abstract class AbstractCommonAttributeSearcher {
|
||||
}
|
||||
return instanceCollatedCommonFiles;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The set of the MIME types that will be checked for extension mismatches
|
||||
* when checkType is ONLY_MEDIA.
|
||||
* ".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec"
|
||||
* ".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", //NON-NLS
|
||||
* ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv", ".flv", ".swf"
|
||||
* when checkType is ONLY_MEDIA. ".jpg", ".jpeg", ".png", ".psd", ".nef",
|
||||
* ".tiff", ".bmp", ".tec" ".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v",
|
||||
* //NON-NLS ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm",
|
||||
* ".wmv", ".mpv", ".flv", ".swf"
|
||||
*/
|
||||
static final Set<String> MEDIA_PICS_VIDEO_MIME_TYPES = Stream.of(
|
||||
"image/bmp", //NON-NLS
|
||||
@ -157,11 +165,9 @@ public abstract class AbstractCommonAttributeSearcher {
|
||||
|
||||
/*
|
||||
* The set of the MIME types that will be checked for extension mismatches
|
||||
* when checkType is ONLY_TEXT_FILES.
|
||||
* ".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx"
|
||||
* ".txt", ".rtf", ".log", ".text", ".xml"
|
||||
* ".html", ".htm", ".css", ".js", ".php", ".aspx"
|
||||
* ".pdf"
|
||||
* when checkType is ONLY_TEXT_FILES. ".doc", ".docx", ".odt", ".xls",
|
||||
* ".xlsx", ".ppt", ".pptx" ".txt", ".rtf", ".log", ".text", ".xml" ".html",
|
||||
* ".htm", ".css", ".js", ".php", ".aspx" ".pdf"
|
||||
*/
|
||||
static final Set<String> TEXT_FILES_MIME_TYPES = Stream.of(
|
||||
"text/plain", //NON-NLS
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -20,12 +20,16 @@
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
|
||||
import static org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher.MEDIA_PICS_VIDEO_MIME_TYPES;
|
||||
|
||||
/**
|
||||
* Algorithm which finds files anywhere in the Central Repo which also occur in
|
||||
@ -36,25 +40,44 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut
|
||||
/**
|
||||
*
|
||||
* @param filterByMediaMimeType match only on files whose mime types can be
|
||||
* broadly categorized as media types
|
||||
* @param filterByDocMimeType match only on files whose mime types can be
|
||||
* broadly categorized as document types
|
||||
* broadly categorized as media types
|
||||
* @param filterByDocMimeType match only on files whose mime types can be
|
||||
* broadly categorized as document types
|
||||
* @param corAttrType attribute type
|
||||
* @param percentageThreshold omit any matches with frequency above this
|
||||
* threshold
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public AllInterCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, corAttrType, percentageThreshold);
|
||||
public AllInterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||
super(filterByMediaMimeType, filterByDocMimeType, corAttrType, percentageThreshold);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonAttributeSearchResults findMatches() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap(), corAttrType);
|
||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(corAttrType);
|
||||
Map<Integer, CommonAttributeValueList> interCaseCommonFiles = eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase());
|
||||
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType);
|
||||
|
||||
Set<String> mimeTypesToFilterOn = new HashSet<>();
|
||||
if (isFilterByMedia()) {
|
||||
mimeTypesToFilterOn.addAll(MEDIA_PICS_VIDEO_MIME_TYPES);
|
||||
}
|
||||
if (isFilterByDoc()) {
|
||||
mimeTypesToFilterOn.addAll(TEXT_FILES_MIME_TYPES);
|
||||
}
|
||||
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType, mimeTypesToFilterOn);
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - attr type",
|
||||
"# {1} - threshold string",
|
||||
"AllInterCaseCommonAttributeSearcher.buildTabTitle.titleInterAll=Common Properties (All Central Repository Cases, {0}{1})"})
|
||||
@Override
|
||||
String buildTabTitle() {
|
||||
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterAll();
|
||||
return String.format(titleTemplate, new Object[]{this.corAttrType.getDisplayName()});
|
||||
String getTabTitle() {
|
||||
String typeString = this.corAttrType.getDisplayName();
|
||||
if (typeString.equals("Files")) {
|
||||
typeString = this.buildCategorySelectionString();
|
||||
}
|
||||
return Bundle.AllInterCaseCommonAttributeSearcher_buildTabTitle_titleInterAll(typeString, this.getPercentThresholdString());
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -20,6 +20,7 @@
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.util.Map;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
|
||||
/**
|
||||
@ -27,15 +28,18 @@ import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
*/
|
||||
final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAttributeSearcher {
|
||||
|
||||
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS
|
||||
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != " + FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS
|
||||
|
||||
/**
|
||||
* Implements the algorithm for getting common files across all data
|
||||
* sources.
|
||||
*
|
||||
* @param dataSourceIdMap a map of obj_id to datasource name
|
||||
* @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types
|
||||
* @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types
|
||||
* @param dataSourceIdMap a map of obj_id to datasource name
|
||||
* @param filterByMediaMimeType match only on files whose mime types can be
|
||||
* broadly categorized as media types
|
||||
* @param filterByDocMimeType match only on files whose mime types can be
|
||||
* broadly categorized as document types
|
||||
* @param percentageThreshold omit any matches with frequency above this threshold
|
||||
*/
|
||||
public AllIntraCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) {
|
||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||
@ -44,14 +48,17 @@ final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAt
|
||||
|
||||
@Override
|
||||
protected String buildSqlSelectStatement() {
|
||||
Object[] args = new String[] {SELECT_PREFIX, determineMimeTypeFilter()};
|
||||
Object[] args = new String[]{SELECT_PREFIX, determineMimeTypeFilter()};
|
||||
return String.format(WHERE_CLAUSE, args);
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - build category",
|
||||
"# {1} - threshold string",
|
||||
"AllIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraAll=Common Properties (All Data Sources, {0}{1})"
|
||||
})
|
||||
@Override
|
||||
String buildTabTitle() {
|
||||
final String buildCategorySelectionString = this.buildCategorySelectionString();
|
||||
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraAll();
|
||||
return String.format(titleTemplate, new Object[]{buildCategorySelectionString});
|
||||
String getTabTitle() {
|
||||
return Bundle.AllIntraCaseCommonAttributeSearcher_buildTabTitle_titleIntraAll(this.buildCategorySelectionString(), this.getPercentThresholdString());
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,42 @@
|
||||
CommonFilesPanel.commonFilesSearchLabel.text=<html>Find files in multiple data sources in the current case.</html>
|
||||
CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates:
|
||||
CommonFilesPanel.jRadioButton1.text=jRadioButton1
|
||||
CommonFilesPanel.jRadioButton2.text=With previous cases in the Central Repository
|
||||
CommonFilesPanel.jRadioButton2.text=Between current case and cases in Central Repository
|
||||
CommonFilesPanel.intraCaseRadio.label=Correlate within current case only
|
||||
CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo)
|
||||
IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source
|
||||
IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below:
|
||||
IntraCasePanel.selectDataSourceComboBox.actionCommand=
|
||||
InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case:
|
||||
InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case
|
||||
CommonAttributePanel.jCheckBox1.text=Hide files found in over
|
||||
CommonAttributePanel.jLabel1.text=% of data sources in central repository.
|
||||
CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in central repository.
|
||||
CommonAttributePanel.percentageThresholdTextOne.text=20
|
||||
CommonAttributePanel.percentageThresholdCheck.text_1=Hide files found in over
|
||||
CommonAttributePanel.intraCaseRadio.text=Within current case
|
||||
CommonAttributePanel.commonFilesSearchLabel1.text=<html>Find common files to correlate data soures or cases.</html>
|
||||
CommonAttributePanel.errorText.text=<html>In order to search, you must select a file category.</html>
|
||||
CommonAttributePanel.categoriesLabel.text=File Types To Include:
|
||||
CommonAttributePanel.documentsCheckbox.text=Documents
|
||||
CommonAttributePanel.pictureVideoCheckbox.text=Pictures and Videos
|
||||
CommonAttributePanel.selectedFileCategoriesButton.toolTipText=Select from the options below...
|
||||
CommonAttributePanel.selectedFileCategoriesButton.text=Only the selected file types:
|
||||
CommonAttributePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results...
|
||||
CommonAttributePanel.allFileCategoriesRadioButton.text=All file types
|
||||
CommonAttributePanel.cancelButton.actionCommand=Cancel
|
||||
CommonAttributePanel.cancelButton.text=Cancel
|
||||
CommonAttributePanel.searchButton.text=Search
|
||||
CommonAttributePanel.jCheckBox1.text=Hide files found in over
|
||||
CommonAttributePanel.jLabel1.text=% of data sources in central repository.
|
||||
CommonAttributePanel.percentageThreshold.text=20
|
||||
CommonAttributePanel.jLabel1.text_1=% of data sources in central repository.
|
||||
CommonAttributePanel.percentageThresholdCheck.text_1=Hide files found in over
|
||||
InterCasePanel.comboBoxLabel.text=Select correlation type to search:
|
||||
InterCasePanel.correlationTypeComboBox.toolTipText=Selected Correlation Type
|
||||
CommonAttributePanel.commonFilesSearchLabel2.text=Scope of Search
|
||||
IntraCasePanel.selectedFileCategoriesButton.text=Only the selected file types:
|
||||
IntraCasePanel.categoriesLabel.text=File Types to Show:
|
||||
IntraCasePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results...
|
||||
IntraCasePanel.allFileCategoriesRadioButton.text=All file types
|
||||
IntraCasePanel.documentsCheckbox.text=Documents
|
||||
IntraCasePanel.pictureVideoCheckbox.text=Pictures and Videos
|
||||
IntraCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options below...
|
||||
CommonAttributePanel.percentageThresholdTextTwo.text_1=% of data sources in Central Repository.
|
||||
CommonAttributePanel.percentageThresholdCheck.text_1_1=Hide items found in over
|
||||
CommonAttributePanel.intraCaseRadio.text=Between data sources in current case
|
||||
CommonAttributePanel.errorText.text=<html>In order to search, you must select a file category.</html>
|
||||
CommonAttributePanel.searchButton.text=Search
|
||||
InterCasePanel.categoriesLabel.text=File Types To Show:
|
||||
InterCasePanel.documentsCheckbox.text=Documents
|
||||
InterCasePanel.pictureVideoCheckbox.text=Pictures and Videos
|
||||
InterCasePanel.selectedFileCategoriesButton.toolTipText=Select from the options below...
|
||||
InterCasePanel.selectedFileCategoriesButton.text=Only the selected file types:
|
||||
InterCasePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results...
|
||||
InterCasePanel.allFileCategoriesRadioButton.text=All file types
|
||||
InterCasePanel.specificCentralRepoCaseCheckbox.text=Common items need to exist in a specific case:
|
||||
IntraCasePanel.onlySpecificDataSourceCheckbox.text=Common items need to exist in a specific data source:
|
||||
CommonAttributePanel.interCasePanel.border.title=Central Repository Options
|
||||
CommonAttributePanel.intraCasePanel.border.title=Current Case Options
|
||||
CommonAttributePanel.commonItemSearchDescription.text=<html>Find items that exist in multiple data sources or cases</html>
|
||||
CommonAttributePanel.scopeLabel.text=Scope of Search:
|
||||
InterCasePanel.correlationComboBoxLabel.text=Property Type to Match:
|
||||
CommonAttributePanel.percentageThresholdInputBox.text=20
|
||||
|
@ -22,6 +22,8 @@ import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
@ -47,7 +49,7 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode {
|
||||
*
|
||||
*/
|
||||
public CaseDBCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource) {
|
||||
super(fsContent);
|
||||
super(fsContent, false);
|
||||
this.caseName = caseName;
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
@ -84,16 +86,21 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode {
|
||||
final String NO_DESCR = Bundle.CommonFilesSearchResultsViewerTable_noDescText();
|
||||
|
||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, this.getContent().getName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
this.addScoreProperty(sheetSet, tags);
|
||||
this.addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
this.addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, this.getContent().getParentPath()));
|
||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsCsvList(this.getContent())));
|
||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource()));
|
||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType())));
|
||||
this.addTagProperty(sheetSet, tags);
|
||||
|
||||
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, caseName));
|
||||
return sheet;
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -21,9 +21,8 @@ package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
@ -31,6 +30,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
@ -45,17 +45,15 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
||||
private final Integer crFileId;
|
||||
private CorrelationAttributeInstance currentAttribute;
|
||||
private final CorrelationAttributeInstance.Type correlationType;
|
||||
private final Map<String, Long> dataSourceNameToIdMap;
|
||||
|
||||
CentralRepoCommonAttributeInstance(Integer attrInstId, Map<Long, String> dataSourceIdToNameMap, CorrelationAttributeInstance.Type correlationType) {
|
||||
CentralRepoCommonAttributeInstance(Integer attrInstId, CorrelationAttributeInstance.Type correlationType) {
|
||||
super();
|
||||
this.crFileId = attrInstId;
|
||||
this.dataSourceNameToIdMap = invertMap(dataSourceIdToNameMap);
|
||||
this.correlationType = correlationType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CorrelationAttributeInstance.Type getCorrelationAttributeInstanceType(){
|
||||
public CorrelationAttributeInstance.Type getCorrelationAttributeInstanceType() {
|
||||
return this.correlationType;
|
||||
}
|
||||
|
||||
@ -71,22 +69,35 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
||||
|
||||
final CorrelationAttributeInstance currentAttributeInstance = this.currentAttribute;
|
||||
|
||||
String currentFullPath = currentAttributeInstance.getFilePath();
|
||||
String currentDataSource = currentAttributeInstance.getCorrelationDataSource().getName();
|
||||
try {
|
||||
String currentFullPath = currentAttributeInstance.getFilePath();
|
||||
currentCase = Case.getCurrentCaseThrows();
|
||||
|
||||
if (this.dataSourceNameToIdMap.containsKey(currentDataSource)) {
|
||||
Long dataSourceObjectId = this.dataSourceNameToIdMap.get(currentDataSource);
|
||||
|
||||
try {
|
||||
currentCase = Case.getCurrentCaseThrows();
|
||||
// Only attempt to make the abstract file if the attribute is from the current case
|
||||
if (currentCase.getName().equals(currentAttributeInstance.getCorrelationCase().getCaseUUID())) {
|
||||
|
||||
SleuthkitCase tskDb = currentCase.getSleuthkitCase();
|
||||
|
||||
// Find the correct data source
|
||||
Optional<DataSource> dataSource = tskDb.getDataSources().stream()
|
||||
.filter(p -> p.getDeviceId().equals(currentAttribute.getCorrelationDataSource().getDeviceID()))
|
||||
.findFirst();
|
||||
if (!dataSource.isPresent()) {
|
||||
LOGGER.log(Level.WARNING, String.format("Unable to find data source with device ID %s in the current case", currentAttribute.getCorrelationDataSource().getDeviceID()));
|
||||
return null;
|
||||
}
|
||||
|
||||
File fileFromPath = new File(currentFullPath);
|
||||
String fileName = fileFromPath.getName();
|
||||
String parentPath = (fileFromPath.getParent() + File.separator).replace("\\", "/");
|
||||
|
||||
final String whereClause = String.format("lower(name) = '%s' AND md5 = '%s' AND lower(parent_path) = '%s' AND data_source_obj_id = %s", fileName, currentAttribute.getCorrelationValue(), parentPath, dataSourceObjectId);
|
||||
// Create the parent path. Make sure not to add a separator if there is already one there.
|
||||
String parentPath = fileFromPath.getParent();
|
||||
if (!parentPath.endsWith(File.separator)) {
|
||||
parentPath += File.separator;
|
||||
}
|
||||
parentPath = parentPath.replace("\\", "/");
|
||||
|
||||
final String whereClause = String.format("lower(name) = '%s' AND md5 = '%s' AND lower(parent_path) = '%s' AND data_source_obj_id = %s", fileName, currentAttribute.getCorrelationValue(), parentPath, dataSource.get().getId());
|
||||
List<AbstractFile> potentialAbstractFiles = tskDb.findAllFilesWhere(whereClause);
|
||||
|
||||
if (potentialAbstractFiles.isEmpty()) {
|
||||
@ -97,46 +108,31 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr
|
||||
} else {
|
||||
return potentialAbstractFiles.get(0);
|
||||
}
|
||||
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentAttributeInstance.getFilePath()}), ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayableItemNode[] generateNodes() {
|
||||
|
||||
// @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes
|
||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(correlationType);
|
||||
CorrelationAttributeInstance corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId);
|
||||
List<DisplayableItemNode> attrInstNodeList = new ArrayList<>(0);
|
||||
String currCaseDbName = Case.getCurrentCase().getDisplayName();
|
||||
|
||||
try {
|
||||
this.setCurrentAttributeInst(corrAttr);
|
||||
|
||||
AbstractFile abstractFileForAttributeInstance = this.getAbstractFile();
|
||||
DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createNode(corrAttr, abstractFileForAttributeInstance, currCaseDbName);
|
||||
DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createNode(currentAttribute, abstractFileForAttributeInstance, currCaseDbName);
|
||||
attrInstNodeList.add(generatedInstNode);
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with md5: %s. Node not created.", new Object[]{corrAttr.getCorrelationValue()}), ex);
|
||||
LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with md5: %s. Node not created.", new Object[]{currentAttribute.getCorrelationValue()}), ex);
|
||||
}
|
||||
|
||||
return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]);
|
||||
}
|
||||
|
||||
private Map<String, Long> invertMap(Map<Long, String> dataSourceIdToNameMap) {
|
||||
HashMap<String, Long> invertedMap = new HashMap<>();
|
||||
for (Map.Entry<Long, String> entry : dataSourceIdToNameMap.entrySet()) {
|
||||
invertedMap.put(entry.getValue(), entry.getKey());
|
||||
}
|
||||
return invertedMap;
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,12 @@
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="fileTypeFilterButtonGroup">
|
||||
</Component>
|
||||
<Component class="javax.swing.ButtonGroup" name="interIntraButtonGroup">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[450, 440]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[450, 440]"/>
|
||||
<Dimension value="[450, 460]"/>
|
||||
</Property>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
@ -32,7 +27,7 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-72,0,0,1,-61"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,118,0,0,1,-62"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
@ -40,13 +35,13 @@
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[450, 440]"/>
|
||||
<Dimension value="[450, 460]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[450, 440]"/>
|
||||
<Dimension value="[450, 460]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[450, 440]"/>
|
||||
<Dimension value="[450, 460]"/>
|
||||
</Property>
|
||||
<Property name="requestFocusEnabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
@ -59,55 +54,49 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="errorText" pref="300" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="65" max="-2" attributes="0"/>
|
||||
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="scopeLabel" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="percentageThresholdCheck" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="filler1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="80" max="-2" attributes="0"/>
|
||||
<Component id="filler2" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="errorText" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="percentageThresholdInputBox" min="-2" pref="40" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="percentageThresholdTextTwo" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="commonFilesSearchLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="intraCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="interCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="commonFilesSearchLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="categoriesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="selectedFileCategoriesButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="commonItemSearchDescription" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="intraCaseRadio" max="32767" attributes="0"/>
|
||||
<Component id="interCaseRadio" pref="383" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="allFileCategoriesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="layoutPanel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="percentageThresholdCheck" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="percentageThresholdTextOne" min="-2" pref="40" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="percentageThresholdTextTwo" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="interCasePanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="intraCasePanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesLabel" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -117,42 +106,29 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="commonFilesSearchLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="commonFilesSearchLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="commonItemSearchDescription" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="scopeLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="interCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Component id="layoutPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="categoriesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="allFileCategoriesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="interCasePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="intraCasePanel" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="percentageThresholdCheck" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="percentageThresholdTextOne" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="percentageThresholdInputBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="percentageThresholdTextTwo" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="filler2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="filler1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="searchButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="errorText" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="dataSourcesLabel" min="-2" pref="14" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="searchButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="errorText" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -160,10 +136,10 @@
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="commonFilesSearchLabel2">
|
||||
<Component class="javax.swing.JLabel" name="scopeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.commonFilesSearchLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.scopeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
@ -180,85 +156,6 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="searchButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="cancelButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.cancelButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="horizontalTextPosition" type="int" value="10"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="allFileCategoriesRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="fileTypeFilterButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.allFileCategoriesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.allFileCategoriesRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allFileCategoriesRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="selectedFileCategoriesButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="fileTypeFilterButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.selectedFileCategoriesButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectedFileCategoriesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="pictureVideoCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.pictureVideoCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pictureVideoCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="documentsCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.documentsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="categoriesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.categoriesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="errorText">
|
||||
<Properties>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
@ -270,10 +167,10 @@
|
||||
<Property name="verticalAlignment" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="commonFilesSearchLabel1">
|
||||
<Component class="javax.swing.JLabel" name="commonItemSearchDescription">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.commonFilesSearchLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.commonItemSearchDescription.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
@ -305,40 +202,21 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="interCaseRadioActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="java.awt.Panel" name="layoutPanel">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel" name="intraCasePanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="card3"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="org.sleuthkit.autopsy.commonfilesearch.InterCasePanel" name="interCasePanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="card2"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JCheckBox" name="percentageThresholdCheck">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.percentageThresholdCheck.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.percentageThresholdCheck.text_1_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="percentageThresholdCheckActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="percentageThresholdTextOne">
|
||||
<Component class="javax.swing.JTextField" name="percentageThresholdInputBox">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.percentageThresholdTextOne.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.percentageThresholdInputBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[40, 24]"/>
|
||||
@ -358,25 +236,45 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.Box$Filler" name="filler1">
|
||||
<Component class="org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel" name="intraCasePanel">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 32767]"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Current Case Options">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.intraCasePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32779, 192]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[204, 192]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[430, 192]"/>
|
||||
</Property>
|
||||
<Property name="verifyInputWhenFocusTarget" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.Box$Filler" name="filler2">
|
||||
<Component class="org.sleuthkit.autopsy.commonfilesearch.InterCasePanel" name="interCasePanel">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 32767]"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Central Repository Options">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonAttributePanel.interCasePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[430, 230]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[430, 230]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.Glue"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="dataSourcesLabel">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
|
@ -19,14 +19,16 @@
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
@ -35,39 +37,15 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
final public class CommonAttributeSearchAction extends CallableSystemAction {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommonAttributeSearchAction.class.getName());
|
||||
|
||||
|
||||
private static CommonAttributeSearchAction instance = null;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
CommonAttributeSearchAction() {
|
||||
super();
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(){
|
||||
boolean shouldBeEnabled = false;
|
||||
try {
|
||||
//dont refactor any of this to pull out common expressions - order of evaluation of each expression is significant
|
||||
shouldBeEnabled =
|
||||
(Case.isCaseOpen() &&
|
||||
Case.getCurrentCase().getDataSources().size() > 1)
|
||||
||
|
||||
(EamDb.isEnabled() &&
|
||||
EamDb.getInstance() != null &&
|
||||
EamDb.getInstance().getCases().size() > 1 &&
|
||||
Case.isCaseOpen() &&
|
||||
Case.getCurrentCase() != null &&
|
||||
EamDb.getInstance().getCase(Case.getCurrentCase()) != null);
|
||||
|
||||
} catch(TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting data sources for action enabled check", ex);
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting CR cases for action enabled check", ex);
|
||||
}
|
||||
return super.isEnabled() && shouldBeEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default CommonAttributeSearchAction.
|
||||
*
|
||||
* @return the default instance of this action
|
||||
*/
|
||||
public static synchronized CommonAttributeSearchAction getDefault() {
|
||||
if (instance == null) {
|
||||
instance = new CommonAttributeSearchAction();
|
||||
@ -75,18 +53,105 @@ final public class CommonAttributeSearchAction extends CallableSystemAction {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CommonAttributeSearchAction for opening the common attribute
|
||||
* search dialog
|
||||
*/
|
||||
private CommonAttributeSearchAction() {
|
||||
super();
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return super.isEnabled() && Case.isCaseOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
new CommonAttributePanel().setVisible(true);
|
||||
createAndShowPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction() {
|
||||
new CommonAttributePanel().setVisible(true);
|
||||
createAndShowPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the commonAttributePanel and display it.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CommonAttributeSearchAction.openPanel.intro=The common property search feature is not available because:",
|
||||
"CommonAttributeSearchAction.openPanel.resolution=\n\nAddress one of these issues to enable this feature.",
|
||||
"CommonAttributeSearchAction.openPanel.noCaseOpen=\n - No case is open.",
|
||||
"CommonAttributeSearchAction.openPanel.notEnoughDataSources=\n - There are not multiple data sources in the current case.",
|
||||
"CommonAttributeSearchAction.openPanel.centralRepoDisabled=\n - The Central Repository is disabled.",
|
||||
"CommonAttributeSearchAction.openPanel.caseNotInCentralRepo=\n - The current case is not in the Central Repository.",
|
||||
"CommonAttributeSearchAction.openPanel.notEnoughCases=\n - Fewer than 2 cases exist in the Central Repository.",
|
||||
"CommonAttributeSearchAction.openPanel.centralRepoInvalid=\n - The Central Repository configuration is invalid."})
|
||||
private void createAndShowPanel() {
|
||||
new SwingWorker<Boolean, Void>() {
|
||||
|
||||
String reason = Bundle.CommonAttributeSearchAction_openPanel_intro();
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground() throws Exception {
|
||||
// Test whether we should open the common files panel
|
||||
if (!Case.isCaseOpen()) {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_noCaseOpen();
|
||||
return false;
|
||||
}
|
||||
if (Case.getCurrentCase().getDataSources().size() > 1) {
|
||||
// There are enough data sources to run the intra case seach
|
||||
return true;
|
||||
} else {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_notEnoughDataSources();
|
||||
}
|
||||
if (!EamDb.isEnabled()) {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_centralRepoDisabled();
|
||||
return false;
|
||||
}
|
||||
if (EamDb.getInstance() == null) {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_centralRepoInvalid();
|
||||
return false;
|
||||
}
|
||||
if (EamDb.getInstance().getCases().size() < 2) {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_notEnoughCases();
|
||||
return false;
|
||||
}
|
||||
if (EamDb.getInstance().getCase(Case.getCurrentCase()) == null) {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_caseNotInCentralRepo();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
protected void done() {
|
||||
super.done();
|
||||
try {
|
||||
boolean openPanel = get();
|
||||
if (openPanel) {
|
||||
CommonAttributePanel commonAttributePanel = new CommonAttributePanel();
|
||||
//In order to update errors the CommonAttributePanel needs to observe its sub panels
|
||||
commonAttributePanel.observeSubPanels();
|
||||
commonAttributePanel.setVisible(true);
|
||||
} else {
|
||||
reason += Bundle.CommonAttributeSearchAction_openPanel_resolution();
|
||||
NotifyDescriptor descriptor = new NotifyDescriptor.Message(reason, NotifyDescriptor.INFORMATION_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(descriptor);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Unexpected exception while opening Common Properties Search", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
.execute();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"CommonAttributeSearchAction.getName.text=Common Attribute Search"})
|
||||
"CommonAttributeSearchAction.getName.text=Common Property Search"})
|
||||
@Override
|
||||
public String getName() {
|
||||
return Bundle.CommonAttributeSearchAction_getName_text();
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -22,15 +22,18 @@ package org.sleuthkit.autopsy.commonfilesearch;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Stores the results from the various types of common attribute searching
|
||||
@ -39,37 +42,47 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
final public class CommonAttributeSearchResults {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommonAttributeSearchResults.class.getName());
|
||||
|
||||
|
||||
// maps instance count to list of attribute values.
|
||||
private final Map<Integer, CommonAttributeValueList> instanceCountToAttributeValues;
|
||||
|
||||
private final Set<String> mimeTypesToInclude;
|
||||
private final int percentageThreshold;
|
||||
private final int resultTypeId;
|
||||
|
||||
|
||||
/**
|
||||
* Create a values object which can be handed off to the node factories.
|
||||
*
|
||||
* @param values list of CommonAttributeValue indexed by size of
|
||||
* CommonAttributeValue
|
||||
* @param metadata list of CommonAttributeValue indexed by size
|
||||
* of CommonAttributeValue
|
||||
* @param percentageThreshold threshold to filter out files which are too
|
||||
* common, value of 0 is disabled
|
||||
* @param resultType The type of Correlation Attribute being
|
||||
* searched for
|
||||
* @param mimeTypesToFilterOn Set of mime types to include for intercase
|
||||
* searches
|
||||
*/
|
||||
CommonAttributeSearchResults(Map<Integer, CommonAttributeValueList> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType) {
|
||||
CommonAttributeSearchResults(Map<Integer, CommonAttributeValueList> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType, Set<String> mimeTypesToFilterOn) {
|
||||
//wrap in a new object in case any client code has used an unmodifiable collection
|
||||
this.instanceCountToAttributeValues = new HashMap<>(metadata);
|
||||
this.percentageThreshold = percentageThreshold;
|
||||
this.resultTypeId = resultType.getId();
|
||||
this.mimeTypesToInclude = mimeTypesToFilterOn;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Create a values object which can be handed off to the node factories.
|
||||
*
|
||||
* @param values list of CommonAttributeValue indexed by size of
|
||||
* CommonAttributeValue
|
||||
* @param metadata list of CommonAttributeValue indexed by size
|
||||
* of CommonAttributeValue
|
||||
* @param percentageThreshold threshold to filter out files which are too
|
||||
* common, value of 0 is disabled
|
||||
*/
|
||||
CommonAttributeSearchResults(Map<Integer, CommonAttributeValueList> metadata, int percentageThreshold) {
|
||||
//wrap in a new object in case any client code has used an unmodifiable collection
|
||||
this.instanceCountToAttributeValues = new HashMap<>(metadata);
|
||||
this.percentageThreshold = percentageThreshold;
|
||||
this.resultTypeId = CorrelationAttributeInstance.FILES_TYPE_ID;
|
||||
this.mimeTypesToInclude = new HashSet<>(); //don't filter on mimetypes
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,6 +92,7 @@ final public class CommonAttributeSearchResults {
|
||||
* <code>getValues()</code>.
|
||||
*
|
||||
* @param instanceCount key
|
||||
*
|
||||
* @return list of values which represent matches
|
||||
*/
|
||||
CommonAttributeValueList getAttributeValuesForInstanceCount(Integer instanceCount) {
|
||||
@ -93,79 +107,107 @@ final public class CommonAttributeSearchResults {
|
||||
* @return map of sizes of children to list of matches
|
||||
*/
|
||||
public Map<Integer, CommonAttributeValueList> getMetadata() throws EamDbException {
|
||||
if(this.percentageThreshold == 0){
|
||||
if (this.percentageThreshold == 0 && mimeTypesToInclude.isEmpty()) {
|
||||
return Collections.unmodifiableMap(this.instanceCountToAttributeValues);
|
||||
} else {
|
||||
return this.getMetadata(this.percentageThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an unmodifiable collection of values, indexed by number of
|
||||
* grandchildren, which represents the common attributes found in the
|
||||
* search.
|
||||
*
|
||||
* Remove results which are not found in the portion of available data
|
||||
*
|
||||
* Remove results which are not found in the portion of available data
|
||||
* sources described by maximumPercentageThreshold.
|
||||
*
|
||||
*
|
||||
* @return metadata
|
||||
*/
|
||||
private Map<Integer, CommonAttributeValueList> getMetadata(int maximumPercentageThreshold) throws EamDbException {
|
||||
|
||||
if(maximumPercentageThreshold == 0){
|
||||
return Collections.unmodifiableMap(this.instanceCountToAttributeValues);
|
||||
}
|
||||
|
||||
CorrelationAttributeInstance.Type fileAttributeType = CorrelationAttributeInstance
|
||||
CorrelationAttributeInstance.Type attributeType = CorrelationAttributeInstance
|
||||
.getDefaultCorrelationTypes()
|
||||
.stream()
|
||||
.filter(filterType -> filterType.getId() == this.resultTypeId)
|
||||
.findFirst().get();
|
||||
|
||||
|
||||
EamDb eamDb = EamDb.getInstance();
|
||||
|
||||
|
||||
Map<Integer, List<CommonAttributeValue>> itemsToRemove = new HashMap<>();
|
||||
|
||||
for(Entry<Integer, CommonAttributeValueList> listOfValues : Collections.unmodifiableMap(this.instanceCountToAttributeValues).entrySet()){
|
||||
|
||||
//Call countUniqueDataSources once to reduce the number of DB queries needed to get
|
||||
//the frequencyPercentage
|
||||
Double uniqueCaseDataSourceTuples = eamDb.getCountUniqueDataSources().doubleValue();
|
||||
|
||||
for (Entry<Integer, CommonAttributeValueList> listOfValues : Collections.unmodifiableMap(this.instanceCountToAttributeValues).entrySet()) {
|
||||
|
||||
final Integer key = listOfValues.getKey();
|
||||
final CommonAttributeValueList values = listOfValues.getValue();
|
||||
|
||||
for(CommonAttributeValue value : values.getDelayedMetadataList()){ // Need the real metadata
|
||||
|
||||
try {
|
||||
int frequencyPercentage = eamDb.getFrequencyPercentage(new CorrelationAttributeInstance(fileAttributeType, value.getValue()));
|
||||
|
||||
if(frequencyPercentage > maximumPercentageThreshold){
|
||||
if(itemsToRemove.containsKey(key)){
|
||||
itemsToRemove.get(key).add(value);
|
||||
} else {
|
||||
List<CommonAttributeValue> toRemove = new ArrayList<>();
|
||||
toRemove.add(value);
|
||||
itemsToRemove.put(key, toRemove);
|
||||
|
||||
for (CommonAttributeValue value : values.getDelayedMetadataList()) { // Need the real metadata
|
||||
|
||||
//Intracase common attribute searches will have been created with an empty mimeTypesToInclude list
|
||||
//because when performing intra case search this filtering will have been done during the query of the case database
|
||||
boolean mimeTypeToRemove = false; //allow code to be more efficient by not attempting to remove the same value multiple times
|
||||
if (!mimeTypesToInclude.isEmpty()) { //only do the mime type filtering when mime types aren't empty
|
||||
for (AbstractCommonAttributeInstance commonAttr : value.getInstances()) {
|
||||
AbstractFile abstractFile = commonAttr.getAbstractFile();
|
||||
if (abstractFile != null) {
|
||||
String mimeType = commonAttr.getAbstractFile().getMIMEType();
|
||||
if (mimeType != null && !mimeTypesToInclude.contains(mimeType)) {
|
||||
if (itemsToRemove.containsKey(key)) {
|
||||
itemsToRemove.get(key).add(value);
|
||||
} else {
|
||||
List<CommonAttributeValue> toRemove = new ArrayList<>();
|
||||
toRemove.add(value);
|
||||
itemsToRemove.put(key, toRemove);
|
||||
}
|
||||
//value will be removed as the mime type existed and was not in the set to be included
|
||||
//because value is removed this value does not need to be checked further
|
||||
mimeTypeToRemove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mimeTypeToRemove) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(CorrelationAttributeNormalizationException ex){
|
||||
LOGGER.log(Level.WARNING, "Unable to determine frequency percentage attribute - frequency filter may not be accurate for these results.", ex);
|
||||
}
|
||||
if (!mimeTypeToRemove && maximumPercentageThreshold != 0) { //only do the frequency filtering when a max % was set
|
||||
try {
|
||||
Double uniqueTypeValueTuples = eamDb.getCountUniqueCaseDataSourceTuplesHavingTypeValue(
|
||||
attributeType, value.getValue()).doubleValue();
|
||||
Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
|
||||
int frequencyPercentage = commonalityPercentage.intValue();
|
||||
if (frequencyPercentage > maximumPercentageThreshold) {
|
||||
if (itemsToRemove.containsKey(key)) {
|
||||
itemsToRemove.get(key).add(value);
|
||||
} else {
|
||||
List<CommonAttributeValue> toRemove = new ArrayList<>();
|
||||
toRemove.add(value);
|
||||
itemsToRemove.put(key, toRemove);
|
||||
}
|
||||
}
|
||||
} catch (CorrelationAttributeNormalizationException ex) {
|
||||
LOGGER.log(Level.WARNING, "Unable to determine frequency percentage attribute - frequency filter may not be accurate for these results.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Entry<Integer, List<CommonAttributeValue>> valuesToRemove : itemsToRemove.entrySet()){
|
||||
|
||||
|
||||
for (Entry<Integer, List<CommonAttributeValue>> valuesToRemove : itemsToRemove.entrySet()) {
|
||||
final Integer key = valuesToRemove.getKey();
|
||||
final List<CommonAttributeValue> values = valuesToRemove.getValue();
|
||||
|
||||
for (CommonAttributeValue value : values){
|
||||
for (CommonAttributeValue value : values) {
|
||||
final CommonAttributeValueList instanceCountValue = this.instanceCountToAttributeValues.get(key);
|
||||
instanceCountValue.removeMetaData(value);
|
||||
|
||||
if(instanceCountValue.getDelayedMetadataList().isEmpty()){ // Check the real metadata
|
||||
this.instanceCountToAttributeValues.remove(key);
|
||||
if (instanceCountValue != null) {
|
||||
instanceCountValue.removeMetaData(value);
|
||||
if (instanceCountValue.getDelayedMetadataList().isEmpty()) { // Check the real metadata
|
||||
this.instanceCountToAttributeValues.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Collections.unmodifiableMap(this.instanceCountToAttributeValues);
|
||||
}
|
||||
|
||||
@ -178,7 +220,7 @@ final public class CommonAttributeSearchResults {
|
||||
|
||||
int count = 0;
|
||||
for (CommonAttributeValueList data : this.instanceCountToAttributeValues.values()) {
|
||||
for(CommonAttributeValue md5 : data.getDelayedMetadataList()){
|
||||
for (CommonAttributeValue md5 : data.getDelayedMetadataList()) {
|
||||
count += md5.getInstanceCount();
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -29,14 +29,13 @@ import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||
import org.sleuthkit.autopsy.corecomponents.DelayedLoadChildNodesOnTreeExpansion;
|
||||
|
||||
/**
|
||||
* <code>DataResultViewerTable</code> which overrides the default column
|
||||
* header width calculations. The <code>CommonAttributesSearchResultsViewerTable</code>
|
||||
* presents multiple tiers of data which are not always present and it may not
|
||||
* make sense to try to calculate the column widths for such tables by sampling
|
||||
* rows and looking for wide cells. Rather, we just pick some reasonable values.
|
||||
* <code>DataResultViewerTable</code> which overrides the default column header
|
||||
* width calculations. The <code>CommonAttributesSearchResultsViewerTable</code>
|
||||
* presents multiple tiers of data which are not always present and it may not
|
||||
* make sense to try to calculate the column widths for such tables by sampling
|
||||
* rows and looking for wide cells. Rather, we just pick some reasonable values.
|
||||
*/
|
||||
public class CommonAttributesSearchResultsViewerTable extends DataResultViewerTable {
|
||||
|
||||
@ -44,7 +43,7 @@ public class CommonAttributesSearchResultsViewerTable extends DataResultViewerTa
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommonAttributesSearchResultsViewerTable.class.getName());
|
||||
|
||||
|
||||
private static final int DEFAULT_WIDTH = 100;
|
||||
|
||||
static {
|
||||
@ -60,19 +59,20 @@ public class CommonAttributesSearchResultsViewerTable extends DataResultViewerTa
|
||||
|
||||
COLUMN_WIDTHS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements a DataResultViewerTable which constructs a tabular result viewer that
|
||||
* displays the children of the given root node using an OutlineView. The explorer
|
||||
* manager will be discovered at runtime.
|
||||
*
|
||||
* Adds a TreeExpansionsListener to the outlineView to receive tree expansion events
|
||||
* which dynamically loads children nodes when requested.
|
||||
* Implements a DataResultViewerTable which constructs a tabular result
|
||||
* viewer that displays the children of the given root node using an
|
||||
* OutlineView. The explorer manager will be discovered at runtime.
|
||||
*
|
||||
* Adds a TreeExpansionsListener to the outlineView to receive tree
|
||||
* expansion events which dynamically loads children nodes when requested.
|
||||
*/
|
||||
public CommonAttributesSearchResultsViewerTable() {
|
||||
super();
|
||||
outlineView.addTreeExpansionListener(new DelayedLoadChildNodesOnTreeExpansion());
|
||||
addTreeExpansionListener(new InstanceCountNodeTreeExpansionListener());
|
||||
}
|
||||
|
||||
|
||||
@NbBundle.Messages({
|
||||
"CommonFilesSearchResultsViewerTable.noDescText= ",
|
||||
"CommonFilesSearchResultsViewerTable.filesColLbl=Files",
|
||||
@ -96,8 +96,8 @@ public class CommonAttributesSearchResultsViewerTable extends DataResultViewerTa
|
||||
final String headerValue = column.getHeaderValue().toString();
|
||||
|
||||
final Integer defaultWidth = COLUMN_WIDTHS.get(headerValue);
|
||||
|
||||
if(defaultWidth == null){
|
||||
|
||||
if (defaultWidth == null) {
|
||||
column.setPreferredWidth(DEFAULT_WIDTH);
|
||||
LOGGER.log(Level.SEVERE, String.format("Tried to set width on a column not supported by the CommonFilesSearchResultsViewerTable: %s", headerValue));
|
||||
} else {
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
* Node used to indicate the number of matches found with the MD5 children of
|
||||
* this Node.
|
||||
*/
|
||||
final public class InstanceCountNode extends DisplayableItemNode {
|
||||
public final class InstanceCountNode extends DisplayableItemNode {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(InstanceCountNode.class.getName());
|
||||
|
||||
@ -74,11 +74,10 @@ final public class InstanceCountNode extends DisplayableItemNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the node, by dynamically loading in the children when called, and
|
||||
* calling the CommonAttributeValueNodeFactory to generate nodes for the
|
||||
* children in attributeValues.
|
||||
* Creates the Children of this node. By doing this here instead of in the
|
||||
* constructor, lazy creation of the Children is made possible.
|
||||
*/
|
||||
public void refresh() {
|
||||
void createChildren() {
|
||||
attributeValues.displayDelayedMetadata();
|
||||
setChildren(Children.create(new CommonAttributeValueNodeFactory(attributeValues.getMetadataList()), true));
|
||||
}
|
||||
|
@ -1,54 +1,54 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.corecomponents;
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import javax.swing.event.TreeExpansionEvent;
|
||||
import javax.swing.event.TreeExpansionListener;
|
||||
import org.openide.explorer.view.Visualizer;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||
|
||||
/**
|
||||
* A tree expansion listener that will trigger a recreation of childs through
|
||||
* its child factory on re-expansion of a node (causes to recreate the
|
||||
* ChildFactory for this purpose.).
|
||||
* A tree expansion listener used to do lazy creation of the Childfren of an
|
||||
* InstanceCountNode when the node is expanded.
|
||||
*/
|
||||
public final class DelayedLoadChildNodesOnTreeExpansion implements TreeExpansionListener {
|
||||
|
||||
/**
|
||||
* A flag for avoiding endless recursion inside the expansion listener that
|
||||
* could trigger collapsing and (re-)expanding nodes again.
|
||||
* @param event
|
||||
*/
|
||||
final class InstanceCountNodeTreeExpansionListener implements TreeExpansionListener {
|
||||
|
||||
@Override
|
||||
public synchronized void treeCollapsed(final TreeExpansionEvent event) {
|
||||
// Do nothing on collapse. Netbeans should manage nodes falling out of scope and GC.
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void treeExpanded(final TreeExpansionEvent event) {
|
||||
Node eventNode = Visualizer.findNode(event.getPath().getLastPathComponent());
|
||||
final Node eventNode = Visualizer.findNode(event.getPath().getLastPathComponent());
|
||||
if (eventNode instanceof TableFilterNode) {
|
||||
final TableFilterNode node = (TableFilterNode) eventNode;
|
||||
node.refresh();
|
||||
final TableFilterNode tableFilterNode = (TableFilterNode) eventNode;
|
||||
final DataResultFilterNode dataResultFilterNode = tableFilterNode.getLookup().lookup(DataResultFilterNode.class);
|
||||
if (dataResultFilterNode != null) {
|
||||
final InstanceCountNode instanceCountNode = dataResultFilterNode.getLookup().lookup(InstanceCountNode.class);
|
||||
if (instanceCountNode != null) {
|
||||
instanceCountNode.createChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.util.Map;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
@ -48,8 +47,8 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
InterCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||
InterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||
super(filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||
dbManager = EamDb.getInstance();
|
||||
this.corAttrType = corAttrType;
|
||||
}
|
||||
|
@ -20,71 +20,72 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="anyCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="specificCentralRepoCaseCheckbox" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="correlationComboBoxLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="categoriesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="allFileCategoriesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="selectedFileCategoriesButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="documentsCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pictureVideoCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="caseComboBox" min="-2" pref="261" max="-2" attributes="0"/>
|
||||
<Group type="103" alignment="1" groupAlignment="0" attributes="0">
|
||||
<Component id="comboBoxLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="correlationTypeComboBox" min="-2" pref="260" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="caseComboBox" max="32767" attributes="0"/>
|
||||
<Component id="correlationTypeComboBox" alignment="1" pref="353" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="anyCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="specificCentralRepoCaseCheckbox" min="-2" pref="18" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="caseComboBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="comboBoxLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="correlationComboBoxLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="correlationTypeComboBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="categoriesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="allFileCategoriesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JRadioButton" name="anyCentralRepoCaseRadio">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.anyCentralRepoCaseRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="anyCentralRepoCaseRadioActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="specificCentralRepoCaseRadio">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.specificCentralRepoCaseRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="specificCentralRepoCaseRadioActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="caseComboBox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
@ -96,10 +97,10 @@
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="comboBoxLabel">
|
||||
<Component class="javax.swing.JLabel" name="correlationComboBoxLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.comboBoxLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.correlationComboBoxLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -112,9 +113,90 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.correlationTypeComboBox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="correlationTypeComboBoxActionPerformed"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="categoriesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.categoriesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="allFileCategoriesRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.allFileCategoriesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.allFileCategoriesRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allFileCategoriesRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="selectedFileCategoriesButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.selectedFileCategoriesButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectedFileCategoriesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="pictureVideoCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.pictureVideoCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pictureVideoCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="documentsCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.documentsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="specificCentralRepoCaseCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="InterCasePanel.specificCentralRepoCaseCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="specificCentralRepoCaseCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -24,6 +24,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
@ -33,44 +35,81 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
* UI controls for Common Files Search scenario where the user intends to find
|
||||
* common files between cases in addition to the present case.
|
||||
*/
|
||||
public class InterCasePanel extends javax.swing.JPanel {
|
||||
|
||||
public final class InterCasePanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Observable fileTypeFilterObservable;
|
||||
static final int NO_CASE_SELECTED = -1;
|
||||
|
||||
|
||||
private ComboBoxModel<String> casesList = new DataSourceComboBoxModel();
|
||||
|
||||
|
||||
private final Map<Integer, String> caseMap;
|
||||
|
||||
//True if we are looking in any or all cases,
|
||||
// false if we must find matches in a given case plus the current case
|
||||
private boolean anyCase;
|
||||
|
||||
|
||||
private Map<String, CorrelationAttributeInstance.Type> correlationTypeFilters;
|
||||
|
||||
|
||||
/**
|
||||
* Creates new form InterCasePanel
|
||||
*/
|
||||
public InterCasePanel() {
|
||||
initComponents();
|
||||
this.caseMap = new HashMap<>();
|
||||
this.anyCase = true;
|
||||
|
||||
|
||||
fileTypeFilterObservable = new Observable() {
|
||||
@Override
|
||||
public void notifyObservers() {
|
||||
//set changed before notify observers
|
||||
//we want this observerable to always cause the observer to update when notified
|
||||
this.setChanged();
|
||||
super.notifyObservers();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void specificCaseSelected(boolean selected) {
|
||||
this.specificCentralRepoCaseRadio.setEnabled(selected);
|
||||
if (this.specificCentralRepoCaseRadio.isEnabled()) {
|
||||
this.caseComboBox.setEnabled(true);
|
||||
this.caseComboBox.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the EamDB is enabled, the UI will populate the correlation type ComboBox with
|
||||
* available types in the CR.
|
||||
* Add an Observer to the Observable portion of this panel so that it can be
|
||||
* notified of changes to this panel.
|
||||
*
|
||||
* @param observer the object which is observing this panel
|
||||
*/
|
||||
void addObserver(Observer observer) {
|
||||
fileTypeFilterObservable.addObserver(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has selected to show only results of specific file types.
|
||||
*
|
||||
* @return if the selected file categories button is enabled AND selected,
|
||||
* true for enabled AND selected false for not selected OR not
|
||||
* enabled
|
||||
*/
|
||||
boolean fileCategoriesButtonIsSelected() {
|
||||
return selectedFileCategoriesButton.isEnabled() && selectedFileCategoriesButton.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has selected selected to show Picture and Video files as part
|
||||
* of the filtered results.
|
||||
*
|
||||
* @return if the pictures and video checkbox is enabled AND selected, true
|
||||
* for enabled AND selected false for not selected OR not enabled
|
||||
*/
|
||||
boolean pictureVideoCheckboxIsSelected() {
|
||||
return pictureVideoCheckbox.isEnabled() && pictureVideoCheckbox.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has selected selected to show Document files as part of the
|
||||
* filtered results.
|
||||
*
|
||||
* @return if the documents checkbox is enabled AND selected, true for
|
||||
* enabled AND selected false for not selected OR not enabled
|
||||
*/
|
||||
boolean documentsCheckboxIsSelected() {
|
||||
return documentsCheckbox.isEnabled() && documentsCheckbox.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the EamDB is enabled, the UI will populate the correlation type
|
||||
* ComboBox with available types in the CR.
|
||||
*/
|
||||
void setupCorrelationTypeFilter() {
|
||||
this.correlationTypeFilters = new HashMap<>();
|
||||
@ -84,7 +123,6 @@ public class InterCasePanel extends javax.swing.JPanel {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
this.correlationTypeComboBox.setSelectedIndex(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,138 +135,257 @@ public class InterCasePanel extends javax.swing.JPanel {
|
||||
private void initComponents() {
|
||||
|
||||
buttonGroup = new javax.swing.ButtonGroup();
|
||||
anyCentralRepoCaseRadio = new javax.swing.JRadioButton();
|
||||
specificCentralRepoCaseRadio = new javax.swing.JRadioButton();
|
||||
caseComboBox = new javax.swing.JComboBox<>();
|
||||
comboBoxLabel = new javax.swing.JLabel();
|
||||
correlationComboBoxLabel = new javax.swing.JLabel();
|
||||
correlationTypeComboBox = new javax.swing.JComboBox<>();
|
||||
|
||||
buttonGroup.add(anyCentralRepoCaseRadio);
|
||||
anyCentralRepoCaseRadio.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(anyCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anyCentralRepoCaseRadio.text")); // NOI18N
|
||||
anyCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
anyCentralRepoCaseRadioActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(specificCentralRepoCaseRadio);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseRadio.text")); // NOI18N
|
||||
specificCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
specificCentralRepoCaseRadioActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
categoriesLabel = new javax.swing.JLabel();
|
||||
allFileCategoriesRadioButton = new javax.swing.JRadioButton();
|
||||
selectedFileCategoriesButton = new javax.swing.JRadioButton();
|
||||
pictureVideoCheckbox = new javax.swing.JCheckBox();
|
||||
documentsCheckbox = new javax.swing.JCheckBox();
|
||||
specificCentralRepoCaseCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
caseComboBox.setModel(casesList);
|
||||
caseComboBox.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(comboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.comboBoxLabel.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(correlationComboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationComboBoxLabel.text")); // NOI18N
|
||||
|
||||
correlationTypeComboBox.setSelectedItem(null);
|
||||
correlationTypeComboBox.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationTypeComboBox.toolTipText")); // NOI18N
|
||||
correlationTypeComboBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
correlationTypeComboBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.categoriesLabel.text")); // NOI18N
|
||||
categoriesLabel.setEnabled(false);
|
||||
categoriesLabel.setName(""); // NOI18N
|
||||
|
||||
buttonGroup.add(allFileCategoriesRadioButton);
|
||||
allFileCategoriesRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.allFileCategoriesRadioButton.text")); // NOI18N
|
||||
allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N
|
||||
allFileCategoriesRadioButton.setEnabled(false);
|
||||
allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
allFileCategoriesRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(selectedFileCategoriesButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.selectedFileCategoriesButton.text")); // NOI18N
|
||||
selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N
|
||||
selectedFileCategoriesButton.setEnabled(false);
|
||||
selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
selectedFileCategoriesButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
pictureVideoCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.pictureVideoCheckbox.text")); // NOI18N
|
||||
pictureVideoCheckbox.setEnabled(false);
|
||||
pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
pictureVideoCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
documentsCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.documentsCheckbox.text")); // NOI18N
|
||||
documentsCheckbox.setEnabled(false);
|
||||
documentsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
documentsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseCheckbox, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseCheckbox.text")); // NOI18N
|
||||
specificCentralRepoCaseCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
specificCentralRepoCaseCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(specificCentralRepoCaseCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(anyCentralRepoCaseRadio)
|
||||
.addComponent(specificCentralRepoCaseRadio)
|
||||
.addComponent(correlationComboBoxLabel)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(categoriesLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(19, 19, 19)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(allFileCategoriesRadioButton)
|
||||
.addComponent(selectedFileCategoriesButton)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(documentsCheckbox)
|
||||
.addComponent(pictureVideoCheckbox))))))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(comboBoxLabel)
|
||||
.addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE)))))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(caseComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(correlationTypeComboBox, 0, 353, Short.MAX_VALUE))))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(anyCentralRepoCaseRadio)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(specificCentralRepoCaseRadio)
|
||||
.addContainerGap()
|
||||
.addComponent(specificCentralRepoCaseCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(comboBoxLabel)
|
||||
.addComponent(correlationComboBoxLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(categoriesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(allFileCategoriesRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(selectedFileCategoriesButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pictureVideoCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(documentsCheckbox)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed
|
||||
this.caseComboBox.setEnabled(true);
|
||||
if(this.caseComboBox.isEnabled() && this.caseComboBox.getSelectedItem() == null){
|
||||
private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed
|
||||
//When the allFileCategoriesRadioButton is selected disable the options
|
||||
//related to selected file categories and notify observers that the panel has changed
|
||||
//incase the current settings are invalid
|
||||
pictureVideoCheckbox.setEnabled(false);
|
||||
documentsCheckbox.setEnabled(false);
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed
|
||||
|
||||
private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed
|
||||
//When the selectedFileCategoriesButton is selected enable its related options
|
||||
//and notify observers that the panel has changed incase the current settings are invalid
|
||||
pictureVideoCheckbox.setEnabled(true);
|
||||
documentsCheckbox.setEnabled(true);
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed
|
||||
|
||||
private void specificCentralRepoCaseCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseCheckboxActionPerformed
|
||||
//When the specificCentralRepoCaseCheckbox is clicked update its related options
|
||||
this.caseComboBox.setEnabled(specificCentralRepoCaseCheckbox.isSelected());
|
||||
if (specificCentralRepoCaseCheckbox.isSelected()) {
|
||||
this.caseComboBox.setSelectedIndex(0);
|
||||
}
|
||||
this.anyCase = false;
|
||||
}//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed
|
||||
}//GEN-LAST:event_specificCentralRepoCaseCheckboxActionPerformed
|
||||
|
||||
private void anyCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anyCentralRepoCaseRadioActionPerformed
|
||||
this.caseComboBox.setEnabled(false);
|
||||
this.anyCase = true;
|
||||
}//GEN-LAST:event_anyCentralRepoCaseRadioActionPerformed
|
||||
|
||||
private void correlationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_correlationTypeComboBoxActionPerformed
|
||||
boolean enableFileTypesFilter = this.correlationTypeComboBox.getSelectedItem().equals("Files");
|
||||
categoriesLabel.setEnabled(enableFileTypesFilter);
|
||||
allFileCategoriesRadioButton.setEnabled(enableFileTypesFilter);
|
||||
selectedFileCategoriesButton.setEnabled(enableFileTypesFilter);
|
||||
boolean enableIndividualFilters = (enableFileTypesFilter && selectedFileCategoriesButton.isSelected());
|
||||
pictureVideoCheckbox.setEnabled(enableIndividualFilters);
|
||||
documentsCheckbox.setEnabled(enableIndividualFilters);
|
||||
}//GEN-LAST:event_correlationTypeComboBoxActionPerformed
|
||||
|
||||
private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed
|
||||
//notify observers that the panel has changed incase the current settings are invalid
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_pictureVideoCheckboxActionPerformed
|
||||
|
||||
private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed
|
||||
//notify observers that the panel has changed incase the current settings are invalid
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_documentsCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JRadioButton anyCentralRepoCaseRadio;
|
||||
private javax.swing.JRadioButton allFileCategoriesRadioButton;
|
||||
private javax.swing.ButtonGroup buttonGroup;
|
||||
private javax.swing.JComboBox<String> caseComboBox;
|
||||
private javax.swing.JLabel comboBoxLabel;
|
||||
private javax.swing.JLabel categoriesLabel;
|
||||
private javax.swing.JLabel correlationComboBoxLabel;
|
||||
private javax.swing.JComboBox<String> correlationTypeComboBox;
|
||||
private javax.swing.JRadioButton specificCentralRepoCaseRadio;
|
||||
private javax.swing.JCheckBox documentsCheckbox;
|
||||
private javax.swing.JCheckBox pictureVideoCheckbox;
|
||||
private javax.swing.JRadioButton selectedFileCategoriesButton;
|
||||
private javax.swing.JCheckBox specificCentralRepoCaseCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Get the map of cases which was used to populate the combo box on
|
||||
* this panel.
|
||||
*
|
||||
* @return an unmodifiable copy of the map of cases
|
||||
*/
|
||||
Map<Integer, String> getCaseMap() {
|
||||
return Collections.unmodifiableMap(this.caseMap);
|
||||
}
|
||||
|
||||
void setCaseList(DataSourceComboBoxModel dataSourceComboBoxModel) {
|
||||
/**
|
||||
* Set the datamodel for the combo box which displays the cases in
|
||||
* the central repository
|
||||
*
|
||||
* @param dataSourceComboBoxModel the DataSourceComboBoxModel to use
|
||||
*/
|
||||
void setCaseComboboxModel(DataSourceComboBoxModel dataSourceComboBoxModel) {
|
||||
this.casesList = dataSourceComboBoxModel;
|
||||
this.caseComboBox.setModel(dataSourceComboBoxModel);
|
||||
}
|
||||
|
||||
void rigForMultipleCases(boolean multipleCases) {
|
||||
this.anyCentralRepoCaseRadio.setEnabled(multipleCases);
|
||||
this.anyCentralRepoCaseRadio.setEnabled(multipleCases);
|
||||
|
||||
if(!multipleCases){
|
||||
this.specificCentralRepoCaseRadio.setSelected(true);
|
||||
this.specificCaseSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the map of cases that this panel allows the user to select from
|
||||
*
|
||||
* @param caseMap A map of cases
|
||||
*/
|
||||
void setCaseMap(Map<Integer, String> caseMap) {
|
||||
this.caseMap.clear();
|
||||
this.caseMap.putAll(caseMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the central repository has multiple cases in it.
|
||||
*
|
||||
* @return true when the central repository has 2 or more case, false if it
|
||||
* has 0 or 1 case in it.
|
||||
*/
|
||||
boolean centralRepoHasMultipleCases() {
|
||||
return this.caseMap.size() >= 2;
|
||||
}
|
||||
|
||||
Integer getSelectedCaseId(){
|
||||
if(this.anyCase){
|
||||
return InterCasePanel.NO_CASE_SELECTED;
|
||||
}
|
||||
|
||||
for(Entry<Integer, String> entry : this.caseMap.entrySet()){
|
||||
if(entry.getValue().equals(this.caseComboBox.getSelectedItem())){
|
||||
return entry.getKey();
|
||||
|
||||
/**
|
||||
* Get the ID for the selected case
|
||||
*
|
||||
* @return the ID of the selected case or InterCasePanel.NO_CASE_SELECTED
|
||||
* when none selected
|
||||
*/
|
||||
Integer getSelectedCaseId() {
|
||||
if (specificCentralRepoCaseCheckbox.isSelected()) {
|
||||
for (Entry<Integer, String> entry : this.caseMap.entrySet()) {
|
||||
if (entry.getValue().equals(this.caseComboBox.getSelectedItem())) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return InterCasePanel.NO_CASE_SELECTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the selected Correlation Type by getting the Type from the stored HashMap.
|
||||
* Returns the selected Correlation Type by getting the Type from the stored
|
||||
* HashMap.
|
||||
*
|
||||
* @return Type the selected Correlation Type to query for.
|
||||
*/
|
||||
CorrelationAttributeInstance.Type getSelectedCorrelationType() {
|
||||
|
@ -44,8 +44,6 @@ import org.sleuthkit.datamodel.HashUtility;
|
||||
*/
|
||||
final class InterCaseSearchResultsProcessor {
|
||||
|
||||
private Map<Long, String> dataSources;
|
||||
|
||||
/**
|
||||
* The CorrelationAttributeInstance.Type this Processor will query on
|
||||
*/
|
||||
@ -70,9 +68,8 @@ final class InterCaseSearchResultsProcessor {
|
||||
* @param dataSources the cases to filter and correlate on
|
||||
* @param theType the type of CR data to search
|
||||
*/
|
||||
InterCaseSearchResultsProcessor(Map<Long, String> dataSources, CorrelationAttributeInstance.Type theType) {
|
||||
InterCaseSearchResultsProcessor(CorrelationAttributeInstance.Type theType) {
|
||||
this.correlationType = theType;
|
||||
this.dataSources = dataSources;
|
||||
interCaseWhereClause = getInterCaseWhereClause();
|
||||
singleInterCaseWhereClause = getSingleInterCaseWhereClause();
|
||||
}
|
||||
@ -101,18 +98,6 @@ final class InterCaseSearchResultsProcessor {
|
||||
return sqlString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in the CentralRepoCommonAttributeInstance to find common attribute
|
||||
* instances and generate nodes at the UI level.
|
||||
*
|
||||
* @param theType the type of CR data to search
|
||||
*/
|
||||
InterCaseSearchResultsProcessor(CorrelationAttributeInstance.Type theType) {
|
||||
this.correlationType = theType;
|
||||
interCaseWhereClause = getInterCaseWhereClause();
|
||||
singleInterCaseWhereClause = getSingleInterCaseWhereClause();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a single CorrelationAttribute given an id.
|
||||
*
|
||||
@ -212,11 +197,16 @@ final class InterCaseSearchResultsProcessor {
|
||||
countAndAddCommonAttributes(corValue, resultId);
|
||||
|
||||
}
|
||||
//Add the final instances
|
||||
CommonAttributeValueList value = new CommonAttributeValueList();
|
||||
//Add the final instance(s)
|
||||
if (commonAttributeValue != null) {
|
||||
value.addMetadataToList(commonAttributeValue);
|
||||
instanceCollatedCommonFiles.put(commonAttributeValue.getInstanceCount(), value);
|
||||
int size = commonAttributeValue.getInstanceCount();
|
||||
if (instanceCollatedCommonFiles.containsKey(size)) {
|
||||
instanceCollatedCommonFiles.get(size).addMetadataToList(commonAttributeValue);
|
||||
} else {
|
||||
CommonAttributeValueList value = new CommonAttributeValueList();
|
||||
value.addMetadataToList(commonAttributeValue);
|
||||
instanceCollatedCommonFiles.put(size, value);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS
|
||||
@ -252,7 +242,9 @@ final class InterCaseSearchResultsProcessor {
|
||||
// we don't *have* all the information for the rows in the CR,
|
||||
// so we need to consult the present case via the SleuthkitCase object
|
||||
// Later, when the FileInstanceNode is built. Therefore, build node generators for now.
|
||||
AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId, InterCaseSearchResultsProcessor.this.dataSources, correlationType);
|
||||
CentralRepoCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId, correlationType);
|
||||
CorrelationAttributeInstance corrAttr = findSingleCorrelationAttribute(resultId);
|
||||
searchResult.setCurrentAttributeInst(corrAttr);
|
||||
commonAttributeValue.addInstance(searchResult);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -46,6 +47,8 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt
|
||||
|
||||
private static final String FILTER_BY_MIME_TYPES_WHERE_CLAUSE = " and mime_type in (%s)"; //NON-NLS // where %s is csv list of mime_types to filter on
|
||||
|
||||
private final Map<Long, String> dataSourceIdToNameMap;
|
||||
|
||||
/**
|
||||
* Subclass this to implement different algorithms for getting common files.
|
||||
*
|
||||
@ -56,7 +59,13 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt
|
||||
* broadly categorized as document types
|
||||
*/
|
||||
IntraCaseCommonAttributeSearcher(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) {
|
||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||
super(filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||
this.dataSourceIdToNameMap = dataSourceIdMap;
|
||||
}
|
||||
|
||||
|
||||
Map<Long, String> getDataSourceIdToNameMap() {
|
||||
return Collections.unmodifiableMap(this.dataSourceIdToNameMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,62 +23,58 @@
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="allDataSourcesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="withinDataSourceRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="selectDataSourceComboBox" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
|
||||
<Component id="selectDataSourceComboBox" min="-2" pref="261" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="categoriesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="allFileCategoriesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="onlySpecificDataSourceCheckbox" pref="384" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="allDataSourcesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="withinDataSourceRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="onlySpecificDataSourceCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="selectDataSourceComboBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="categoriesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="allFileCategoriesRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pictureVideoCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="documentsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JRadioButton" name="allDataSourcesRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.allDataSourcesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allDataSourcesRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="withinDataSourceRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.withinDataSourceRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="withinDataSourceRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="selectDataSourceComboBox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
@ -86,12 +82,93 @@
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectDataSourceComboBoxActionPerformed"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="categoriesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.categoriesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="selectedFileCategoriesButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.selectedFileCategoriesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.selectedFileCategoriesButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectedFileCategoriesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="pictureVideoCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.pictureVideoCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pictureVideoCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="documentsCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.documentsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="allFileCategoriesRadioButton">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.allFileCategoriesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.allFileCategoriesRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allFileCategoriesRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="onlySpecificDataSourceCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="IntraCasePanel.onlySpecificDataSourceCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[243, 23]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[243, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[243, 23]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="onlySpecificDataSourceCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -23,19 +23,21 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import javax.swing.ComboBoxModel;
|
||||
|
||||
/**
|
||||
* UI controls for Common Files Search scenario where the user intends to find
|
||||
* common files between datasources. It is an inner panel which provides the ability
|
||||
* to select all datasources or a single datasource from a dropdown list of
|
||||
* sources in the current case.
|
||||
* common files between datasources. It is an inner panel which provides the
|
||||
* ability to select all datasources or a single datasource from a dropdown list
|
||||
* of sources in the current case.
|
||||
*/
|
||||
public class IntraCasePanel extends javax.swing.JPanel {
|
||||
|
||||
public final class IntraCasePanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
static final long NO_DATA_SOURCE_SELECTED = -1;
|
||||
|
||||
private boolean singleDataSource;
|
||||
private final Observable fileTypeFilterObservable;
|
||||
private ComboBoxModel<String> dataSourcesList = new DataSourceComboBoxModel();
|
||||
private final Map<Long, String> dataSourceMap;
|
||||
|
||||
@ -45,26 +47,86 @@ public class IntraCasePanel extends javax.swing.JPanel {
|
||||
public IntraCasePanel() {
|
||||
initComponents();
|
||||
this.dataSourceMap = new HashMap<>();
|
||||
this.singleDataSource = true;
|
||||
this.onlySpecificDataSourceCheckbox.setEnabled(true);
|
||||
fileTypeFilterObservable = new Observable() {
|
||||
@Override
|
||||
public void notifyObservers() {
|
||||
//set changed before notify observers
|
||||
//we want this observerable to always cause the observer to update when notified
|
||||
this.setChanged();
|
||||
super.notifyObservers();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Map<Long, String> getDataSourceMap(){
|
||||
|
||||
/**
|
||||
* Add an Observer to the Observable portion of this panel so that it can be
|
||||
* notified of changes to this panel.
|
||||
*
|
||||
* @param observer the object which is observing this panel
|
||||
*/
|
||||
void addObserver(Observer observer) {
|
||||
fileTypeFilterObservable.addObserver(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map of datasources which was used to populate the combo box on
|
||||
* this panel.
|
||||
*
|
||||
* @return an unmodifiable copy of the map of datasources
|
||||
*/
|
||||
Map<Long, String> getDataSourceMap() {
|
||||
return Collections.unmodifiableMap(this.dataSourceMap);
|
||||
}
|
||||
|
||||
Long getSelectedDataSourceId(){
|
||||
if(!this.singleDataSource){
|
||||
return IntraCasePanel.NO_DATA_SOURCE_SELECTED;
|
||||
}
|
||||
|
||||
for(Entry<Long, String> entry : this.dataSourceMap.entrySet()){
|
||||
if(entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())){
|
||||
return entry.getKey();
|
||||
|
||||
/**
|
||||
* Get the ID for the datasource selected in the combo box.
|
||||
*
|
||||
* @return the selected datasource ID or
|
||||
* IntraCasePanel.NO_DATA_SOURCE_SELECTED if none is selected
|
||||
*/
|
||||
Long getSelectedDataSourceId() {
|
||||
if (onlySpecificDataSourceCheckbox.isSelected()) {
|
||||
for (Entry<Long, String> entry : this.dataSourceMap.entrySet()) {
|
||||
if (entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IntraCasePanel.NO_DATA_SOURCE_SELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has selected to show only results of specific file types.
|
||||
*
|
||||
* @return if the selected file categories button is selected, true for
|
||||
* selected false for not selected
|
||||
*/
|
||||
boolean fileCategoriesButtonIsSelected() {
|
||||
return selectedFileCategoriesButton.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has selected selected to show Picture and Video files as part
|
||||
* of the filtered results.
|
||||
*
|
||||
* @return if the pictures and video checkbox is enabled AND selected, true
|
||||
* for enabled AND selected false for not selected OR not enabled
|
||||
*/
|
||||
boolean pictureVideoCheckboxIsSelected() {
|
||||
return pictureVideoCheckbox.isEnabled() && pictureVideoCheckbox.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user has selected selected to show Document files as part of the
|
||||
* filtered results.
|
||||
*
|
||||
* @return if the documents checkbox is enabled AND selected, true for
|
||||
* enabled AND selected false for not selected OR not enabled
|
||||
*/
|
||||
boolean documentsCheckboxIsSelected() {
|
||||
return documentsCheckbox.isEnabled() && documentsCheckbox.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
@ -76,32 +138,67 @@ public class IntraCasePanel extends javax.swing.JPanel {
|
||||
private void initComponents() {
|
||||
|
||||
buttonGroup = new javax.swing.ButtonGroup();
|
||||
allDataSourcesRadioButton = new javax.swing.JRadioButton();
|
||||
withinDataSourceRadioButton = new javax.swing.JRadioButton();
|
||||
selectDataSourceComboBox = new javax.swing.JComboBox<>();
|
||||
|
||||
buttonGroup.add(allDataSourcesRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(allDataSourcesRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allDataSourcesRadioButton.text")); // NOI18N
|
||||
allDataSourcesRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
allDataSourcesRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
allDataSourcesRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(withinDataSourceRadioButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(withinDataSourceRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.withinDataSourceRadioButton.text")); // NOI18N
|
||||
withinDataSourceRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
withinDataSourceRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
withinDataSourceRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
categoriesLabel = new javax.swing.JLabel();
|
||||
selectedFileCategoriesButton = new javax.swing.JRadioButton();
|
||||
pictureVideoCheckbox = new javax.swing.JCheckBox();
|
||||
documentsCheckbox = new javax.swing.JCheckBox();
|
||||
allFileCategoriesRadioButton = new javax.swing.JRadioButton();
|
||||
onlySpecificDataSourceCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
selectDataSourceComboBox.setModel(dataSourcesList);
|
||||
selectDataSourceComboBox.setActionCommand(org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.selectDataSourceComboBox.actionCommand")); // NOI18N
|
||||
selectDataSourceComboBox.setEnabled(false);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.categoriesLabel.text")); // NOI18N
|
||||
categoriesLabel.setName(""); // NOI18N
|
||||
|
||||
buttonGroup.add(selectedFileCategoriesButton);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.selectedFileCategoriesButton.text")); // NOI18N
|
||||
selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N
|
||||
selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
selectedFileCategoriesButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
pictureVideoCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.pictureVideoCheckbox.text")); // NOI18N
|
||||
pictureVideoCheckbox.setEnabled(false);
|
||||
pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
pictureVideoCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
documentsCheckbox.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.documentsCheckbox.text")); // NOI18N
|
||||
documentsCheckbox.setEnabled(false);
|
||||
documentsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
documentsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(allFileCategoriesRadioButton);
|
||||
allFileCategoriesRadioButton.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allFileCategoriesRadioButton.text")); // NOI18N
|
||||
allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N
|
||||
allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
allFileCategoriesRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(onlySpecificDataSourceCheckbox, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.onlySpecificDataSourceCheckbox.text")); // NOI18N
|
||||
onlySpecificDataSourceCheckbox.setMaximumSize(new java.awt.Dimension(243, 23));
|
||||
onlySpecificDataSourceCheckbox.setMinimumSize(new java.awt.Dimension(243, 23));
|
||||
onlySpecificDataSourceCheckbox.setPreferredSize(new java.awt.Dimension(243, 23));
|
||||
onlySpecificDataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
onlySpecificDataSourceCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
@ -109,65 +206,111 @@ public class IntraCasePanel extends javax.swing.JPanel {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(allDataSourcesRadioButton)
|
||||
.addComponent(withinDataSourceRadioButton)))
|
||||
.addGap(21, 21, 21)
|
||||
.addComponent(selectDataSourceComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(27, 27, 27)
|
||||
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(categoriesLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(19, 19, 19)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(allFileCategoriesRadioButton)
|
||||
.addComponent(selectedFileCategoriesButton)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(21, 21, 21)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(documentsCheckbox)
|
||||
.addComponent(pictureVideoCheckbox))))))
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
.addComponent(onlySpecificDataSourceCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, 384, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(allDataSourcesRadioButton)
|
||||
.addContainerGap()
|
||||
.addComponent(onlySpecificDataSourceCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(withinDataSourceRadioButton)
|
||||
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(categoriesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(allFileCategoriesRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(selectedFileCategoriesButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pictureVideoCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(documentsCheckbox)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed
|
||||
selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected());
|
||||
singleDataSource = false;
|
||||
}//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed
|
||||
private void selectedFileCategoriesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectedFileCategoriesButtonActionPerformed
|
||||
//When the selectedFileCategoriesButton is selected enable its related options
|
||||
//and notify observers that the panel has changed incase the current settings are invalid
|
||||
pictureVideoCheckbox.setEnabled(true);
|
||||
documentsCheckbox.setEnabled(true);
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_selectedFileCategoriesButtonActionPerformed
|
||||
|
||||
private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed
|
||||
withinDataSourceSelected(withinDataSourceRadioButton.isSelected());
|
||||
}//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed
|
||||
private void allFileCategoriesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allFileCategoriesRadioButtonActionPerformed
|
||||
//When the allFileCategoriesRadioButton is selected disable the options
|
||||
//related to selected file categories and notify observers that the panel has changed
|
||||
//incase the current settings are invalid
|
||||
pictureVideoCheckbox.setEnabled(false);
|
||||
documentsCheckbox.setEnabled(false);
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_allFileCategoriesRadioButtonActionPerformed
|
||||
|
||||
private void withinDataSourceSelected(boolean selected) {
|
||||
selectDataSourceComboBox.setEnabled(selected);
|
||||
private void onlySpecificDataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onlySpecificDataSourceCheckboxActionPerformed
|
||||
//When the onlySpecificDataSourceCheckbox is clicked update its related options
|
||||
selectDataSourceComboBox.setEnabled(onlySpecificDataSourceCheckbox.isSelected());
|
||||
if (selectDataSourceComboBox.isEnabled()) {
|
||||
selectDataSourceComboBox.setSelectedIndex(0);
|
||||
singleDataSource = true;
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_onlySpecificDataSourceCheckboxActionPerformed
|
||||
|
||||
private void pictureVideoCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pictureVideoCheckboxActionPerformed
|
||||
//notify observers that the panel has changed incase the current settings are invalid
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_pictureVideoCheckboxActionPerformed
|
||||
|
||||
private void documentsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentsCheckboxActionPerformed
|
||||
//notify observers that the panel has changed incase the current settings are invalid
|
||||
fileTypeFilterObservable.notifyObservers();
|
||||
}//GEN-LAST:event_documentsCheckboxActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JRadioButton allDataSourcesRadioButton;
|
||||
private javax.swing.JRadioButton allFileCategoriesRadioButton;
|
||||
private javax.swing.ButtonGroup buttonGroup;
|
||||
private javax.swing.JLabel categoriesLabel;
|
||||
private javax.swing.JCheckBox documentsCheckbox;
|
||||
private javax.swing.JCheckBox onlySpecificDataSourceCheckbox;
|
||||
private javax.swing.JCheckBox pictureVideoCheckbox;
|
||||
private javax.swing.JComboBox<String> selectDataSourceComboBox;
|
||||
private javax.swing.JRadioButton withinDataSourceRadioButton;
|
||||
private javax.swing.JRadioButton selectedFileCategoriesButton;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
void setDataModel(DataSourceComboBoxModel dataSourceComboBoxModel) {
|
||||
/**
|
||||
* Set the datamodel for the combo box which displays the data sources in
|
||||
* the current case
|
||||
*
|
||||
* @param dataSourceComboBoxModel the DataSourceComboBoxModel to use
|
||||
*/
|
||||
void setDatasourceComboboxModel(DataSourceComboBoxModel dataSourceComboBoxModel) {
|
||||
this.dataSourcesList = dataSourceComboBoxModel;
|
||||
this.selectDataSourceComboBox.setModel(dataSourcesList);
|
||||
}
|
||||
|
||||
void rigForMultipleDataSources(boolean multipleDataSources) {
|
||||
this.withinDataSourceRadioButton.setEnabled(multipleDataSources);
|
||||
this.allDataSourcesRadioButton.setSelected(!multipleDataSources);
|
||||
this.withinDataSourceRadioButton.setSelected(multipleDataSources);
|
||||
this.withinDataSourceSelected(multipleDataSources);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the map of datasources that this panel allows the user to select
|
||||
* from
|
||||
*
|
||||
* @param dataSourceMap A map of datasources
|
||||
*/
|
||||
void setDataSourceMap(Map<Long, String> dataSourceMap) {
|
||||
this.dataSourceMap.clear();
|
||||
this.dataSourceMap.putAll(dataSourceMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -20,13 +20,17 @@
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
|
||||
import static org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher.MEDIA_PICS_VIDEO_MIME_TYPES;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -42,11 +46,14 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri
|
||||
* @param correlationCaseId
|
||||
* @param filterByMediaMimeType
|
||||
* @param filterByDocMimeType
|
||||
* @param corAttrType
|
||||
* @param percentageThreshold
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType,
|
||||
public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, boolean filterByMediaMimeType,
|
||||
boolean filterByDocMimeType, Type corAttrType, int percentageThreshold) throws EamDbException {
|
||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, corAttrType, percentageThreshold);
|
||||
super(filterByMediaMimeType, filterByDocMimeType, corAttrType, percentageThreshold);
|
||||
|
||||
this.corrleationCaseId = correlationCaseId;
|
||||
this.correlationCaseName = "";
|
||||
@ -56,9 +63,8 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri
|
||||
* Collect metadata required to render the tree table where matches must
|
||||
* occur in the case with the given ID.
|
||||
*
|
||||
* @param correlationCaseId id of case where matches must occur (no other
|
||||
* matches will be shown)
|
||||
* @return business object needed to populate tree table with results
|
||||
*
|
||||
* @throws TskCoreException
|
||||
* @throws NoCurrentCaseException
|
||||
* @throws SQLException
|
||||
@ -73,15 +79,30 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri
|
||||
}
|
||||
|
||||
CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
|
||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap(), this.corAttrType);
|
||||
InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.corAttrType);
|
||||
Map<Integer, CommonAttributeValueList> interCaseCommonFiles = eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase);
|
||||
|
||||
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType);
|
||||
Set<String> mimeTypesToFilterOn = new HashSet<>();
|
||||
if (isFilterByMedia()) {
|
||||
mimeTypesToFilterOn.addAll(MEDIA_PICS_VIDEO_MIME_TYPES);
|
||||
}
|
||||
if (isFilterByDoc()) {
|
||||
mimeTypesToFilterOn.addAll(TEXT_FILES_MIME_TYPES);
|
||||
}
|
||||
return new CommonAttributeSearchResults(interCaseCommonFiles, this.frequencyPercentageThreshold, this.corAttrType, mimeTypesToFilterOn);
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - case name",
|
||||
"# {1} - attr type",
|
||||
"# {2} - threshold string",
|
||||
"SingleInterCaseCommonAttributeSearcher.buildTabTitle.titleInterSingle=Common Properties (Central Repository Case: {0}, {1}{2})"})
|
||||
|
||||
@Override
|
||||
String buildTabTitle() {
|
||||
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterSingle();
|
||||
return String.format(titleTemplate, new Object[]{this.correlationCaseName, this.corAttrType.getDisplayName()});
|
||||
String getTabTitle() {
|
||||
String typeString = this.corAttrType.getDisplayName();
|
||||
if (typeString.equals("Files")) {
|
||||
typeString = this.buildCategorySelectionString();
|
||||
}
|
||||
return Bundle.SingleInterCaseCommonAttributeSearcher_buildTabTitle_titleInterSingle(this.correlationCaseName, typeString, this.getPercentThresholdString());
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
*
|
||||
* Copyright 2018 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.
|
||||
@ -20,6 +20,7 @@
|
||||
package org.sleuthkit.autopsy.commonfilesearch;
|
||||
|
||||
import java.util.Map;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
|
||||
/**
|
||||
@ -27,19 +28,22 @@ import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
*/
|
||||
final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommonAttributeSearcher {
|
||||
|
||||
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS
|
||||
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != " + FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS
|
||||
private final Long selectedDataSourceId;
|
||||
private final String dataSourceName;
|
||||
|
||||
/**
|
||||
* Implements the algorithm for getting common files that appear at least
|
||||
* once in the given data source
|
||||
* @param dataSourceId data source id for which common files must appear at least once
|
||||
* @param dataSourceIdMap a map of obj_id to datasource name
|
||||
*
|
||||
* @param dataSourceId data source id for which common files must
|
||||
* appear at least once
|
||||
* @param dataSourceIdMap a map of obj_id to datasource name
|
||||
* @param filterByMediaMimeType match only on files whose mime types can be
|
||||
* broadly categorized as media types
|
||||
* @param filterByDocMimeType match only on files whose mime types can be
|
||||
* broadly categorized as document types
|
||||
* broadly categorized as media types
|
||||
* @param filterByDocMimeType match only on files whose mime types can be
|
||||
* broadly categorized as document types
|
||||
* @param percentageThreshold omit any matches with frequency above this threshold
|
||||
*/
|
||||
public SingleIntraCaseCommonAttributeSearcher(Long dataSourceId, Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType, int percentageThreshold) {
|
||||
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType, percentageThreshold);
|
||||
@ -53,10 +57,13 @@ final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommo
|
||||
return String.format(SingleIntraCaseCommonAttributeSearcher.WHERE_CLAUSE, args);
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - data source name",
|
||||
"# {1} - build category",
|
||||
"# {2} - threshold string",
|
||||
"SingleIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraSingle=Common Properties (Data Source: {0}, {1}{2})"})
|
||||
@Override
|
||||
public String buildTabTitle() {
|
||||
final String buildCategorySelectionString = this.buildCategorySelectionString();
|
||||
final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraSingle();
|
||||
return String.format(titleTemplate, new Object[]{this.dataSourceName, buildCategorySelectionString});
|
||||
String getTabTitle() {
|
||||
return Bundle.SingleIntraCaseCommonAttributeSearcher_buildTabTitle_titleIntraSingle(this.dataSourceName, this.buildCategorySelectionString(), this.getPercentThresholdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ import java.util.logging.Level;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
@ -68,10 +70,18 @@ final class RelationshipNode extends BlackboardArtifactNode {
|
||||
}
|
||||
|
||||
sheetSet.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
final BlackboardArtifact artifact = getArtifact();
|
||||
BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(getArtifact().getArtifactTypeID());
|
||||
if (null != fromID) {
|
||||
@ -120,7 +130,6 @@ final class RelationshipNode extends BlackboardArtifactNode {
|
||||
break;
|
||||
}
|
||||
}
|
||||
addTagProperty(sheetSet, tags);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
@ -234,12 +234,12 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
}
|
||||
|
||||
if (commentDataFound == false) {
|
||||
addMessage(html, "There is no comment data for the selected content in the central repository.");
|
||||
addMessage(html, "There is no comment data for the selected content in the Central Repository.");
|
||||
}
|
||||
} catch (EamDbException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error connecting to the central repository database.", ex); // NON-NLS
|
||||
logger.log(Level.SEVERE, "Error connecting to the Central Repository database.", ex); // NON-NLS
|
||||
} catch (CorrelationAttributeNormalizationException ex) {
|
||||
logger.log(Level.SEVERE, "Error normalizing instance from repository database.", ex); // NON-NLS
|
||||
logger.log(Level.SEVERE, "Error normalizing instance from Central Repository database.", ex); // NON-NLS
|
||||
}
|
||||
endSection(html);
|
||||
}
|
||||
@ -273,7 +273,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
* @param message The message text.
|
||||
*/
|
||||
private void addMessage(StringBuilder html, String message) {
|
||||
html.append("<p style=\"font-style:italic;\">")
|
||||
html.append("<p style=\"font-size:11px;font-style:italic;\">")
|
||||
.append(message)
|
||||
.append("</p><br>"); //NON-NLS
|
||||
}
|
||||
@ -299,12 +299,11 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
|
||||
/**
|
||||
* Add a data table containing information about a correlation attribute
|
||||
* instance in the central repository.
|
||||
* instance in the Central Repository.
|
||||
*
|
||||
* @param html The HTML text to add the table to.
|
||||
* @param attributeInstance The attribute instance whose information will be
|
||||
* used to populate the table.
|
||||
* @param correlationType The correlation data type.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"AnnotationsContentViewer.centralRepositoryEntryDataLabel.case=Case:",
|
||||
|
@ -37,6 +37,8 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
@ -729,15 +731,22 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
||||
|
||||
AbstractFile file = getContent();
|
||||
sheetSet.put(new NodeProperty<>("Name", "Name", "Name", file.getName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
sheetSet.put(new NodeProperty<>("Size", "Size", "Size", file.getSize()));
|
||||
sheetSet.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", StringUtils.defaultString(file.getMIMEType())));
|
||||
sheetSet.put(new NodeProperty<>("Known", "Known", "Known", file.getKnown().getName()));
|
||||
|
||||
addTagProperty(sheetSet, tags);
|
||||
return sheet;
|
||||
}
|
||||
}
|
||||
|
269
Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
Normal file → Executable file
@ -22,16 +22,24 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
@ -43,11 +51,8 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.tabulardatareader.AbstractReader;
|
||||
import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException;
|
||||
import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException;
|
||||
import org.sleuthkit.autopsy.tabulardatareader.FileReaderFactory;
|
||||
|
||||
/**
|
||||
* A file content viewer for SQLite database files.
|
||||
@ -62,7 +67,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||
private final SQLiteTableView selectedTableView = new SQLiteTableView();
|
||||
private AbstractFile sqliteDbFile;
|
||||
private File tmpDbFile;
|
||||
private AbstractReader sqliteReader;
|
||||
private Connection connection;
|
||||
private int numRows; // num of rows in the selected table
|
||||
private int currPage = 0; // curr page of rows being displayed
|
||||
|
||||
@ -339,9 +344,13 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||
numEntriesField.setText("");
|
||||
|
||||
// close DB connection to file
|
||||
if (null != sqliteReader) {
|
||||
sqliteReader.close();
|
||||
sqliteReader = null;
|
||||
if (null != connection) {
|
||||
try {
|
||||
connection.close();
|
||||
connection = null;
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to close DB connection to file.", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
sqliteDbFile = null;
|
||||
@ -358,46 +367,66 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||
"SQLiteViewer.errorMessage.failedToQueryDatabase=The database tables in the file could not be read.",
|
||||
"SQLiteViewer.errorMessage.failedToinitJDBCDriver=The JDBC driver for SQLite could not be loaded.",
|
||||
"# {0} - exception message", "SQLiteViewer.errorMessage.unexpectedError=An unexpected error occurred:\n{0).",})
|
||||
private void processSQLiteFile() {
|
||||
private void processSQLiteFile() {
|
||||
|
||||
tablesDropdownList.removeAllItems();
|
||||
|
||||
try {
|
||||
String localDiskPath = Case.getCurrentCaseThrows().getTempDirectory() +
|
||||
File.separator + sqliteDbFile.getName();
|
||||
|
||||
sqliteReader = FileReaderFactory.createReader(SUPPORTED_MIMETYPES[0], sqliteDbFile, localDiskPath);
|
||||
|
||||
Map<String, String> dbTablesMap = sqliteReader.getTableSchemas();
|
||||
|
||||
String localDiskPath = SqliteUtil.writeAbstractFileToLocalDisk(sqliteDbFile);
|
||||
SqliteUtil.findAndCopySQLiteMetaFile(sqliteDbFile);
|
||||
// Load the SQLite JDBC driver, if necessary.
|
||||
Class.forName("org.sqlite.JDBC"); //NON-NLS
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + localDiskPath); //NON-NLS
|
||||
|
||||
Collection<String> dbTablesMap = getTables();
|
||||
if (dbTablesMap.isEmpty()) {
|
||||
tablesDropdownList.addItem(Bundle.SQLiteViewer_comboBox_noTableEntry());
|
||||
tablesDropdownList.setEnabled(false);
|
||||
} else {
|
||||
dbTablesMap.keySet().forEach((tableName) -> {
|
||||
dbTablesMap.forEach((tableName) -> {
|
||||
tablesDropdownList.addItem(tableName);
|
||||
});
|
||||
}
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Current case has been closed", ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_noCurrentCase());
|
||||
} catch (FileReaderException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Failed to get tables from DB file '%s' (objId=%d)", //NON-NLS
|
||||
sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
|
||||
MessageNotifyUtil.Message.error(
|
||||
Bundle.SQLiteViewer_errorMessage_failedToQueryDatabase());
|
||||
} catch (FileReaderInitException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Failed to create a SQLiteReader '%s' (objId=%d)", //NON-NLS
|
||||
sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to initialize JDBC SQLite '%s' (objId=%d)", sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_failedToinitJDBCDriver());
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to get tables from DB file '%s' (objId=%d)", sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_failedToQueryDatabase());
|
||||
} catch (IOException | NoCurrentCaseException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to create temp copy of DB file '%s' (objId=%d)", sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_failedToExtractFile());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a collection of table names from the SQLite database file.
|
||||
*
|
||||
* @return A collection of table names
|
||||
*/
|
||||
private Collection<String> getTables() throws SQLException {
|
||||
Collection<String> tableNames = new LinkedList<>();
|
||||
try (Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(
|
||||
"SELECT name FROM sqlite_master "
|
||||
+ " WHERE type= 'table' ")){
|
||||
while (resultSet.next()) {
|
||||
tableNames.add(resultSet.getString("name")); //NON-NLS
|
||||
}
|
||||
}
|
||||
return tableNames;
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"# {0} - tableName",
|
||||
"SQLiteViewer.selectTable.errorText=Error getting row count for table: {0}"
|
||||
})
|
||||
private void selectTable(String tableName) {
|
||||
try {
|
||||
numRows = sqliteReader.getRowCountFromTable(tableName);
|
||||
|
||||
try (Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(
|
||||
"SELECT count (*) as count FROM " + "\"" + tableName + "\"")) { //NON-NLS{
|
||||
|
||||
numRows = resultSet.getInt("count");
|
||||
numEntriesField.setText(numRows + " entries");
|
||||
|
||||
currPage = 1;
|
||||
@ -416,12 +445,9 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||
selectedTableView.setupTable(Collections.emptyList());
|
||||
}
|
||||
|
||||
} catch (FileReaderException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Failed to load table %s from DB file '%s' (objId=%d)", tableName, //NON-NLS
|
||||
sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
|
||||
MessageNotifyUtil.Message.error(
|
||||
Bundle.SQLiteViewer_selectTable_errorText(tableName));
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to load table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_selectTable_errorText(tableName));
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,108 +455,109 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||
"SQLiteViewer.readTable.errorText=Error getting rows for table: {0}"})
|
||||
private void readTable(String tableName, int startRow, int numRowsToRead) {
|
||||
|
||||
try {
|
||||
List<Map<String, Object>> rows = sqliteReader.getRowsFromTable(
|
||||
tableName, startRow, numRowsToRead);
|
||||
try (
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(
|
||||
"SELECT * FROM " + "\"" + tableName + "\""
|
||||
+ " LIMIT " + Integer.toString(numRowsToRead)
|
||||
+ " OFFSET " + Integer.toString(startRow - 1))) {
|
||||
|
||||
List<Map<String, Object>> rows = resultSetToArrayList(resultSet);
|
||||
if (Objects.nonNull(rows)) {
|
||||
selectedTableView.setupTable(rows);
|
||||
} else {
|
||||
selectedTableView.setupTable(Collections.emptyList());
|
||||
}
|
||||
} catch (FileReaderException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Failed to read table %s from DB file '%s' (objId=%d)", tableName, //NON-NLS
|
||||
sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
|
||||
MessageNotifyUtil.Message.error(
|
||||
Bundle.SQLiteViewer_readTable_errorText(tableName));
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to read table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_readTable_errorText(tableName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a sqlite table into a CSV file.
|
||||
*
|
||||
* @param file
|
||||
* @param tableName
|
||||
* @param rowMap A list of rows in the table, where each row is represented as a column-value
|
||||
* map.
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"SQLiteViewer.exportTableToCsv.FileName=File name: ",
|
||||
"SQLiteViewer.exportTableToCsv.TableName=Table name: "
|
||||
})
|
||||
public void exportTableToCSV(File file, String tableName,
|
||||
List<Map<String, Object>> rowMap) throws FileNotFoundException, IOException{
|
||||
|
||||
File csvFile;
|
||||
String fileName = file.getName();
|
||||
if (FilenameUtils.getExtension(fileName).equalsIgnoreCase("csv")) {
|
||||
csvFile = file;
|
||||
} else {
|
||||
csvFile = new File(file.toString() + ".csv");
|
||||
}
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(csvFile, false)) {
|
||||
|
||||
out.write((Bundle.SQLiteViewer_exportTableToCsv_FileName() + csvFile.getName() + "\n").getBytes());
|
||||
out.write((Bundle.SQLiteViewer_exportTableToCsv_TableName() + tableName + "\n").getBytes());
|
||||
|
||||
String header = createColumnHeader(rowMap.get(0)).concat("\n");
|
||||
out.write(header.getBytes());
|
||||
|
||||
for (Map<String, Object> maps : rowMap) {
|
||||
String row = maps.values()
|
||||
.stream()
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.joining(","))
|
||||
.concat("\n");
|
||||
out.write(row.getBytes());
|
||||
@NbBundle.Messages("SQLiteViewer.BlobNotShown.message=BLOB Data not shown")
|
||||
private List<Map<String, Object>> resultSetToArrayList(ResultSet resultSet) throws SQLException {
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
int columns = metaData.getColumnCount();
|
||||
ArrayList<Map<String, Object>> rowlist = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
Map<String, Object> row = new LinkedHashMap<>(columns);
|
||||
for (int i = 1; i <= columns; ++i) {
|
||||
if (resultSet.getObject(i) == null) {
|
||||
row.put(metaData.getColumnName(i), "");
|
||||
} else {
|
||||
if (metaData.getColumnTypeName(i).compareToIgnoreCase("blob") == 0) {
|
||||
row.put(metaData.getColumnName(i), Bundle.SQLiteViewer_BlobNotShown_message());
|
||||
} else {
|
||||
row.put(metaData.getColumnName(i), resultSet.getObject(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
rowlist.add(row);
|
||||
}
|
||||
|
||||
return rowlist;
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"SQLiteViewer.exportTableToCsv.write.errText=Failed to export table content to csv file.",
|
||||
@NbBundle.Messages({"SQLiteViewer.exportTableToCsv.write.errText=Failed to export table content to csv file.",
|
||||
"SQLiteViewer.exportTableToCsv.FileName=File name: ",
|
||||
"SQLiteViewer.exportTableToCsv.TableName=Table name: "
|
||||
})
|
||||
private void exportTableToCsv(File file) {
|
||||
String tableName = (String) this.tablesDropdownList.getSelectedItem();
|
||||
try {
|
||||
List<Map<String, Object>> currentTableRows =
|
||||
sqliteReader.getRowsFromTable(tableName);
|
||||
try (
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery("SELECT * FROM " + "\"" + tableName + "\"")) {
|
||||
List<Map<String, Object>> currentTableRows = resultSetToArrayList(resultSet);
|
||||
|
||||
if (Objects.isNull(currentTableRows) || currentTableRows.isEmpty()) {
|
||||
logger.log(Level.INFO, String.format(
|
||||
"The table %s is empty. (objId=%d)", tableName, //NON-NLS
|
||||
sqliteDbFile.getId()));
|
||||
logger.log(Level.INFO, String.format("The table %s is empty. (objId=%d)", tableName, sqliteDbFile.getId())); //NON-NLS
|
||||
} else {
|
||||
exportTableToCSV(file, tableName, currentTableRows);
|
||||
File csvFile;
|
||||
String fileName = file.getName();
|
||||
if (FilenameUtils.getExtension(fileName).equalsIgnoreCase("csv")) {
|
||||
csvFile = file;
|
||||
} else {
|
||||
csvFile = new File(file.toString() + ".csv");
|
||||
}
|
||||
|
||||
try (FileOutputStream out = new FileOutputStream(csvFile, false)) {
|
||||
|
||||
out.write((Bundle.SQLiteViewer_exportTableToCsv_FileName() + csvFile.getName() + "\n").getBytes());
|
||||
out.write((Bundle.SQLiteViewer_exportTableToCsv_TableName() + tableName + "\n").getBytes());
|
||||
// Set up the column names
|
||||
Map<String, Object> row = currentTableRows.get(0);
|
||||
StringBuffer header = new StringBuffer();
|
||||
for (Map.Entry<String, Object> col : row.entrySet()) {
|
||||
String colName = col.getKey();
|
||||
if (header.length() > 0) {
|
||||
header.append(',').append(colName);
|
||||
} else {
|
||||
header.append(colName);
|
||||
}
|
||||
}
|
||||
out.write(header.append('\n').toString().getBytes());
|
||||
|
||||
for (Map<String, Object> maps : currentTableRows) {
|
||||
StringBuffer valueLine = new StringBuffer();
|
||||
maps.values().forEach((value) -> {
|
||||
if (valueLine.length() > 0) {
|
||||
valueLine.append(',').append(value.toString());
|
||||
} else {
|
||||
valueLine.append(value.toString());
|
||||
}
|
||||
});
|
||||
out.write(valueLine.append('\n').toString().getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileReaderException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Failed to read table %s from DB file '%s' (objId=%d)", //NON-NLS
|
||||
tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
|
||||
MessageNotifyUtil.Message.error(
|
||||
Bundle.SQLiteViewer_readTable_errorText(tableName));
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to read table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_readTable_errorText(tableName));
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Failed to export table %s to file '%s'", tableName, file.getName()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(
|
||||
Bundle.SQLiteViewer_exportTableToCsv_write_errText());
|
||||
logger.log(Level.SEVERE, String.format("Failed to export table %s to file '%s'", tableName, file.getName()), ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_exportTableToCsv_write_errText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a comma seperated header string from the keys of the column
|
||||
* row map.
|
||||
*
|
||||
* @param row column header row map
|
||||
* @return comma seperated header string
|
||||
*/
|
||||
private String createColumnHeader(Map<String, Object> row) {
|
||||
return row.entrySet()
|
||||
.stream()
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
}
|
||||
|
130
Core/src/org/sleuthkit/autopsy/contentviewers/SqliteUtil.java
Executable file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018-2018 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.contentviewers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
||||
import org.sleuthkit.autopsy.casemodule.services.Services;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Sqlite utility class. Find and copy metafiles, write sqlite abstract files to
|
||||
* temp directory, and generate unique temp directory paths.
|
||||
*/
|
||||
final class SqliteUtil {
|
||||
|
||||
private SqliteUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded implementation of
|
||||
* {@link #findAndCopySQLiteMetaFile(AbstractFile, String) findAndCopySQLiteMetaFile}
|
||||
* , automatically tries to copy -wal and -shm files without needing to know
|
||||
* their existence.
|
||||
*
|
||||
* @param sqliteFile file which has -wal and -shm meta files
|
||||
*
|
||||
* @throws NoCurrentCaseException Case has been closed.
|
||||
* @throws TskCoreException fileManager cannot find AbstractFile
|
||||
* files.
|
||||
* @throws IOException Issue during writing to file.
|
||||
*/
|
||||
public static void findAndCopySQLiteMetaFile(AbstractFile sqliteFile)
|
||||
throws NoCurrentCaseException, TskCoreException, IOException {
|
||||
|
||||
findAndCopySQLiteMetaFile(sqliteFile, sqliteFile.getName() + "-wal");
|
||||
findAndCopySQLiteMetaFile(sqliteFile, sqliteFile.getName() + "-shm");
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a meta file associated with the give SQLite database. If
|
||||
* found, it copies this file into the temp directory of the current case.
|
||||
*
|
||||
* @param sqliteFile file being processed
|
||||
* @param metaFileName name of meta file to look for
|
||||
*
|
||||
* @throws NoCurrentCaseException Case has been closed.
|
||||
* @throws TskCoreException fileManager cannot find AbstractFile
|
||||
* files.
|
||||
* @throws IOException Issue during writing to file.
|
||||
*/
|
||||
public static void findAndCopySQLiteMetaFile(AbstractFile sqliteFile,
|
||||
String metaFileName) throws NoCurrentCaseException, TskCoreException, IOException {
|
||||
|
||||
Case openCase = Case.getCurrentCaseThrows();
|
||||
SleuthkitCase sleuthkitCase = openCase.getSleuthkitCase();
|
||||
Services services = new Services(sleuthkitCase);
|
||||
FileManager fileManager = services.getFileManager();
|
||||
|
||||
List<AbstractFile> metaFiles = fileManager.findFiles(
|
||||
sqliteFile.getDataSource(), metaFileName,
|
||||
sqliteFile.getParent().getName());
|
||||
|
||||
if (metaFiles != null) {
|
||||
for (AbstractFile metaFile : metaFiles) {
|
||||
writeAbstractFileToLocalDisk(metaFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the file contents into a unique path in the current case temp
|
||||
* directory.
|
||||
*
|
||||
* @param file AbstractFile from the data source
|
||||
*
|
||||
* @return The path of the file on disk
|
||||
*
|
||||
* @throws IOException Exception writing file contents
|
||||
* @throws NoCurrentCaseException Current case closed during file copying
|
||||
*/
|
||||
public static String writeAbstractFileToLocalDisk(AbstractFile file)
|
||||
throws IOException, NoCurrentCaseException {
|
||||
|
||||
String localDiskPath = getUniqueTempDirectoryPath(file);
|
||||
File localDatabaseFile = new File(localDiskPath);
|
||||
if (!localDatabaseFile.exists()) {
|
||||
ContentUtils.writeToFile(file, localDatabaseFile);
|
||||
}
|
||||
return localDiskPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique local disk path that resides in the temp directory of
|
||||
* the current case.
|
||||
*
|
||||
* @param file The database abstract file
|
||||
*
|
||||
* @return Unique local disk path living in the temp directory of the case
|
||||
*
|
||||
* @throws org.sleuthkit.autopsy.casemodule.NoCurrentCaseException
|
||||
*/
|
||||
public static String getUniqueTempDirectoryPath(AbstractFile file) throws NoCurrentCaseException {
|
||||
return Case.getCurrentCaseThrows().getTempDirectory()
|
||||
+ File.separator + file.getId() + file.getName();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013-2017 Basis Technology Corp.
|
||||
* Copyright 2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -71,6 +71,7 @@ public final class UserPreferences {
|
||||
private static final int LOG_FILE_NUM_INT = 10;
|
||||
public static final String GROUP_ITEMS_IN_TREE_BY_DATASOURCE = "GroupItemsInTreeByDataSource"; //NON-NLS
|
||||
public static final String SHOW_ONLY_CURRENT_USER_TAGS = "ShowOnlyCurrentUserTags";
|
||||
public static final String HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES = "HideCentralRepoCommentsAndOccurrences";
|
||||
|
||||
// Prevent instantiation.
|
||||
private UserPreferences() {
|
||||
@ -189,10 +190,12 @@ public final class UserPreferences {
|
||||
preferences.putInt(NUMBER_OF_FILE_INGEST_THREADS, value);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean groupItemsInTreeByDatasource() {
|
||||
return preferences.getBoolean(GROUP_ITEMS_IN_TREE_BY_DATASOURCE, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void setGroupItemsInTreeByDatasource(boolean value) {
|
||||
preferences.putBoolean(GROUP_ITEMS_IN_TREE_BY_DATASOURCE, value);
|
||||
}
|
||||
@ -218,6 +221,30 @@ public final class UserPreferences {
|
||||
preferences.putBoolean(SHOW_ONLY_CURRENT_USER_TAGS, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user preference which identifies whether the Central Repository
|
||||
* should be called to get comments and occurrences for the (C)omments and
|
||||
* (O)ccurrences columns in the result view.
|
||||
*
|
||||
* @return True if hiding Central Repository data for comments and
|
||||
* occurrences; otherwise false.
|
||||
*/
|
||||
public static boolean hideCentralRepoCommentsAndOccurrences() {
|
||||
return preferences.getBoolean(HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the user preference which identifies whether the Central Repository
|
||||
* should be called to get comments and occurrences for the (C)omments and
|
||||
* (O)ccurrences columns in the result view.
|
||||
*
|
||||
* @param value The value of which to assign to the user preference.
|
||||
*/
|
||||
public static void setHideCentralRepoCommentsAndOccurrences(boolean value) {
|
||||
preferences.putBoolean(HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads persisted case database connection info.
|
||||
*
|
||||
|
@ -35,7 +35,7 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" pref="479" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -64,15 +64,11 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="logoPanel" pref="1010" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="viewPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="runtimePanel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="runtimePanel" max="32767" attributes="0"/>
|
||||
<Component id="logoPanel" alignment="0" pref="1002" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -81,14 +77,11 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="viewPanel" max="32767" attributes="0"/>
|
||||
<Component id="runtimePanel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="runtimePanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="logoPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace pref="185" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -128,7 +121,7 @@
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="agencyLogoPreview" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace pref="479" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -232,219 +225,6 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="viewPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="View">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.viewPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="useGMTTimeRB" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="keepCurrentViewerRB" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useBestViewerRB" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesHideKnownCB" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="viewsHideKnownCB" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dataSourcesHideSlackCB" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="viewsHideSlackCB" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useLocalTimeRB" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="158" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabelHideSlackFiles" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabelTimeDisplay" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabelHideKnownFiles" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabelSelectFile" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="30" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabelSelectFile" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="useBestViewerRB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="keepCurrentViewerRB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="jLabelHideKnownFiles" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesHideKnownCB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="viewsHideKnownCB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabelHideSlackFiles" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesHideSlackCB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="viewsHideSlackCB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabelTimeDisplay" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="useLocalTimeRB" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useGMTTimeRB" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabelSelectFile">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.jLabelSelectFile.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="useBestViewerRB">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="fileSelectionButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useBestViewerRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useBestViewerRB.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useBestViewerRBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="keepCurrentViewerRB">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="fileSelectionButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.keepCurrentViewerRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="keepCurrentViewerRBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabelHideKnownFiles">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.jLabelHideKnownFiles.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="dataSourcesHideKnownCB">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.dataSourcesHideKnownCB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dataSourcesHideKnownCBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="viewsHideKnownCB">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.viewsHideKnownCB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="viewsHideKnownCBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabelHideSlackFiles">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.jLabelHideSlackFiles.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="dataSourcesHideSlackCB">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.dataSourcesHideSlackCB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dataSourcesHideSlackCBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="viewsHideSlackCB">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.viewsHideSlackCB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="viewsHideSlackCBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabelTimeDisplay">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.jLabelTimeDisplay.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="useLocalTimeRB">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="displayTimesButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useLocalTimeRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useLocalTimeRBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="useGMTTimeRB">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="displayTimesButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="AutopsyOptionsPanel.useGMTTimeRB.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useGMTTimeRBActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="runtimePanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
@ -471,7 +251,7 @@
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="maxMemoryUnitsLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="restartNecessaryWarning" max="32767" attributes="0"/>
|
||||
<Component id="restartNecessaryWarning" pref="783" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="maxMemoryUnitsLabel" min="-2" max="-2" attributes="0"/>
|
||||
|
@ -285,16 +285,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
* Load the saved user preferences.
|
||||
*/
|
||||
void load() {
|
||||
boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer();
|
||||
keepCurrentViewerRB.setSelected(keepPreferredViewer);
|
||||
useBestViewerRB.setSelected(!keepPreferredViewer);
|
||||
dataSourcesHideKnownCB.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree());
|
||||
viewsHideKnownCB.setSelected(UserPreferences.hideKnownFilesInViewsTree());
|
||||
dataSourcesHideSlackCB.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree());
|
||||
viewsHideSlackCB.setSelected(UserPreferences.hideSlackFilesInViewsTree());
|
||||
boolean useLocalTime = UserPreferences.displayTimesInLocalTime();
|
||||
useLocalTimeRB.setSelected(useLocalTime);
|
||||
useGMTTimeRB.setSelected(!useLocalTime);
|
||||
String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP);
|
||||
boolean useDefault = (path == null || path.isEmpty());
|
||||
defaultLogoRB.setSelected(useDefault);
|
||||
@ -350,12 +340,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
* Store the current user preferences.
|
||||
*/
|
||||
void store() {
|
||||
UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRB.isSelected());
|
||||
UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCB.isSelected());
|
||||
UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCB.isSelected());
|
||||
UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCB.isSelected());
|
||||
UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCB.isSelected());
|
||||
UserPreferences.setDisplayTimesInLocalTime(useLocalTimeRB.isSelected());
|
||||
UserPreferences.setLogFileCount(Integer.parseInt(logFileCount.getText()));
|
||||
if (!agencyLogoPathField.getText().isEmpty()) {
|
||||
File file = new File(agencyLogoPathField.getText());
|
||||
@ -535,19 +519,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
defaultLogoRB = new javax.swing.JRadioButton();
|
||||
specifyLogoRB = new javax.swing.JRadioButton();
|
||||
agencyLogoPathFieldValidationLabel = new javax.swing.JLabel();
|
||||
viewPanel = new javax.swing.JPanel();
|
||||
jLabelSelectFile = new javax.swing.JLabel();
|
||||
useBestViewerRB = new javax.swing.JRadioButton();
|
||||
keepCurrentViewerRB = new javax.swing.JRadioButton();
|
||||
jLabelHideKnownFiles = new javax.swing.JLabel();
|
||||
dataSourcesHideKnownCB = new javax.swing.JCheckBox();
|
||||
viewsHideKnownCB = new javax.swing.JCheckBox();
|
||||
jLabelHideSlackFiles = new javax.swing.JLabel();
|
||||
dataSourcesHideSlackCB = new javax.swing.JCheckBox();
|
||||
viewsHideSlackCB = new javax.swing.JCheckBox();
|
||||
jLabelTimeDisplay = new javax.swing.JLabel();
|
||||
useLocalTimeRB = new javax.swing.JRadioButton();
|
||||
useGMTTimeRB = new javax.swing.JRadioButton();
|
||||
runtimePanel = new javax.swing.JPanel();
|
||||
maxMemoryLabel = new javax.swing.JLabel();
|
||||
maxMemoryUnitsLabel = new javax.swing.JLabel();
|
||||
@ -624,7 +595,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addComponent(agencyLogoPathFieldValidationLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(479, Short.MAX_VALUE))
|
||||
);
|
||||
logoPanelLayout.setVerticalGroup(
|
||||
logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@ -643,139 +614,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
viewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewPanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabelSelectFile, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelSelectFile.text")); // NOI18N
|
||||
|
||||
fileSelectionButtonGroup.add(useBestViewerRB);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useBestViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.text")); // NOI18N
|
||||
useBestViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.toolTipText")); // NOI18N
|
||||
useBestViewerRB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useBestViewerRBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
fileSelectionButtonGroup.add(keepCurrentViewerRB);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(keepCurrentViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.text")); // NOI18N
|
||||
keepCurrentViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText")); // NOI18N
|
||||
keepCurrentViewerRB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
keepCurrentViewerRBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabelHideKnownFiles, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelHideKnownFiles.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.dataSourcesHideKnownCB.text")); // NOI18N
|
||||
dataSourcesHideKnownCB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dataSourcesHideKnownCBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(viewsHideKnownCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewsHideKnownCB.text")); // NOI18N
|
||||
viewsHideKnownCB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
viewsHideKnownCBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabelHideSlackFiles, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelHideSlackFiles.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.dataSourcesHideSlackCB.text")); // NOI18N
|
||||
dataSourcesHideSlackCB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dataSourcesHideSlackCBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(viewsHideSlackCB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewsHideSlackCB.text")); // NOI18N
|
||||
viewsHideSlackCB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
viewsHideSlackCBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jLabelTimeDisplay, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelTimeDisplay.text")); // NOI18N
|
||||
|
||||
displayTimesButtonGroup.add(useLocalTimeRB);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useLocalTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useLocalTimeRB.text")); // NOI18N
|
||||
useLocalTimeRB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useLocalTimeRBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
displayTimesButtonGroup.add(useGMTTimeRB);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useGMTTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useGMTTimeRB.text")); // NOI18N
|
||||
useGMTTimeRB.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useGMTTimeRBActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout viewPanelLayout = new javax.swing.GroupLayout(viewPanel);
|
||||
viewPanel.setLayout(viewPanelLayout);
|
||||
viewPanelLayout.setHorizontalGroup(
|
||||
viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, viewPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(viewPanelLayout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(viewPanelLayout.createSequentialGroup()
|
||||
.addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(useGMTTimeRB)
|
||||
.addComponent(keepCurrentViewerRB)
|
||||
.addComponent(useBestViewerRB)
|
||||
.addComponent(dataSourcesHideKnownCB)
|
||||
.addComponent(viewsHideKnownCB))
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(viewPanelLayout.createSequentialGroup()
|
||||
.addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(dataSourcesHideSlackCB)
|
||||
.addComponent(viewsHideSlackCB)
|
||||
.addComponent(useLocalTimeRB))
|
||||
.addContainerGap(158, Short.MAX_VALUE))))
|
||||
.addGroup(viewPanelLayout.createSequentialGroup()
|
||||
.addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabelHideSlackFiles)
|
||||
.addComponent(jLabelTimeDisplay)
|
||||
.addComponent(jLabelHideKnownFiles)
|
||||
.addComponent(jLabelSelectFile))
|
||||
.addGap(30, 30, 30))))
|
||||
);
|
||||
viewPanelLayout.setVerticalGroup(
|
||||
viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, viewPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabelSelectFile)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(useBestViewerRB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(keepCurrentViewerRB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jLabelHideKnownFiles)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dataSourcesHideKnownCB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(viewsHideKnownCB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabelHideSlackFiles)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dataSourcesHideSlackCB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(viewsHideSlackCB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabelTimeDisplay)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(useLocalTimeRB)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(useGMTTimeRB))
|
||||
);
|
||||
|
||||
runtimePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.runtimePanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(maxMemoryLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryLabel.text")); // NOI18N
|
||||
@ -831,7 +669,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||
.addComponent(maxMemoryUnitsLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 783, Short.MAX_VALUE))
|
||||
.addGroup(runtimePanelLayout.createSequentialGroup()
|
||||
.addComponent(maxMemoryUnitsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
@ -884,26 +722,21 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1010, Short.MAX_VALUE)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(viewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1002, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGap(0, 0, 0)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(viewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap()
|
||||
.addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
.addContainerGap(185, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
jScrollPane1.setViewportView(jPanel1);
|
||||
@ -917,7 +750,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
@ -940,38 +773,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_memFieldKeyReleased
|
||||
|
||||
private void useGMTTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_useGMTTimeRBActionPerformed
|
||||
|
||||
private void useLocalTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_useLocalTimeRBActionPerformed
|
||||
|
||||
private void viewsHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideSlackCBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_viewsHideSlackCBActionPerformed
|
||||
|
||||
private void dataSourcesHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideSlackCBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_dataSourcesHideSlackCBActionPerformed
|
||||
|
||||
private void viewsHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideKnownCBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_viewsHideKnownCBActionPerformed
|
||||
|
||||
private void dataSourcesHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideKnownCBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_dataSourcesHideKnownCBActionPerformed
|
||||
|
||||
private void keepCurrentViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_keepCurrentViewerRBActionPerformed
|
||||
|
||||
private void useBestViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRBActionPerformed
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_useBestViewerRBActionPerformed
|
||||
|
||||
private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed
|
||||
agencyLogoPathField.setEnabled(true);
|
||||
browseLogosButton.setEnabled(true);
|
||||
@ -1028,18 +829,11 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JLabel agencyLogoPathFieldValidationLabel;
|
||||
private javax.swing.JLabel agencyLogoPreview;
|
||||
private javax.swing.JButton browseLogosButton;
|
||||
private javax.swing.JCheckBox dataSourcesHideKnownCB;
|
||||
private javax.swing.JCheckBox dataSourcesHideSlackCB;
|
||||
private javax.swing.JRadioButton defaultLogoRB;
|
||||
private javax.swing.ButtonGroup displayTimesButtonGroup;
|
||||
private javax.swing.ButtonGroup fileSelectionButtonGroup;
|
||||
private javax.swing.JLabel jLabelHideKnownFiles;
|
||||
private javax.swing.JLabel jLabelHideSlackFiles;
|
||||
private javax.swing.JLabel jLabelSelectFile;
|
||||
private javax.swing.JLabel jLabelTimeDisplay;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JRadioButton keepCurrentViewerRB;
|
||||
private javax.swing.JTextField logFileCount;
|
||||
private javax.swing.JTextField logNumAlert;
|
||||
private javax.swing.JPanel logoPanel;
|
||||
@ -1055,12 +849,6 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JRadioButton specifyLogoRB;
|
||||
private javax.swing.JLabel systemMemoryTotal;
|
||||
private javax.swing.JLabel totalMemoryLabel;
|
||||
private javax.swing.JRadioButton useBestViewerRB;
|
||||
private javax.swing.JRadioButton useGMTTimeRB;
|
||||
private javax.swing.JRadioButton useLocalTimeRB;
|
||||
private javax.swing.JPanel viewPanel;
|
||||
private javax.swing.JCheckBox viewsHideKnownCB;
|
||||
private javax.swing.JCheckBox viewsHideSlackCB;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ LBL_Description=<div style=\"font-size: 12pt; font-family: Verdana, 'Verdana CE'
|
||||
Format_OperatingSystem_Value={0} version {1} running on {2}
|
||||
LBL_Copyright=<div style\="font-size\: 12pt; font-family\: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif; ">Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools. <br><ul><li>General Information: <a style\="color\: \#1E2A60;" href\="http\://www.sleuthkit.org">http\://www.sleuthkit.org</a>.</li><li>Training: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/autopsy-training">http://www.basistech.com/autopsy-training</a></li><li>Commercial Support: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/digital-forensics/autopsy/support/">http://www.basistech.com/digital-forensics/autopsy/support/</a></li></ul>Copyright © 2003-2018. </div>
|
||||
URL_ON_IMG=http://www.sleuthkit.org/
|
||||
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.8.0/
|
||||
FILE_FOR_LOCAL_HELP=file:///
|
||||
INDEX_FOR_LOCAL_HELP=/docs/index.html
|
||||
LBL_Close=Close
|
||||
@ -96,17 +95,6 @@ DataResultViewerThumbnail.comboBox.mediumThumbnails=Medium Thumbnails
|
||||
DataResultViewerThumbnail.comboBox.largeThumbnails=Large Thumbnails
|
||||
DataResultViewerThumbnail.switchPage.done.errMsg=Error making thumbnails\: {0}
|
||||
AboutWindowPanel.actVerboseLogging.text=Activate verbose logging
|
||||
AutopsyOptionsPanel.viewsHideKnownCB.text=Views area
|
||||
AutopsyOptionsPanel.dataSourcesHideKnownCB.text=Data Sources area (the directory hierarchy)
|
||||
AutopsyOptionsPanel.useBestViewerRB.toolTipText=For example, change from Hex to Media when a JPEG is selected.
|
||||
AutopsyOptionsPanel.useBestViewerRB.text=Change to the most specific file viewer
|
||||
AutopsyOptionsPanel.useGMTTimeRB.text=Use GMT
|
||||
AutopsyOptionsPanel.useLocalTimeRB.text=Use local time zone
|
||||
AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText=For example, stay in Hex view when a JPEG is selected.
|
||||
AutopsyOptionsPanel.keepCurrentViewerRB.text=Stay on the same file viewer
|
||||
AutopsyOptionsPanel.jLabelSelectFile.text=When selecting a file:
|
||||
AutopsyOptionsPanel.jLabelHideKnownFiles.text=Hide known files (i.e. those in the NIST NSRL) in the:
|
||||
AutopsyOptionsPanel.jLabelTimeDisplay.text=When displaying times:
|
||||
OptionsCategory_Name_Multi_User_Settings=Multi-User
|
||||
OptionsCategory_Keywords_Multi_User_Options=Multi-User Settings
|
||||
MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings
|
||||
@ -153,9 +141,6 @@ MultiUserSettingsPanel.lbTestSolrWarning.text=
|
||||
MultiUserSettingsPanel.lbTestDbWarning.text=
|
||||
MultiUserSettingsPanel.KeywordSearchNull=Cannot find keyword search service
|
||||
MultiUserSettingsPanel.InvalidPortNumber=Invalid port number
|
||||
AutopsyOptionsPanel.jLabelHideSlackFiles.text=Hide slack files in the:
|
||||
AutopsyOptionsPanel.dataSourcesHideSlackCB.text=Data Sources area (the directory hierarchy)
|
||||
AutopsyOptionsPanel.viewsHideSlackCB.text=Views area
|
||||
AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText=
|
||||
AutopsyOptionsPanel.agencyLogoPathField.text=
|
||||
SortChooserDialog.label=remove
|
||||
@ -177,7 +162,33 @@ AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo
|
||||
AutopsyOptionsPanel.agencyLogoPreview.text=<html><div style='text-align: center;'>No logo<br>selected</div></html>
|
||||
AutopsyOptionsPanel.logoPanel.border.title=Logo
|
||||
AutopsyOptionsPanel.runtimePanel.border.title=Runtime
|
||||
AutopsyOptionsPanel.viewPanel.border.title=View
|
||||
DataResultPanel.matchLabel.text=Results
|
||||
DataResultPanel.numberOfChildNodesLabel.text=0
|
||||
DataResultPanel.descriptionLabel.text=directoryPath
|
||||
ViewPreferencesPanel.selectFileLabel.text=When selecting a file:
|
||||
ViewPreferencesPanel.globalSettingsPanel.border.title=Global Settings
|
||||
ViewPreferencesPanel.displayTimeLabel.text=When displaying times:
|
||||
ViewPreferencesPanel.hideSlackFilesLabel.text=Hide slack files in the:
|
||||
ViewPreferencesPanel.groupByDataSourceCheckbox.text=Group by data source
|
||||
ViewPreferencesPanel.hideKnownFilesLabel.text=Hide known files (i.e. those in the NIST NSRL) in the:
|
||||
ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text=Tags area in the tree
|
||||
ViewPreferencesPanel.currentCaseSettingsPanel.border.title=Current Case Settings
|
||||
OptionsCategory_Name_View=View
|
||||
OptionsCategory_Keywords_View=View
|
||||
ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=For example, change from Hex to Media when a JPEG is selected.
|
||||
ViewPreferencesPanel.useBestViewerRadioButton.text=Change to the most specific file viewer
|
||||
ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=For example, stay in Hex view when a JPEG is selected.
|
||||
ViewPreferencesPanel.keepCurrentViewerRadioButton.text=Stay on the same file viewer
|
||||
ViewPreferencesPanel.useLocalTimeRadioButton.text=Use local time zone
|
||||
ViewPreferencesPanel.useGMTTimeRadioButton.text=Use GMT
|
||||
ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text=Data Sources area (the directory hierarchy)
|
||||
ViewPreferencesPanel.viewsHideKnownCheckbox.text=Views area
|
||||
ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text=Data Sources area (the directory hierarchy)
|
||||
ViewPreferencesPanel.viewsHideSlackCheckbox.text=Views area
|
||||
ViewPreferencesPanel.currentSessionSettingsPanel.border.title=Current Session Settings
|
||||
ViewPreferencesPanel.hideRejectedResultsCheckbox.text=Hide rejected results
|
||||
ViewPreferencesPanel.hideOtherUsersTagsLabel.text=Hide other users' tags in the:
|
||||
ViewPreferencesPanel.centralRepoLabel.text=Do not use Central Repository for:
|
||||
ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text=C(omments) and O(ccurences) columns to reduce loading times
|
||||
ViewPreferencesPanel.deletedFilesLimitCheckbox.text=Limit to 10,000
|
||||
ViewPreferencesPanel.deletedFilesLimitLabel.text=Limit number of deleted files displayed:
|
||||
|
@ -79,17 +79,6 @@ DataResultViewerThumbnail.comboBox.mediumThumbnails=\u30b5\u30e0\u30cd\u30a4\u30
|
||||
DataResultViewerThumbnail.comboBox.largeThumbnails=\u30b5\u30e0\u30cd\u30a4\u30eb\uff08\u5927\uff09
|
||||
DataResultViewerThumbnail.switchPage.done.errMsg=\u30b5\u30e0\u30cd\u30a4\u30eb\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0}
|
||||
AboutWindowPanel.actVerboseLogging.text=Verbose\u30ed\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8
|
||||
AutopsyOptionsPanel.viewsHideKnownCB.text=\u30d3\u30e5\u30fc\u30a8\u30ea\u30a2
|
||||
AutopsyOptionsPanel.dataSourcesHideKnownCB.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09
|
||||
AutopsyOptionsPanel.useBestViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002
|
||||
AutopsyOptionsPanel.useBestViewerRB.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4
|
||||
AutopsyOptionsPanel.useGMTTimeRB.text=GMT\u3092\u4f7f\u7528
|
||||
AutopsyOptionsPanel.useLocalTimeRB.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528
|
||||
AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002
|
||||
AutopsyOptionsPanel.keepCurrentViewerRB.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528
|
||||
AutopsyOptionsPanel.jLabelSelectFile.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a
|
||||
AutopsyOptionsPanel.jLabelHideKnownFiles.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u6b21\u306b\u96a0\u3059\uff1a
|
||||
AutopsyOptionsPanel.jLabelTimeDisplay.text=\u6642\u9593\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a
|
||||
OptionsCategory_Name_Multi_User_Settings=\u8907\u6570\u306e\u30e6\u30fc\u30b6\u30fc
|
||||
OptionsCategory_Keywords_Multi_User_Options=\u8907\u6570\u306e\u30e6\u30fc\u30b6\u30fc\u30aa\u30d7\u30b7\u30e7\u30f3
|
||||
MultiUserSettingsPanel.lbSolrSettings.text=Solr\u8a2d\u5b9a
|
||||
@ -131,3 +120,14 @@ MediaViewImagePanel.externalViewerButton.text=\u5916\u90e8\u30d3\u30e5\u30fc\u30
|
||||
DataResultPanel.matchLabel.text=\u7d50\u679c
|
||||
DataResultPanel.numberOfChildNodesLabel.text=0
|
||||
DataResultPanel.descriptionLabel.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30d1\u30b9
|
||||
ViewPreferencesPanel.selectFileLabel.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a
|
||||
ViewPreferencesPanel.displayTimeLabel.text=\u6642\u9593\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a
|
||||
ViewPreferencesPanel.hideKnownFilesLabel.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u6b21\u306b\u96a0\u3059\uff1a
|
||||
ViewPreferencesPanel.useBestViewerRadioButton.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002
|
||||
ViewPreferencesPanel.useBestViewerRadioButton.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4
|
||||
ViewPreferencesPanel.keepCurrentViewerRadioButton.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528
|
||||
ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002
|
||||
ViewPreferencesPanel.useLocalTimeRadioButton.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528
|
||||
ViewPreferencesPanel.useGMTTimeRadioButton.text=GMT\u3092\u4f7f\u7528
|
||||
ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09
|
||||
ViewPreferencesPanel.viewsHideKnownCheckbox.text=\u30d3\u30e5\u30fc\u30a8\u30ea\u30a2
|
||||
|
@ -29,7 +29,6 @@
|
||||
<Container class="org.openide.explorer.view.OutlineView" name="outlineView">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new OutlineView(DataResultViewerTable.FIRST_COLUMN_LABEL);"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.corecomponents;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.FontMetrics;
|
||||
@ -47,6 +46,7 @@ import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.TableColumnModelEvent;
|
||||
import javax.swing.event.TableColumnModelListener;
|
||||
import javax.swing.event.TreeExpansionListener;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
@ -96,7 +96,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
private static final ImageIcon NOTABLE_ICON_SCORE = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false));
|
||||
@NbBundle.Messages("DataResultViewerTable.firstColLbl=Name")
|
||||
static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl();
|
||||
static private final Color TAGGED_ROW_COLOR = new Color(255, 255, 195);
|
||||
private final String title;
|
||||
private final Map<String, ETableColumn> columnMap;
|
||||
private final Map<Integer, Property<?>> propertiesMap;
|
||||
@ -160,7 +159,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
outline.setRootVisible(false);
|
||||
outline.setDragEnabled(false);
|
||||
outline.setDefaultRenderer(Object.class, new ColorTagCustomRenderer());
|
||||
|
||||
/*
|
||||
* Add a table listener to the child OutlineView (explorer view) to
|
||||
@ -268,6 +266,16 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tree expansion listener to the OutlineView of this tabular results
|
||||
* viewer.
|
||||
*
|
||||
* @param listener The listener
|
||||
*/
|
||||
protected void addTreeExpansionListener(TreeExpansionListener listener) {
|
||||
outlineView.addTreeExpansionListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the Outline view of this tabular result viewer by creating column
|
||||
* headers based on the children of the current root node. The persisted
|
||||
@ -664,19 +672,25 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
private class IconRendererTableListener implements TableColumnModelListener {
|
||||
|
||||
@NbBundle.Messages({"DataResultViewerTable.commentRender.name=C",
|
||||
"DataResultViewerTable.commentRender.toolTip=C(omments) indicates whether the item has a comment",
|
||||
"DataResultViewerTable.scoreRender.name=S",
|
||||
"DataResultViewerTable.countRender.name=O"})
|
||||
"DataResultViewerTable.scoreRender.toolTip=S(core) indicates whether the item is interesting or notable",
|
||||
"DataResultViewerTable.countRender.name=O",
|
||||
"DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository"})
|
||||
@Override
|
||||
public void columnAdded(TableColumnModelEvent e) {
|
||||
if (e.getSource() instanceof ETableColumnModel) {
|
||||
TableColumn column = ((TableColumnModel) e.getSource()).getColumn(e.getToIndex());
|
||||
if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_commentRender_name())) {
|
||||
//if the current column is a comment column set the cell renderer to be the HasCommentCellRenderer
|
||||
outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_commentRender_toolTip());
|
||||
column.setCellRenderer(new HasCommentCellRenderer());
|
||||
} else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_scoreRender_name())) {
|
||||
//if the current column is a score column set the cell renderer to be the ScoreCellRenderer
|
||||
outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_scoreRender_toolTip());
|
||||
column.setCellRenderer(new ScoreCellRenderer());
|
||||
} else if (column.getHeaderValue().toString().equals(Bundle.DataResultViewerTable_countRender_name())) {
|
||||
outlineView.setPropertyColumnDescription(column.getHeaderValue().toString(), Bundle.DataResultViewerTable_countRender_toolTip());
|
||||
column.setCellRenderer(new CountCellRenderer());
|
||||
}
|
||||
}
|
||||
@ -842,54 +856,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This custom renderer extends the renderer that was already being used by
|
||||
* the outline table. This renderer colors a row if the tags property of the
|
||||
* node is not empty.
|
||||
*/
|
||||
private class ColorTagCustomRenderer extends DefaultOutlineCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
|
||||
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
|
||||
// only override the color if a node is not selected
|
||||
if (rootNode != null && !isSelected) {
|
||||
Node node = rootNode.getChildren().getNodeAt(table.convertRowIndexToModel(row));
|
||||
boolean tagFound = false;
|
||||
if (node != null) {
|
||||
Node.PropertySet[] propSets = node.getPropertySets();
|
||||
if (propSets.length != 0) {
|
||||
// currently, a node has only one property set, named Sheet.PROPERTIES ("properties")
|
||||
Node.Property<?>[] props = propSets[0].getProperties();
|
||||
for (Property<?> prop : props) {
|
||||
if ("Tags".equals(prop.getName())) {//NON-NLS
|
||||
try {
|
||||
tagFound = !prop.getValue().equals("");
|
||||
} catch (IllegalAccessException | InvocationTargetException ignore) {
|
||||
//if unable to get the tags property value, treat it like it not having a comment
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//if the node does have associated tags, set its background color
|
||||
if (tagFound) {
|
||||
component.setBackground(TAGGED_ROW_COLOR);
|
||||
}
|
||||
}
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A renderer which based on the contents of the cell will display an icon
|
||||
* to indicate the presence of a comment related to the content.
|
||||
*/
|
||||
private final class HasCommentCellRenderer extends ColorTagCustomRenderer {
|
||||
private final class HasCommentCellRenderer extends DefaultOutlineCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -900,7 +871,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
setBackground(component.getBackground()); //inherit highlighting
|
||||
setBackground(component.getBackground()); //inherit highlighting for selection
|
||||
setHorizontalAlignment(CENTER);
|
||||
Object switchValue = null;
|
||||
if ((value instanceof NodeProperty)) {
|
||||
@ -949,14 +920,14 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* A renderer which based on the contents of the cell will display an icon
|
||||
* to indicate the score associated with the item.
|
||||
*/
|
||||
private final class ScoreCellRenderer extends ColorTagCustomRenderer {
|
||||
private final class ScoreCellRenderer extends DefaultOutlineCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
setBackground(component.getBackground()); //inherit highlighting
|
||||
setBackground(component.getBackground()); //inherit highlighting for selection
|
||||
setHorizontalAlignment(CENTER);
|
||||
Object switchValue = null;
|
||||
if ((value instanceof NodeProperty)) {
|
||||
@ -998,14 +969,14 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
* A renderer which based on the contents of the cell will display an empty
|
||||
* cell if no count was available.
|
||||
*/
|
||||
private final class CountCellRenderer extends ColorTagCustomRenderer {
|
||||
private final class CountCellRenderer extends DefaultOutlineCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
setBackground(component.getBackground()); //inherit highlighting
|
||||
setBackground(component.getBackground()); //inherit highlighting for selection
|
||||
setHorizontalAlignment(LEFT);
|
||||
Object countValue = null;
|
||||
if ((value instanceof NodeProperty)) {
|
||||
@ -1076,7 +1047,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
protected org.openide.explorer.view.OutlineView outlineView;
|
||||
private org.openide.explorer.view.OutlineView outlineView;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Multi_User_Settings",
|
||||
iconBase = "org/sleuthkit/autopsy/images/User-Group-icon-green32.png",
|
||||
position = 3,
|
||||
position = 4,
|
||||
keywords = "#OptionsCategory_Keywords_Multi_User_Options",
|
||||
keywordsCategory = "Multi-User")
|
||||
public final class MultiUserSettingsPanelController extends OptionsPanelController {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2014 Basis Technology Corp.
|
||||
* Copyright 2011-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -33,9 +33,9 @@ import org.openide.awt.ActionRegistration;
|
||||
import org.openide.awt.HtmlBrowser;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.Version;
|
||||
|
||||
/**
|
||||
* Implements a hyperlink to the Online Documentation.
|
||||
@ -69,12 +69,12 @@ public final class OnlineHelpAction implements ActionListener {
|
||||
*/
|
||||
private void viewOnlineHelp() {
|
||||
try {
|
||||
uri = new URI(NbBundle.getMessage(OnlineHelpAction.class, "URL_ON_HELP"));
|
||||
uri = new URI("http://sleuthkit.org/autopsy/docs/user-docs/" + Version.getVersion() + "/");
|
||||
} catch (URISyntaxException ex) {
|
||||
Logger.log(Level.SEVERE, "Unable to load Online Documentation", ex); //NON-NLS
|
||||
}
|
||||
if (uri != null) {
|
||||
// Display URL in the SYstem browser
|
||||
// Display URL in the System browser
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
Desktop desktop = Desktop.getDesktop();
|
||||
try {
|
||||
|
@ -128,16 +128,6 @@ public class TableFilterNode extends FilterNode {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the inner node, which depending on the actual node type that was wrapped
|
||||
* could trigger a dynamic refresh of the children, if supported.
|
||||
*/
|
||||
void refresh() {
|
||||
DataResultFilterNode innerNode = getLookup().lookup(DataResultFilterNode.class);
|
||||
innerNode.refresh();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the column order key, which allows custom column ordering to be
|
||||
|
452
Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
Executable file
@ -0,0 +1,452 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="viewPreferencesScrollPane" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="viewPreferencesScrollPane" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="viewPreferencesScrollPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="viewPreferencesPanel">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="currentSessionSettingsPanel" max="32767" attributes="0"/>
|
||||
<Component id="currentCaseSettingsPanel" max="32767" attributes="0"/>
|
||||
<Component id="globalSettingsPanel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="globalSettingsPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="currentCaseSettingsPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="currentSessionSettingsPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="globalSettingsPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Global Settings">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.globalSettingsPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="commentsOccurencesColumnsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="hideOtherUsersTagsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deletedFilesLimitCheckbox" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="hideKnownFilesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" alignment="0" groupAlignment="1" attributes="0">
|
||||
<Group type="103" alignment="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dataSourcesHideSlackCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="viewsHideSlackCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="hideSlackFilesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dataSourcesHideKnownCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="viewsHideKnownCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="displayTimeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="keepCurrentViewerRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useBestViewerRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useGMTTimeRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useLocalTimeRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="selectFileLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="hideOtherUsersTagsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="centralRepoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deletedFilesLimitLabel" alignment="0" min="-2" pref="215" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="10" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="hideKnownFilesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesHideKnownCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="viewsHideKnownCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="hideSlackFilesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dataSourcesHideSlackCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="viewsHideSlackCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="selectFileLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="useBestViewerRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="keepCurrentViewerRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="displayTimeLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="useLocalTimeRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="useGMTTimeRadioButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="hideOtherUsersTagsLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="hideOtherUsersTagsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="centralRepoLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="commentsOccurencesColumnsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="deletedFilesLimitLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deletedFilesLimitCheckbox" min="-2" pref="33" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="selectFileLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.selectFileLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="useBestViewerRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.useBestViewerRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.useBestViewerRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useBestViewerRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="keepCurrentViewerRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.keepCurrentViewerRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="keepCurrentViewerRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hideKnownFilesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.hideKnownFilesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="dataSourcesHideKnownCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dataSourcesHideKnownCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="viewsHideKnownCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.viewsHideKnownCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="viewsHideKnownCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hideSlackFilesLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.hideSlackFilesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="dataSourcesHideSlackCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dataSourcesHideSlackCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="viewsHideSlackCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.viewsHideSlackCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="viewsHideSlackCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="displayTimeLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.displayTimeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="useLocalTimeRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.useLocalTimeRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useLocalTimeRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="useGMTTimeRadioButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.useGMTTimeRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useGMTTimeRadioButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="hideOtherUsersTagsCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hideOtherUsersTagsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="hideOtherUsersTagsLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.hideOtherUsersTagsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="commentsOccurencesColumnsCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="commentsOccurencesColumnsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="centralRepoLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.centralRepoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="deletedFilesLimitCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.deletedFilesLimitCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deletedFilesLimitCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="deletedFilesLimitLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.deletedFilesLimitLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="currentCaseSettingsPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Current Case Settings">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.currentCaseSettingsPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="groupByDataSourceCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="groupByDataSourceCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="groupByDataSourceCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.groupByDataSourceCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="groupByDataSourceCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="currentSessionSettingsPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Current Session Settings">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.currentSessionSettingsPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</TitledBorder>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="hideRejectedResultsCheckbox" min="-2" pref="259" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="hideRejectedResultsCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="hideRejectedResultsCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="ViewPreferencesPanel.hideRejectedResultsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hideRejectedResultsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
566
Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
Executable file
@ -0,0 +1,566 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 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.corecomponents;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.swing.JPanel;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.deletedFiles.DeletedFilePreferences;
|
||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||
|
||||
/**
|
||||
* Panel for configuring view preferences.
|
||||
*/
|
||||
public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
|
||||
|
||||
private final boolean immediateUpdates;
|
||||
|
||||
/**
|
||||
* Creates new form ViewPreferencesPanel
|
||||
*
|
||||
* @param immediateUpdates If true, value changes will be persisted at the
|
||||
* moment they occur.
|
||||
*/
|
||||
public ViewPreferencesPanel(boolean immediateUpdates) {
|
||||
initComponents();
|
||||
this.immediateUpdates = immediateUpdates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
// Global Settings
|
||||
boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer();
|
||||
keepCurrentViewerRadioButton.setSelected(keepPreferredViewer);
|
||||
useBestViewerRadioButton.setSelected(!keepPreferredViewer);
|
||||
|
||||
boolean useLocalTime = UserPreferences.displayTimesInLocalTime();
|
||||
useLocalTimeRadioButton.setSelected(useLocalTime);
|
||||
useGMTTimeRadioButton.setSelected(!useLocalTime);
|
||||
|
||||
dataSourcesHideKnownCheckbox.setSelected(UserPreferences.hideKnownFilesInDataSourcesTree());
|
||||
viewsHideKnownCheckbox.setSelected(UserPreferences.hideKnownFilesInViewsTree());
|
||||
|
||||
dataSourcesHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInDataSourcesTree());
|
||||
viewsHideSlackCheckbox.setSelected(UserPreferences.hideSlackFilesInViewsTree());
|
||||
|
||||
commentsOccurencesColumnsCheckbox.setEnabled(EamDbUtil.useCentralRepo());
|
||||
commentsOccurencesColumnsCheckbox.setSelected(UserPreferences.hideCentralRepoCommentsAndOccurrences());
|
||||
|
||||
deletedFilesLimitCheckbox.setSelected(DeletedFilePreferences.getDefault().getShouldLimitDeletedFiles());
|
||||
|
||||
// Current Case Settings
|
||||
boolean caseIsOpen = Case.isCaseOpen();
|
||||
currentCaseSettingsPanel.setEnabled(caseIsOpen);
|
||||
groupByDataSourceCheckbox.setEnabled(caseIsOpen);
|
||||
|
||||
hideOtherUsersTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags());
|
||||
groupByDataSourceCheckbox.setSelected(Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true));
|
||||
|
||||
// Current Session Settings
|
||||
hideRejectedResultsCheckbox.setSelected(DirectoryTreeTopComponent.getDefault().getShowRejectedResults() == false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store() {
|
||||
UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRadioButton.isSelected());
|
||||
UserPreferences.setDisplayTimesInLocalTime(useLocalTimeRadioButton.isSelected());
|
||||
UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCheckbox.isSelected());
|
||||
UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCheckbox.isSelected());
|
||||
UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected());
|
||||
UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected());
|
||||
UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected());
|
||||
UserPreferences.setHideCentralRepoCommentsAndOccurrences(commentsOccurencesColumnsCheckbox.isSelected());
|
||||
|
||||
storeGroupItemsInTreeByDataSource();
|
||||
|
||||
DirectoryTreeTopComponent.getDefault().setShowRejectedResults(hideRejectedResultsCheckbox.isSelected() == false);
|
||||
|
||||
DeletedFilePreferences.getDefault().setShouldLimitDeletedFiles(deletedFilesLimitCheckbox.isSelected());
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the 'groupByDataSourceCheckbox' value.
|
||||
*
|
||||
* Note: The value will not be stored if the value hasn't previously been
|
||||
* stored and the checkbox isn't selected. This is so GroupDataSourcesDialog
|
||||
* can prompt the user for this in the event the value hasn't been
|
||||
* initialized.
|
||||
*/
|
||||
private void storeGroupItemsInTreeByDataSource() {
|
||||
if (Case.isCaseOpen() && (CasePreferences.getGroupItemsInTreeByDataSource() != null || groupByDataSourceCheckbox.isSelected())) {
|
||||
CasePreferences.setGroupItemsInTreeByDataSource(groupByDataSourceCheckbox.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
viewPreferencesScrollPane = new javax.swing.JScrollPane();
|
||||
viewPreferencesPanel = new javax.swing.JPanel();
|
||||
globalSettingsPanel = new javax.swing.JPanel();
|
||||
selectFileLabel = new javax.swing.JLabel();
|
||||
useBestViewerRadioButton = new javax.swing.JRadioButton();
|
||||
keepCurrentViewerRadioButton = new javax.swing.JRadioButton();
|
||||
hideKnownFilesLabel = new javax.swing.JLabel();
|
||||
dataSourcesHideKnownCheckbox = new javax.swing.JCheckBox();
|
||||
viewsHideKnownCheckbox = new javax.swing.JCheckBox();
|
||||
hideSlackFilesLabel = new javax.swing.JLabel();
|
||||
dataSourcesHideSlackCheckbox = new javax.swing.JCheckBox();
|
||||
viewsHideSlackCheckbox = new javax.swing.JCheckBox();
|
||||
displayTimeLabel = new javax.swing.JLabel();
|
||||
useLocalTimeRadioButton = new javax.swing.JRadioButton();
|
||||
useGMTTimeRadioButton = new javax.swing.JRadioButton();
|
||||
hideOtherUsersTagsCheckbox = new javax.swing.JCheckBox();
|
||||
hideOtherUsersTagsLabel = new javax.swing.JLabel();
|
||||
commentsOccurencesColumnsCheckbox = new javax.swing.JCheckBox();
|
||||
centralRepoLabel = new javax.swing.JLabel();
|
||||
deletedFilesLimitCheckbox = new javax.swing.JCheckBox();
|
||||
deletedFilesLimitLabel = new javax.swing.JLabel();
|
||||
currentCaseSettingsPanel = new javax.swing.JPanel();
|
||||
groupByDataSourceCheckbox = new javax.swing.JCheckBox();
|
||||
currentSessionSettingsPanel = new javax.swing.JPanel();
|
||||
hideRejectedResultsCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
viewPreferencesScrollPane.setBorder(null);
|
||||
|
||||
globalSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.globalSettingsPanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(selectFileLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.selectFileLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useBestViewerRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useBestViewerRadioButton.text")); // NOI18N
|
||||
useBestViewerRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useBestViewerRadioButton.toolTipText")); // NOI18N
|
||||
useBestViewerRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useBestViewerRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(keepCurrentViewerRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.keepCurrentViewerRadioButton.text")); // NOI18N
|
||||
keepCurrentViewerRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.keepCurrentViewerRadioButton.toolTipText")); // NOI18N
|
||||
keepCurrentViewerRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
keepCurrentViewerRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(hideKnownFilesLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideKnownFilesLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideKnownCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.dataSourcesHideKnownCheckbox.text")); // NOI18N
|
||||
dataSourcesHideKnownCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dataSourcesHideKnownCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(viewsHideKnownCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.viewsHideKnownCheckbox.text")); // NOI18N
|
||||
viewsHideKnownCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
viewsHideKnownCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(hideSlackFilesLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideSlackFilesLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dataSourcesHideSlackCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.dataSourcesHideSlackCheckbox.text")); // NOI18N
|
||||
dataSourcesHideSlackCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dataSourcesHideSlackCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(viewsHideSlackCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.viewsHideSlackCheckbox.text")); // NOI18N
|
||||
viewsHideSlackCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
viewsHideSlackCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(displayTimeLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.displayTimeLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useLocalTimeRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useLocalTimeRadioButton.text")); // NOI18N
|
||||
useLocalTimeRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useLocalTimeRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(useGMTTimeRadioButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.useGMTTimeRadioButton.text")); // NOI18N
|
||||
useGMTTimeRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useGMTTimeRadioButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsCheckbox.text")); // NOI18N
|
||||
hideOtherUsersTagsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
hideOtherUsersTagsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(hideOtherUsersTagsLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideOtherUsersTagsLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(commentsOccurencesColumnsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text")); // NOI18N
|
||||
commentsOccurencesColumnsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
commentsOccurencesColumnsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(centralRepoLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.centralRepoLabel.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deletedFilesLimitCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.deletedFilesLimitCheckbox.text")); // NOI18N
|
||||
deletedFilesLimitCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deletedFilesLimitCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deletedFilesLimitLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.deletedFilesLimitLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout globalSettingsPanelLayout = new javax.swing.GroupLayout(globalSettingsPanel);
|
||||
globalSettingsPanel.setLayout(globalSettingsPanelLayout);
|
||||
globalSettingsPanelLayout.setHorizontalGroup(
|
||||
globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(commentsOccurencesColumnsCheckbox)
|
||||
.addComponent(hideOtherUsersTagsCheckbox)
|
||||
.addComponent(deletedFilesLimitCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(hideKnownFilesLabel)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(dataSourcesHideSlackCheckbox)
|
||||
.addComponent(viewsHideSlackCheckbox)))
|
||||
.addComponent(hideSlackFilesLabel))
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(dataSourcesHideKnownCheckbox)
|
||||
.addComponent(viewsHideKnownCheckbox)))))
|
||||
.addGap(18, 18, 18)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(displayTimeLabel)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addGap(10, 10, 10)
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(keepCurrentViewerRadioButton)
|
||||
.addComponent(useBestViewerRadioButton)
|
||||
.addComponent(useGMTTimeRadioButton)
|
||||
.addComponent(useLocalTimeRadioButton)))
|
||||
.addComponent(selectFileLabel)))
|
||||
.addComponent(hideOtherUsersTagsLabel)
|
||||
.addComponent(centralRepoLabel)
|
||||
.addComponent(deletedFilesLimitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 10, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
globalSettingsPanelLayout.setVerticalGroup(
|
||||
globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addComponent(hideKnownFilesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dataSourcesHideKnownCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(viewsHideKnownCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hideSlackFilesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dataSourcesHideSlackCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(viewsHideSlackCheckbox))
|
||||
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
|
||||
.addComponent(selectFileLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(useBestViewerRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(keepCurrentViewerRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(displayTimeLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(useLocalTimeRadioButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(useGMTTimeRadioButton)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hideOtherUsersTagsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(hideOtherUsersTagsCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(centralRepoLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(commentsOccurencesColumnsCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(deletedFilesLimitLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(deletedFilesLimitCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
|
||||
currentCaseSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentCaseSettingsPanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(groupByDataSourceCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.groupByDataSourceCheckbox.text")); // NOI18N
|
||||
groupByDataSourceCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
groupByDataSourceCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout currentCaseSettingsPanelLayout = new javax.swing.GroupLayout(currentCaseSettingsPanel);
|
||||
currentCaseSettingsPanel.setLayout(currentCaseSettingsPanelLayout);
|
||||
currentCaseSettingsPanelLayout.setHorizontalGroup(
|
||||
currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(currentCaseSettingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(groupByDataSourceCheckbox)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
currentCaseSettingsPanelLayout.setVerticalGroup(
|
||||
currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(currentCaseSettingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(groupByDataSourceCheckbox))
|
||||
);
|
||||
|
||||
currentSessionSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.currentSessionSettingsPanel.border.title"))); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(hideRejectedResultsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.hideRejectedResultsCheckbox.text")); // NOI18N
|
||||
hideRejectedResultsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
hideRejectedResultsCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout currentSessionSettingsPanelLayout = new javax.swing.GroupLayout(currentSessionSettingsPanel);
|
||||
currentSessionSettingsPanel.setLayout(currentSessionSettingsPanelLayout);
|
||||
currentSessionSettingsPanelLayout.setHorizontalGroup(
|
||||
currentSessionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(currentSessionSettingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(hideRejectedResultsCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
currentSessionSettingsPanelLayout.setVerticalGroup(
|
||||
currentSessionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(currentSessionSettingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(hideRejectedResultsCheckbox))
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout viewPreferencesPanelLayout = new javax.swing.GroupLayout(viewPreferencesPanel);
|
||||
viewPreferencesPanel.setLayout(viewPreferencesPanelLayout);
|
||||
viewPreferencesPanelLayout.setHorizontalGroup(
|
||||
viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, viewPreferencesPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(globalSettingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
viewPreferencesPanelLayout.setVerticalGroup(
|
||||
viewPreferencesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(viewPreferencesPanelLayout.createSequentialGroup()
|
||||
.addComponent(globalSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
viewPreferencesScrollPane.setViewportView(viewPreferencesPanel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(viewPreferencesScrollPane)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(viewPreferencesScrollPane)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void useBestViewerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRadioButtonActionPerformed
|
||||
useBestViewerRadioButton.setSelected(true);
|
||||
keepCurrentViewerRadioButton.setSelected(false);
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setKeepPreferredContentViewer(false);
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_useBestViewerRadioButtonActionPerformed
|
||||
|
||||
private void keepCurrentViewerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRadioButtonActionPerformed
|
||||
useBestViewerRadioButton.setSelected(false);
|
||||
keepCurrentViewerRadioButton.setSelected(true);
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setKeepPreferredContentViewer(true);
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_keepCurrentViewerRadioButtonActionPerformed
|
||||
|
||||
private void useLocalTimeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRadioButtonActionPerformed
|
||||
useLocalTimeRadioButton.setSelected(true);
|
||||
useGMTTimeRadioButton.setSelected(false);
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setDisplayTimesInLocalTime(true);
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_useLocalTimeRadioButtonActionPerformed
|
||||
|
||||
private void useGMTTimeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRadioButtonActionPerformed
|
||||
useLocalTimeRadioButton.setSelected(false);
|
||||
useGMTTimeRadioButton.setSelected(true);
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setDisplayTimesInLocalTime(false);
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_useGMTTimeRadioButtonActionPerformed
|
||||
|
||||
private void dataSourcesHideKnownCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideKnownCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_dataSourcesHideKnownCheckboxActionPerformed
|
||||
|
||||
private void viewsHideKnownCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideKnownCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setHideKnownFilesInViewsTree(viewsHideKnownCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_viewsHideKnownCheckboxActionPerformed
|
||||
|
||||
private void dataSourcesHideSlackCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideSlackCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_dataSourcesHideSlackCheckboxActionPerformed
|
||||
|
||||
private void viewsHideSlackCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideSlackCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_viewsHideSlackCheckboxActionPerformed
|
||||
|
||||
private void hideOtherUsersTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideOtherUsersTagsCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_hideOtherUsersTagsCheckboxActionPerformed
|
||||
|
||||
private void groupByDataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_groupByDataSourceCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
storeGroupItemsInTreeByDataSource();
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_groupByDataSourceCheckboxActionPerformed
|
||||
|
||||
private void hideRejectedResultsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideRejectedResultsCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
DirectoryTreeTopComponent.getDefault().setShowRejectedResults(hideRejectedResultsCheckbox.isSelected() == false);
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_hideRejectedResultsCheckboxActionPerformed
|
||||
|
||||
private void commentsOccurencesColumnsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_commentsOccurencesColumnsCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
UserPreferences.setHideCentralRepoCommentsAndOccurrences(commentsOccurencesColumnsCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_commentsOccurencesColumnsCheckboxActionPerformed
|
||||
|
||||
private void deletedFilesLimitCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deletedFilesLimitCheckboxActionPerformed
|
||||
if (immediateUpdates) {
|
||||
DeletedFilePreferences.getDefault().setShouldLimitDeletedFiles(deletedFilesLimitCheckbox.isSelected());
|
||||
} else {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}
|
||||
}//GEN-LAST:event_deletedFilesLimitCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel centralRepoLabel;
|
||||
private javax.swing.JCheckBox commentsOccurencesColumnsCheckbox;
|
||||
private javax.swing.JPanel currentCaseSettingsPanel;
|
||||
private javax.swing.JPanel currentSessionSettingsPanel;
|
||||
private javax.swing.JCheckBox dataSourcesHideKnownCheckbox;
|
||||
private javax.swing.JCheckBox dataSourcesHideSlackCheckbox;
|
||||
private javax.swing.JCheckBox deletedFilesLimitCheckbox;
|
||||
private javax.swing.JLabel deletedFilesLimitLabel;
|
||||
private javax.swing.JLabel displayTimeLabel;
|
||||
private javax.swing.JPanel globalSettingsPanel;
|
||||
private javax.swing.JCheckBox groupByDataSourceCheckbox;
|
||||
private javax.swing.JLabel hideKnownFilesLabel;
|
||||
private javax.swing.JCheckBox hideOtherUsersTagsCheckbox;
|
||||
private javax.swing.JLabel hideOtherUsersTagsLabel;
|
||||
private javax.swing.JCheckBox hideRejectedResultsCheckbox;
|
||||
private javax.swing.JLabel hideSlackFilesLabel;
|
||||
private javax.swing.JRadioButton keepCurrentViewerRadioButton;
|
||||
private javax.swing.JLabel selectFileLabel;
|
||||
private javax.swing.JRadioButton useBestViewerRadioButton;
|
||||
private javax.swing.JRadioButton useGMTTimeRadioButton;
|
||||
private javax.swing.JRadioButton useLocalTimeRadioButton;
|
||||
private javax.swing.JPanel viewPreferencesPanel;
|
||||
private javax.swing.JScrollPane viewPreferencesScrollPane;
|
||||
private javax.swing.JCheckBox viewsHideKnownCheckbox;
|
||||
private javax.swing.JCheckBox viewsHideSlackCheckbox;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 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.corecomponents;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import javax.swing.JComponent;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Controller for the main settings panel
|
||||
*/
|
||||
@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_View",
|
||||
iconBase = "org/sleuthkit/autopsy/images/view-preferences-32.png",
|
||||
position = 2,
|
||||
keywords = "#OptionsCategory_Keywords_View",
|
||||
keywordsCategory = "View")
|
||||
public final class ViewPreferencesPanelController extends OptionsPanelController {
|
||||
|
||||
private ViewPreferencesPanel panel;
|
||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
private boolean changed;
|
||||
private static final Logger logger = Logger.getLogger(ViewPreferencesPanelController.class.getName());
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
getPanel().load();
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyChanges() {
|
||||
getPanel().store();
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent(Lookup masterLookup) {
|
||||
return getPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (pcs.getPropertyChangeListeners().length == 0) {
|
||||
pcs.addPropertyChangeListener(l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
/**
|
||||
* Note the NetBeans Framework does not appear to call this at all. We
|
||||
* are using NetBeans 7.3.1 Build 201306052037. Perhaps in a future
|
||||
* version of the Framework this will be resolved, but for now, simply
|
||||
* don't unregister anything and add one time only in the
|
||||
* addPropertyChangeListener() method above.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an instance of the ViewPreferencesPanel.
|
||||
*
|
||||
* @return A ViewPreferencesPanel instance.
|
||||
*/
|
||||
private ViewPreferencesPanel getPanel() {
|
||||
if (panel == null) {
|
||||
panel = new ViewPreferencesPanel(false);
|
||||
panel.addPropertyChangeListener((PropertyChangeEvent evt) -> {
|
||||
if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) {
|
||||
changed();
|
||||
}
|
||||
});
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed whenever a property change occurs.
|
||||
*/
|
||||
@Messages({"ViewOptionsController.moduleErr=Error processing value changes.",
|
||||
"ViewOptionsController.moduleErr.msg=Value change processing failed."})
|
||||
void changed() {
|
||||
if (!changed) {
|
||||
changed = true;
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Error processing property change", ex); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(
|
||||
Bundle.ViewOptionsController_moduleErr(),
|
||||
Bundle.ViewOptionsController_moduleErr_msg(),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error processing property change validation.", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(
|
||||
Bundle.ViewOptionsController_moduleErr(),
|
||||
Bundle.ViewOptionsController_moduleErr_msg(),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
@ -39,18 +39,23 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||
@ThreadSafe
|
||||
public class History<T> {
|
||||
|
||||
// Stack of things that were previously shown before an 'advance' was done
|
||||
@GuardedBy("this")
|
||||
private final ObservableStack<T> historyStack = new ObservableStack<>();
|
||||
|
||||
// stack of things that were previously shown before a 'retreat' (i.e. a back) was done
|
||||
@GuardedBy("this")
|
||||
private final ObservableStack<T> forwardStack = new ObservableStack<>();
|
||||
|
||||
// what is currently being shown
|
||||
@GuardedBy("this")
|
||||
private final ReadOnlyObjectWrapper<T> currentState = new ReadOnlyObjectWrapper<>();
|
||||
|
||||
// Is the forward stack empty?
|
||||
@GuardedBy("this")
|
||||
private final ReadOnlyBooleanWrapper canAdvance = new ReadOnlyBooleanWrapper();
|
||||
|
||||
// is the historyStack empty?
|
||||
@GuardedBy("this")
|
||||
private final ReadOnlyBooleanWrapper canRetreat = new ReadOnlyBooleanWrapper();
|
||||
|
||||
|
@ -195,7 +195,6 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
"AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
|
||||
"AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
|
||||
"AbstractAbstractFileNode.knownColLbl=Known",
|
||||
"AbstractAbstractFileNode.inHashsetsColLbl=In Hashsets",
|
||||
"AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
|
||||
"AbstractAbstractFileNode.objectId=Object ID",
|
||||
"AbstractAbstractFileNode.mimeType=MIME Type",
|
||||
@ -219,7 +218,6 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
|
||||
TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()),
|
||||
KNOWN(AbstractAbstractFileNode_knownColLbl()),
|
||||
HASHSETS(AbstractAbstractFileNode_inHashsetsColLbl()),
|
||||
MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
|
||||
ObjectID(AbstractAbstractFileNode_objectId()),
|
||||
MIMETYPE(AbstractAbstractFileNode_mimeType()),
|
||||
@ -262,7 +260,6 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
map.put(TYPE_DIR.toString(), content.getDirType().getLabel());
|
||||
map.put(TYPE_META.toString(), content.getMetaType().toString());
|
||||
map.put(KNOWN.toString(), content.getKnown().getName());
|
||||
map.put(HASHSETS.toString(), getHashSetHitsCsvList(content));
|
||||
map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
|
||||
map.put(ObjectID.toString(), content.getId());
|
||||
map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
|
||||
@ -339,10 +336,11 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
"AbstractAbstractFileNode.createSheet.notableFile.description=File recognized as notable.",
|
||||
"AbstractAbstractFileNode.createSheet.interestingResult.description=File has interesting result associated with it.",
|
||||
"AbstractAbstractFileNode.createSheet.taggedFile.description=File has been tagged.",
|
||||
"AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag."})
|
||||
"AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag.",
|
||||
"AbstractAbstractFileNode.createSheet.noScore.description=No score"})
|
||||
protected final void addScoreProperty(Sheet.Set sheetSet, List<ContentTag> tags) {
|
||||
Score score = Score.NO_SCORE;
|
||||
String description = NO_DESCR;
|
||||
String description = Bundle.AbstractAbstractFileNode_createSheet_noScore_description();
|
||||
if (content.getKnown() == TskData.FileKnown.BAD) {
|
||||
score = Score.NOTABLE_SCORE;
|
||||
description = Bundle.AbstractAbstractFileNode_createSheet_notableFile_description();
|
||||
@ -402,6 +400,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
*
|
||||
* @param sheetSet the modifiable Sheet.Set returned by
|
||||
* Sheet.get(Sheet.PROPERTIES)
|
||||
* @deprecated
|
||||
*/
|
||||
@NbBundle.Messages("AbstractAbstractFileNode.tagsProperty.displayName=Tags")
|
||||
@Deprecated
|
||||
@ -418,21 +417,6 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
.collect(Collectors.joining(", "))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by subclasses of AbstractAbstractFileNode to add the tags property
|
||||
* to their sheets.
|
||||
*
|
||||
* @param sheetSet the modifiable Sheet.Set returned by
|
||||
* Sheet.get(Sheet.PROPERTIES)
|
||||
* @param tags the list of tags associated with the file
|
||||
*/
|
||||
protected final void addTagProperty(Sheet.Set sheetSet, List<ContentTag> tags) {
|
||||
sheetSet.put(new NodeProperty<>("Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
|
||||
NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
|
||||
.distinct()
|
||||
.collect(Collectors.joining(", "))));
|
||||
}
|
||||
|
||||
private static String getContentPath(AbstractFile file) {
|
||||
try {
|
||||
return file.getUniquePath();
|
||||
@ -462,7 +446,9 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
* @param file The file.
|
||||
*
|
||||
* @return The CSV list of hash set names.
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
protected static String getHashSetHitsCsvList(AbstractFile file) {
|
||||
try {
|
||||
return StringUtils.join(file.getHashSetNames(), ", ");
|
||||
|
@ -24,6 +24,8 @@ import java.util.Map;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.ContentTag;
|
||||
@ -82,12 +84,20 @@ public abstract class AbstractFsContentNode<T extends AbstractFile> extends Abst
|
||||
AbstractFilePropertyType.NAME.toString(),
|
||||
NO_DESCR,
|
||||
getName()));
|
||||
//add the cr status property before the propertyMap to ensure it is early in column order
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
//add the comment property before the propertyMap to ensure it is early in column order
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences()== false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
|
||||
for (AbstractFilePropertyType propType : AbstractFilePropertyType.values()) {
|
||||
final String propString = propType.toString();
|
||||
sheetSet.put(new NodeProperty<>(propString, propString, NO_DESCR, map.get(propString)));
|
||||
@ -96,9 +106,6 @@ public abstract class AbstractFsContentNode<T extends AbstractFile> extends Abst
|
||||
sheetSet.put(new NodeProperty<>(HIDE_PARENT, HIDE_PARENT, HIDE_PARENT, HIDE_PARENT));
|
||||
}
|
||||
|
||||
// add tags property to the sheet
|
||||
addTagProperty(sheetSet, tags);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,12 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -53,10 +55,10 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString()) &&
|
||||
UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
refreshChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@ -83,7 +85,7 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
||||
try {
|
||||
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
List<DataSource> dataSources = tskCase.getDataSources();
|
||||
List<DataSourceGrouping> keys = new ArrayList<>();
|
||||
dataSources.forEach((datasource) -> {
|
||||
|
@ -55,11 +55,13 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.Score;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus;
|
||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -350,10 +352,18 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"),
|
||||
NO_DESCR,
|
||||
this.getSourceName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
|
||||
try {
|
||||
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||
@ -501,7 +511,6 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
NO_DESCR,
|
||||
path));
|
||||
}
|
||||
addTagProperty(sheetSet, tags);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
@ -556,6 +565,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
* @param tags the list of tags which should appear as the value for the
|
||||
* property
|
||||
*/
|
||||
@Deprecated
|
||||
protected final void addTagProperty(Sheet.Set sheetSet, List<Tag> tags) {
|
||||
sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(),
|
||||
NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", "))));
|
||||
@ -618,16 +628,34 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
"BlackboardArtifactNode.createSheet.notableFile.description=Associated file recognized as notable.",
|
||||
"BlackboardArtifactNode.createSheet.interestingResult.description=Result has an interesting result associated with it.",
|
||||
"BlackboardArtifactNode.createSheet.taggedItem.description=Result or associated file has been tagged.",
|
||||
"BlackboardArtifactNode.createSheet.notableTaggedItem.description=Result or associated file tagged with notable tag."})
|
||||
"BlackboardArtifactNode.createSheet.notableTaggedItem.description=Result or associated file tagged with notable tag.",
|
||||
"BlackboardArtifactNode.createSheet.noScore.description=No score"})
|
||||
protected final void addScoreProperty(Sheet.Set sheetSet, List<Tag> tags) {
|
||||
Score score = Score.NO_SCORE;
|
||||
String description = "";
|
||||
String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description();
|
||||
if (associated instanceof AbstractFile) {
|
||||
if (((AbstractFile) associated).getKnown() == TskData.FileKnown.BAD) {
|
||||
score = Score.NOTABLE_SCORE;
|
||||
description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description();
|
||||
}
|
||||
}
|
||||
//if the artifact being viewed is a hashhit check if the hashset is notable
|
||||
if ((score == Score.NO_SCORE || score == Score.INTERESTING_SCORE) && content.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
|
||||
try {
|
||||
BlackboardAttribute attr = content.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME));
|
||||
List<HashDbManager.HashDb> notableHashsets = HashDbManager.getInstance().getKnownBadFileHashSets();
|
||||
for (HashDbManager.HashDb hashDb : notableHashsets) {
|
||||
if (hashDb.getHashSetName().equals(attr.getValueString())) {
|
||||
score = Score.NOTABLE_SCORE;
|
||||
description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
//unable to get the attribute so we can not update the status based on the attribute
|
||||
logger.log(Level.WARNING, "Unable to get TSK_SET_NAME attribute for artifact of type TSK_HASHSET_HIT with artifact ID " + content.getArtifactID(), ex);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (score == Score.NO_SCORE && !content.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT).isEmpty()) {
|
||||
score = Score.INTERESTING_SCORE;
|
||||
@ -670,8 +698,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex);
|
||||
}
|
||||
catch (CorrelationAttributeNormalizationException ex) {
|
||||
} catch (CorrelationAttributeNormalizationException ex) {
|
||||
logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex);
|
||||
}
|
||||
sheetSet.put(
|
||||
|
@ -10,7 +10,6 @@ AbstractAbstractFileNode.modeColLbl=\u30e2\u30fc\u30c9
|
||||
AbstractAbstractFileNode.useridColLbl=\u30e6\u30fc\u30b6ID
|
||||
AbstractAbstractFileNode.groupidColLbl=\u30b0\u30eb\u30fc\u30d7ID
|
||||
AbstractAbstractFileNode.knownColLbl=\u65e2\u77e5
|
||||
AbstractAbstractFileNode.inHashsetsColLbl=HashSet\u306b\u5b58\u5728
|
||||
AbstractAbstractFileNode.md5HashColLbl=MD5\u30cf\u30c3\u30b7\u30e5
|
||||
AbstractContentChildren.CreateTSKNodeVisitor.exception.noNodeMsg=\u6307\u5b9a\u3055\u308c\u305fSleuthkitItem\u306e\u30ce\u30fc\u30c9\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
|
||||
AbstractContentChildren.createAutopsyNodeVisitor.exception.noNodeMsg=\u6307\u5b9a\u3055\u308c\u305f\u8868\u793a\u53ef\u80fd\u306a\u30a2\u30a4\u30c6\u30e0(DisplayableItem)\u306e\u30ce\u30fc\u30c9\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
|
||||
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -39,10 +40,12 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import static org.sleuthkit.autopsy.datamodel.Bundle.*;
|
||||
import org.sleuthkit.autopsy.deletedFiles.DeletedFilePreferences;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
@ -109,11 +112,11 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
this.skCase = skCase;
|
||||
this.datasourceObjId = dsObjId;
|
||||
}
|
||||
|
||||
|
||||
long filteringDataSourceObjId() {
|
||||
return this.datasourceObjId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T accept(AutopsyItemVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
@ -189,9 +192,10 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
* fired. Other nodes are listening to this for changes.
|
||||
*/
|
||||
private static final class DeletedContentsChildrenObservable extends Observable {
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
|
||||
Case.Events.DATA_SOURCE_ADDED,
|
||||
Case.Events.CURRENT_CASE
|
||||
Case.Events.DATA_SOURCE_ADDED,
|
||||
Case.Events.CURRENT_CASE
|
||||
);
|
||||
|
||||
DeletedContentsChildrenObservable() {
|
||||
@ -211,12 +215,11 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
|
||||
/**
|
||||
* + // @@@ COULD CHECK If the new file is deleted
|
||||
* before notifying... Checking for a current case is a
|
||||
* stop gap measure + update(); until a different way of
|
||||
* handling the closing of cases is worked out.
|
||||
* Currently, remote events may be received for a case
|
||||
* that is already closed.
|
||||
* + // @@@ COULD CHECK If the new file is deleted before
|
||||
* notifying... Checking for a current case is a stop gap
|
||||
* measure + update(); until a different way of handling the
|
||||
* closing of cases is worked out. Currently, remote events
|
||||
* may be received for a case that is already closed.
|
||||
*/
|
||||
try {
|
||||
Case.getCurrentCaseThrows();
|
||||
@ -232,10 +235,10 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|
||||
|| eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
|
||||
/**
|
||||
* Checking for a current case is a stop gap measure
|
||||
* until a different way of handling the closing of
|
||||
* cases is worked out. Currently, remote events may be
|
||||
* received for a case that is already closed.
|
||||
* Checking for a current case is a stop gap measure until a
|
||||
* different way of handling the closing of cases is worked
|
||||
* out. Currently, remote events may be received for a case
|
||||
* that is already closed.
|
||||
*/
|
||||
try {
|
||||
Case.getCurrentCaseThrows();
|
||||
@ -280,7 +283,7 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
// Use version that has observer for updates
|
||||
@Deprecated
|
||||
DeletedContentNode(SleuthkitCase skCase, DeletedContent.DeletedContentFilter filter, long dsObjId) {
|
||||
super(Children.create(new DeletedContentChildren(filter, skCase, null, dsObjId ), true), Lookups.singleton(filter.getDisplayName()));
|
||||
super(Children.create(new DeletedContentChildren(filter, skCase, null, dsObjId), true), Lookups.singleton(filter.getDisplayName()));
|
||||
this.filter = filter;
|
||||
this.datasourceObjId = dsObjId;
|
||||
init();
|
||||
@ -364,7 +367,7 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
private final SleuthkitCase skCase;
|
||||
private final DeletedContent.DeletedContentFilter filter;
|
||||
private static final Logger logger = Logger.getLogger(DeletedContentChildren.class.getName());
|
||||
private static final int MAX_OBJECTS = 10001;
|
||||
|
||||
private final Observable notifier;
|
||||
private final long datasourceObjId;
|
||||
|
||||
@ -383,7 +386,7 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
refresh(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -406,18 +409,19 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
+ "There are more Deleted Files than can be displayed."
|
||||
+ " Only the first {0} Deleted Files will be shown."})
|
||||
protected boolean createKeys(List<AbstractFile> list) {
|
||||
DeletedFilePreferences deletedPreferences = DeletedFilePreferences.getDefault();
|
||||
List<AbstractFile> queryList = runFsQuery();
|
||||
if (queryList.size() == MAX_OBJECTS) {
|
||||
if (deletedPreferences.getShouldLimitDeletedFiles() && queryList.size() == deletedPreferences.getDeletedFilesLimit()) {
|
||||
queryList.remove(queryList.size() - 1);
|
||||
// only show the dialog once - not each time we refresh
|
||||
if (maxFilesDialogShown == false) {
|
||||
maxFilesDialogShown = true;
|
||||
SwingUtilities.invokeLater(()
|
||||
-> JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
||||
DeletedContent_createKeys_maxObjects_msg(MAX_OBJECTS - 1))
|
||||
DeletedContent_createKeys_maxObjects_msg(deletedPreferences.getDeletedFilesLimit() - 1))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
list.addAll(queryList);
|
||||
return true;
|
||||
}
|
||||
@ -460,11 +464,13 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
+ " OR known IS NULL)"; //NON-NLS
|
||||
}
|
||||
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
query += " AND data_source_obj_id = " + filteringDSObjId;
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
query += " AND data_source_obj_id = " + filteringDSObjId;
|
||||
}
|
||||
DeletedFilePreferences deletedPreferences = DeletedFilePreferences.getDefault();
|
||||
if (deletedPreferences.getShouldLimitDeletedFiles()) {
|
||||
query += " LIMIT " + deletedPreferences.getDeletedFilesLimit(); //NON-NLS
|
||||
}
|
||||
|
||||
query += " LIMIT " + MAX_OBJECTS; //NON-NLS
|
||||
return query;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013-16 Basis Technology Corp.
|
||||
* Copyright 2013-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -19,31 +19,20 @@
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.Border;
|
||||
import javafx.scene.layout.BorderStroke;
|
||||
import javafx.scene.layout.BorderStrokeStyle;
|
||||
import javafx.scene.layout.BorderWidths;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.datamodel.Bundle;
|
||||
|
||||
/**
|
||||
* Enum to represent the six categories in the DHS image categorization scheme.
|
||||
*/
|
||||
@NbBundle.Messages({"Category.one=CAT-1: Child Exploitation (Illegal)",
|
||||
@NbBundle.Messages({
|
||||
"Category.one=CAT-1: Child Exploitation (Illegal)",
|
||||
"Category.two=CAT-2: Child Exploitation (Non-Illegal/Age Difficult)",
|
||||
"Category.three=CAT-3: CGI/Animation (Child Exploitive)",
|
||||
"Category.four=CAT-4: Exemplar/Comparison (Internal Use Only)",
|
||||
@ -56,29 +45,32 @@ public enum DhsImageCategory {
|
||||
* preserves the fact that lower category numbers are first/most sever,
|
||||
* except 0 which is last
|
||||
*/
|
||||
ONE(Color.RED, 1, Bundle.Category_one()),
|
||||
TWO(Color.ORANGE, 2, Bundle.Category_two()),
|
||||
THREE(Color.YELLOW, 3, Bundle.Category_three()),
|
||||
FOUR(Color.BISQUE, 4, Bundle.Category_four()),
|
||||
FIVE(Color.GREEN, 5, Bundle.Category_five()),
|
||||
ZERO(Color.LIGHTGREY, 0, Bundle.Category_zero());
|
||||
ONE(Color.RED, 1, Bundle.Category_one(), "cat1.png"),
|
||||
TWO(Color.ORANGE, 2, Bundle.Category_two(), "cat2.png"),
|
||||
THREE(Color.YELLOW, 3, Bundle.Category_three(), "cat3.png"),
|
||||
FOUR(Color.BISQUE, 4, Bundle.Category_four(), "cat4.png"),
|
||||
FIVE(Color.GREEN, 5, Bundle.Category_five(), "cat5.png"),
|
||||
ZERO(Color.LIGHTGREY, 0, Bundle.Category_zero(), "cat0.png");
|
||||
|
||||
private static final BorderWidths BORDER_WIDTHS_2 = new BorderWidths(2);
|
||||
private static final CornerRadii CORNER_RADII_4 = new CornerRadii(4);
|
||||
/** Map from displayName to enum value */
|
||||
private static final Map<String, DhsImageCategory> nameMap
|
||||
= Maps.uniqueIndex(Arrays.asList(values()), DhsImageCategory::getDisplayName);
|
||||
|
||||
public static ImmutableList<DhsImageCategory> getNonZeroCategories() {
|
||||
return nonZeroCategories;
|
||||
private final Color color;
|
||||
private final String displayName;
|
||||
private final int id;
|
||||
private final Image icon;
|
||||
|
||||
private DhsImageCategory(Color color, int id, String name, String filename) {
|
||||
this.color = color;
|
||||
this.displayName = name;
|
||||
this.id = id;
|
||||
this.icon = new Image(getClass().getResourceAsStream("/org/sleuthkit/autopsy/images/" + filename));
|
||||
}
|
||||
|
||||
private static final ImmutableList<DhsImageCategory> nonZeroCategories =
|
||||
ImmutableList.of(DhsImageCategory.FIVE, DhsImageCategory.FOUR, DhsImageCategory.THREE, DhsImageCategory.TWO, DhsImageCategory.ONE);
|
||||
|
||||
/**
|
||||
* map from displayName to enum value
|
||||
*/
|
||||
private static final Map<String, DhsImageCategory> nameMap =
|
||||
Stream.of(values()).collect(Collectors.toMap(DhsImageCategory::getDisplayName,
|
||||
Function.identity()));
|
||||
public static ImmutableList<DhsImageCategory> getNonZeroCategories() {
|
||||
return ImmutableList.of(FIVE, FOUR, THREE, TWO, ONE);
|
||||
}
|
||||
|
||||
public static DhsImageCategory fromDisplayName(String displayName) {
|
||||
return nameMap.get(displayName);
|
||||
@ -92,19 +84,6 @@ public enum DhsImageCategory {
|
||||
return nameMap.containsKey(tName) == false;
|
||||
}
|
||||
|
||||
private final Color color;
|
||||
|
||||
private final String displayName;
|
||||
|
||||
private final int id;
|
||||
private Image snapshot;
|
||||
|
||||
private DhsImageCategory(Color color, int id, String name) {
|
||||
this.color = color;
|
||||
this.displayName = name;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getCategoryNumber() {
|
||||
return id;
|
||||
}
|
||||
@ -122,15 +101,7 @@ public enum DhsImageCategory {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
synchronized public Node getGraphic() {
|
||||
if (snapshot == null) {
|
||||
Region region = new Region();
|
||||
region.setBackground(new Background(new BackgroundFill(getColor(), CORNER_RADII_4, Insets.EMPTY)));
|
||||
region.setPrefSize(16, 16);
|
||||
region.setBorder(new Border(new BorderStroke(getColor().darker(), BorderStrokeStyle.SOLID, CORNER_RADII_4, BORDER_WIDTHS_2)));
|
||||
Scene scene = new Scene(region, 16, 16, Color.TRANSPARENT);
|
||||
snapshot = region.snapshot(null, null);
|
||||
}
|
||||
return new ImageView(snapshot);
|
||||
public Node getGraphic() {
|
||||
return new ImageView(icon);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -39,6 +40,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -161,7 +163,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
|
||||
+ "attribute_type_id=" + pathAttrId //NON-NLS
|
||||
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
|
||||
+ " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
@ -34,6 +35,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -290,10 +292,9 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<BlackboardArtifact.Type> list) {
|
||||
//TEST COMMENT
|
||||
if (skCase != null) {
|
||||
try {
|
||||
List<BlackboardArtifact.Type> types = (UserPreferences.groupItemsInTreeByDatasource()) ?
|
||||
List<BlackboardArtifact.Type> types = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ?
|
||||
blackboard.getArtifactTypesInUse(datasourceObjId) :
|
||||
skCase.getArtifactTypesInUse() ;
|
||||
|
||||
@ -358,7 +359,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
||||
// a performance increase might be had by adding a
|
||||
// "getBlackboardArtifactCount()" method to skCase
|
||||
try {
|
||||
this.childCount = UserPreferences.groupItemsInTreeByDatasource() ?
|
||||
this.childCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ?
|
||||
blackboard.getArtifactsCount(type.getTypeID(), datasourceObjId) :
|
||||
skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
|
||||
} catch (TskException ex) {
|
||||
@ -483,7 +484,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
||||
if (skCase != null) {
|
||||
try {
|
||||
List<BlackboardArtifact> arts =
|
||||
UserPreferences.groupItemsInTreeByDatasource() ?
|
||||
Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ?
|
||||
blackboard.getArtifacts(type.getTypeID(), datasourceObjId) :
|
||||
skCase.getBlackboardArtifacts(type.getTypeID());
|
||||
list.addAll(arts);
|
||||
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -36,6 +37,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -445,8 +447,8 @@ public class FileSize implements AutopsyVisitableItem {
|
||||
query += " AND (type != " + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() + ")"; //NON-NLS
|
||||
}
|
||||
|
||||
// filter by datasource if indicated in user preferences
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
// filter by datasource if indicated in case preferences
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
query += " AND data_source_obj_id = " + filteringDSObjId;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -37,6 +38,7 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -363,7 +365,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
+ (UserPreferences.hideKnownFilesInViewsTree()
|
||||
? " AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")"
|
||||
: " ")
|
||||
+ (UserPreferences.groupItemsInTreeByDatasource()
|
||||
+ (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? " AND data_source_obj_id = " + filteringDataSourceObjId()
|
||||
: " ")
|
||||
+ " AND (extension IN (" + filter.getFilter().stream()
|
||||
|
@ -28,6 +28,7 @@ import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -41,6 +42,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import static org.sleuthkit.autopsy.core.UserPreferences.hideKnownFilesInViewsTree;
|
||||
@ -101,7 +103,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
+ TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()
|
||||
+ (hideSlackFilesInViewsTree() ? "" : ("," + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal()))
|
||||
+ "))"
|
||||
+ ( UserPreferences.groupItemsInTreeByDatasource() ? " AND data_source_obj_id = " + this.filteringDataSourceObjId() : " ")
|
||||
+ ( Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ? " AND data_source_obj_id = " + this.filteringDataSourceObjId() : " ")
|
||||
+ (hideKnownFilesInViewsTree() ? (" AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")") : "");
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -41,6 +42,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -141,7 +143,7 @@ public class HashsetHits implements AutopsyVisitableItem {
|
||||
+ "attribute_type_id=" + setNameId //NON-NLS
|
||||
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
|
||||
+ " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -41,8 +42,8 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
@ -132,7 +133,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
+ "attribute_type_id=" + setNameId //NON-NLS
|
||||
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
|
||||
+ " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
|
||||
}
|
||||
|
||||
@ -474,11 +475,13 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
BlackboardArtifact art = skCase.getBlackboardArtifact(id);
|
||||
artifactHits.put(id, art);
|
||||
}
|
||||
list.add(id);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "TSK Exception occurred", ex); //NON-NLS
|
||||
}
|
||||
});
|
||||
|
||||
list.addAll(artifactHits.keySet());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -43,6 +44,7 @@ import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -321,7 +323,7 @@ public class KeywordHits implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
String queryStr = KEYWORD_HIT_ATTRIBUTES_QUERY;
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
queryStr += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,8 @@ import org.openide.util.Utilities;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
@ -46,6 +48,7 @@ import org.sleuthkit.datamodel.TskData;
|
||||
*/
|
||||
public class LayoutFileNode extends AbstractAbstractFileNode<LayoutFile> {
|
||||
|
||||
@Deprecated
|
||||
public static enum LayoutContentPropertyType {
|
||||
|
||||
PARTS {
|
||||
@ -90,18 +93,23 @@ public class LayoutFileNode extends AbstractAbstractFileNode<LayoutFile> {
|
||||
NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.displayName"),
|
||||
NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.desc"),
|
||||
getName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.noDescr.text");
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
|
||||
}
|
||||
|
||||
// add tags property to the sheet
|
||||
addTagProperty(sheetSet, tags);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
@ -145,7 +153,6 @@ public class LayoutFileNode extends AbstractAbstractFileNode<LayoutFile> {
|
||||
|
||||
void fillPropertyMap(Map<String, Object> map) {
|
||||
AbstractAbstractFileNode.fillPropertyMap(map, getContent());
|
||||
map.put(LayoutContentPropertyType.PARTS.toString(), content.getNumParts());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,6 +24,8 @@ import java.util.Map;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.datamodel.ContentTag;
|
||||
import org.sleuthkit.datamodel.LocalDirectory;
|
||||
|
||||
@ -63,10 +65,18 @@ public class LocalDirectoryNode extends SpecialDirectoryNode {
|
||||
Bundle.LocalDirectoryNode_createSheet_name_displayName(),
|
||||
Bundle.LocalDirectoryNode_createSheet_name_desc(),
|
||||
getName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
// At present, a LocalDirectory will never be a datasource - the top level of a logical
|
||||
// file set is a VirtualDirectory
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
@ -76,7 +86,6 @@ public class LocalDirectoryNode extends SpecialDirectoryNode {
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
|
||||
}
|
||||
addTagProperty(sheetSet, tags);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ import org.openide.util.Utilities;
|
||||
import org.sleuthkit.autopsy.actions.AddContentTagAction;
|
||||
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||
@ -82,18 +84,23 @@ public class LocalFileNode extends AbstractAbstractFileNode<AbstractFile> {
|
||||
NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.displayName"),
|
||||
NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.desc"),
|
||||
getName()));
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.noDescr.text");
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
|
||||
}
|
||||
|
||||
// add tags property to the sheet
|
||||
addTagProperty(sheetSet, tags);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.openide.util.NbBundle;
|
||||
@ -27,6 +28,7 @@ import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.FileSearchAction;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SpecialDirectory;
|
||||
|
||||
/**
|
||||
@ -60,7 +62,11 @@ public abstract class SpecialDirectoryNode extends AbstractAbstractFileNode<Spec
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(new FileSearchAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text()));
|
||||
actions.add(new RunIngestModulesAction(content));
|
||||
if (content.isDataSource()) {
|
||||
actions.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));
|
||||
} else {
|
||||
actions.add(new RunIngestModulesAction(content));
|
||||
}
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions.toArray(new Action[0]);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
@ -34,6 +35,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
@ -244,11 +246,11 @@ public class Tags implements AutopsyVisitableItem {
|
||||
List<TagName> tagNamesInUse;
|
||||
if (UserPreferences.showOnlyCurrentUserTags()) {
|
||||
String userName = System.getProperty(USER_NAME_PROPERTY);
|
||||
tagNamesInUse = UserPreferences.groupItemsInTreeByDatasource()
|
||||
tagNamesInUse = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUseForUser(datasourceObjId, userName)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUseForUser(userName);
|
||||
} else {
|
||||
tagNamesInUse = UserPreferences.groupItemsInTreeByDatasource()
|
||||
tagNamesInUse = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse(datasourceObjId)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse();
|
||||
}
|
||||
@ -301,7 +303,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
TagsManager tm = Case.getCurrentCaseThrows().getServices().getTagsManager();
|
||||
if (UserPreferences.showOnlyCurrentUserTags()) {
|
||||
String userName = System.getProperty(USER_NAME_PROPERTY);
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
tagsCount = tm.getContentTagsCountByTagNameForUser(tagName, datasourceObjId, userName);
|
||||
tagsCount += tm.getBlackboardArtifactTagsCountByTagNameForUser(tagName, datasourceObjId, userName);
|
||||
} else {
|
||||
@ -309,7 +311,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
tagsCount += tm.getBlackboardArtifactTagsCountByTagNameForUser(tagName, userName);
|
||||
}
|
||||
} else {
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
tagsCount = tm.getContentTagsCountByTagName(tagName, datasourceObjId);
|
||||
tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName, datasourceObjId);
|
||||
} else {
|
||||
@ -422,11 +424,11 @@ public class Tags implements AutopsyVisitableItem {
|
||||
|
||||
if (UserPreferences.showOnlyCurrentUserTags()) {
|
||||
String userName = System.getProperty(USER_NAME_PROPERTY);
|
||||
tagsCount = UserPreferences.groupItemsInTreeByDatasource()
|
||||
tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagNameForUser(tagName, datasourceObjId, userName)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagNameForUser(tagName, userName);
|
||||
} else {
|
||||
tagsCount = UserPreferences.groupItemsInTreeByDatasource()
|
||||
tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName, datasourceObjId)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName);
|
||||
}
|
||||
@ -484,7 +486,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
protected boolean createKeys(List<ContentTag> keys) {
|
||||
// Use the content tags bearing the specified tag name as the keys.
|
||||
try {
|
||||
List<ContentTag> contentTags = UserPreferences.groupItemsInTreeByDatasource()
|
||||
List<ContentTag> contentTags = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName, datasourceObjId)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName);
|
||||
if (UserPreferences.showOnlyCurrentUserTags()) {
|
||||
@ -542,11 +544,11 @@ public class Tags implements AutopsyVisitableItem {
|
||||
try {
|
||||
if (UserPreferences.showOnlyCurrentUserTags()) {
|
||||
String userName = System.getProperty(USER_NAME_PROPERTY);
|
||||
tagsCount = UserPreferences.groupItemsInTreeByDatasource()
|
||||
tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagNameForUser(tagName, datasourceObjId, userName)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagNameForUser(tagName, userName);
|
||||
} else {
|
||||
tagsCount = UserPreferences.groupItemsInTreeByDatasource()
|
||||
tagsCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName, datasourceObjId)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName);
|
||||
}
|
||||
@ -604,7 +606,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
protected boolean createKeys(List<BlackboardArtifactTag> keys) {
|
||||
try {
|
||||
// Use the blackboard artifact tags bearing the specified tag name as the keys.
|
||||
List<BlackboardArtifactTag> artifactTags = UserPreferences.groupItemsInTreeByDatasource()
|
||||
List<BlackboardArtifactTag> artifactTags = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
? Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName, datasourceObjId)
|
||||
: Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName);
|
||||
if (UserPreferences.showOnlyCurrentUserTags()) {
|
||||
|
@ -29,6 +29,8 @@ import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.ContentTag;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@ -90,10 +92,17 @@ public class VirtualDirectoryNode extends SpecialDirectoryNode {
|
||||
NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.desc"),
|
||||
getName()));
|
||||
if (!this.content.isDataSource()) {
|
||||
CorrelationAttributeInstance correlationAttribute = getCorrelationAttributeInstance();
|
||||
addScoreProperty(sheetSet, tags);
|
||||
|
||||
CorrelationAttributeInstance correlationAttribute = null;
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
correlationAttribute = getCorrelationAttributeInstance();
|
||||
}
|
||||
addCommentProperty(sheetSet, tags, correlationAttribute);
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
|
||||
if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) {
|
||||
addCountProperty(sheetSet, correlationAttribute);
|
||||
}
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
fillPropertyMap(map, getContent());
|
||||
|
||||
@ -101,7 +110,6 @@ public class VirtualDirectoryNode extends SpecialDirectoryNode {
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
|
||||
}
|
||||
addTagProperty(sheetSet, tags);
|
||||
} else {
|
||||
sheetSet.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_type_name(),
|
||||
Bundle.VirtualDirectoryNode_createSheet_type_displayName(),
|
||||
|
@ -57,6 +57,7 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||
@ -149,12 +150,14 @@ final public class Accounts implements AutopsyVisitableItem {
|
||||
* Returns the clause to filter artifacts by data source.
|
||||
*
|
||||
* @return A clause that will or will not filter artifacts by datasource
|
||||
* based on the UserPreferences groupItemsInTreeByDatasource setting
|
||||
* based on the CasePreferences groupItemsInTreeByDataSource setting
|
||||
*/
|
||||
private String getFilterByDataSourceClause() {
|
||||
return (UserPreferences.groupItemsInTreeByDatasource()) ?
|
||||
" AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " "
|
||||
: " ";
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
return " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " ";
|
||||
}
|
||||
|
||||
return " ";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,6 +167,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
||||
* @return An Action that will toggle whether rejected artifacts are shown
|
||||
* in the tree rooted by this Accounts instance.
|
||||
*/
|
||||
@Deprecated
|
||||
public Action newToggleShowRejectedAction() {
|
||||
return new ToggleShowRejected();
|
||||
}
|
||||
@ -1686,6 +1690,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
||||
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private final class ToggleShowRejected extends AbstractAction {
|
||||
|
||||
@NbBundle.Messages("ToggleShowRejected.name=Show Rejected Results")
|
||||
@ -1699,6 +1704,16 @@ final public class Accounts implements AutopsyVisitableItem {
|
||||
reviewStatusBus.post(new ReviewStatusChangeEvent(Collections.emptySet(), null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user interface to show or hide rejected artifacts.
|
||||
*
|
||||
* @param showRejected Show rejected artifacts? Yes if true; otherwise no.
|
||||
*/
|
||||
public void setShowRejected(boolean showRejected) {
|
||||
this.showRejected = showRejected;
|
||||
reviewStatusBus.post(new ReviewStatusChangeEvent(Collections.emptySet(), null));
|
||||
}
|
||||
|
||||
private abstract class ReviewStatusAction extends AbstractAction {
|
||||
|
||||
|
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 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.deletedFiles;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||
|
||||
/**
|
||||
* Class to store settings related to the display of deleted files.
|
||||
*/
|
||||
public class DeletedFilePreferences {
|
||||
|
||||
private static final String SETTINGS_FILE = "DeletedFilePreferences.properties"; //NON-NLS
|
||||
private static final String KEY_LIMIT_DELETED_FILES = "limitDeletedFiles"; //NON-NLS
|
||||
private static final String KEY_LIMIT_VALUE = "limitValue";
|
||||
private static final String VALUE_TRUE = "true"; //NON-NLS
|
||||
private static final String VALUE_FALSE = "false"; //NON-NLS
|
||||
private static final int DEFAULT_MAX_OBJECTS = 10001;
|
||||
private static final Logger logger = Logger.getLogger(CasePreferences.class.getName());
|
||||
private static DeletedFilePreferences defaultInstance;
|
||||
private static boolean limitDeletedFiles = true;
|
||||
private static int deletedFilesLimit = DEFAULT_MAX_OBJECTS;
|
||||
|
||||
/**
|
||||
* Get the settings for the display of deleted files.
|
||||
*
|
||||
* @return defaultInstance with freshly loaded
|
||||
*/
|
||||
public static synchronized DeletedFilePreferences getDefault() {
|
||||
if (defaultInstance == null) {
|
||||
defaultInstance = new DeletedFilePreferences();
|
||||
}
|
||||
defaultInstance.loadFromStorage();
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent instantiation.
|
||||
*/
|
||||
private DeletedFilePreferences() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the 'limitDeletedFiles' value. This can be true or false. It will
|
||||
* default to true if it was not saved correctly previously.s
|
||||
*
|
||||
* @return true if the number of deleted files displayed should be limied,
|
||||
* false if it should not be limited.
|
||||
*/
|
||||
public boolean getShouldLimitDeletedFiles() {
|
||||
return limitDeletedFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'limitDeletedFiles' value to true or false.
|
||||
*
|
||||
* @param value true if the number of deleted files displayed should be
|
||||
* limied, false if it should not be limited.
|
||||
*/
|
||||
public void setShouldLimitDeletedFiles(boolean value) {
|
||||
limitDeletedFiles = value;
|
||||
saveToStorage();
|
||||
DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the 'limitValue' value. This is an interger value and will default to
|
||||
* DEFAULT_MAX_OBJECTS if it was not previously saved correctly.
|
||||
*
|
||||
* @return an integer representing the max number of deleted files to display.
|
||||
*/
|
||||
public int getDeletedFilesLimit() {
|
||||
return deletedFilesLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'limitValue' for max number of deleted files to display.
|
||||
*
|
||||
* @param value an integer representing the max number of deleted files to display.
|
||||
*/
|
||||
public void setDeletedFilesLimit(int value) {
|
||||
deletedFilesLimit = value;
|
||||
saveToStorage();
|
||||
DirectoryTreeTopComponent.getDefault().refreshContentTreeSafe();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load deleted file preferences from the settings file.
|
||||
*/
|
||||
private void loadFromStorage() {
|
||||
Path settingsFile = Paths.get(PlatformUtil.getUserConfigDirectory(), SETTINGS_FILE); //NON-NLS
|
||||
if (settingsFile.toFile().exists()) {
|
||||
// Read the settings
|
||||
try (InputStream inputStream = Files.newInputStream(settingsFile)) {
|
||||
Properties props = new Properties();
|
||||
props.load(inputStream);
|
||||
String limitDeletedFilesValue = props.getProperty(KEY_LIMIT_DELETED_FILES);
|
||||
if (limitDeletedFilesValue != null) {
|
||||
switch (limitDeletedFilesValue) {
|
||||
case VALUE_TRUE:
|
||||
limitDeletedFiles = true;
|
||||
break;
|
||||
case VALUE_FALSE:
|
||||
limitDeletedFiles = false;
|
||||
break;
|
||||
default:
|
||||
logger.log(Level.WARNING, String.format("Unexpected value '%s' for limit deleted files using value of true instead",
|
||||
limitDeletedFilesValue));
|
||||
limitDeletedFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String limitValue = props.getProperty(KEY_LIMIT_VALUE);
|
||||
try {
|
||||
if (limitValue != null) {
|
||||
deletedFilesLimit = Integer.valueOf(limitValue);
|
||||
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
logger.log(Level.INFO, String.format("Unexpected value '%s' for limit, expected an integer using default of 10,001 instead",
|
||||
limitValue));
|
||||
deletedFilesLimit = DEFAULT_MAX_OBJECTS;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error reading deletedFilesPreferences file", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store deleted file preferences in the settings file.
|
||||
*/
|
||||
private void saveToStorage() {
|
||||
Path settingsFile = Paths.get(PlatformUtil.getUserConfigDirectory(), SETTINGS_FILE); //NON-NLS
|
||||
Properties props = new Properties();
|
||||
props.setProperty(KEY_LIMIT_DELETED_FILES, (limitDeletedFiles ? VALUE_TRUE : VALUE_FALSE));
|
||||
props.setProperty(KEY_LIMIT_VALUE, String.valueOf(deletedFilesLimit));
|
||||
try (OutputStream fos = Files.newOutputStream(settingsFile)) {
|
||||
props.store(fos, ""); //NON-NLS
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error writing deletedFilesPreferences file", ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -59,7 +59,6 @@ DirectoryTreeFilterNode.action.collapseAll.text=Collapse All
|
||||
DirectoryTreeFilterNode.action.openFileSrcByAttr.text=Open File Search by Attributes
|
||||
DirectoryTreeFilterNode.action.runIngestMods.text=Run Ingest Modules
|
||||
DirectoryTreeTopComponent.action.viewArtContent.text=View Artifact Content
|
||||
DirectoryTreeTopComponent.showRejectedCheckBox.text=Show Rejected Results
|
||||
ExplorerNodeActionVisitor.action.imgDetails.title=Image Details
|
||||
ExplorerNodeActionVisitor.action.extUnallocToSingleFiles=Extract Unallocated Space to Single Files
|
||||
ExplorerNodeActionVisitor.action.fileSystemDetails.title=File System Details
|
||||
@ -119,10 +118,9 @@ AddExternalViewerRulePanel.browseButton.text=Browse
|
||||
AddExternalViewerRulePanel.exePathTextField.text=
|
||||
AddExternalViewerRulePanel.exePathLabel.text=Path of the program to use for files with this type or extension
|
||||
AddExternalViewerRulePanel.extRadioButton.text=Extension
|
||||
DirectoryTreeTopComponent.groupByDatasourceCheckBox.text=Group by Data Source
|
||||
GroupDataSourcesDialog.dataSourceCountLabel.text=jLabel1
|
||||
GroupDataSourcesDialog.queryLabel.text=Would you like to group by data source for faster loading?
|
||||
GroupDataSourcesDialog.yesButton.text=Yes
|
||||
GroupDataSourcesDialog.noButton.text=No
|
||||
GroupDataSourcesDialog.title=Group by Data Source?
|
||||
DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text=Hide Other User's Tags
|
||||
DirectoryTreeTopComponent.openViewPreferencesButton.text=
|
||||
|
@ -140,18 +140,6 @@ public class DataResultFilterNode extends FilterNode {
|
||||
this.sourceEm = em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the inner node. If the actual underlying node is an InstanceCountNode,
|
||||
* refresh() that node, which refreshes the children.
|
||||
*
|
||||
*/
|
||||
public void refresh() {
|
||||
if (getOriginal() instanceof InstanceCountNode) {
|
||||
InstanceCountNode innerNode = getLookup().lookup(InstanceCountNode.class);
|
||||
innerNode.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a node used to wrap another node before passing it to the
|
||||
* result viewers. The wrapper node defines the actions associated with the
|
||||
|
@ -1,6 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Container class="javax.swing.JPopupMenu" name="viewPreferencesPopupMenu">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
</Container>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
@ -16,18 +24,14 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="treeView" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="treeView" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="backButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="forwardButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||
<Component id="showOnlyCurrentUserTagsCheckbox" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="showRejectedCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="groupByDatasourceCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="140" max="32767" attributes="0"/>
|
||||
<Component id="openViewPreferencesButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
@ -35,27 +39,14 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="showRejectedCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="showOnlyCurrentUserTagsCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="groupByDatasourceCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="forwardButton" max="32767" attributes="1"/>
|
||||
<Component id="backButton" min="-2" max="-2" attributes="1"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="openViewPreferencesButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="backButton" min="-2" max="-2" attributes="1"/>
|
||||
<Component id="forwardButton" min="-2" max="-2" attributes="1"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="treeView" pref="843" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="treeView" pref="919" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -76,7 +67,7 @@
|
||||
<Component class="javax.swing.JButton" name="backButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_back_large.png"/>
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_back.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.backButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
@ -84,7 +75,7 @@
|
||||
<Property name="borderPainted" type="boolean" value="false"/>
|
||||
<Property name="contentAreaFilled" type="boolean" value="false"/>
|
||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_back_disabled_large.png"/>
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_back_disabled.png"/>
|
||||
</Property>
|
||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||
<Insets value="[2, 0, 2, 0]"/>
|
||||
@ -96,10 +87,10 @@
|
||||
<Dimension value="[5, 5]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32, 32]"/>
|
||||
<Dimension value="[24, 24]"/>
|
||||
</Property>
|
||||
<Property name="rolloverIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_back_hover_large.png"/>
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_back_hover.png"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -109,7 +100,7 @@
|
||||
<Component class="javax.swing.JButton" name="forwardButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_forward_large.png"/>
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_forward.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.forwardButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
@ -117,7 +108,7 @@
|
||||
<Property name="borderPainted" type="boolean" value="false"/>
|
||||
<Property name="contentAreaFilled" type="boolean" value="false"/>
|
||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_forward_disabled_large.png"/>
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_forward_disabled.png"/>
|
||||
</Property>
|
||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||
<Insets value="[2, 0, 2, 0]"/>
|
||||
@ -129,41 +120,43 @@
|
||||
<Dimension value="[5, 5]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32, 32]"/>
|
||||
<Dimension value="[24, 24]"/>
|
||||
</Property>
|
||||
<Property name="rolloverIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_forward_hover_large.png"/>
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/btn_step_forward_hover.png"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="forwardButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="showRejectedCheckBox">
|
||||
<Component class="javax.swing.JButton" name="openViewPreferencesButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.showRejectedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/view-preferences-23.png"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="groupByDatasourceCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.groupByDatasourceCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.openViewPreferencesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
|
||||
<EmptyBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="borderPainted" type="boolean" value="false"/>
|
||||
<Property name="contentAreaFilled" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[24, 24]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[24, 24]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[24, 24]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="groupByDatasourceCheckBoxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="showOnlyCurrentUserTagsCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showOnlyCurrentUserTagsCheckboxActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openViewPreferencesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
|
@ -24,11 +24,6 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
@ -40,10 +35,11 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.prefs.PreferenceChangeEvent;
|
||||
import java.util.prefs.PreferenceChangeListener;
|
||||
import java.util.Properties;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
@ -60,6 +56,7 @@ import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.TopComponent;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
@ -67,6 +64,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.corecomponents.ViewPreferencesPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
import org.sleuthkit.autopsy.datamodel.ArtifactNodeSelectionInfo;
|
||||
@ -105,12 +103,15 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
private final transient ExplorerManager em = new ExplorerManager();
|
||||
private static DirectoryTreeTopComponent instance;
|
||||
private final DataResultTopComponent dataResult = new DataResultTopComponent(Bundle.DirectoryTreeTopComponent_resultsView_title());
|
||||
private final ViewPreferencesPanel viewPreferencesPanel = new ViewPreferencesPanel(true);
|
||||
private final LinkedList<String[]> backList;
|
||||
private final LinkedList<String[]> forwardList;
|
||||
private static final String PREFERRED_ID = "DirectoryTreeTopComponent"; //NON-NLS
|
||||
private static final Logger LOGGER = Logger.getLogger(DirectoryTreeTopComponent.class.getName());
|
||||
private AutopsyTreeChildFactory autopsyTreeChildFactory;
|
||||
private Children autopsyTreeChildren;
|
||||
private Accounts accounts;
|
||||
private boolean showRejectedResults;
|
||||
private static final long DEFAULT_DATASOURCE_GROUPING_THRESHOLD = 5; // Threshold for prompting the user about grouping by data source
|
||||
private static final String GROUPING_THRESHOLD_NAME = "GroupDataSourceThreshold";
|
||||
private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS
|
||||
@ -136,9 +137,25 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
this.forwardList = new LinkedList<>();
|
||||
backButton.setEnabled(false);
|
||||
forwardButton.setEnabled(false);
|
||||
|
||||
viewPreferencesPopupMenu.add(viewPreferencesPanel);
|
||||
viewPreferencesPopupMenu.setSize(viewPreferencesPanel.getPreferredSize().width + 6, viewPreferencesPanel.getPreferredSize().height + 6);
|
||||
viewPreferencesPopupMenu.addPopupMenuListener(new PopupMenuListener() {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
openViewPreferencesButton.setSelected(true);
|
||||
}
|
||||
|
||||
groupByDatasourceCheckBox.setSelected(UserPreferences.groupItemsInTreeByDatasource());
|
||||
showOnlyCurrentUserTagsCheckbox.setSelected(UserPreferences.showOnlyCurrentUserTags());
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
|
||||
openViewPreferencesButton.setSelected(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent e) {
|
||||
openViewPreferencesButton.setSelected(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,9 +166,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
@Override
|
||||
public void preferenceChange(PreferenceChangeEvent evt) {
|
||||
switch (evt.getKey()) {
|
||||
case UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME:
|
||||
case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE:
|
||||
case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE:
|
||||
case UserPreferences.GROUP_ITEMS_IN_TREE_BY_DATASOURCE:
|
||||
case UserPreferences.HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES:
|
||||
case UserPreferences.KEEP_PREFERRED_VIEWER:
|
||||
refreshContentTreeSafe();
|
||||
break;
|
||||
case UserPreferences.SHOW_ONLY_CURRENT_USER_TAGS:
|
||||
@ -159,7 +178,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
break;
|
||||
case UserPreferences.HIDE_KNOWN_FILES_IN_VIEWS_TREE:
|
||||
case UserPreferences.HIDE_SLACK_FILES_IN_VIEWS_TREE:
|
||||
// TODO: Need a way to refresh the Views subtree
|
||||
// TODO: Need a way to refresh the Views subtree alone.
|
||||
refreshContentTreeSafe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -182,6 +202,28 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
public DataResultTopComponent getDirectoryListing() {
|
||||
return this.dataResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show rejected results?
|
||||
*
|
||||
* @return True if showing rejected results; otherwise false.
|
||||
*/
|
||||
public boolean getShowRejectedResults() {
|
||||
return showRejectedResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter to determine if rejected results should be shown or not.
|
||||
*
|
||||
* @param showRejectedResults True if showing rejected results; otherwise
|
||||
* false.
|
||||
*/
|
||||
public void setShowRejectedResults(boolean showRejectedResults) {
|
||||
this.showRejectedResults = showRejectedResults;
|
||||
if (accounts != null) {
|
||||
accounts.setShowRejected(showRejectedResults);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
@ -191,60 +233,57 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
viewPreferencesPopupMenu = new javax.swing.JPopupMenu();
|
||||
treeView = new BeanTreeView();
|
||||
backButton = new javax.swing.JButton();
|
||||
forwardButton = new javax.swing.JButton();
|
||||
showRejectedCheckBox = new javax.swing.JCheckBox();
|
||||
groupByDatasourceCheckBox = new javax.swing.JCheckBox();
|
||||
showOnlyCurrentUserTagsCheckbox = new javax.swing.JCheckBox();
|
||||
openViewPreferencesButton = new javax.swing.JButton();
|
||||
|
||||
treeView.setBorder(null);
|
||||
|
||||
backButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_back_large.png"))); // NOI18N
|
||||
backButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_back.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(backButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.backButton.text")); // NOI18N
|
||||
backButton.setBorderPainted(false);
|
||||
backButton.setContentAreaFilled(false);
|
||||
backButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_back_disabled_large.png"))); // NOI18N
|
||||
backButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_back_disabled.png"))); // NOI18N
|
||||
backButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
backButton.setMaximumSize(new java.awt.Dimension(55, 100));
|
||||
backButton.setMinimumSize(new java.awt.Dimension(5, 5));
|
||||
backButton.setPreferredSize(new java.awt.Dimension(32, 32));
|
||||
backButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_back_hover_large.png"))); // NOI18N
|
||||
backButton.setPreferredSize(new java.awt.Dimension(24, 24));
|
||||
backButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_back_hover.png"))); // NOI18N
|
||||
backButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
backButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
forwardButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_forward_large.png"))); // NOI18N
|
||||
forwardButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_forward.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(forwardButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.forwardButton.text")); // NOI18N
|
||||
forwardButton.setBorderPainted(false);
|
||||
forwardButton.setContentAreaFilled(false);
|
||||
forwardButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_forward_disabled_large.png"))); // NOI18N
|
||||
forwardButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_forward_disabled.png"))); // NOI18N
|
||||
forwardButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
forwardButton.setMaximumSize(new java.awt.Dimension(55, 100));
|
||||
forwardButton.setMinimumSize(new java.awt.Dimension(5, 5));
|
||||
forwardButton.setPreferredSize(new java.awt.Dimension(32, 32));
|
||||
forwardButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_forward_hover_large.png"))); // NOI18N
|
||||
forwardButton.setPreferredSize(new java.awt.Dimension(24, 24));
|
||||
forwardButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/btn_step_forward_hover.png"))); // NOI18N
|
||||
forwardButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
forwardButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(showRejectedCheckBox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.showRejectedCheckBox.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(groupByDatasourceCheckBox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.groupByDatasourceCheckBox.text")); // NOI18N
|
||||
groupByDatasourceCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
openViewPreferencesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/view-preferences-23.png"))); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(openViewPreferencesButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.openViewPreferencesButton.text")); // NOI18N
|
||||
openViewPreferencesButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
openViewPreferencesButton.setBorderPainted(false);
|
||||
openViewPreferencesButton.setContentAreaFilled(false);
|
||||
openViewPreferencesButton.setMaximumSize(new java.awt.Dimension(24, 24));
|
||||
openViewPreferencesButton.setMinimumSize(new java.awt.Dimension(24, 24));
|
||||
openViewPreferencesButton.setPreferredSize(new java.awt.Dimension(24, 24));
|
||||
openViewPreferencesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
groupByDatasourceCheckBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(showOnlyCurrentUserTagsCheckbox, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.showOnlyCurrentUserTagsCheckbox.text")); // NOI18N
|
||||
showOnlyCurrentUserTagsCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
showOnlyCurrentUserTagsCheckboxActionPerformed(evt);
|
||||
openViewPreferencesButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@ -254,36 +293,24 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(treeView)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(showOnlyCurrentUserTagsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(showRejectedCheckBox)
|
||||
.addComponent(groupByDatasourceCheckBox))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 140, Short.MAX_VALUE)
|
||||
.addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 0, 0)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(5, 5, 5)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(showRejectedCheckBox)
|
||||
.addComponent(showOnlyCurrentUserTagsCheckbox))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(groupByDatasourceCheckBox))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(forwardButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||
.addComponent(openViewPreferencesButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 843, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0))
|
||||
.addComponent(treeView, javax.swing.GroupLayout.DEFAULT_SIZE, 919, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -336,21 +363,17 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
this.setCursor(null);
|
||||
}//GEN-LAST:event_forwardButtonActionPerformed
|
||||
|
||||
private void groupByDatasourceCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_groupByDatasourceCheckBoxActionPerformed
|
||||
UserPreferences.setGroupItemsInTreeByDatasource(this.groupByDatasourceCheckBox.isSelected());
|
||||
}//GEN-LAST:event_groupByDatasourceCheckBoxActionPerformed
|
||||
|
||||
private void showOnlyCurrentUserTagsCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showOnlyCurrentUserTagsCheckboxActionPerformed
|
||||
UserPreferences.setShowOnlyCurrentUserTags(this.showOnlyCurrentUserTagsCheckbox.isSelected());
|
||||
}//GEN-LAST:event_showOnlyCurrentUserTagsCheckboxActionPerformed
|
||||
private void openViewPreferencesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openViewPreferencesButtonActionPerformed
|
||||
viewPreferencesPanel.load();
|
||||
viewPreferencesPopupMenu.show(openViewPreferencesButton, 0, openViewPreferencesButton.getHeight() - 1);
|
||||
}//GEN-LAST:event_openViewPreferencesButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton backButton;
|
||||
private javax.swing.JButton forwardButton;
|
||||
private javax.swing.JCheckBox groupByDatasourceCheckBox;
|
||||
private javax.swing.JCheckBox showOnlyCurrentUserTagsCheckbox;
|
||||
private javax.swing.JCheckBox showRejectedCheckBox;
|
||||
private javax.swing.JButton openViewPreferencesButton;
|
||||
private javax.swing.JScrollPane treeView;
|
||||
private javax.swing.JPopupMenu viewPreferencesPopupMenu;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
@ -406,43 +429,17 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
* Ask the user if they want to group by data source when opening a large
|
||||
* case.
|
||||
*
|
||||
* @param currentCase
|
||||
* @param dataSourceCount
|
||||
* @param dataSourceCount The number of data sources in the case.
|
||||
*/
|
||||
private void promptForDataSourceGrouping(Case currentCase, int dataSourceCount) {
|
||||
Path settingsFile = Paths.get(currentCase.getConfigDirectory(), SETTINGS_FILE); //NON-NLS
|
||||
if (settingsFile.toFile().exists()) {
|
||||
// Read the setting
|
||||
try (InputStream inputStream = Files.newInputStream(settingsFile)) {
|
||||
Properties props = new Properties();
|
||||
props.load(inputStream);
|
||||
if (props.getProperty("groupByDataSource", "false").equals("true")) {
|
||||
UserPreferences.setGroupItemsInTreeByDatasource(true);
|
||||
groupByDatasourceCheckBox.setSelected(true);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error reading settings file", ex);
|
||||
}
|
||||
} else {
|
||||
private void promptForDataSourceGrouping(int dataSourceCount) {
|
||||
if (CasePreferences.getGroupItemsInTreeByDataSource() == null) {
|
||||
GroupDataSourcesDialog dialog = new GroupDataSourcesDialog(dataSourceCount);
|
||||
dialog.display();
|
||||
if (dialog.groupByDataSourceSelected()) {
|
||||
UserPreferences.setGroupItemsInTreeByDatasource(true);
|
||||
groupByDatasourceCheckBox.setSelected(true);
|
||||
}
|
||||
|
||||
// Save the response
|
||||
Properties props = new Properties();
|
||||
if (dialog.groupByDataSourceSelected()) {
|
||||
props.setProperty("groupByDataSource", "true");
|
||||
CasePreferences.setGroupItemsInTreeByDataSource(true);
|
||||
refreshContentTreeSafe();
|
||||
} else {
|
||||
props.setProperty("groupByDataSource", "false");
|
||||
}
|
||||
|
||||
try (OutputStream fos = Files.newOutputStream(settingsFile)) {
|
||||
props.store(fos, ""); //NON-NLS
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error writing settings file", ex);
|
||||
CasePreferences.setGroupItemsInTreeByDataSource(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -488,9 +485,9 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
|
||||
try {
|
||||
int dataSourceCount = currentCase.getDataSources().size();
|
||||
if (!UserPreferences.groupItemsInTreeByDatasource()
|
||||
if (!Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)
|
||||
&& dataSourceCount > threshold) {
|
||||
promptForDataSourceGrouping(currentCase, dataSourceCount);
|
||||
promptForDataSourceGrouping(dataSourceCount);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error loading data sources", ex);
|
||||
@ -545,11 +542,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
Children resultsChildren = results.getChildren();
|
||||
Arrays.stream(resultsChildren.getNodes()).forEach(tree::expandNode);
|
||||
|
||||
Accounts accounts = resultsChildren.findChild(Accounts.NAME).getLookup().lookup(Accounts.class);
|
||||
if (!Objects.isNull(accounts)) {
|
||||
showRejectedCheckBox.setAction(accounts.newToggleShowRejectedAction());
|
||||
showRejectedCheckBox.setSelected(false);
|
||||
}
|
||||
accounts = resultsChildren.findChild(Accounts.NAME).getLookup().lookup(Accounts.class);
|
||||
}
|
||||
|
||||
Node views = rootChildren.findChild(ViewsNode.NAME);
|
||||
@ -917,8 +910,12 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
*/
|
||||
private void refreshTagsTree() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// if no open case or has no data then there is no tree to rebuild
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) {
|
||||
// Ensure the component children have been created first.
|
||||
if (autopsyTreeChildren == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||
for (Node dataSource : autopsyTreeChildren.getNodes()) {
|
||||
Node tagsNode = dataSource.getChildren().findChild(Tags.getTagsDisplayName());
|
||||
if (tagsNode != null) {
|
||||
|
@ -34,7 +34,7 @@ import org.openide.util.Lookup;
|
||||
iconBase = "org/sleuthkit/autopsy/directorytree/external-viewer-rules-32x32.png",
|
||||
keywords = "#OptionsCategory_Keywords_ExternalViewer",
|
||||
keywordsCategory = "ExternalViewer",
|
||||
position = 12
|
||||
position = 13
|
||||
)
|
||||
public final class ExternalViewerOptionsPanelController extends OptionsPanelController {
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2017 Basis Technology Corp.
|
||||
* Copyright 2011-2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -35,6 +35,7 @@ import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
@ -138,9 +139,8 @@ public class ViewContextAction extends AbstractAction {
|
||||
*/
|
||||
DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance();
|
||||
ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager();
|
||||
|
||||
Node parentTreeViewNode;
|
||||
if (UserPreferences.groupItemsInTreeByDatasource()) { // 'Group by Data Source' view
|
||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { // 'Group by Data Source' view
|
||||
|
||||
SleuthkitCase skCase;
|
||||
String dsname;
|
||||
@ -162,7 +162,7 @@ public class ViewContextAction extends AbstractAction {
|
||||
logger.log(Level.SEVERE, "Failed to locate data source node in tree."); //NON-NLS
|
||||
return;
|
||||
}
|
||||
} catch (NoCurrentCaseException| TskDataException | TskCoreException ex) {
|
||||
} catch (NoCurrentCaseException | TskDataException | TskCoreException ex) {
|
||||
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotFindNode());
|
||||
logger.log(Level.SEVERE, "Failed to locate data source node in tree.", ex); //NON-NLS
|
||||
return;
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 611 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 761 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 756 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 639 B |