mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-02 07:19:53 +00:00
Fixed merge conflicts with 3275_OpenMultiUserCaseWaitCursor.
This commit is contained in:
@@ -7,6 +7,7 @@ file.reference.jdom-2.0.5-contrib.jar=release/modules/ext/jdom-2.0.5-contrib.jar
|
||||
file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar
|
||||
file.reference.jsoup-1.10.3.jar=release/modules/ext/jsoup-1.10.3.jar
|
||||
file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar
|
||||
file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar
|
||||
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
|
||||
file.reference.metadata-extractor-2.9.1.jar=release/modules/ext/metadata-extractor-2.9.1.jar
|
||||
file.reference.postgresql-9.4.1211.jre7.jar=release/modules/ext/postgresql-9.4.1211.jre7.jar
|
||||
@@ -26,10 +27,12 @@ file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8
|
||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javadoc.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar
|
||||
license.file=../LICENSE-2.0.txt
|
||||
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
|
||||
source.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar
|
||||
spec.version.base=10.9
|
||||
|
||||
|
||||
@@ -336,6 +336,10 @@
|
||||
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/LGoodDatePicker-10.3.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/LGoodDatePicker-10.3.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/Tsk_DataModel_PostgreSQL.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/Tsk_DataModel_PostgreSQL.jar</binary-origin>
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.logging.Level;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.RootPaneContainer;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
@@ -56,13 +57,15 @@ import org.sleuthkit.datamodel.Image;
|
||||
*/
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.AddImageAction")
|
||||
@ActionRegistration(displayName = "#CTL_AddImage", lazy = false)
|
||||
@ActionReferences(value = {@ActionReference(path = "Toolbars/Case", position = 100)})
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Toolbars/Case", position = 100)})
|
||||
@ServiceProvider(service = AddImageAction.class)
|
||||
public final class AddImageAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Dimension SIZE = new Dimension(875, 550);
|
||||
private final ChangeSupport cleanupSupport = new ChangeSupport(this);
|
||||
// private final static MouseAdapter mouseDisabler = new MouseAdapter() {};
|
||||
|
||||
// Keys into the WizardDescriptor properties that pass information between stages of the wizard
|
||||
// <TYPE>: <DESCRIPTION>
|
||||
@@ -116,6 +119,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
||||
String optionsDlgTitle = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.title");
|
||||
String optionsDlgMessage = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg");
|
||||
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
|
||||
RootPaneContainer root = (RootPaneContainer) WindowManager.getDefault().getMainWindow();
|
||||
root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
root.getGlassPane().setVisible(true);
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
iterator = new AddImageWizardIterator(this);
|
||||
wizardDescriptor = new WizardDescriptor(iterator);
|
||||
@@ -129,7 +135,8 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
||||
dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
|
||||
Dimension d = dialog.getSize();
|
||||
dialog.setSize(SIZE);
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
root.getGlassPane().setVisible(false);
|
||||
dialog.setVisible(true);
|
||||
dialog.toFront();
|
||||
|
||||
|
||||
@@ -158,11 +158,15 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (UserPreferences.getIsMultiUserModeEnabled()) {
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
|
||||
if (multiUserCaseWindow == null) {
|
||||
multiUserCaseWindow = MultiUserCasesDialog.getInstance();
|
||||
}
|
||||
multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
|
||||
multiUserCaseWindow.setVisible(true);
|
||||
|
||||
WindowManager.getDefault().getMainWindow().setCursor(null);
|
||||
} else {
|
||||
openCaseSelectionWindow();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -239,7 +240,9 @@ public class CueBannerPanel extends javax.swing.JPanel {
|
||||
}//GEN-LAST:event_newCaseButtonActionPerformed
|
||||
|
||||
private void openCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openCaseButtonActionPerformed
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
Lookup.getDefault().lookup(CaseOpenAction.class).actionPerformed(evt);
|
||||
setCursor(null);
|
||||
}//GEN-LAST:event_openCaseButtonActionPerformed
|
||||
|
||||
private void openRecentCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRecentCaseButtonActionPerformed
|
||||
|
||||
@@ -179,7 +179,7 @@ final class TagNameDefinition implements Comparable<TagNameDefinition> {
|
||||
return displayName + "," + description + "," + color.name() + "," + knownStatus.toString();
|
||||
}
|
||||
|
||||
private TagName saveToCase(SleuthkitCase caseDb) {
|
||||
TagName saveToCase(SleuthkitCase caseDb) {
|
||||
TagName tagName = null;
|
||||
try {
|
||||
tagName = caseDb.addOrUpdateTagName(displayName, description, color, knownStatus);
|
||||
|
||||
@@ -128,6 +128,9 @@ public class TagsManager implements Closeable {
|
||||
*/
|
||||
TagsManager(SleuthkitCase caseDb) {
|
||||
this.caseDb = caseDb;
|
||||
for (TagNameDefinition tagName : TagNameDefinition.getTagNameDefinitions()) {
|
||||
tagName.saveToCase(caseDb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-31
@@ -433,36 +433,6 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global file instances matching the given eamArtifact and convert
|
||||
* them to central repository artifact instances.
|
||||
*
|
||||
* @param eamArtifact Artifact to use for ArtifactTypeEnum matching
|
||||
*
|
||||
* @return List of central repository artifact instances, empty list if none
|
||||
* found
|
||||
*/
|
||||
public Collection<CorrelationAttributeInstance> getReferenceInstancesAsArtifactInstances(CorrelationAttribute eamArtifact) {
|
||||
Collection<CorrelationAttributeInstance> eamArtifactInstances = new ArrayList<>();
|
||||
// FUTURE: support other reference types
|
||||
if (eamArtifact.getCorrelationType().getId() != CorrelationAttribute.FILES_TYPE_ID) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
Collection<EamGlobalFileInstance> eamGlobalFileInstances = dbManager.getReferenceInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
|
||||
eamGlobalFileInstances.forEach((eamGlobalFileInstance) -> {
|
||||
eamArtifactInstances.add(new CorrelationAttributeInstance(
|
||||
null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus(), CorrelationAttributeInstance.GlobalStatus.GLOBAL
|
||||
));
|
||||
});
|
||||
return eamArtifactInstances;
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error getting reference instances from database.", ex); // NON-NLS
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Node node) {
|
||||
if (!EamDb.isEnabled()) {
|
||||
@@ -517,7 +487,6 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
|
||||
|
||||
// get correlation and reference set instances from DB
|
||||
corAttrInstances.addAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
|
||||
corAttrInstances.addAll(getReferenceInstancesAsArtifactInstances(corAttr));
|
||||
|
||||
corAttrInstances.forEach((corAttrInstance) -> {
|
||||
CorrelationAttribute newCeArtifact = new CorrelationAttribute(
|
||||
|
||||
+1
-6
@@ -36,8 +36,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
"DataContentViewerOtherCasesTableModel.path=Path",
|
||||
"DataContentViewerOtherCasesTableModel.type=Correlation Type",
|
||||
"DataContentViewerOtherCasesTableModel.value=Correlation Value",
|
||||
"DataContentViewerOtherCasesTableModel.scope=Scope",
|
||||
"DataContentViewerOtherCasesTableModel.known=Known",
|
||||
"DataContentViewerOtherCasesTableModel.known=Tagged",
|
||||
"DataContentViewerOtherCasesTableModel.comment=Comment",
|
||||
"DataContentViewerOtherCasesTableModel.noData=No Data.",})
|
||||
enum TableColumns {
|
||||
@@ -48,7 +47,6 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
TYPE(Bundle.DataContentViewerOtherCasesTableModel_type(), 100),
|
||||
VALUE(Bundle.DataContentViewerOtherCasesTableModel_value(), 200),
|
||||
KNOWN(Bundle.DataContentViewerOtherCasesTableModel_known(), 50),
|
||||
SCOPE(Bundle.DataContentViewerOtherCasesTableModel_scope(), 50),
|
||||
FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 450),
|
||||
COMMENT(Bundle.DataContentViewerOtherCasesTableModel_comment(), 200),
|
||||
DEVICE(Bundle.DataContentViewerOtherCasesTableModel_device(), 250);
|
||||
@@ -156,9 +154,6 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
|
||||
case VALUE:
|
||||
value = eamArtifact.getCorrelationValue();
|
||||
break;
|
||||
case SCOPE:
|
||||
value = eamArtifactInstance.getGlobalStatus().toString();
|
||||
break;
|
||||
case KNOWN:
|
||||
value = eamArtifactInstance.getKnownStatus().getName();
|
||||
break;
|
||||
|
||||
@@ -34,9 +34,12 @@ import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil.updateSchemaVersion;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
@@ -77,7 +80,7 @@ public 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
|
||||
@@ -140,7 +143,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
/**
|
||||
* 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
|
||||
@@ -226,7 +229,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
EamDbUtil.closePreparedStatement(preparedStatement);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
|
||||
|
||||
// get a new version with the updated ID
|
||||
return getCaseByUUID(eamCase.getCaseUUID());
|
||||
}
|
||||
@@ -255,12 +258,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
autopsyCase.getCaseNotes());
|
||||
return newCase(curCeCase);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CorrelationCase getCase(Case autopsyCase) throws EamDbException {
|
||||
return getCaseByUUID(autopsyCase.getName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates an existing Case in the database
|
||||
@@ -434,8 +436,8 @@ public 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
|
||||
@@ -608,7 +610,7 @@ public 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
|
||||
@@ -664,7 +666,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @param value The correlation value
|
||||
*
|
||||
* @return Number of artifact instances having ArtifactType and
|
||||
* ArtifactValue.
|
||||
* ArtifactValue.
|
||||
*/
|
||||
@Override
|
||||
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
|
||||
@@ -779,11 +781,11 @@ public 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 {
|
||||
@@ -999,12 +1001,14 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an eamArtifact instance to the given knownStatus. If eamArtifact
|
||||
* Sets an eamArtifact instance to the given knownStatus.
|
||||
* knownStatus should be BAD if the file has been tagged with a notable tag and
|
||||
* UNKNOWN otherwise. If eamArtifact
|
||||
* exists, it is updated. If eamArtifact does not exist it is added with the
|
||||
* given status.
|
||||
*
|
||||
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
|
||||
* @param knownStatus The status to change the artifact to
|
||||
* @param knownStatus The status to change the artifact to. Should never be KNOWN
|
||||
*/
|
||||
@Override
|
||||
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
@@ -1070,7 +1074,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
if (null == correlationCaseWithId) {
|
||||
correlationCaseWithId = newCase(eamInstance.getCorrelationCase());
|
||||
}
|
||||
|
||||
|
||||
if (null == getDataSource(correlationCaseWithId, eamInstance.getCorrelationDataSource().getDeviceID())) {
|
||||
newDataSource(eamInstance.getCorrelationDataSource());
|
||||
}
|
||||
@@ -1187,7 +1191,7 @@ public 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
|
||||
*/
|
||||
@@ -1230,24 +1234,26 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
|
||||
return caseNames.stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a reference set and all entries contained in it.
|
||||
*
|
||||
* @param referenceSetID
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void deleteReferenceSet(int referenceSetID) throws EamDbException{
|
||||
public void deleteReferenceSet(int referenceSetID) throws EamDbException {
|
||||
deleteReferenceSetEntries(referenceSetID);
|
||||
deleteReferenceSetEntry(referenceSetID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the entry for this set from the reference_sets table
|
||||
*
|
||||
* @param referenceSetID
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
private void deleteReferenceSetEntry(int referenceSetID) throws EamDbException{
|
||||
private void deleteReferenceSetEntry(int referenceSetID) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
@@ -1262,21 +1268,22 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
} finally {
|
||||
EamDbUtil.closePreparedStatement(preparedStatement);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove all entries for this reference set from the reference tables
|
||||
* (Currently only removes entries from the reference_file table)
|
||||
*
|
||||
* @param referenceSetID
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
private void deleteReferenceSetEntries(int referenceSetID) throws EamDbException{
|
||||
private void deleteReferenceSetEntries(int referenceSetID) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement = null;
|
||||
String sql = "DELETE FROM %s WHERE reference_set_id=?";
|
||||
|
||||
|
||||
// When other reference types are added, this will need to loop over all the tables
|
||||
String fileTableName = EamDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID));
|
||||
|
||||
@@ -1289,12 +1296,14 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
} finally {
|
||||
EamDbUtil.closePreparedStatement(preparedStatement);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a reference set with the given parameters exists in the central repository.
|
||||
* Used to check whether reference sets saved in the settings are still present.
|
||||
* Check whether a reference set with the given parameters exists in the
|
||||
* central repository. Used to check whether reference sets saved in the
|
||||
* settings are still present.
|
||||
*
|
||||
* @param referenceSetID
|
||||
* @param setName
|
||||
* @param version
|
||||
@@ -1302,37 +1311,39 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException{
|
||||
public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException {
|
||||
EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
|
||||
if(refSet == null){
|
||||
if (refSet == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return(refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
|
||||
|
||||
return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given file hash is in this reference set.
|
||||
* Only searches the reference_files table.
|
||||
* Check if the given file hash is in this reference set. Only searches the
|
||||
* reference_files table.
|
||||
*
|
||||
* @param hash
|
||||
* @param referenceSetID
|
||||
* @return true if the hash is found in the reference set
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException{
|
||||
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException {
|
||||
return isValueInReferenceSet(hash, referenceSetID, CorrelationAttribute.FILES_TYPE_ID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given value is in a specific reference set
|
||||
*
|
||||
* @param value
|
||||
* @param referenceSetID
|
||||
* @param correlationTypeID
|
||||
* @param correlationTypeID
|
||||
* @return true if the value is found in the reference set
|
||||
*/
|
||||
@Override
|
||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException{
|
||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException {
|
||||
|
||||
Connection conn = connect();
|
||||
|
||||
@@ -1340,7 +1351,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql = "SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
|
||||
|
||||
|
||||
String fileTableName = EamDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
|
||||
|
||||
try {
|
||||
@@ -1506,15 +1517,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the organization associated with the given reference set.
|
||||
*
|
||||
* @param referenceSetID ID of the reference set
|
||||
* @return The organization object
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException{
|
||||
public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException {
|
||||
|
||||
EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
|
||||
return (getOrganizationByID(globalSet.getOrgID()));
|
||||
@@ -1524,7 +1536,7 @@ public 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
|
||||
*/
|
||||
@@ -1550,8 +1562,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
}
|
||||
|
||||
@Messages({"AbstractSqlEamDb.deleteOrganization.inUseException.message=Can not delete organization "
|
||||
+ "which is currently in use by a case or reference set in the central repository.",
|
||||
"AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
|
||||
+ "which is currently in use by a case or reference set in the central repository.",
|
||||
"AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
|
||||
@Override
|
||||
public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
@@ -1598,7 +1610,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
PreparedStatement preparedStatement1 = null;
|
||||
PreparedStatement preparedStatement2 = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, import_date) VALUES (?, ?, ?, ?, ?, ?)";
|
||||
String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
|
||||
|
||||
try {
|
||||
@@ -1608,7 +1620,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
preparedStatement1.setString(3, eamGlobalSet.getVersion());
|
||||
preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
|
||||
preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
|
||||
preparedStatement1.setString(6, eamGlobalSet.getImportDate().toString());
|
||||
preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
|
||||
preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
|
||||
|
||||
preparedStatement1.executeUpdate();
|
||||
|
||||
@@ -1664,22 +1677,24 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all reference sets
|
||||
*
|
||||
* @param correlationType Type of sets to return
|
||||
*
|
||||
* @return List of all reference sets in the central repository
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamGlobalSet> getAllReferenceSets() throws EamDbException{
|
||||
public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
|
||||
List<EamGlobalSet> results = new ArrayList<>();
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement1 = null;
|
||||
ResultSet resultSet = null;
|
||||
String sql1 = "SELECT * FROM reference_sets";
|
||||
String sql1 = "SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
|
||||
|
||||
try {
|
||||
preparedStatement1 = conn.prepareStatement(sql1);
|
||||
@@ -1702,8 +1717,7 @@ public 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
|
||||
*/
|
||||
@@ -1729,17 +1743,19 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a reference set with the given name/version is in the central repo.
|
||||
* Used to check for name collisions when creating reference sets.
|
||||
* Check whether a reference set with the given name/version is in the
|
||||
* central repo. Used to check for name collisions when creating reference
|
||||
* sets.
|
||||
*
|
||||
* @param referenceSetName
|
||||
* @param version
|
||||
* @return true if a matching set is found
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException{
|
||||
public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException {
|
||||
Connection conn = connect();
|
||||
|
||||
PreparedStatement preparedStatement1 = null;
|
||||
@@ -1754,13 +1770,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return (resultSet.next());
|
||||
|
||||
} catch (SQLException ex) {
|
||||
throw new EamDbException("Error testing whether reference set exists (name: " + referenceSetName
|
||||
throw new EamDbException("Error testing whether reference set exists (name: " + referenceSetName
|
||||
+ " version: " + version, ex); // NON-NLS
|
||||
} finally {
|
||||
EamDbUtil.closePreparedStatement(preparedStatement1);
|
||||
EamDbUtil.closeResultSet(resultSet);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1808,7 +1824,7 @@ public 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
|
||||
@@ -1938,7 +1954,7 @@ public 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
|
||||
*/
|
||||
@@ -1973,7 +1989,7 @@ public 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
|
||||
*/
|
||||
@@ -2074,7 +2090,7 @@ public 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
|
||||
*
|
||||
@@ -2144,7 +2160,7 @@ public 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
|
||||
*
|
||||
@@ -2159,8 +2175,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")),
|
||||
resultSet.getString("file_path"),
|
||||
resultSet.getString("comment"),
|
||||
TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
TskData.FileKnown.valueOf(resultSet.getByte("known_status"))
|
||||
);
|
||||
|
||||
return eamArtifactInstance;
|
||||
@@ -2182,7 +2197,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return eamOrganization;
|
||||
}
|
||||
|
||||
private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) throws SQLException {
|
||||
private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
|
||||
if (null == resultSet) {
|
||||
return null;
|
||||
}
|
||||
@@ -2194,6 +2209,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
resultSet.getString("version"),
|
||||
TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
|
||||
resultSet.getBoolean("read_only"),
|
||||
EamDb.getInstance().getCorrelationTypeById(resultSet.getInt("type")),
|
||||
LocalDate.parse(resultSet.getString("import_date"))
|
||||
);
|
||||
|
||||
@@ -2216,4 +2232,82 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
||||
return eamGlobalFileInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the schema of the database (if needed)
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void upgradeSchema() throws EamDbException, SQLException {
|
||||
|
||||
ResultSet resultSet = null;
|
||||
Statement statement;
|
||||
Connection conn = null;
|
||||
try {
|
||||
|
||||
conn = connect();
|
||||
conn.setAutoCommit(false);
|
||||
statement = conn.createStatement();
|
||||
|
||||
int minorVersion = 0;
|
||||
int majorVersion = 0;
|
||||
resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'");
|
||||
if (resultSet.next()) {
|
||||
String minorVersionStr = resultSet.getString("value");
|
||||
try {
|
||||
minorVersion = Integer.parseInt(minorVersionStr);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new EamDbException("Bad value for schema minor version (" + minorVersionStr + ") - database is corrupt");
|
||||
}
|
||||
}
|
||||
|
||||
resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_VERSION'");
|
||||
if (resultSet.next()) {
|
||||
String majorVersionStr = resultSet.getString("value");
|
||||
try {
|
||||
majorVersion = Integer.parseInt(majorVersionStr);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new EamDbException("Bad value for schema version (" + majorVersionStr + ") - database is corrupt");
|
||||
}
|
||||
}
|
||||
|
||||
CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
|
||||
if (dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)) {
|
||||
LOGGER.log(Level.INFO, "Central Repository is up to date");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update from 1.0 to 1.1
|
||||
if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0) {
|
||||
statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS
|
||||
statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS
|
||||
statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS
|
||||
|
||||
// There's an outide chance that the user has already made an organization with the default name,
|
||||
// and the default org being missing will not impact any database operations, so continue on
|
||||
// regardless of whether this succeeds.
|
||||
EamDbUtil.insertDefaultOrganization(conn);
|
||||
}
|
||||
|
||||
if (!updateSchemaVersion(conn)) {
|
||||
throw new EamDbException("Error updating schema version");
|
||||
}
|
||||
|
||||
conn.commit();
|
||||
LOGGER.log(Level.INFO, "Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION);
|
||||
} catch (SQLException | EamDbException ex) {
|
||||
try {
|
||||
if (conn != null) {
|
||||
conn.rollback();
|
||||
}
|
||||
} catch (SQLException ex2) {
|
||||
LOGGER.log(Level.SEVERE, "Database rollback failed", ex2);
|
||||
}
|
||||
throw ex;
|
||||
} finally {
|
||||
EamDbUtil.closeResultSet(resultSet);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-48
@@ -28,29 +28,12 @@ import org.sleuthkit.datamodel.TskData;
|
||||
* CorrelationAttribute. Includes its data source, path, etc.
|
||||
*
|
||||
*/
|
||||
@Messages({"EamArtifactInstances.globalStatus.local=Local",
|
||||
"EamArtifactInstances.globalStatus.global=Global",
|
||||
@Messages({
|
||||
"EamArtifactInstances.knownStatus.bad=Bad",
|
||||
"EamArtifactInstances.knownStatus.known=Known",
|
||||
"EamArtifactInstances.knownStatus.unknown=Unknown"})
|
||||
public class CorrelationAttributeInstance implements Serializable {
|
||||
|
||||
public enum GlobalStatus {
|
||||
LOCAL(Bundle.EamArtifactInstances_globalStatus_local()),
|
||||
GLOBAL(Bundle.EamArtifactInstances_globalStatus_global());
|
||||
|
||||
private final String globalStatus;
|
||||
|
||||
private GlobalStatus(String globalStatus) {
|
||||
this.globalStatus = globalStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return globalStatus;
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int ID;
|
||||
@@ -59,13 +42,12 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
private String filePath;
|
||||
private String comment;
|
||||
private TskData.FileKnown knownStatus;
|
||||
private GlobalStatus globalStatus;
|
||||
|
||||
public CorrelationAttributeInstance(
|
||||
CorrelationCase eamCase,
|
||||
CorrelationDataSource eamDataSource
|
||||
) {
|
||||
this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
|
||||
this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN);
|
||||
}
|
||||
|
||||
public CorrelationAttributeInstance(
|
||||
@@ -73,7 +55,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath
|
||||
) {
|
||||
this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
|
||||
this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN);
|
||||
}
|
||||
|
||||
public CorrelationAttributeInstance(
|
||||
@@ -82,7 +64,7 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
String filePath,
|
||||
String comment
|
||||
) {
|
||||
this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL);
|
||||
this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN);
|
||||
}
|
||||
|
||||
public CorrelationAttributeInstance(
|
||||
@@ -90,20 +72,18 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath,
|
||||
String comment,
|
||||
TskData.FileKnown knownStatus,
|
||||
GlobalStatus globalStatus
|
||||
TskData.FileKnown knownStatus
|
||||
) {
|
||||
this(-1, eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus);
|
||||
this(-1, eamCase, eamDataSource, filePath, comment, knownStatus);
|
||||
}
|
||||
|
||||
public CorrelationAttributeInstance(
|
||||
CorrelationAttributeInstance(
|
||||
int ID,
|
||||
CorrelationCase eamCase,
|
||||
CorrelationDataSource eamDataSource,
|
||||
String filePath,
|
||||
String comment,
|
||||
TskData.FileKnown knownStatus,
|
||||
GlobalStatus globalStatus
|
||||
TskData.FileKnown knownStatus
|
||||
) {
|
||||
this.ID = ID;
|
||||
this.correlationCase = eamCase;
|
||||
@@ -112,7 +92,6 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
this.filePath = filePath.toLowerCase();
|
||||
this.comment = comment;
|
||||
this.knownStatus = knownStatus;
|
||||
this.globalStatus = globalStatus;
|
||||
}
|
||||
|
||||
public Boolean equals(CorrelationAttributeInstance otherInstance) {
|
||||
@@ -120,7 +99,6 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
&& (this.getCorrelationCase().equals(otherInstance.getCorrelationCase()))
|
||||
&& (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource()))
|
||||
&& (this.getFilePath().equals(otherInstance.getFilePath()))
|
||||
&& (this.getGlobalStatus().equals(otherInstance.getGlobalStatus()))
|
||||
&& (this.getKnownStatus().equals(otherInstance.getKnownStatus()))
|
||||
&& (this.getComment().equals(otherInstance.getComment())));
|
||||
}
|
||||
@@ -131,7 +109,6 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
+ this.getCorrelationCase().getCaseUUID()
|
||||
+ this.getCorrelationDataSource().getName()
|
||||
+ this.getFilePath()
|
||||
+ this.getGlobalStatus()
|
||||
+ this.getKnownStatus()
|
||||
+ this.getComment();
|
||||
}
|
||||
@@ -179,31 +156,22 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the knownStatus
|
||||
* Get this knownStatus. This only indicates whether an item has been
|
||||
* tagged as notable and should never return KNOWN.
|
||||
*
|
||||
* @return BAD if the item has been tagged as notable, UNKNOWN otherwise
|
||||
*/
|
||||
public TskData.FileKnown getKnownStatus() {
|
||||
return knownStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param knownStatus the knownStatus to set
|
||||
* Set the knownStatus. This only indicates whether an item has been
|
||||
* tagged as notable and should never be set to KNOWN.
|
||||
*
|
||||
* @param knownStatus Should be BAD if the item is tagged as notable, UNKNOWN otherwise
|
||||
*/
|
||||
public void setKnownStatus(TskData.FileKnown knownStatus) {
|
||||
this.knownStatus = knownStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the globalStatus
|
||||
*/
|
||||
public GlobalStatus getGlobalStatus() {
|
||||
return globalStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param globalStatus the globalStatus to set
|
||||
*/
|
||||
public void setGlobalStatus(GlobalStatus globalStatus) {
|
||||
this.globalStatus = globalStatus;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.HashUtility;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
@@ -105,8 +106,7 @@ public class EamArtifactUtil {
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, bbSourceFile.getDataSource()),
|
||||
bbSourceFile.getParentPath() + bbSourceFile.getName(),
|
||||
"",
|
||||
TskData.FileKnown.UNKNOWN,
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
TskData.FileKnown.UNKNOWN
|
||||
);
|
||||
|
||||
// add the instance details
|
||||
@@ -227,7 +227,7 @@ public class EamArtifactUtil {
|
||||
*
|
||||
* @return The new EamArtifact or null if creation failed
|
||||
*/
|
||||
public static CorrelationAttribute getEamArtifactFromContent(Content content, TskData.FileKnown knownStatus, String comment) {
|
||||
public static CorrelationAttribute getCorrelationAttributeFromContent(Content content, TskData.FileKnown knownStatus, String comment) {
|
||||
|
||||
if (!(content instanceof AbstractFile)) {
|
||||
return null;
|
||||
@@ -241,7 +241,7 @@ public class EamArtifactUtil {
|
||||
|
||||
// We need a hash to make the artifact
|
||||
String md5 = af.getMd5Hash();
|
||||
if (md5 == null || md5.isEmpty()) {
|
||||
if (md5 == null || md5.isEmpty() || HashUtility.isNoDataMd5(md5)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -258,8 +258,7 @@ public class EamArtifactUtil {
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, af.getDataSource()),
|
||||
af.getParentPath() + af.getName(),
|
||||
comment,
|
||||
TskData.FileKnown.BAD,
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
knownStatus
|
||||
);
|
||||
eamArtifact.addInstance(cei);
|
||||
return eamArtifact;
|
||||
|
||||
@@ -18,10 +18,13 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber;
|
||||
|
||||
/**
|
||||
* Main interface for interacting with the database
|
||||
@@ -29,6 +32,8 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
public interface EamDb {
|
||||
|
||||
public static final int SCHEMA_VERSION = 1;
|
||||
public static final CaseDbSchemaVersionNumber CURRENT_DB_SCHEMA_VERSION
|
||||
= new CaseDbSchemaVersionNumber(1, 1);
|
||||
|
||||
/**
|
||||
* Get the instance
|
||||
@@ -98,7 +103,7 @@ public interface 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
|
||||
@@ -119,7 +124,7 @@ public interface EamDb {
|
||||
/**
|
||||
* 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
|
||||
@@ -141,8 +146,6 @@ public interface EamDb {
|
||||
* @param autopsyCase The case to add
|
||||
*/
|
||||
CorrelationCase newCase(Case autopsyCase) throws EamDbException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates an existing Case in the database
|
||||
@@ -153,13 +156,13 @@ public interface EamDb {
|
||||
|
||||
/**
|
||||
* Retrieves Central Repo case based on an Autopsy Case
|
||||
*
|
||||
*
|
||||
* @param autopsyCase Autopsy case to find corresponding CR case for
|
||||
* @return CR Case
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
CorrelationCase getCase(Case autopsyCase) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves Case details based on Case UUID
|
||||
*
|
||||
@@ -186,8 +189,8 @@ public interface 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
|
||||
@@ -224,7 +227,7 @@ public interface 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
|
||||
@@ -241,7 +244,7 @@ public interface EamDb {
|
||||
* @param value Value to search for
|
||||
*
|
||||
* @return Number of artifact instances having ArtifactType and
|
||||
* ArtifactValue.
|
||||
* ArtifactValue.
|
||||
*/
|
||||
Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException;
|
||||
|
||||
@@ -278,11 +281,11 @@ public interface 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
|
||||
*/
|
||||
Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException;
|
||||
|
||||
@@ -344,7 +347,7 @@ public interface EamDb {
|
||||
* @param value Value to search for
|
||||
*
|
||||
* @return List of cases containing this artifact with instances marked as
|
||||
* bad
|
||||
* bad
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@@ -352,14 +355,17 @@ public interface EamDb {
|
||||
|
||||
/**
|
||||
* Remove a reference set and all values contained in it.
|
||||
*
|
||||
* @param referenceSetID
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public void deleteReferenceSet(int referenceSetID) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a reference set with the given parameters exists in the central repository.
|
||||
* Used to check whether reference sets saved in the settings are still present.
|
||||
* Check whether a reference set with the given parameters exists in the
|
||||
* central repository. Used to check whether reference sets saved in the
|
||||
* settings are still present.
|
||||
*
|
||||
* @param referenceSetID
|
||||
* @param referenceSetName
|
||||
* @param version
|
||||
@@ -367,36 +373,40 @@ public interface EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public boolean referenceSetIsValid(int referenceSetID, String referenceSetName, String version) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a reference set with the given name/version is in the central repo.
|
||||
* Used to check for name collisions when creating reference sets.
|
||||
* Check whether a reference set with the given name/version is in the
|
||||
* central repo. Used to check for name collisions when creating reference
|
||||
* sets.
|
||||
*
|
||||
* @param referenceSetName
|
||||
* @param version
|
||||
* @return true if a matching set is found
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given file hash is in this reference set.
|
||||
* Only searches the reference_files table.
|
||||
* Check if the given file hash is in this reference set. Only searches the
|
||||
* reference_files table.
|
||||
*
|
||||
* @param hash
|
||||
* @param referenceSetID
|
||||
* @return true if the hash is found in the reference set
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given value is in a specific reference set
|
||||
*
|
||||
* @param value
|
||||
* @param referenceSetID
|
||||
* @param correlationTypeID
|
||||
* @param correlationTypeID
|
||||
* @return true if the hash is found in the reference set
|
||||
*/
|
||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException;
|
||||
|
||||
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Is the artifact known as bad according to the reference entries?
|
||||
*
|
||||
@@ -413,7 +423,7 @@ public interface EamDb {
|
||||
* @param eamOrg The organization to add
|
||||
*
|
||||
* @return the Organization ID of the newly created organization.
|
||||
*
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
long newOrganization(EamOrganization eamOrg) throws EamDbException;
|
||||
@@ -440,9 +450,10 @@ public interface EamDb {
|
||||
|
||||
/**
|
||||
* Get the organization associated with the given reference set.
|
||||
*
|
||||
* @param referenceSetID ID of the reference set
|
||||
* @return The organization object
|
||||
* @throws EamDbException
|
||||
* @throws EamDbException
|
||||
*/
|
||||
EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException;
|
||||
|
||||
@@ -450,7 +461,7 @@ public interface 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
|
||||
*/
|
||||
@@ -458,13 +469,13 @@ public interface EamDb {
|
||||
|
||||
/**
|
||||
* Delete an organization if it is not being used by any case.
|
||||
*
|
||||
*
|
||||
* @param organizationToDelete the organization to be deleted
|
||||
*
|
||||
* @throws EamDbException
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Add a new Global Set
|
||||
*
|
||||
@@ -486,33 +497,34 @@ public interface EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
EamGlobalSet getReferenceSetByID(int globalSetID) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Get all reference sets
|
||||
*
|
||||
* @param correlationType Type of sets to return
|
||||
*
|
||||
* @return List of all reference sets in the central repository
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
List<EamGlobalSet> getAllReferenceSets() throws EamDbException;
|
||||
List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException;
|
||||
|
||||
|
||||
/**
|
||||
* Insert the bulk collection of Global File Instances
|
||||
*
|
||||
* @param globalInstances a Set of EamGlobalFileInstances to insert into the
|
||||
* db.
|
||||
* @param contentType the Type of the global instances
|
||||
* db.
|
||||
* @param contentType the Type of the global instances
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@@ -521,7 +533,7 @@ public interface 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
|
||||
@@ -546,7 +558,7 @@ public interface EamDb {
|
||||
* used to correlate artifacts.
|
||||
*
|
||||
* @return List of EamArtifact.Type's. If none are defined in the database,
|
||||
* the default list will be returned.
|
||||
* the default list will be returned.
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@@ -557,7 +569,7 @@ public interface 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
|
||||
*/
|
||||
@@ -568,7 +580,7 @@ public interface 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
|
||||
*/
|
||||
@@ -593,4 +605,23 @@ public interface EamDb {
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException;
|
||||
|
||||
/**
|
||||
* Upgrade the schema of the database (if needed)
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
public void upgradeSchema() throws EamDbException, SQLException;
|
||||
|
||||
/**
|
||||
* Gets an exclusive lock (if applicable). Will return the lock if
|
||||
* successful, null if unsuccessful because locking isn't supported, and
|
||||
* throw an exception if we should have been able to get the lock but failed
|
||||
* (meaning the database is in use).
|
||||
*
|
||||
* @return the lock, or null if locking is not supported
|
||||
* @throws EamDbException if the coordination service is running but we fail
|
||||
* to get the lock
|
||||
*/
|
||||
public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException;
|
||||
}
|
||||
|
||||
Executable → Regular
+84
-9
@@ -25,7 +25,9 @@ import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDb.SCHEMA_VERSION;
|
||||
import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDb.CURRENT_DB_SCHEMA_VERSION;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
|
||||
@@ -133,20 +135,33 @@ public class EamDbUtil {
|
||||
*
|
||||
* @return true on success, else false
|
||||
*/
|
||||
public static boolean insertSchemaVersion(Connection conn) {
|
||||
PreparedStatement preparedStatement = null;
|
||||
static boolean updateSchemaVersion(Connection conn) {
|
||||
|
||||
Statement statement;
|
||||
ResultSet resultSet;
|
||||
String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)";
|
||||
try {
|
||||
preparedStatement = conn.prepareStatement(sql);
|
||||
preparedStatement.setString(1, "SCHEMA_VERSION");
|
||||
preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION));
|
||||
preparedStatement.executeUpdate();
|
||||
statement = conn.createStatement();
|
||||
resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_VERSION'");
|
||||
if (resultSet.next()) {
|
||||
int id = resultSet.getInt("id");
|
||||
statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMajor() + " WHERE id=" + id);
|
||||
} else {
|
||||
statement.execute("INSERT INTO db_info (name, value) VALUES ('SCHEMA_VERSION', '" + CURRENT_DB_SCHEMA_VERSION.getMajor() + "')");
|
||||
}
|
||||
|
||||
resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_MINOR_VERSION'");
|
||||
if (resultSet.next()) {
|
||||
int id = resultSet.getInt("id");
|
||||
statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMinor() + " WHERE id=" + id);
|
||||
} else {
|
||||
statement.execute("INSERT INTO db_info (name, value) VALUES ('SCHEMA_MINOR_VERSION', '" + CURRENT_DB_SCHEMA_VERSION.getMinor() + "')");
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex);
|
||||
return false;
|
||||
} finally {
|
||||
EamDbUtil.closePreparedStatement(preparedStatement);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,6 +191,66 @@ public class EamDbUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the current central reposity to the newest version. If the upgrade
|
||||
* fails, the central repository will be disabled and the current settings
|
||||
* will be cleared.
|
||||
*
|
||||
* @return true if the upgrade succeeds, false otherwise.
|
||||
*/
|
||||
public static boolean upgradeDatabase() {
|
||||
if (!EamDb.isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CoordinationService.Lock lock = null;
|
||||
try {
|
||||
EamDb db = EamDb.getInstance();
|
||||
|
||||
// This may return null if locking isn't supported, which is fine. It will
|
||||
// throw an exception if locking is supported but we can't get the lock
|
||||
// (meaning the database is in use by another user)
|
||||
lock = db.getExclusiveMultiUserDbLock();
|
||||
|
||||
db.upgradeSchema();
|
||||
|
||||
} catch (EamDbException | SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error updating central repository", ex);
|
||||
|
||||
// Disable the central repo and clear the current settings.
|
||||
try{
|
||||
if (null != EamDb.getInstance()) {
|
||||
EamDb.getInstance().shutdownConnections();
|
||||
}
|
||||
} catch (EamDbException ex2){
|
||||
LOGGER.log(Level.SEVERE, "Error shutting down central repo connection pool", ex);
|
||||
}
|
||||
setUseCentralRepo(false);
|
||||
EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.DISABLED.name());
|
||||
EamDbPlatformEnum.saveSelectedPlatform();
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
if(lock != null){
|
||||
try{
|
||||
lock.release();
|
||||
} catch (CoordinationServiceException ex){
|
||||
LOGGER.log(Level.SEVERE, "Error releasing database lock", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default organization name
|
||||
*
|
||||
* @return the default org name
|
||||
*/
|
||||
static String getDefaultOrgName() {
|
||||
return DEFAULT_ORG_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given org is the default organization.
|
||||
*
|
||||
|
||||
@@ -32,6 +32,7 @@ public class EamGlobalSet {
|
||||
private String version;
|
||||
private TskData.FileKnown fileKnownStatus;
|
||||
private boolean isReadOnly;
|
||||
private CorrelationAttribute.Type type;
|
||||
private LocalDate importDate;
|
||||
|
||||
public EamGlobalSet(
|
||||
@@ -41,6 +42,7 @@ public class EamGlobalSet {
|
||||
String version,
|
||||
TskData.FileKnown knownStatus,
|
||||
boolean isReadOnly,
|
||||
CorrelationAttribute.Type type,
|
||||
LocalDate importDate) {
|
||||
this.globalSetID = globalSetID;
|
||||
this.orgID = orgID;
|
||||
@@ -48,6 +50,7 @@ public class EamGlobalSet {
|
||||
this.version = version;
|
||||
this.fileKnownStatus = knownStatus;
|
||||
this.isReadOnly = isReadOnly;
|
||||
this.type = type;
|
||||
this.importDate = importDate;
|
||||
}
|
||||
|
||||
@@ -57,8 +60,9 @@ public class EamGlobalSet {
|
||||
String version,
|
||||
TskData.FileKnown knownStatus,
|
||||
boolean isReadOnly,
|
||||
CorrelationAttribute.Type type,
|
||||
LocalDate importDate) {
|
||||
this(-1, orgID, setName, version, knownStatus, isReadOnly, importDate);
|
||||
this(-1, orgID, setName, version, knownStatus, isReadOnly, type, importDate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,8 +81,9 @@ public class EamGlobalSet {
|
||||
String setName,
|
||||
String version,
|
||||
TskData.FileKnown knownStatus,
|
||||
boolean isReadOnly) {
|
||||
this(-1, orgID, setName, version, knownStatus, isReadOnly, LocalDate.now());
|
||||
boolean isReadOnly,
|
||||
CorrelationAttribute.Type type) {
|
||||
this(-1, orgID, setName, version, knownStatus, isReadOnly, type, LocalDate.now());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,6 +169,24 @@ public class EamGlobalSet {
|
||||
public void setFileKnownStatus(TskData.FileKnown fileKnownStatus) {
|
||||
this.fileKnownStatus = fileKnownStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of reference set
|
||||
*
|
||||
* @return the type (files, phone numbers, etc)
|
||||
*/
|
||||
public CorrelationAttribute.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of reference set
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
void setType(CorrelationAttribute.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the importDate
|
||||
|
||||
@@ -21,8 +21,13 @@ package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionCancelledException;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
@@ -185,5 +190,36 @@ public class PostgresEamDb extends AbstractSqlEamDb {
|
||||
protected String getConflictClause() {
|
||||
return CONFLICT_CLAUSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an exclusive lock (if applicable).
|
||||
* Will return the lock if successful, null if unsuccessful because locking
|
||||
* isn't supported, and throw an exception if we should have been able to get the
|
||||
* lock but failed (meaning the database is in use).
|
||||
* @return the lock, or null if locking is not supported
|
||||
* @throws EamDbException if the coordination service is running but we fail to get the lock
|
||||
*/
|
||||
@Override
|
||||
public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{
|
||||
try {
|
||||
// First check if multi user mode is enabled - if not there's no point trying to get a lock
|
||||
if( ! UserPreferences.getIsMultiUserModeEnabled()){
|
||||
return null;
|
||||
}
|
||||
|
||||
String databaseNodeName = dbSettings.getHost() + "_" + dbSettings.getDbName();
|
||||
CoordinationService.Lock lock = CoordinationService.getInstance().tryGetExclusiveLock(CoordinationService.CategoryNode.CENTRAL_REPO, databaseNodeName, 5, TimeUnit.MINUTES);
|
||||
|
||||
if(lock != null){
|
||||
return lock;
|
||||
}
|
||||
throw new EamDbException("Error acquiring database lock");
|
||||
} catch (InterruptedException ex){
|
||||
throw new EamDbException("Error acquiring database lock");
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
// This likely just means the coordination service isn't running, which is ok
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Executable → Regular
+2
-1
@@ -356,6 +356,7 @@ public final class PostgresEamDbSettings {
|
||||
createReferenceSetsTable.append("version text NOT NULL,");
|
||||
createReferenceSetsTable.append("known_status integer NOT NULL,");
|
||||
createReferenceSetsTable.append("read_only boolean NOT NULL,");
|
||||
createReferenceSetsTable.append("type integer NOT NULL,");
|
||||
createReferenceSetsTable.append("import_date text NOT NULL,");
|
||||
createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
|
||||
createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)");
|
||||
@@ -485,7 +486,7 @@ public final class PostgresEamDbSettings {
|
||||
}
|
||||
|
||||
boolean result = EamDbUtil.insertDefaultCorrelationTypes(conn)
|
||||
&& EamDbUtil.insertSchemaVersion(conn)
|
||||
&& EamDbUtil.updateSchemaVersion(conn)
|
||||
&& EamDbUtil.insertDefaultOrganization(conn);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
|
||||
/**
|
||||
* Sqlite implementation of the Central Repository database.
|
||||
@@ -549,11 +550,14 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an eamArtifact instance as the given knownStatus. If eamArtifact
|
||||
* exists, it is updated. If eamArtifact does not exist nothing happens
|
||||
* Sets an eamArtifact instance to the given knownStatus.
|
||||
* knownStatus should be BAD if the file has been tagged with a notable tag and
|
||||
* UNKNOWN otherwise. If eamArtifact
|
||||
* exists, it is updated. If eamArtifact does not exist it is added with the
|
||||
* given status.
|
||||
*
|
||||
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
|
||||
* @param knownStatus The known status of the artifact
|
||||
* @param knownStatus The status to change the artifact to. Should never be KNOWN
|
||||
*/
|
||||
@Override
|
||||
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
|
||||
@@ -806,15 +810,17 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
/**
|
||||
* Get all reference sets
|
||||
*
|
||||
* @param correlationType Type of sets to return
|
||||
*
|
||||
* @return List of all reference sets in the central repository
|
||||
*
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public List<EamGlobalSet> getAllReferenceSets() throws EamDbException{
|
||||
public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
|
||||
try{
|
||||
acquireSharedLock();
|
||||
return super.getAllReferenceSets();
|
||||
return super.getAllReferenceSets(correlationType);
|
||||
} finally {
|
||||
releaseSharedLock();
|
||||
}
|
||||
@@ -986,6 +992,34 @@ public class SqliteEamDb extends AbstractSqlEamDb {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the schema of the database (if needed)
|
||||
* @throws EamDbException
|
||||
*/
|
||||
@Override
|
||||
public void upgradeSchema() throws EamDbException, SQLException {
|
||||
try{
|
||||
acquireExclusiveLock();
|
||||
super.upgradeSchema();
|
||||
} finally {
|
||||
releaseExclusiveLock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an exclusive lock (if applicable).
|
||||
* Will return the lock if successful, null if unsuccessful because locking
|
||||
* isn't supported, and throw an exception if we should have been able to get the
|
||||
* lock but failed (meaning the database is in use).
|
||||
* @return the lock, or null if locking is not supported
|
||||
* @throws EamDbException if the coordination service is running but we fail to get the lock
|
||||
*/
|
||||
@Override
|
||||
public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{
|
||||
// Multiple users are not supported for SQLite
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the lock that provides exclusive access to the case database.
|
||||
* Call this method in a try block with a call to
|
||||
|
||||
Executable → Regular
+2
-3
@@ -85,8 +85,6 @@ public final class SqliteEamDbSettings {
|
||||
} catch (NumberFormatException ex) {
|
||||
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void saveSettings() {
|
||||
@@ -300,6 +298,7 @@ public final class SqliteEamDbSettings {
|
||||
createReferenceSetsTable.append("version text NOT NULL,");
|
||||
createReferenceSetsTable.append("known_status integer NOT NULL,");
|
||||
createReferenceSetsTable.append("read_only boolean NOT NULL,");
|
||||
createReferenceSetsTable.append("type integer NOT NULL,");
|
||||
createReferenceSetsTable.append("import_date text NOT NULL,");
|
||||
createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,");
|
||||
createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)");
|
||||
@@ -434,7 +433,7 @@ public final class SqliteEamDbSettings {
|
||||
}
|
||||
|
||||
boolean result = EamDbUtil.insertDefaultCorrelationTypes(conn)
|
||||
&& EamDbUtil.insertSchemaVersion(conn)
|
||||
&& EamDbUtil.updateSchemaVersion(conn)
|
||||
&& EamDbUtil.insertDefaultOrganization(conn);
|
||||
EamDbUtil.closeConnection(conn);
|
||||
return result;
|
||||
|
||||
+2
-2
@@ -191,7 +191,7 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(af,
|
||||
final CorrelationAttribute eamArtifact = EamArtifactUtil.getCorrelationAttributeFromContent(af,
|
||||
knownStatus, comment);
|
||||
|
||||
if (eamArtifact != null) {
|
||||
@@ -394,7 +394,7 @@ final class CaseEventListener implements PropertyChangeListener {
|
||||
}
|
||||
//if the file will have no tags with a status which would prevent the current status from being changed
|
||||
if (!hasTagWithConflictingKnownStatus) {
|
||||
final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(contentTag.getContent(),
|
||||
final CorrelationAttribute eamArtifact = EamArtifactUtil.getCorrelationAttributeFromContent(contentTag.getContent(),
|
||||
tagName.getKnownStatus(), "");
|
||||
if (eamArtifact != null) {
|
||||
EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, tagName.getKnownStatus());
|
||||
|
||||
@@ -18,8 +18,13 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.eventlisteners;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import org.openide.modules.ModuleInstall;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
@@ -40,18 +45,32 @@ public class Installer extends ModuleInstall {
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
private Installer() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository upgrade failed",
|
||||
"Installer.centralRepoUpgradeFailed.message=Failed to upgrade central repository. It has been disabled."
|
||||
})
|
||||
@Override
|
||||
public void restored() {
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
ieListener.installListeners();
|
||||
|
||||
// TODO: create a thread pool to process Runners.
|
||||
// Perform the database upgrade and inform the user if it fails
|
||||
if (!EamDbUtil.upgradeDatabase()) {
|
||||
if (RuntimeProperties.runningWithGUI()) {
|
||||
WindowManager.getDefault().invokeWhenUIReady(() -> {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Installer.centralRepoUpgradeFailed.message"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Installer.centralRepoUpgradeFailed.title"),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,7 +47,6 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.HashUtility;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
|
||||
import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener;
|
||||
|
||||
/**
|
||||
@@ -105,22 +104,21 @@ class IngestModule implements FileIngestModule {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
// If unknown to both the hash module and as a globally known artifact in the EAM DB, correlate to other cases
|
||||
if (af.getKnown() == TskData.FileKnown.UNKNOWN) {
|
||||
// query db for artifact instances having this MD5 and knownStatus = "Bad".
|
||||
/* Search the central repo to see if this file was previously
|
||||
* marked as being bad. Create artifact if it was. */
|
||||
if (af.getKnown() != TskData.FileKnown.KNOWN) {
|
||||
try {
|
||||
// if af.getKnown() is "UNKNOWN" and this artifact instance was marked bad in a previous case,
|
||||
// create TSK_INTERESTING_FILE artifact on BB.
|
||||
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(filesType, md5);
|
||||
if (!caseDisplayNames.isEmpty()) {
|
||||
postCorrelatedBadFileToBlackboard(af, caseDisplayNames);
|
||||
}
|
||||
} catch (EamDbException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex); // NON-NLS
|
||||
LOGGER.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// insert this file into the central repository
|
||||
try {
|
||||
CorrelationAttribute eamArtifact = new CorrelationAttribute(filesType, md5);
|
||||
CorrelationAttributeInstance cefi = new CorrelationAttributeInstance(
|
||||
@@ -128,8 +126,7 @@ class IngestModule implements FileIngestModule {
|
||||
eamDataSource,
|
||||
af.getParentPath() + af.getName(),
|
||||
null,
|
||||
TskData.FileKnown.UNKNOWN,
|
||||
CorrelationAttributeInstance.GlobalStatus.LOCAL
|
||||
TskData.FileKnown.UNKNOWN // NOTE: Known status in the CR is based on tagging, not hashes like the Case Database.
|
||||
);
|
||||
eamArtifact.addInstance(cefi);
|
||||
dbManager.prepareBulkArtifact(eamArtifact);
|
||||
|
||||
+33
-2
@@ -18,11 +18,14 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.optionspanel;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
@@ -77,6 +80,32 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
IngestManager.getInstance().addIngestJobEventListener(ingestJobEventListener);
|
||||
ingestStateUpdated();
|
||||
}
|
||||
|
||||
@Messages({"GlobalSettingsPanel.updateFailed.title=Update failed",
|
||||
"GlobalSettingsPanel.updateFailed.message=Failed to update database. Central repository has been disabled."
|
||||
})
|
||||
private void updateDatabase(){
|
||||
|
||||
if(EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED)){
|
||||
return;
|
||||
}
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
|
||||
try {
|
||||
boolean result = EamDbUtil.upgradeDatabase();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
if(! result){
|
||||
JOptionPane.showMessageDialog(null,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"GlobalSettingsPanel.updateFailed.message"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"GlobalSettingsPanel.updateFailed.title"),
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
@@ -315,6 +344,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed
|
||||
store();
|
||||
EamDbSettingsDialog dialog = new EamDbSettingsDialog();
|
||||
updateDatabase();
|
||||
load(); // reload db settings content and update buttons
|
||||
if (dialog.wasConfigurationChanged()) {
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
@@ -323,8 +353,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
|
||||
private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed
|
||||
//if saved setting is disabled checkbox should be disabled already
|
||||
enableDatabaseConfigureButton(cbUseCentralRepo.isSelected());
|
||||
enableButtonSubComponents(cbUseCentralRepo.isSelected() && !EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED));
|
||||
store();
|
||||
updateDatabase();
|
||||
load();
|
||||
this.ingestStateUpdated();
|
||||
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
|
||||
}//GEN-LAST:event_cbUseCentralRepoActionPerformed
|
||||
|
||||
@@ -451,7 +451,8 @@ public final class CoordinationService {
|
||||
|
||||
CASES("cases"),
|
||||
MANIFESTS("manifests"),
|
||||
CONFIG("config");
|
||||
CONFIG("config"),
|
||||
CENTRAL_REPO("centralRepository");
|
||||
|
||||
private final String displayName;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
@@ -32,8 +33,10 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
|
||||
|
||||
@@ -42,7 +45,7 @@ import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
|
||||
* are more directories.
|
||||
*/
|
||||
public class DirectoryNode extends AbstractFsContentNode<AbstractFile> {
|
||||
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(DirectoryNode.class.getName());
|
||||
|
||||
public static final String DOTDOTDIR = NbBundle.getMessage(DirectoryNode.class, "DirectoryNode.parFolder.text");
|
||||
@@ -88,17 +91,19 @@ public class DirectoryNode extends AbstractFsContentNode<AbstractFile> {
|
||||
actionsList.add(null); // creates a menu separator
|
||||
}
|
||||
actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "DirectoryNode.viewInNewWin.text"), this));
|
||||
actionsList.add(ViewFileInTimelineAction.createViewFileAction(getContent()));
|
||||
actionsList.add(ViewFileInTimelineAction.createViewFileAction(content));
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(ExtractAction.getInstance());
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(new RunIngestModulesAction(Collections.<Content>singletonList(content)));
|
||||
actionsList.add(null); // creates a menu separator
|
||||
actionsList.add(AddContentTagAction.getInstance());
|
||||
|
||||
|
||||
final Collection<AbstractFile> selectedFilesList = new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class));
|
||||
if(selectedFilesList.size() == 1) {
|
||||
if (selectedFilesList.size() == 1) {
|
||||
actionsList.add(DeleteFileContentTagAction.getInstance());
|
||||
}
|
||||
|
||||
|
||||
actionsList.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actionsList.toArray(new Action[actionsList.size()]);
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_ADDED), this);
|
||||
this.em.addPropertyChangeListener(this);
|
||||
IngestManager.getInstance().addIngestJobEventListener(this);
|
||||
@@ -642,7 +643,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
* @param newNodes
|
||||
*/
|
||||
@NbBundle.Messages("DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.")
|
||||
private void respondSelection(final Node[] oldNodes, final Node[] newNodes) {
|
||||
void respondSelection(final Node[] oldNodes, final Node[] newNodes) {
|
||||
if (!Case.isCaseOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,13 @@ final class ExtractUnallocAction extends AbstractAction {
|
||||
uw.execute();
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Tried to get unallocated content from volume ID but " + u.VolumeId + u.llf == null ? "its list of unallocated files was null" : "the volume is locked"); //NON-NLS
|
||||
if(lockedVols.contains(u.getFileName())){
|
||||
logger.log(Level.WARNING, "Tried to get unallocated content but the volume is locked"); // NON_NLS
|
||||
} else if (u.llf == null){
|
||||
logger.log(Level.SEVERE, "Tried to get unallocated content but the list of unallocated files was null"); //NON-NLS
|
||||
} else {
|
||||
logger.log(Level.INFO, "No unallocated files found in volume"); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isImage && !copyList.isEmpty()) {
|
||||
@@ -449,7 +455,7 @@ final class ExtractUnallocAction extends AbstractAction {
|
||||
public List<LayoutFile> visit(Directory dir) {
|
||||
try {
|
||||
for (Content c : dir.getChildren()) {
|
||||
if (c instanceof VirtualDirectory) {
|
||||
if ((c instanceof VirtualDirectory) && (c.getName().equals(VirtualDirectory.NAME_UNALLOC))) {
|
||||
return c.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class ViewContextAction extends AbstractAction {
|
||||
public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) {
|
||||
super(displayName);
|
||||
this.content = artifactNode.getLookup().lookup(AbstractFile.class);
|
||||
if(this.content != null) {
|
||||
if (this.content != null) {
|
||||
AbstractFile file = (AbstractFile) content;
|
||||
if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree())
|
||||
|| (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) {
|
||||
@@ -122,8 +122,7 @@ public class ViewContextAction extends AbstractAction {
|
||||
@Override
|
||||
@Messages({
|
||||
"ViewContextAction.errorMessage.cannotFindDirectory=Failed to locate directory.",
|
||||
"ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.",
|
||||
})
|
||||
"ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.",})
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
EventQueue.invokeLater(() -> {
|
||||
/*
|
||||
@@ -132,7 +131,6 @@ public class ViewContextAction extends AbstractAction {
|
||||
DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance();
|
||||
ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager();
|
||||
Node parentTreeViewNode = treeViewExplorerMgr.getRootContext().getChildren().findChild(DataSourcesNode.NAME);
|
||||
|
||||
/*
|
||||
* Get the parent content for the content to be selected in the
|
||||
* results view. If the parent content is null, then the specified
|
||||
@@ -204,11 +202,21 @@ public class ViewContextAction extends AbstractAction {
|
||||
undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content));
|
||||
TreeView treeView = treeViewTopComponent.getTree();
|
||||
treeView.expandNode(parentTreeViewNode);
|
||||
try {
|
||||
treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode});
|
||||
} catch (PropertyVetoException ex) {
|
||||
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory());
|
||||
logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS
|
||||
if (treeViewTopComponent.getSelectedNode().getDisplayName().equals(parentTreeViewNode.getDisplayName())) {
|
||||
//In the case where our tree view already has the destination directory selected
|
||||
//due to an optimization in the ExplorerManager.setExploredContextAndSelection method
|
||||
//the property change we listen for to call DirectoryTreeTopComponent.respondSelection
|
||||
//will not be sent so we call it manually ourselves after making
|
||||
//the directory listing the active tab.
|
||||
treeViewTopComponent.setDirectoryListingActive();
|
||||
treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode});
|
||||
} else {
|
||||
try {
|
||||
treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode});
|
||||
} catch (PropertyVetoException ex) {
|
||||
MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory());
|
||||
logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -264,5 +272,5 @@ public class ViewContextAction extends AbstractAction {
|
||||
return parent == null ? lineage : parent.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@ DateSearchPanel.createdCheckBox.text=Created
|
||||
DateSearchPanel.accessedCheckBox.text=Accessed
|
||||
DateSearchPanel.changedCheckBox.text=Changed
|
||||
DateSearchPanel.modifiedCheckBox.text=Modified
|
||||
DateSearchPanel.dateToButtonCalendar.text=
|
||||
DateSearchPanel.dateToTextField.text=
|
||||
DateSearchPanel.jLabel1.text=to
|
||||
DateSearchPanel.dateFromTextField.text=
|
||||
DateSearchPanel.dateFromButtonCalendar.text=
|
||||
NameSearchPanel.nameCheckBox.text=Name:
|
||||
NameSearchPanel.noteNameLabel.text=<html>*Note: Name match is case insensitive and matches any part of the file name. Regular expressions are not currently supported.</html>
|
||||
NameSearchPanel.searchTextField.text=
|
||||
|
||||
@@ -82,7 +82,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
|
||||
// convert the date from the selected timezone to get the GMT
|
||||
long fromDate = 0;
|
||||
String startDateValue = panel.getDateFromTextField().getText();
|
||||
String startDateValue = panel.getFromDate();
|
||||
Calendar startDate = getCalendarDate(startDateValue);
|
||||
if (!startDateValue.isEmpty()) {
|
||||
if (startDate != null) {
|
||||
@@ -91,7 +91,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
}
|
||||
|
||||
long toDate = 0;
|
||||
String endDateValue = panel.getDateToTextField().getText();
|
||||
String endDateValue = panel.getToDate();
|
||||
Calendar endDate = getCalendarDate(endDateValue);
|
||||
if (!endDateValue.isEmpty()) {
|
||||
if (endDate != null) {
|
||||
@@ -199,7 +199,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
|
||||
@Override
|
||||
public void addActionListener(ActionListener l) {
|
||||
getComponent().addActionListener(l);
|
||||
getComponent().addDateChangeListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -210,8 +210,8 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
public boolean isValid() {
|
||||
|
||||
DateSearchPanel panel = this.getComponent();
|
||||
Calendar startDate = getCalendarDate(panel.getDateFromTextField().getText());
|
||||
Calendar endDate = getCalendarDate(panel.getDateToTextField().getText());
|
||||
Calendar startDate = getCalendarDate(panel.getFromDate());
|
||||
Calendar endDate = getCalendarDate(panel.getToDate());
|
||||
|
||||
if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) {
|
||||
setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate());
|
||||
|
||||
@@ -55,28 +55,11 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="dateCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dateFromTextField" min="-2" pref="92" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="dateFromButtonCalendar" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="dateToTextField" min="-2" pref="92" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="26" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
@@ -98,27 +81,31 @@
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="33" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="dateCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="fromDatePicker" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="toDatePicker" min="-2" max="-2" attributes="0"/>
|
||||
<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">
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="dateCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dateFromTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="dateCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="dateToButtonCalendar" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dateToTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="dateFromButtonCalendar" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fromDatePicker" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="toDatePicker" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
@@ -147,20 +134,6 @@
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JFormattedTextField" name="dateToTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateToTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="dateToTextFieldFocusLost"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(this.dateFormat);"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
@@ -199,36 +172,22 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="10" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JFormattedTextField" name="dateFromTextField">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateFromTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="dateFromTextFieldFocusLost"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(this.dateFormat);"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="10" style="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="Tahoma" size="10" style="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="modifiedCheckBox">
|
||||
@@ -275,25 +234,23 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createdCheckBoxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton" name="dateFromButtonCalendar">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateFromButtonCalendar.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Component class="com.github.lgooddatepicker.components.DatePicker" name="fromDatePicker">
|
||||
<Events>
|
||||
<EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="dateFromPopupChanged"/>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="fromDatePickerFocusLost"/>
|
||||
<EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="fromDatePickerPropertyChange"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DatePicker(fromDateSettings);"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton" name="dateToButtonCalendar">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateToButtonCalendar.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Component class="com.github.lgooddatepicker.components.DatePicker" name="toDatePicker">
|
||||
<Events>
|
||||
<EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="dateToPopupChanged"/>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="toDatePickerFocusLost"/>
|
||||
<EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="toDatePickerPropertyChange"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DatePicker(toDateSettings);"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011-2017 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,22 +21,28 @@ package org.sleuthkit.autopsy.filesearch;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import com.github.lgooddatepicker.components.DatePicker;
|
||||
import com.github.lgooddatepicker.optionalusertools.PickerUtilities;
|
||||
import com.github.lgooddatepicker.components.DatePickerSettings;
|
||||
import com.github.lgooddatepicker.optionalusertools.DateChangeListener;
|
||||
import com.github.lgooddatepicker.zinternaltools.DateChangeEvent;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Subpanel with controls for file data filtering.
|
||||
*/
|
||||
class DateSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
private final DatePickerSettings fromDateSettings = new DatePickerSettings();
|
||||
private final DatePickerSettings toDateSettings = new DatePickerSettings();
|
||||
DateFormat dateFormat;
|
||||
List<String> timeZones;
|
||||
|
||||
@@ -49,10 +55,11 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
|
||||
dateFromTextField.setComponentPopupMenu(rightClickMenu);
|
||||
dateToTextField.setComponentPopupMenu(rightClickMenu);
|
||||
|
||||
fromDateSettings.setFormatForDatesCommonEra(PickerUtilities.createFormatterFromPatternString("MM/dd/yyyy", fromDateSettings.getLocale()));
|
||||
toDateSettings.setFormatForDatesCommonEra(PickerUtilities.createFormatterFromPatternString("MM/dd/yyyy", toDateSettings.getLocale()));
|
||||
fromDateSettings.setAllowKeyboardEditing(false);
|
||||
toDateSettings.setAllowKeyboardEditing(false);
|
||||
|
||||
ActionListener actList = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -77,41 +84,7 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
copyMenuItem.addActionListener(actList);
|
||||
pasteMenuItem.addActionListener(actList);
|
||||
selectAllMenuItem.addActionListener(actList);
|
||||
this.dateFromTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
});
|
||||
|
||||
this.dateToTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
this.setComponentsEnabled();
|
||||
}
|
||||
|
||||
@@ -131,12 +104,12 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
return dateCheckBox;
|
||||
}
|
||||
|
||||
JFormattedTextField getDateFromTextField() {
|
||||
return dateFromTextField;
|
||||
String getFromDate() {
|
||||
return fromDatePicker.getText();
|
||||
}
|
||||
|
||||
JFormattedTextField getDateToTextField() {
|
||||
return dateToTextField;
|
||||
String getToDate() {
|
||||
return toDatePicker.getText();
|
||||
}
|
||||
|
||||
JCheckBox getModifiedCheckBox() {
|
||||
@@ -157,11 +130,9 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
private void setComponentsEnabled() {
|
||||
boolean enable = this.dateCheckBox.isSelected();
|
||||
this.dateFromTextField.setEnabled(enable);
|
||||
this.dateFromButtonCalendar.setEnabled(enable);
|
||||
this.fromDatePicker.setEnabled(enable);
|
||||
this.jLabel1.setEnabled(enable);
|
||||
this.dateToTextField.setEnabled(enable);
|
||||
this.dateToButtonCalendar.setEnabled(enable);
|
||||
this.toDatePicker.setEnabled(enable);
|
||||
this.jLabel2.setEnabled(enable);
|
||||
this.jLabel3.setEnabled(enable);
|
||||
this.jLabel4.setEnabled(enable);
|
||||
@@ -186,21 +157,19 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
copyMenuItem = new javax.swing.JMenuItem();
|
||||
pasteMenuItem = new javax.swing.JMenuItem();
|
||||
selectAllMenuItem = new javax.swing.JMenuItem();
|
||||
dateToTextField = new JFormattedTextField(this.dateFormat);
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
dateCheckBox = new javax.swing.JCheckBox();
|
||||
timeZoneComboBox = new JComboBox<>(this.timeZones.toArray(new String[this.timeZones.size()]));
|
||||
timeZoneComboBox.setRenderer(new DateSearchFilter.ComboBoxRenderer());
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
dateFromTextField = new JFormattedTextField(this.dateFormat);
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
modifiedCheckBox = new javax.swing.JCheckBox();
|
||||
changedCheckBox = new javax.swing.JCheckBox();
|
||||
accessedCheckBox = new javax.swing.JCheckBox();
|
||||
createdCheckBox = new javax.swing.JCheckBox();
|
||||
dateFromButtonCalendar = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton();
|
||||
dateToButtonCalendar = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton();
|
||||
fromDatePicker = new DatePicker(fromDateSettings);
|
||||
toDatePicker = new DatePicker(toDateSettings);
|
||||
|
||||
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.cutMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(cutMenuItem);
|
||||
@@ -214,14 +183,6 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.selectAllMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(selectAllMenuItem);
|
||||
|
||||
dateToTextField.setEditable(false);
|
||||
dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N
|
||||
dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
dateToTextFieldFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel1.text")); // NOI18N
|
||||
|
||||
jLabel4.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel4.text")); // NOI18N
|
||||
@@ -233,19 +194,11 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||
jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
|
||||
jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||
|
||||
dateFromTextField.setEditable(false);
|
||||
dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N
|
||||
dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
dateFromTextFieldFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel2.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||
jLabel2.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel2.text")); // NOI18N
|
||||
jLabel2.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||
|
||||
modifiedCheckBox.setSelected(true);
|
||||
modifiedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.modifiedCheckBox.text")); // NOI18N
|
||||
@@ -279,17 +232,25 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
dateFromButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromButtonCalendar.text")); // NOI18N
|
||||
dateFromButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
|
||||
fromDatePicker.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
fromDatePickerFocusLost(evt);
|
||||
}
|
||||
});
|
||||
fromDatePicker.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
|
||||
public void propertyChange(java.beans.PropertyChangeEvent evt) {
|
||||
dateFromPopupChanged(evt);
|
||||
fromDatePickerPropertyChange(evt);
|
||||
}
|
||||
});
|
||||
|
||||
dateToButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToButtonCalendar.text")); // NOI18N
|
||||
dateToButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
|
||||
toDatePicker.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
toDatePickerFocusLost(evt);
|
||||
}
|
||||
});
|
||||
toDatePicker.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
|
||||
public void propertyChange(java.beans.PropertyChangeEvent evt) {
|
||||
dateToPopupChanged(evt);
|
||||
toDatePickerPropertyChange(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -298,25 +259,11 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(dateCheckBox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jLabel3)))
|
||||
.addContainerGap(26, Short.MAX_VALUE))
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel2)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(jLabel3)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@@ -333,23 +280,28 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(changedCheckBox)))
|
||||
.addGap(33, 33, 33))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(dateCheckBox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(fromDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(10, 10, 10)
|
||||
.addComponent(toDatePicker, 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()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(dateCheckBox)
|
||||
.addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(dateCheckBox)
|
||||
.addGap(18, 18, 18))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(fromDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(toDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel3)
|
||||
@@ -369,45 +321,6 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void dateFromTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateFromTextFieldFocusLost
|
||||
// set the "from" calendar button to listen to change in the text field
|
||||
String fromDateString = this.dateFromTextField.getText();
|
||||
if (!fromDateString.equals("")) {
|
||||
try {
|
||||
Date fromDate = dateFormat.parse(fromDateString);
|
||||
dateFromButtonCalendar.setTargetDate(fromDate);
|
||||
} catch (ParseException ex) {
|
||||
// for now, no need to show the error message to the user her
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_dateFromTextFieldFocusLost
|
||||
|
||||
private void dateToTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateToTextFieldFocusLost
|
||||
// set the "to" calendar button to listen to change in the text field
|
||||
String toDateString = this.dateToTextField.getText();
|
||||
if (!toDateString.equals("")) {
|
||||
try {
|
||||
Date toDate = dateFormat.parse(toDateString);
|
||||
dateToButtonCalendar.setTargetDate(toDate);
|
||||
} catch (ParseException ex) {
|
||||
// for now, no need to show the error message to the user here
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_dateToTextFieldFocusLost
|
||||
|
||||
private void dateFromPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateFromPopupChanged
|
||||
if (evt.getNewValue() instanceof Date) {
|
||||
setFromDate((Date) evt.getNewValue());
|
||||
}
|
||||
}//GEN-LAST:event_dateFromPopupChanged
|
||||
|
||||
private void dateToPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateToPopupChanged
|
||||
if (evt.getNewValue() instanceof Date) {
|
||||
setToDate((Date) evt.getNewValue());
|
||||
}
|
||||
|
||||
}//GEN-LAST:event_dateToPopupChanged
|
||||
|
||||
private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed
|
||||
this.setComponentsEnabled();
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
@@ -429,6 +342,44 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}//GEN-LAST:event_changedCheckBoxActionPerformed
|
||||
|
||||
private void fromDatePickerPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_fromDatePickerPropertyChange
|
||||
if (evt.getNewValue() instanceof Date) {
|
||||
setFromDate((Date) evt.getNewValue());
|
||||
}
|
||||
}//GEN-LAST:event_fromDatePickerPropertyChange
|
||||
|
||||
private void toDatePickerPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_toDatePickerPropertyChange
|
||||
if (evt.getNewValue() instanceof Date) {
|
||||
setToDate((Date) evt.getNewValue());
|
||||
}
|
||||
}//GEN-LAST:event_toDatePickerPropertyChange
|
||||
|
||||
private void fromDatePickerFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_fromDatePickerFocusLost
|
||||
// set the "from" calendar button to listen to change in the text field
|
||||
String fromDateString = this.fromDatePicker.getText();
|
||||
if (!fromDateString.equals("")) {
|
||||
try {
|
||||
Date fromDate = dateFormat.parse(fromDateString);
|
||||
fromDatePicker.setDate(fromDate.toInstant().atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
|
||||
} catch (ParseException ex) {
|
||||
// for now, no need to show the error message to the user her
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_fromDatePickerFocusLost
|
||||
|
||||
private void toDatePickerFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_toDatePickerFocusLost
|
||||
// set the "to" calendar button to listen to change in the text field
|
||||
String toDateString = this.toDatePicker.getText();
|
||||
if (!toDateString.equals("")) {
|
||||
try {
|
||||
Date toDate = dateFormat.parse(toDateString);
|
||||
toDatePicker.setDate(toDate.toInstant().atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
|
||||
} catch (ParseException ex) {
|
||||
// for now, no need to show the error message to the user here
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_toDatePickerFocusLost
|
||||
|
||||
/**
|
||||
* Validate and set the datetime field on the screen given a datetime
|
||||
* string.
|
||||
@@ -437,12 +388,18 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
private void setFromDate(Date date) {
|
||||
String dateStringResult = "";
|
||||
Instant ins = null;
|
||||
if (date != null) {
|
||||
dateStringResult = dateFormat.format(date);
|
||||
ins = date.toInstant();
|
||||
}
|
||||
|
||||
dateFromTextField.setText(dateStringResult);
|
||||
dateFromButtonCalendar.setTargetDate(date);
|
||||
fromDatePicker.setText(dateStringResult);
|
||||
if (ins != null) {
|
||||
fromDatePicker.setDate(ins.atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
|
||||
} else {
|
||||
fromDatePicker.setDate(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,13 +409,19 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
private void setToDate(Date date) {
|
||||
String dateStringResult = "";
|
||||
Instant ins = null;
|
||||
if (date != null) {
|
||||
dateStringResult = dateFormat.format(date);
|
||||
ins = date.toInstant();
|
||||
}
|
||||
toDatePicker.setText(dateStringResult);
|
||||
if (ins != null) {
|
||||
toDatePicker.setDate(ins.atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate());
|
||||
} else {
|
||||
toDatePicker.setDate(null);
|
||||
}
|
||||
dateToTextField.setText(dateStringResult);
|
||||
dateToButtonCalendar.setTargetDate(date);
|
||||
}
|
||||
|
||||
|
||||
boolean isValidSearch() {
|
||||
return this.accessedCheckBox.isSelected() ||
|
||||
this.changedCheckBox.isSelected() ||
|
||||
@@ -472,10 +435,7 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JCheckBox createdCheckBox;
|
||||
private javax.swing.JMenuItem cutMenuItem;
|
||||
private javax.swing.JCheckBox dateCheckBox;
|
||||
private org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton dateFromButtonCalendar;
|
||||
private javax.swing.JFormattedTextField dateFromTextField;
|
||||
private org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton dateToButtonCalendar;
|
||||
private javax.swing.JFormattedTextField dateToTextField;
|
||||
private com.github.lgooddatepicker.components.DatePicker fromDatePicker;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
@@ -485,10 +445,17 @@ class DateSearchPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JPopupMenu rightClickMenu;
|
||||
private javax.swing.JMenuItem selectAllMenuItem;
|
||||
private javax.swing.JComboBox<String> timeZoneComboBox;
|
||||
private com.github.lgooddatepicker.components.DatePicker toDatePicker;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
void addActionListener(ActionListener l) {
|
||||
dateFromTextField.addActionListener(l);
|
||||
dateToTextField.addActionListener(l);
|
||||
void addDateChangeListener() {
|
||||
DateChangeListener dcl = (DateChangeEvent event) -> {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
};
|
||||
|
||||
fromDatePicker.addDateChangeListener(dcl);
|
||||
toDatePicker.addDateChangeListener(dcl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,7 @@
|
||||
<Component id="filterPanel" pref="266" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@@ -70,9 +67,6 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="FileSearchPanel.searchButton.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="searchButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="errorLabel">
|
||||
<Properties>
|
||||
|
||||
@@ -27,6 +27,7 @@ package org.sleuthkit.autopsy.filesearch;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
@@ -110,7 +111,12 @@ class FileSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addListenerToAll(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
search();
|
||||
}
|
||||
});
|
||||
searchButton.setEnabled(isValidSearch());
|
||||
}
|
||||
|
||||
@@ -284,11 +290,6 @@ class FileSearchPanel extends javax.swing.JPanel {
|
||||
filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS));
|
||||
|
||||
searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N
|
||||
searchButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
searchButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
errorLabel.setForeground(new java.awt.Color(255, 51, 51));
|
||||
errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N
|
||||
@@ -311,17 +312,11 @@ class FileSearchPanel extends javax.swing.JPanel {
|
||||
.addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(searchButton)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(errorLabel)))
|
||||
.addComponent(errorLabel))
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
|
||||
search();
|
||||
}//GEN-LAST:event_searchButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel errorLabel;
|
||||
private javax.swing.JPanel filterPanel;
|
||||
|
||||
+7
-3
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.RootPaneContainer;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.WizardDescriptor;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
@@ -50,6 +51,7 @@ public final class RunIngestModulesAction extends AbstractAction {
|
||||
* used instead of this wizard and is retained for backwards compatibility.
|
||||
*/
|
||||
private static final String EXECUTION_CONTEXT = "org.sleuthkit.autopsy.ingest.RunIngestModulesDialog";
|
||||
|
||||
/**
|
||||
* Display any warnings that the ingestJobSettings have.
|
||||
*
|
||||
@@ -104,12 +106,15 @@ public final class RunIngestModulesAction extends AbstractAction {
|
||||
* argument in the title format string will be supplied by
|
||||
* WizardDescriptor.Panel.getComponent().getName().
|
||||
*/
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
RootPaneContainer root = (RootPaneContainer) WindowManager.getDefault().getMainWindow();
|
||||
root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
root.getGlassPane().setVisible(true);
|
||||
RunIngestModulesWizardIterator wizard = new RunIngestModulesWizardIterator(EXECUTION_CONTEXT, this.ingestType, this.dataSources);
|
||||
WizardDescriptor wiz = new WizardDescriptor(wizard);
|
||||
wiz.setTitleFormat(new MessageFormat("{0}"));
|
||||
wiz.setTitle(Bundle.RunIngestModulesAction_name());
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
root.getGlassPane().setVisible(false);
|
||||
if (DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) {
|
||||
IngestJobSettings ingestJobSettings = wizard.getIngestJobSettings();
|
||||
showWarnings(ingestJobSettings);
|
||||
@@ -117,7 +122,6 @@ public final class RunIngestModulesAction extends AbstractAction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
throw new CloneNotSupportedException("Clone is not supported for the RunIngestModulesAction");
|
||||
|
||||
@@ -31,6 +31,7 @@ import javax.swing.JOptionPane;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
|
||||
@@ -527,7 +528,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
|
||||
|
||||
try{
|
||||
int referenceSetID = EamDb.getInstance().newReferenceSet(new EamGlobalSet(selectedOrg.getOrgID(), hashSetNameTextField.getText(),
|
||||
"", fileKnown, false));
|
||||
"", fileKnown, false, EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID)));
|
||||
newHashDb = HashDbManager.getInstance().addExistingCentralRepoHashSet(hashSetNameTextField.getText(),
|
||||
"", referenceSetID,
|
||||
true, sendIngestMessagesCheckbox.isSelected(), type, false);
|
||||
|
||||
@@ -490,7 +490,7 @@ public class HashDbManager implements PropertyChangeListener {
|
||||
List<HashDbInfo> crHashSets = new ArrayList<>();
|
||||
if(EamDb.isEnabled()){
|
||||
try{
|
||||
List<EamGlobalSet> crSets = EamDb.getInstance().getAllReferenceSets();
|
||||
List<EamGlobalSet> crSets = EamDb.getInstance().getAllReferenceSets(EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID));
|
||||
for(EamGlobalSet globalSet:crSets){
|
||||
|
||||
// Defaults for fields not stored in the central repository:
|
||||
|
||||
+2
-1
@@ -237,7 +237,8 @@ class ImportCentralRepoDbProgressDialog extends javax.swing.JDialog implements P
|
||||
|
||||
// Create an empty hashset in the central repository
|
||||
EamDb dbManager = EamDb.getInstance();
|
||||
referenceSetID.set(dbManager.newReferenceSet(new EamGlobalSet(orgId, hashSetName, version, knownStatus, readOnly)));
|
||||
referenceSetID.set(dbManager.newReferenceSet(new EamGlobalSet(orgId, hashSetName, version, knownStatus,
|
||||
readOnly, EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID))));
|
||||
|
||||
// Get the "FILES" content type. This is a database lookup so we
|
||||
// only want to do it once.
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<dependency conf="autopsy_core->*" org="com.googlecode.gstreamer-java" name="gstreamer-java" rev="1.5"/>
|
||||
|
||||
<!-- for file search -->
|
||||
<dependency conf="autopsy_core->*" org="org.jbundle.thin.base.screen" name="jcalendarbutton" rev="1.4.6"/>
|
||||
<dependency conf="autopsy_core->*" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="10.3.1"/>
|
||||
|
||||
<!-- commmon -->
|
||||
|
||||
@@ -44,7 +44,6 @@ file.reference.imgscalr-lib-4.2-sources.jar=release/modules/ext/imgscalr-lib-4.2
|
||||
file.reference.imgscalr-lib-4.2.jar=release/modules/ext/imgscalr-lib-4.2.jar
|
||||
file.reference.javaee-api-5.0-2.jar=release/modules/ext/javaee-api-5.0-2.jar
|
||||
file.reference.javassist-3.12.1.GA.jar=release/modules/ext/javassist-3.12.1.GA.jar
|
||||
file.reference.jcalendarbutton-1.4.6.jar=release/modules/ext/jcalendarbutton-1.4.6.jar
|
||||
file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar
|
||||
file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar
|
||||
file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar
|
||||
|
||||
@@ -215,7 +215,6 @@
|
||||
<package>jfxtras.scene.control</package>
|
||||
<package>jfxtras.scene.layout</package>
|
||||
<package>jfxtras.util</package>
|
||||
<package>net.sourceforge.jcalendarbutton</package>
|
||||
<package>org.apache.avalon.framework</package>
|
||||
<package>org.apache.avalon.framework.activity</package>
|
||||
<package>org.apache.avalon.framework.component</package>
|
||||
@@ -590,7 +589,6 @@
|
||||
<package>org.hyperic.sigar.vmware</package>
|
||||
<package>org.hyperic.sigar.win32</package>
|
||||
<package>org.imgscalr</package>
|
||||
<package>org.jbundle.thin.base.screen.jcalendarbutton</package>
|
||||
<package>org.joda.time</package>
|
||||
<package>org.joda.time.base</package>
|
||||
<package>org.joda.time.chrono</package>
|
||||
@@ -633,7 +631,6 @@
|
||||
<package>org.slf4j.helpers</package>
|
||||
<package>org.slf4j.impl</package>
|
||||
<package>org.slf4j.spi</package>
|
||||
<package>org.sourceforge.jcalendarbutton</package>
|
||||
<package>org.w3c.dom</package>
|
||||
<package>org.w3c.dom.css</package>
|
||||
<package>org.w3c.dom.events</package>
|
||||
@@ -770,10 +767,6 @@
|
||||
<runtime-relative-path>ext/poi-excelant-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-excelant-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jcalendarbutton-1.4.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jcalendarbutton-1.4.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imageio-psd-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imageio-psd-3.2.jar</binary-origin>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<conf name="experimental"/>
|
||||
</configurations>
|
||||
<dependencies>
|
||||
<dependency conf="experimental->default" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="4.3.1"/>
|
||||
<dependency conf="experimental->default" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="10.3.1"/>
|
||||
<dependency conf="experimental->default" org="org.apache.tika" name="tika-core" rev="1.14"/>
|
||||
<dependency conf="experimental->default" org="org.postgresql" name="postgresql" rev="9.4-1201-jdbc41"/>
|
||||
<dependency conf="experimental->default" org="com.mchange" name="c3p0" rev="0.9.5"/>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar
|
||||
file.reference.jackson-core-2.7.0.jar=release/modules/ext/jackson-core-2.7.0.jar
|
||||
file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar
|
||||
file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar
|
||||
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
|
||||
file.reference.postgresql-9.4-1201-jdbc41.jar=release/modules/ext/postgresql-9.4-1201-jdbc41.jar
|
||||
file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar
|
||||
source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-sources.jar
|
||||
javadoc.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar
|
||||
source.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar
|
||||
|
||||
@@ -145,18 +145,18 @@
|
||||
<package>org.sleuthkit.autopsy.experimental.autoingest</package>
|
||||
<package>org.sleuthkit.autopsy.experimental.configuration</package>
|
||||
</public-packages>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mchange-commons-java-0.2.9.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/LGoodDatePicker-4.3.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/LGoodDatePicker-4.3.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/LGoodDatePicker-10.3.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/LGoodDatePicker-10.3.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/mchange-commons-java-0.2.9.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jackson-core-2.7.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jackson-core-2.7.0.jar</binary-origin>
|
||||
|
||||
+13
-14
@@ -31,9 +31,9 @@
|
||||
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="startingDataLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="datePicker" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="7" max="32767" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="metricsButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
@@ -51,8 +51,10 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="metricsButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="datePicker" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="startingDataLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
|
||||
<Component id="startingDataLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="datePicker" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" min="-2" pref="128" max="-2" attributes="0"/>
|
||||
@@ -103,16 +105,6 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="metricsButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="com.github.lgooddatepicker.datepicker.DatePicker" name="datePicker">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestMetricsDialog.datePicker.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DatePicker();"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="startingDataLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
@@ -120,5 +112,12 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="com.github.lgooddatepicker.components.DatePicker" name="datePicker">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestMetricsDialog.datePicker.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
||||
+9
-9
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import com.github.lgooddatepicker.datepicker.DatePicker;
|
||||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Window;
|
||||
@@ -139,8 +138,8 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
reportTextArea = new javax.swing.JTextArea();
|
||||
metricsButton = new javax.swing.JButton();
|
||||
datePicker = new DatePicker();
|
||||
startingDataLabel = new javax.swing.JLabel();
|
||||
datePicker = new com.github.lgooddatepicker.components.DatePicker();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setAlwaysOnTop(true);
|
||||
@@ -166,10 +165,10 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
|
||||
}
|
||||
});
|
||||
|
||||
datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(startingDataLabel, org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.startingDataLabel.text")); // NOI18N
|
||||
|
||||
datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
@@ -180,9 +179,9 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
|
||||
.addComponent(jScrollPane1)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(startingDataLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(metricsButton))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
@@ -195,8 +194,9 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(metricsButton)
|
||||
.addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(startingDataLabel))
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(startingDataLabel)
|
||||
.addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
@@ -220,7 +220,7 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton closeButton;
|
||||
private com.github.lgooddatepicker.datepicker.DatePicker datePicker;
|
||||
private com.github.lgooddatepicker.components.DatePicker datePicker;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JButton metricsButton;
|
||||
private javax.swing.JTextArea reportTextArea;
|
||||
|
||||
+50
-54
@@ -71,10 +71,10 @@
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="mainPanel">
|
||||
<Properties>
|
||||
<Property name="autoscrolls" type="boolean" value="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[657, 425]"/>
|
||||
</Property>
|
||||
<Property name="autoscrolls" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
@@ -136,12 +136,12 @@
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextField" name="tbRootDirectory">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.RuleOutputTooltip_1" 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="[2000, 2000]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.RuleOutputTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="pnEditRule">
|
||||
@@ -161,7 +161,7 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
|
||||
@@ -173,13 +173,6 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="bnSaveRule" min="-2" pref="101" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="comboBoxAttributeComparison" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dateTimePicker" min="-2" pref="306" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tbAttributeValue" pref="158" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
@@ -202,6 +195,13 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="bnDeleteAttribute" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="comboBoxAttributeComparison" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="dateTimePicker" min="-2" pref="306" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tbAttributeValue" pref="158" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
@@ -236,7 +236,7 @@
|
||||
<Component id="tbRuleName" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@@ -259,20 +259,16 @@
|
||||
<EmptySpace min="-2" pref="78" max="-2" attributes="0"/>
|
||||
<Component id="lbAttribute" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="comboBoxAttributeName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="comboBoxArtifactName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="comboBoxValueType" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tbAttributeValue" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dateTimePicker" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="comboBoxAttributeComparison" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="comboBoxAttributeName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="comboBoxArtifactName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="comboBoxValueType" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="tbAttributeValue" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="comboBoxAttributeComparison" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="dateTimePicker" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
@@ -380,12 +376,12 @@
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.FileSizeComparisonTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32, 20]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.FileSizeComparisonTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
@@ -396,12 +392,12 @@
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.MimeTypeComparisonTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32, 20]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.MimeTypeComparisonTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
@@ -409,15 +405,15 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="tbRuleName">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.CurrentlySelectedRuleNameTooltip_1" 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="[10, 1000]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[733, 20]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.CurrentlySelectedRuleNameTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="tbRuleNameKeyTyped"/>
|
||||
@@ -431,10 +427,10 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.SaveText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.SaveTooltip_1" 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="bnSaveRuleActionPerformed"/>
|
||||
@@ -477,10 +473,10 @@
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Select the conditional operator"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32, 23]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Select the conditional operator"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
@@ -488,13 +484,13 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="tbAttributeValue">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Type a value here"/>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[6, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[6, 23]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Type a value here"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="bnAddAttribute">
|
||||
@@ -503,8 +499,8 @@
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/experimental/images/left-arrow-16-icon.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="Add Attribute"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Click to add an attribute to the current rule"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Click to add an attribute to the current rule"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnAddAttributeActionPerformed"/>
|
||||
@@ -533,14 +529,6 @@
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cbAttributeTypeItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="com.github.lgooddatepicker.datetimepicker.DateTimePicker" name="dateTimePicker">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Choose a date and time"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DateTimePicker(null, timeSettings);"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lbArtifact">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Artifact"/>
|
||||
@@ -554,8 +542,8 @@
|
||||
<Component class="javax.swing.JButton" name="bnDeleteAttribute">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Delete Attribute"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Click to remove the selected attribute"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Click to remove the selected attribute"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnDeleteAttributeActionPerformed"/>
|
||||
@@ -593,6 +581,14 @@
|
||||
<Property name="text" type="java.lang.String" value="To save, a rule must have a name and at least one condition."/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="com.github.lgooddatepicker.components.DateTimePicker" name="dateTimePicker">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Choose a date and time"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DateTimePicker(null, timeSettings);"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="bnBrowseReportDirectory">
|
||||
@@ -610,12 +606,12 @@
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="tbReportDirectory">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.ReportOutputFolderTooltip_1" 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="[2000, 2000]"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.ReportOutputFolderTooltip_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="ruleListScrollPane">
|
||||
@@ -630,9 +626,9 @@
|
||||
<Property name="model" type="javax.swing.tree.TreeModel" editor="org.netbeans.modules.form.editors2.TreeModelEditor">
|
||||
<TreeModel code=""/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value="This tree shows the rules to collect files for automatic file export"/>
|
||||
<Property name="name" type="java.lang.String" value="trRuleList" noResource="true"/>
|
||||
<Property name="showsRootHandles" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="This tree shows the rules to collect files for automatic file export"/>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
<Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
@@ -700,10 +696,10 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.DeleteText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="FileExporterSettingsPanel.DeleteTooltip_1" 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="bnDeleteRuleActionPerformed"/>
|
||||
|
||||
+48
-50
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2015 Basis Technology Corp.
|
||||
* Copyright 2015-2017 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -18,9 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import com.github.lgooddatepicker.datetimepicker.DateTimePicker;
|
||||
import com.github.lgooddatepicker.components.DateTimePicker;
|
||||
import com.github.lgooddatepicker.optionalusertools.PickerUtilities;
|
||||
import com.github.lgooddatepicker.timepicker.TimePickerSettings;
|
||||
import com.github.lgooddatepicker.components.TimePickerSettings;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.FocusEvent;
|
||||
@@ -632,7 +632,7 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
comboBoxValueType.setEnabled(null == attributeTypeMap.get(artifactConditionToPopulateWith.getAttributeTypeName()));
|
||||
if (valueType == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||
Instant instant = Instant.ofEpochMilli(artifactConditionToPopulateWith.getDateTimeValue().toDate().getTime());
|
||||
dateTimePicker.setDateTime(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
|
||||
dateTimePicker.setDateTimeStrict(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
|
||||
} else {
|
||||
tbAttributeValue.setText(artifactConditionToPopulateWith.getStringRepresentationOfValue());
|
||||
}
|
||||
@@ -650,30 +650,30 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
mainPanel = new javax.swing.JPanel();
|
||||
tbRootDirectory = new javax.swing.JTextField();
|
||||
pnEditRule = new javax.swing.JPanel();
|
||||
comboBoxMimeValue = new javax.swing.JComboBox<String>();
|
||||
comboBoxMimeValue = new javax.swing.JComboBox<>();
|
||||
cbMimeType = new javax.swing.JCheckBox();
|
||||
spFileSizeValue = new javax.swing.JSpinner();
|
||||
comboBoxFileSizeUnits = new javax.swing.JComboBox<String>();
|
||||
comboBoxFileSizeUnits = new javax.swing.JComboBox<>();
|
||||
cbFileSize = new javax.swing.JCheckBox();
|
||||
comboBoxFileSizeComparison = new javax.swing.JComboBox<String>();
|
||||
comboBoxMimeTypeComparison = new javax.swing.JComboBox<String>();
|
||||
comboBoxFileSizeComparison = new javax.swing.JComboBox<>();
|
||||
comboBoxMimeTypeComparison = new javax.swing.JComboBox<>();
|
||||
tbRuleName = new javax.swing.JTextField();
|
||||
bnSaveRule = new javax.swing.JButton();
|
||||
comboBoxArtifactName = new javax.swing.JComboBox<String>();
|
||||
comboBoxAttributeName = new javax.swing.JComboBox<String>();
|
||||
comboBoxAttributeComparison = new javax.swing.JComboBox<String>();
|
||||
comboBoxArtifactName = new javax.swing.JComboBox<>();
|
||||
comboBoxAttributeName = new javax.swing.JComboBox<>();
|
||||
comboBoxAttributeComparison = new javax.swing.JComboBox<>();
|
||||
tbAttributeValue = new javax.swing.JTextField();
|
||||
bnAddAttribute = new javax.swing.JButton();
|
||||
comboBoxValueType = new javax.swing.JComboBox<String>();
|
||||
comboBoxValueType = new javax.swing.JComboBox<>();
|
||||
cbAttributeType = new javax.swing.JCheckBox();
|
||||
dateTimePicker = new DateTimePicker(null, timeSettings);
|
||||
lbArtifact = new javax.swing.JLabel();
|
||||
lbAttribute = new javax.swing.JLabel();
|
||||
bnDeleteAttribute = new javax.swing.JButton();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
lsAttributeList = new javax.swing.JList<String>();
|
||||
lsAttributeList = new javax.swing.JList<>();
|
||||
lbRuleName = new javax.swing.JLabel();
|
||||
lbSaveRuleHelper = new javax.swing.JLabel();
|
||||
dateTimePicker = new DateTimePicker(null, timeSettings);
|
||||
bnBrowseReportDirectory = new javax.swing.JButton();
|
||||
tbReportDirectory = new javax.swing.JTextField();
|
||||
ruleListScrollPane = new javax.swing.JScrollPane();
|
||||
@@ -690,11 +690,11 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
setName(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.Title")); // NOI18N
|
||||
|
||||
mainPanel.setAutoscrolls(true);
|
||||
mainPanel.setPreferredSize(new java.awt.Dimension(657, 425));
|
||||
mainPanel.setAutoscrolls(true);
|
||||
|
||||
tbRootDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.RuleOutputTooltip_1")); // NOI18N
|
||||
tbRootDirectory.setMaximumSize(new java.awt.Dimension(2000, 2000));
|
||||
tbRootDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.RuleOutputTooltip_1")); // NOI18N
|
||||
|
||||
pnEditRule.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
pnEditRule.setAutoscrolls(true);
|
||||
@@ -716,7 +716,7 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
spFileSizeValue.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(1024), Integer.valueOf(0), null, Integer.valueOf(1)));
|
||||
spFileSizeValue.setModel(new javax.swing.SpinnerNumberModel(1024, 0, null, 1));
|
||||
spFileSizeValue.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeValueToolTip_1")); // NOI18N
|
||||
|
||||
comboBoxFileSizeUnits.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeUnitToolTip_1")); // NOI18N
|
||||
@@ -729,15 +729,15 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
comboBoxFileSizeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeComparisonTooltip_1")); // NOI18N
|
||||
comboBoxFileSizeComparison.setMinimumSize(new java.awt.Dimension(32, 20));
|
||||
comboBoxFileSizeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeComparisonTooltip_1")); // NOI18N
|
||||
|
||||
comboBoxMimeTypeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.MimeTypeComparisonTooltip_1")); // NOI18N
|
||||
comboBoxMimeTypeComparison.setMinimumSize(new java.awt.Dimension(32, 20));
|
||||
comboBoxMimeTypeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.MimeTypeComparisonTooltip_1")); // NOI18N
|
||||
|
||||
tbRuleName.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.CurrentlySelectedRuleNameTooltip_1")); // NOI18N
|
||||
tbRuleName.setMaximumSize(new java.awt.Dimension(10, 1000));
|
||||
tbRuleName.setPreferredSize(new java.awt.Dimension(733, 20));
|
||||
tbRuleName.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.CurrentlySelectedRuleNameTooltip_1")); // NOI18N
|
||||
tbRuleName.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyTyped(java.awt.event.KeyEvent evt) {
|
||||
tbRuleNameKeyTyped(evt);
|
||||
@@ -746,8 +746,8 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
|
||||
bnSaveRule.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/save-icon.png"))); // NOI18N
|
||||
bnSaveRule.setText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.SaveText")); // NOI18N
|
||||
bnSaveRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.SaveTooltip_1")); // NOI18N
|
||||
bnSaveRule.setEnabled(false);
|
||||
bnSaveRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.SaveTooltip_1")); // NOI18N
|
||||
bnSaveRule.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
bnSaveRuleActionPerformed(evt);
|
||||
@@ -772,17 +772,17 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
comboBoxAttributeComparison.setToolTipText("Select the conditional operator");
|
||||
comboBoxAttributeComparison.setMinimumSize(new java.awt.Dimension(32, 23));
|
||||
comboBoxAttributeComparison.setToolTipText("Select the conditional operator");
|
||||
|
||||
tbAttributeValue.setToolTipText("Type a value here");
|
||||
tbAttributeValue.setMinimumSize(new java.awt.Dimension(6, 23));
|
||||
tbAttributeValue.setPreferredSize(new java.awt.Dimension(6, 23));
|
||||
tbAttributeValue.setToolTipText("Type a value here");
|
||||
|
||||
bnAddAttribute.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/left-arrow-16-icon.png"))); // NOI18N
|
||||
bnAddAttribute.setText("Add Attribute");
|
||||
bnAddAttribute.setToolTipText("Click to add an attribute to the current rule");
|
||||
bnAddAttribute.setEnabled(false);
|
||||
bnAddAttribute.setToolTipText("Click to add an attribute to the current rule");
|
||||
bnAddAttribute.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
bnAddAttributeActionPerformed(evt);
|
||||
@@ -804,15 +804,13 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
dateTimePicker.setToolTipText("Choose a date and time");
|
||||
|
||||
lbArtifact.setText("Artifact");
|
||||
|
||||
lbAttribute.setText("Attribute");
|
||||
|
||||
bnDeleteAttribute.setText("Delete Attribute");
|
||||
bnDeleteAttribute.setToolTipText("Click to remove the selected attribute");
|
||||
bnDeleteAttribute.setEnabled(false);
|
||||
bnDeleteAttribute.setToolTipText("Click to remove the selected attribute");
|
||||
bnDeleteAttribute.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
bnDeleteAttributeActionPerformed(evt);
|
||||
@@ -829,6 +827,8 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
lbSaveRuleHelper.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
|
||||
lbSaveRuleHelper.setText("To save, a rule must have a name and at least one condition.");
|
||||
|
||||
dateTimePicker.setToolTipText("Choose a date and time");
|
||||
|
||||
javax.swing.GroupLayout pnEditRuleLayout = new javax.swing.GroupLayout(pnEditRule);
|
||||
pnEditRule.setLayout(pnEditRuleLayout);
|
||||
pnEditRuleLayout.setHorizontalGroup(
|
||||
@@ -845,12 +845,6 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
.addComponent(lbSaveRuleHelper, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(bnSaveRule, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
.addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 306, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tbAttributeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE))
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
@@ -867,7 +861,13 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
.addComponent(bnAddAttribute, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(bnDeleteAttribute)))
|
||||
.addComponent(bnDeleteAttribute))
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
.addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 306, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tbAttributeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)))
|
||||
.addGap(0, 0, Short.MAX_VALUE))))
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@@ -910,17 +910,15 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
.addGap(78, 78, 78)
|
||||
.addComponent(lbAttribute)
|
||||
.addGap(8, 8, 8)
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(pnEditRuleLayout.createSequentialGroup()
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(comboBoxAttributeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(comboBoxArtifactName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(comboBoxValueType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tbAttributeValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(comboBoxAttributeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(comboBoxArtifactName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(comboBoxValueType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(tbAttributeValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(bnAddAttribute)
|
||||
@@ -953,14 +951,14 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
tbReportDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.ReportOutputFolderTooltip_1")); // NOI18N
|
||||
tbReportDirectory.setMaximumSize(new java.awt.Dimension(2000, 2000));
|
||||
tbReportDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.ReportOutputFolderTooltip_1")); // NOI18N
|
||||
|
||||
javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
|
||||
trRuleList.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
|
||||
trRuleList.setToolTipText("This tree shows the rules to collect files for automatic file export");
|
||||
trRuleList.setName("trRuleList"); // NOI18N
|
||||
trRuleList.setShowsRootHandles(true);
|
||||
trRuleList.setToolTipText("This tree shows the rules to collect files for automatic file export");
|
||||
ruleListScrollPane.setViewportView(trRuleList);
|
||||
trRuleList.getAccessibleContext().setAccessibleParent(ruleListScrollPane);
|
||||
|
||||
@@ -1039,8 +1037,8 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
|
||||
bnDeleteRule.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/minus-icon.png"))); // NOI18N
|
||||
bnDeleteRule.setText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.DeleteText")); // NOI18N
|
||||
bnDeleteRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.DeleteTooltip_1")); // NOI18N
|
||||
bnDeleteRule.setEnabled(false);
|
||||
bnDeleteRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.DeleteTooltip_1")); // NOI18N
|
||||
bnDeleteRule.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
bnDeleteRuleActionPerformed(evt);
|
||||
@@ -1260,7 +1258,7 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
}
|
||||
|
||||
if (intrinsicType == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||
LocalDateTime localDateTime = dateTimePicker.getDateTime();
|
||||
LocalDateTime localDateTime = dateTimePicker.getDateTimeStrict();
|
||||
if (localDateTime == null) {
|
||||
throw new IllegalArgumentException("Bad date/time combination");
|
||||
}
|
||||
@@ -2028,7 +2026,7 @@ public final class FileExporterSettingsPanel extends JPanel {
|
||||
private javax.swing.JComboBox<String> comboBoxMimeTypeComparison;
|
||||
private javax.swing.JComboBox<String> comboBoxMimeValue;
|
||||
private javax.swing.JComboBox<String> comboBoxValueType;
|
||||
private com.github.lgooddatepicker.datetimepicker.DateTimePicker dateTimePicker;
|
||||
private com.github.lgooddatepicker.components.DateTimePicker dateTimePicker;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JLabel lbArtifact;
|
||||
private javax.swing.JLabel lbAttribute;
|
||||
|
||||
@@ -18,18 +18,22 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.SwingUtilities;
|
||||
@@ -57,15 +61,20 @@ final class SearchRunner {
|
||||
private static SearchRunner instance = null;
|
||||
private IngestServices services = IngestServices.getInstance();
|
||||
private Ingester ingester = null;
|
||||
private volatile boolean updateTimerRunning = false;
|
||||
private Timer updateTimer;
|
||||
private long defaultUpdateIntervalMs;
|
||||
private volatile boolean periodicSearchTaskRunning = false;
|
||||
private Future<?> jobProcessingTaskFuture;
|
||||
private final ScheduledThreadPoolExecutor jobProcessingExecutor;
|
||||
private static final int NUM_SEARCH_SCHEDULING_THREADS = 1;
|
||||
private static final String SEARCH_SCHEDULER_THREAD_NAME = "periodic-search-scheduler-%d";
|
||||
|
||||
// maps a jobID to the search
|
||||
private Map<Long, SearchJobInfo> jobs = new HashMap<>(); //guarded by "this"
|
||||
private Map<Long, SearchJobInfo> jobs = new ConcurrentHashMap<>();
|
||||
|
||||
SearchRunner() {
|
||||
defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
|
||||
ingester = Ingester.getDefault();
|
||||
updateTimer = new Timer(NbBundle.getMessage(this.getClass(), "SearchRunner.updateTimer.title.text"), true); // run as a daemon
|
||||
jobProcessingExecutor = new ScheduledThreadPoolExecutor(NUM_SEARCH_SCHEDULING_THREADS, new ThreadFactoryBuilder().setNameFormat(SEARCH_SCHEDULER_THREAD_NAME).build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,10 +105,12 @@ final class SearchRunner {
|
||||
jobs.get(jobId).incrementModuleReferenceCount();
|
||||
|
||||
// start the timer, if needed
|
||||
if ((jobs.size() > 0) && (updateTimerRunning == false)) {
|
||||
final long updateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
|
||||
updateTimer.scheduleAtFixedRate(new UpdateTimerTask(), updateIntervalMs, updateIntervalMs);
|
||||
updateTimerRunning = true;
|
||||
if ((jobs.size() > 0) && (periodicSearchTaskRunning == false)) {
|
||||
// reset the default periodic search frequency to the user setting
|
||||
logger.log(Level.INFO, "Resetting periodic search time out to default value"); //NON-NLS
|
||||
defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000;
|
||||
jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), defaultUpdateIntervalMs, MILLISECONDS);
|
||||
periodicSearchTaskRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,26 +120,33 @@ final class SearchRunner {
|
||||
*
|
||||
* @param jobId
|
||||
*/
|
||||
public void endJob(long jobId) {
|
||||
public synchronized void endJob(long jobId) {
|
||||
SearchJobInfo job;
|
||||
boolean readyForFinalSearch = false;
|
||||
synchronized (this) {
|
||||
job = jobs.get(jobId);
|
||||
if (job == null) {
|
||||
return;
|
||||
}
|
||||
job = jobs.get(jobId);
|
||||
if (job == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only do final search if this is the last module/thread in this job to call endJob()
|
||||
if (job.decrementModuleReferenceCount() == 0) {
|
||||
jobs.remove(jobId);
|
||||
readyForFinalSearch = true;
|
||||
}
|
||||
// Only do final search if this is the last module/thread in this job to call endJob()
|
||||
if (job.decrementModuleReferenceCount() == 0) {
|
||||
jobs.remove(jobId);
|
||||
readyForFinalSearch = true;
|
||||
}
|
||||
|
||||
if (readyForFinalSearch) {
|
||||
logger.log(Level.INFO, "Commiting search index before final search for search job {0}", job.getJobId()); //NON-NLS
|
||||
commit();
|
||||
doFinalSearch(job); //this will block until it's done
|
||||
|
||||
// new jobs could have been added while we were doing final search
|
||||
if (jobs.isEmpty()) {
|
||||
// no more jobs left. stop the PeriodicSearchTask.
|
||||
// A new one will be created for future jobs.
|
||||
logger.log(Level.INFO, "No more search jobs. Stopping periodic search task"); //NON-NLS
|
||||
periodicSearchTaskRunning = false;
|
||||
jobProcessingTaskFuture.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,24 +156,31 @@ final class SearchRunner {
|
||||
*
|
||||
* @param jobId
|
||||
*/
|
||||
public void stopJob(long jobId) {
|
||||
logger.log(Level.INFO, "Stopping job {0}", jobId); //NON-NLS
|
||||
public synchronized void stopJob(long jobId) {
|
||||
logger.log(Level.INFO, "Stopping search job {0}", jobId); //NON-NLS
|
||||
commit();
|
||||
|
||||
SearchJobInfo job;
|
||||
synchronized (this) {
|
||||
job = jobs.get(jobId);
|
||||
if (job == null) {
|
||||
return;
|
||||
}
|
||||
job = jobs.get(jobId);
|
||||
if (job == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//stop currentSearcher
|
||||
SearchRunner.Searcher currentSearcher = job.getCurrentSearcher();
|
||||
if ((currentSearcher != null) && (!currentSearcher.isDone())) {
|
||||
currentSearcher.cancel(true);
|
||||
}
|
||||
//stop currentSearcher
|
||||
SearchRunner.Searcher currentSearcher = job.getCurrentSearcher();
|
||||
if ((currentSearcher != null) && (!currentSearcher.isDone())) {
|
||||
logger.log(Level.INFO, "Cancelling search job {0}", jobId); //NON-NLS
|
||||
currentSearcher.cancel(true);
|
||||
}
|
||||
|
||||
jobs.remove(jobId);
|
||||
jobs.remove(jobId);
|
||||
|
||||
if (jobs.isEmpty()) {
|
||||
// no more jobs left. stop the PeriodicSearchTask.
|
||||
// A new one will be created for future jobs.
|
||||
logger.log(Level.INFO, "No more search jobs. Stopping periodic search task"); //NON-NLS
|
||||
periodicSearchTaskRunning = false;
|
||||
jobProcessingTaskFuture.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,37 +248,81 @@ final class SearchRunner {
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer triggered re-search for each job (does a single index commit first)
|
||||
* Task to perform periodic searches for each job (does a single index commit first)
|
||||
*/
|
||||
private class UpdateTimerTask extends TimerTask {
|
||||
private final class PeriodicSearchTask implements Runnable {
|
||||
|
||||
private final Logger logger = Logger.getLogger(SearchRunner.UpdateTimerTask.class.getName());
|
||||
private final Logger logger = Logger.getLogger(SearchRunner.PeriodicSearchTask.class.getName());
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// If no jobs then cancel the task. If more job(s) come along, a new task will start up.
|
||||
if (jobs.isEmpty()) {
|
||||
this.cancel(); //terminate this timer task
|
||||
updateTimerRunning = false;
|
||||
if (jobs.isEmpty() || jobProcessingTaskFuture.isCancelled()) {
|
||||
logger.log(Level.INFO, "Exiting periodic search task"); //NON-NLS
|
||||
periodicSearchTaskRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
commit();
|
||||
|
||||
synchronized (SearchRunner.this) {
|
||||
// Spawn a search thread for each job
|
||||
for (Entry<Long, SearchJobInfo> j : jobs.entrySet()) {
|
||||
SearchJobInfo job = j.getValue();
|
||||
// If no lists or the worker is already running then skip it
|
||||
if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) {
|
||||
logger.log(Level.INFO, "Executing periodic search for search job {0}", job.getJobId());
|
||||
Searcher searcher = new Searcher(job);
|
||||
job.setCurrentSearcher(searcher); //save the ref
|
||||
searcher.execute(); //start thread
|
||||
job.setWorkerRunning(true);
|
||||
logger.log(Level.INFO, "Starting periodic searches");
|
||||
final StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
// NOTE: contents of "jobs" ConcurrentHashMap can be modified in stopJob() and endJob() while we are inside this loop
|
||||
for (Iterator<Entry<Long, SearchJobInfo>> iterator = jobs.entrySet().iterator(); iterator.hasNext();) {
|
||||
SearchJobInfo job = iterator.next().getValue();
|
||||
|
||||
if (jobProcessingTaskFuture.isCancelled()) {
|
||||
logger.log(Level.INFO, "Search has been cancelled. Exiting periodic search task."); //NON-NLS
|
||||
periodicSearchTaskRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If no lists or the worker is already running then skip it
|
||||
if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) {
|
||||
// Spawn a search thread for each job
|
||||
logger.log(Level.INFO, "Executing periodic search for search job {0}", job.getJobId());
|
||||
Searcher searcher = new Searcher(job); // SwingWorker
|
||||
job.setCurrentSearcher(searcher); //save the ref
|
||||
searcher.execute(); //start thread
|
||||
job.setWorkerRunning(true);
|
||||
|
||||
try {
|
||||
// wait for the searcher to finish
|
||||
searcher.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Error performing keyword search: {0}", ex.getMessage()); //NON-NLS
|
||||
services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"SearchRunner.Searcher.done.err.msg"), ex.getMessage()));
|
||||
}// catch and ignore if we were cancelled
|
||||
catch (java.util.concurrent.CancellationException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
stopWatch.stop();
|
||||
logger.log(Level.INFO, "All periodic searches cumulatively took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS
|
||||
|
||||
// calculate "hold off" time
|
||||
final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); // ELDEBUG
|
||||
|
||||
// schedule next PeriodicSearchTask
|
||||
jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSearchMs, MILLISECONDS);
|
||||
|
||||
// exit this thread
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
private long getTimeToNextPeriodicSearch(long lastSerchTimeSec) {
|
||||
// If periodic search takes more than 1/4 of the current periodic search interval, then double the search interval
|
||||
if (lastSerchTimeSec * 1000 < defaultUpdateIntervalMs / 4) {
|
||||
return defaultUpdateIntervalMs;
|
||||
}
|
||||
// double the search interval
|
||||
defaultUpdateIntervalMs = defaultUpdateIntervalMs * 2;
|
||||
logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000});
|
||||
return defaultUpdateIntervalMs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,23 +591,6 @@ final class SearchRunner {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
// call get to see if there were any errors
|
||||
try {
|
||||
logger.log(Level.INFO, "Searcher calling get() on itself in done()"); //NON-NLS
|
||||
get();
|
||||
logger.log(Level.INFO, "Searcher finished calling get() on itself in done()"); //NON-NLS
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
logger.log(Level.SEVERE, "Error performing keyword search: " + e.getMessage()); //NON-NLS
|
||||
services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"SearchRunner.Searcher.done.err.msg"), e.getMessage()));
|
||||
} // catch and ignore if we were cancelled
|
||||
catch (java.util.concurrent.CancellationException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync-up the updated keywords from the currently used lists in the XML
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user