Fixed merge conflicts with 3275_OpenMultiUserCaseWaitCursor.

This commit is contained in:
U-BASIS\dgrove
2017-12-10 20:30:57 -05:00
49 changed files with 1033 additions and 766 deletions
+3
View File
@@ -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
+4
View File
@@ -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);
}
}
/**
@@ -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(
@@ -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);
}
}
}
@@ -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;
}
+84 -9
View File
@@ -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;
}
}
}
@@ -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
@@ -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;
@@ -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);
@@ -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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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;
@@ -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:
@@ -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.
-1
View File
@@ -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 -->
-1
View File
@@ -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
-7
View File
@@ -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>
+1 -1
View File
@@ -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"/>
+3 -3
View File
@@ -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
+8 -8
View File
@@ -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>
@@ -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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -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;
@@ -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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
@@ -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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
@@ -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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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="&lt;String&gt;"/>
@@ -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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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, &quot;{key}&quot;)"/>
</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"/>
@@ -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
*/