Merge remote-tracking branch 'upstream/release-4.5.0' into develop

This commit is contained in:
Richard Cordovano 2017-09-20 09:58:25 -04:00
commit 4741a58478
30 changed files with 942 additions and 523 deletions

View File

@ -125,7 +125,6 @@ public class Case {
private static final String LOG_FOLDER = "Log"; //NON-NLS private static final String LOG_FOLDER = "Log"; //NON-NLS
private static final String REPORTS_FOLDER = "Reports"; //NON-NLS private static final String REPORTS_FOLDER = "Reports"; //NON-NLS
private static final String TEMP_FOLDER = "Temp"; //NON-NLS private static final String TEMP_FOLDER = "Temp"; //NON-NLS
private static final int MIN_SECS_BETWEEN_TSK_ERROR_REPORTS = 60;
private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS
private static final long EXECUTOR_AWAIT_TIMEOUT_SECS = 5; private static final long EXECUTOR_AWAIT_TIMEOUT_SECS = 5;
private static final String CASE_ACTION_THREAD_NAME = "%s-case-action"; private static final String CASE_ACTION_THREAD_NAME = "%s-case-action";

View File

@ -43,7 +43,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
import org.sleuthkit.autopsy.centralrepository.optionspanel.AddNewOrganizationDialog; import org.sleuthkit.autopsy.centralrepository.optionspanel.AddNewOrganizationDialog;
/** /**
* Handle editing details of cases within the Central Repository * Handle editing details of cases within the central repository
*/ */
public class EamCaseEditDetailsDialog extends JDialog { public class EamCaseEditDetailsDialog extends JDialog {
@ -531,14 +531,14 @@ public class EamCaseEditDetailsDialog extends JDialog {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (!EamDb.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.SEVERE, "Central Repository database not enabled"); // NON-NLS LOGGER.log(Level.SEVERE, "Central repository database not enabled"); // NON-NLS
return; return;
} }
try { try {
dbManager.updateCase(eamCase); dbManager.updateCase(eamCase);
} catch (IllegalArgumentException | EamDbException ex) { } catch (IllegalArgumentException | EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to central repository database", ex); // NON-NLS
} finally { } finally {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
} }

View File

@ -66,8 +66,8 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
* View correlation results from other cases * View correlation results from other cases
*/ */
@ServiceProvider(service = DataContentViewer.class, position = 8) @ServiceProvider(service = DataContentViewer.class, position = 8)
@Messages({"DataContentViewerOtherCases.title=Other Data Sources", @Messages({"DataContentViewerOtherCases.title=Other Occurrences",
"DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other data sources.",}) "DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",})
public class DataContentViewerOtherCases extends javax.swing.JPanel implements DataContentViewer { public class DataContentViewerOtherCases extends javax.swing.JPanel implements DataContentViewer {
private final static Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName()); private final static Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName());
@ -370,7 +370,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
* *
* @param node The node to view * @param node The node to view
* *
* @return A collection of Central Repository artifacts to display * @return A collection of central repository artifacts to display
*/ */
private Collection<EamArtifact> getArtifactsFromCorrelatableAttributes(Node node) { private Collection<EamArtifact> getArtifactsFromCorrelatableAttributes(Node node) {
Collection<EamArtifact> ret = new ArrayList<>(); Collection<EamArtifact> ret = new ArrayList<>();
@ -450,7 +450,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
/** /**
* Query the db for artifact instances from other cases correlated to the * Query the db for artifact instances from other cases correlated to the
* given Central Repository artifact. * given central repository artifact.
* *
* @param eamArtifact The artifact to correlate against * @param eamArtifact The artifact to correlate against
* *
@ -474,12 +474,12 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
} }
/** /**
* Get the Global File Instances matching the given eamArtifact and convert * Get the global file instances matching the given eamArtifact and convert
* them to Central Repository Artifact Instancess. * them to central repository artifact instancess.
* *
* @param eamArtifact Artifact to use for ArtifactTypeEnum matching * @param eamArtifact Artifact to use for ArtifactTypeEnum matching
* *
* @return List of Central Repository Artifact Instances, empty list if none * @return List of central repository artifact instances, empty list if none
* found * found
*/ */
public Collection<EamArtifactInstance> getReferenceInstancesAsArtifactInstances(EamArtifact eamArtifact) { public Collection<EamArtifactInstance> getReferenceInstancesAsArtifactInstances(EamArtifact eamArtifact) {
@ -530,8 +530,8 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
* *
* @param node The node being viewed. * @param node The node being viewed.
*/ */
@Messages({"DataContentViewerOtherCases.table.isempty=There are no associated artifacts or files from other cases to display.", @Messages({"DataContentViewerOtherCases.table.isempty=There are no associated artifacts or files from other occurrences to display.",
"DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file; likely missing MD5 hash."}) "DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file."})
private void populateTable(Node node) { private void populateTable(Node node) {
String dataSourceName = getDataSourceNameFromNode(node); String dataSourceName = getDataSourceNameFromNode(node);
String deviceId = getDeviceIdFromNode(node); String deviceId = getDeviceIdFromNode(node);

View File

@ -175,9 +175,9 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
} }
/** /**
* Add one local Central Repository Artifact to the table. * Add one local central repository artifact to the table.
* *
* @param eamArtifact Central Repository Artifact to add to the * @param eamArtifact central repository artifact to add to the
* table * table
*/ */
public void addEamArtifact(EamArtifact eamArtifact) { public void addEamArtifact(EamArtifact eamArtifact) {

View File

@ -170,7 +170,7 @@ public class EamArtifact implements Serializable {
* *
* @param id Unique ID for this Correlation Type * @param id Unique ID for this Correlation Type
* @param displayName Name of this type displayed in the UI. * @param displayName Name of this type displayed in the UI.
* @param dbTableName Central Repository db table where data of this type is stored. * @param dbTableName Central repository db table where data of this type is stored.
* Must start with a lowercase letter and only contain * Must start with a lowercase letter and only contain
* lowercase letters, numbers, and '_' characters. * lowercase letters, numbers, and '_' characters.
* @param supported Is this Type currently supported * @param supported Is this Type currently supported
@ -190,10 +190,10 @@ public class EamArtifact implements Serializable {
/** /**
* Constructior for custom types where we do not know the Type ID until * Constructior for custom types where we do not know the Type ID until
* the row has been entered into the correlation_types table * the row has been entered into the correlation_types table
* in the Central Repository. * in the central repository.
* *
* @param displayName Name of this type displayed in the UI. * @param displayName Name of this type displayed in the UI.
* @param dbTableName Central Repository db table where data of this type is stored * @param dbTableName Central repository db table where data of this type is stored
* Must start with a lowercase letter and only contain * Must start with a lowercase letter and only contain
* lowercase letters, numbers, and '_' characters. * lowercase letters, numbers, and '_' characters.
* @param supported Is this Type currently supported * @param supported Is this Type currently supported

View File

@ -190,7 +190,8 @@ public class IngestEventsListener {
} }
} }
@NbBundle.Messages({"IngestEventsListener.prevcases.text=Previous Cases", @NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
"IngestEventsListener.prevCaseComment.text=Previous Case: ",
"IngestEventsListener.ingestmodule.name=Correlation Engine"}) "IngestEventsListener.ingestmodule.name=Correlation Engine"})
private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List<String> caseDisplayNames) { private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List<String> caseDisplayNames) {
@ -200,9 +201,9 @@ public class IngestEventsListener {
String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name(); String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name();
BlackboardArtifact tifArtifact = af.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT); BlackboardArtifact tifArtifact = af.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.IngestEventsListener_prevcases_text()); Bundle.IngestEventsListener_prevTaggedSet_text());
BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME,
"Previous Case: " + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", ""))); Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
tifArtifact.addAttribute(att); tifArtifact.addAttribute(att);
tifArtifact.addAttribute(att2); tifArtifact.addAttribute(att2);
tifArtifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, bbArtifact.getArtifactID())); tifArtifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, bbArtifact.getArtifactID()));

View File

@ -54,7 +54,8 @@ import org.sleuthkit.datamodel.TskDataException;
* Ingest module for inserting entries into the Central Repository database on * Ingest module for inserting entries into the Central Repository database on
* ingest of a data source * ingest of a data source
*/ */
@Messages({"IngestModule.prevcases.text=Previous Cases"}) @Messages({"IngestModule.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
"IngestModule.prevCaseComment.text=Previous Case: "})
class IngestModule implements FileIngestModule { class IngestModule implements FileIngestModule {
private final static Logger LOGGER = Logger.getLogger(IngestModule.class.getName()); private final static Logger LOGGER = Logger.getLogger(IngestModule.class.getName());
@ -187,7 +188,7 @@ class IngestModule implements FileIngestModule {
// see ArtifactManagerTimeTester for details // see ArtifactManagerTimeTester for details
@Messages({ @Messages({
"IngestModule.notfyBubble.title=Central Repository Not Initialized", "IngestModule.notfyBubble.title=Central Repository Not Initialized",
"IngestModule.errorMessage.isNotEnabled=Central Repository settings are not initialized, cannot run Correlation Engine ingest module." "IngestModule.errorMessage.isNotEnabled=Central repository settings are not initialized, cannot run Correlation Engine ingest module."
}) })
@Override @Override
public void startUp(IngestJobContext context) throws IngestModuleException { public void startUp(IngestJobContext context) throws IngestModuleException {
@ -210,8 +211,8 @@ class IngestModule implements FileIngestModule {
// Don't allow sqlite central repo databases to be used for multi user cases // Don't allow sqlite central repo databases to be used for multi user cases
if((Case.getCurrentCase().getCaseType() == Case.CaseType.MULTI_USER_CASE) if((Case.getCurrentCase().getCaseType() == Case.CaseType.MULTI_USER_CASE)
&& (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.SQLITE)){ && (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.SQLITE)){
LOGGER.log(Level.SEVERE, "Cannot run correlation engine on a multi-user case with a SQLite Central Repository."); LOGGER.log(Level.SEVERE, "Cannot run correlation engine on a multi-user case with a SQLite central repository.");
throw new IngestModuleException("Cannot run on a multi-user case with a SQLite Central Repository."); // NON-NLS throw new IngestModuleException("Cannot run on a multi-user case with a SQLite central repository."); // NON-NLS
} }
jobId = context.getJobId(); jobId = context.getJobId();
eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()); eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName());
@ -230,8 +231,8 @@ class IngestModule implements FileIngestModule {
try { try {
dbManager = EamDb.getInstance(); dbManager = EamDb.getInstance();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to central repository database.", ex); // NON-NLS
throw new IngestModuleException("Error connecting to Central Repository database.", ex); // NON-NLS throw new IngestModuleException("Error connecting to central repository database.", ex); // NON-NLS
} }
try { try {
@ -289,9 +290,9 @@ class IngestModule implements FileIngestModule {
String MODULE_NAME = IngestModuleFactory.getModuleName(); String MODULE_NAME = IngestModuleFactory.getModuleName();
BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT); BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.IngestModule_prevcases_text()); Bundle.IngestModule_prevTaggedSet_text());
BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME,
"Previous Case: " + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", ""))); Bundle.IngestModule_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
tifArtifact.addAttribute(att); tifArtifact.addAttribute(att);
tifArtifact.addAttribute(att2); tifArtifact.addAttribute(att2);
@ -319,7 +320,7 @@ class IngestModule implements FileIngestModule {
String MODULE_NAME = IngestModuleFactory.getModuleName(); String MODULE_NAME = IngestModuleFactory.getModuleName();
BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT); BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.IngestModule_prevcases_text()); Bundle.IngestModule_prevCaseComment_text());
tifArtifact.addAttribute(att); tifArtifact.addAttribute(att);
try { try {

View File

@ -8,7 +8,7 @@ EamPostgresSettingsDialog.bnCancel.text=Cancel
EamPostgresSettingsDialog.lbPort.text=Port : EamPostgresSettingsDialog.lbPort.text=Port :
EamPostgresSettingsDialog.lbHostName.text=Host Name / IP : EamPostgresSettingsDialog.lbHostName.text=Host Name / IP :
EamPostgresSettingsDialog.bnTestConnection.text=Test Connection EamPostgresSettingsDialog.bnTestConnection.text=Test Connection
EamPostgresSettingsDialog.lbDatabaseName.text=Database name : EamPostgresSettingsDialog.lbDatabaseName.text=Database Name :
EamSqliteSettingsDialog.bnCancel.text=Cancel EamSqliteSettingsDialog.bnCancel.text=Cancel
EamSqliteSettingsDialog.lbTestDatabase.text= EamSqliteSettingsDialog.lbTestDatabase.text=
EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection

View File

@ -59,7 +59,7 @@ public class EamDbSettingsDialog extends JDialog {
*/ */
@Messages({"EamDbSettingsDialog.title.text=Central Repository Database Configuration", @Messages({"EamDbSettingsDialog.title.text=Central Repository Database Configuration",
"EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time.", "EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time.",
"EamDbSettingsDialog.lbDatabaseType.text=Database type :", "EamDbSettingsDialog.lbDatabaseType.text=Database Type :",
"EamDbSettingsDialog.fcDatabasePath.title=Select location for central_repository.db"}) "EamDbSettingsDialog.fcDatabasePath.title=Select location for central_repository.db"})
public EamDbSettingsDialog() { public EamDbSettingsDialog() {
@ -94,7 +94,7 @@ public class EamDbSettingsDialog extends JDialog {
@Override @Override
public String getDescription() { public String getDescription() {
return "Directories and Central Repository databases"; return "Directories and central repository databases";
} }
}); });
cbDatabaseType.setSelectedItem(selectedPlatform); cbDatabaseType.setSelectedItem(selectedPlatform);
@ -419,7 +419,7 @@ public class EamDbSettingsDialog extends JDialog {
Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(), Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(),
Bundle.EamDbSettingsDialog_okButton_createDbError_title(), Bundle.EamDbSettingsDialog_okButton_createDbError_title(),
JOptionPane.WARNING_MESSAGE); JOptionPane.WARNING_MESSAGE);
LOGGER.severe("Unable to initialize database schema or insert contents into Central Repository."); LOGGER.severe("Unable to initialize database schema or insert contents into central repository.");
return; return;
} }
break; break;
@ -440,7 +440,7 @@ public class EamDbSettingsDialog extends JDialog {
Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(), Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(),
Bundle.EamDbSettingsDialog_okButton_createDbError_title(), Bundle.EamDbSettingsDialog_okButton_createDbError_title(),
JOptionPane.WARNING_MESSAGE); JOptionPane.WARNING_MESSAGE);
LOGGER.severe("Unable to initialize database schema or insert contents into Central Repository."); LOGGER.severe("Unable to initialize database schema or insert contents into central repository.");
return; return;
} }
break; break;
@ -459,7 +459,7 @@ public class EamDbSettingsDialog extends JDialog {
@Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.", @Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.",
"EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.",
"EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to Central Repository database.", "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database.",
"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", "EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database",
"EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).",
"EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist",

View File

@ -19,32 +19,46 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="pnDatabaseContentButtons" max="32767" attributes="0"/>
<Component id="tbOops" alignment="1" max="32767" attributes="0"/> <Component id="tbOops" alignment="1" max="32767" attributes="0"/>
<Component id="pnDatabaseConfiguration" max="32767" attributes="0"/> <Group type="102" alignment="1" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Component id="cbUseCentralRepo" min="-2" pref="186" max="-2" attributes="0"/> <Component id="lbCentralRepository" alignment="0" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <Component id="pnCorrelationProperties" alignment="0" max="32767" attributes="0"/>
<Component id="pnTagManagement" alignment="0" max="32767" attributes="0"/>
<Component id="pnDatabaseConfiguration" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="cbUseCentralRepo" alignment="0" min="-2" pref="186" max="-2" attributes="0"/>
<Component id="bnImportDatabase" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="lbCentralRepository" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbUseCentralRepo" min="-2" max="-2" attributes="0"/> <Component id="cbUseCentralRepo" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="pnDatabaseConfiguration" min="-2" max="-2" attributes="0"/> <Component id="pnDatabaseConfiguration" min="-2" pref="119" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="pnTagManagement" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="pnCorrelationProperties" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="tbOops" min="-2" max="-2" attributes="0"/> <Component id="tbOops" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="pnDatabaseContentButtons" min="-2" pref="50" max="-2" attributes="0"/> <Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -66,26 +80,26 @@
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbDbPlatformTypeLabel" max="32767" attributes="0"/> <Component id="lbDbPlatformTypeLabel" max="32767" attributes="0"/>
<Component id="lbDbNameLabel" alignment="0" max="32767" attributes="0"/> <Component id="lbDbNameLabel" alignment="0" max="32767" attributes="0"/>
<Component id="lbDbLocationLabel" alignment="0" min="-2" pref="57" max="-2" attributes="0"/> <Component id="lbDbLocationLabel" alignment="0" min="-2" pref="57" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Component id="lbDbNameValue" alignment="0" max="32767" attributes="0"/>
<Component id="lbDbPlatformValue" alignment="0" min="-2" pref="711" max="-2" attributes="0"/> <Component id="lbDbPlatformValue" max="32767" attributes="0"/>
<Component id="lbDbNameValue" alignment="1" min="-2" pref="711" max="-2" attributes="0"/> <Component id="lbDbLocationValue" alignment="0" max="32767" attributes="0"/>
</Group>
<Component id="lbDbLocationValue" alignment="1" min="-2" pref="711" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<Component id="bnDbConfigure" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -107,9 +121,9 @@
<Component id="lbDbLocationLabel" max="32767" attributes="0"/> <Component id="lbDbLocationLabel" max="32767" attributes="0"/>
<Component id="lbDbLocationValue" min="-2" pref="14" max="-2" attributes="0"/> <Component id="lbDbLocationValue" min="-2" pref="14" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace pref="11" max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/> <Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -154,53 +168,81 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="pnDatabaseContentButtons"> <Component class="javax.swing.JCheckBox" name="cbUseCentralRepo">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.cbUseCentralRepo.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="cbUseCentralRepoActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnImportDatabase">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/centralrepository/images/import16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnImportDatabase.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnImportDatabase.actionCommand" 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="bnImportDatabaseActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JPanel" name="pnTagManagement">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;GlobalSettingsPanel.pnTagManagement.border.title&gt;">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.pnTagManagement.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[674, 97]"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/>
</AccessibilityProperties>
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <Group type="102" attributes="0">
<Component id="bnManageTags" min="-2" max="-2" attributes="0"/> <Component id="bnManageTags" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace min="0" pref="555" max="32767" attributes="0"/>
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/> </Group>
<EmptySpace max="32767" attributes="0"/> <Group type="102" attributes="0">
<Component id="manageTagsScrollPane" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="32767" attributes="0"/> <EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Component id="manageTagsScrollPane" min="-2" pref="31" max="-2" attributes="0"/>
<Component id="bnImportDatabase" alignment="3" min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="bnManageTags" alignment="3" min="-2" pref="25" max="-2" attributes="0"/> <Component id="bnManageTags" min="-2" pref="25" max="-2" attributes="0"/>
<Component id="bnManageTypes" alignment="3" min="-2" pref="25" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="34" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JButton" name="bnImportDatabase">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/centralrepository/images/import16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnImportDatabase.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnImportDatabase.actionCommand" 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="bnImportDatabaseActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnManageTags"> <Component class="javax.swing.JButton" name="bnManageTags">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -217,16 +259,42 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnManageTagsActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnManageTagsActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JButton" name="bnManageTypes"> <Container class="javax.swing.JScrollPane" name="manageTagsScrollPane">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnManageProperties.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <Border info="null"/>
</Property> </Property>
</Properties> </Properties>
<Events> <AuxValues>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnManageTypesActionPerformed"/> <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</Events> </AuxValues>
</Component>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="manageTagsTextArea">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="0"/>
</Property>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="2"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.manageTagsTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="wrapStyleWord" type="boolean" value="true"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JTextField" name="tbOops"> <Component class="javax.swing.JTextField" name="tbOops">
@ -244,16 +312,108 @@
<Border info="null"/> <Border info="null"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbOopsActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="cbUseCentralRepo"> <Container class="javax.swing.JPanel" name="pnCorrelationProperties">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.cbUseCentralRepo.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;GlobalSettingsPanel.pnCorrelationProperties.border.title&gt;">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.pnCorrelationProperties.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[674, 93]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="correlationPropertiesScrollPane" pref="642" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<Component id="correlationPropertiesScrollPane" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="bnManageTypes">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnManageProperties.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="bnManageTypesActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="correlationPropertiesScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="correlationPropertiesTextArea">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="0"/>
</Property>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="2"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.correlationPropertiesTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="wrapStyleWord" type="boolean" value="true"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="lbCentralRepository">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="GlobalSettingsPanel.lbCentralRepository.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseCentralRepoActionPerformed"/>
</Events>
</Component> </Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -41,7 +41,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(GlobalSettingsPanel.class.getName()); private static final Logger LOGGER = Logger.getLogger(GlobalSettingsPanel.class.getName());
private final IngestJobEventPropertyChangeListener ingestJobEventListener; private final IngestJobEventPropertyChangeListener ingestJobEventListener;
/** /**
@ -56,7 +56,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
} }
@Messages({"GlobalSettingsPanel.title=Central Repository Settings", @Messages({"GlobalSettingsPanel.title=Central Repository Settings",
"GlobalSettingsPanel.cbUseCentralRepo.text=Use a Central Repository"}) "GlobalSettingsPanel.cbUseCentralRepo.text=Use a central repository",
"GlobalSettingsPanel.pnTagManagement.border.title=Tags",
"GlobalSettingsPanel.pnCorrelationProperties.border.title=Correlation Properties",
"GlobalSettingsPanel.lbCentralRepository.text=A central repository allows you to correlate files and results between cases.",
"GlobalSettingsPanel.manageTagsTextArea.text=Configure which tag names are associated with notable or known bad items. "
+ "When these tags are used, the file or result will be recorded in the central repository. "
+ "If that file or result is seen again in future cases, it will be flagged.",
"GlobalSettingsPanel.correlationPropertiesTextArea.text=Choose which file and result properties to store in the central central repository for later correlation."})
private void customizeComponents() { private void customizeComponents() {
setName(Bundle.GlobalSettingsPanel_title()); setName(Bundle.GlobalSettingsPanel_title());
@ -86,12 +93,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
lbDbPlatformValue = new javax.swing.JLabel(); lbDbPlatformValue = new javax.swing.JLabel();
lbDbNameValue = new javax.swing.JLabel(); lbDbNameValue = new javax.swing.JLabel();
lbDbLocationValue = new javax.swing.JLabel(); lbDbLocationValue = new javax.swing.JLabel();
pnDatabaseContentButtons = new javax.swing.JPanel();
bnImportDatabase = new javax.swing.JButton();
bnManageTags = new javax.swing.JButton();
bnManageTypes = new javax.swing.JButton();
tbOops = new javax.swing.JTextField();
cbUseCentralRepo = new javax.swing.JCheckBox(); cbUseCentralRepo = new javax.swing.JCheckBox();
bnImportDatabase = new javax.swing.JButton();
pnTagManagement = new javax.swing.JPanel();
bnManageTags = new javax.swing.JButton();
manageTagsScrollPane = new javax.swing.JScrollPane();
manageTagsTextArea = new javax.swing.JTextArea();
tbOops = new javax.swing.JTextField();
pnCorrelationProperties = new javax.swing.JPanel();
bnManageTypes = new javax.swing.JButton();
correlationPropertiesScrollPane = new javax.swing.JScrollPane();
correlationPropertiesTextArea = new javax.swing.JTextArea();
lbCentralRepository = new javax.swing.JLabel();
setName(""); // NOI18N setName(""); // NOI18N
@ -117,19 +130,19 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
.addComponent(bnDbConfigure)
.addContainerGap())
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbDbNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbDbLocationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbDbPlatformValue, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
.addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(bnDbConfigure))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
pnDatabaseConfigurationLayout.setVerticalGroup( pnDatabaseConfigurationLayout.setVerticalGroup(
pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -146,11 +159,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bnDbConfigure) .addComponent(bnDbConfigure)
.addContainerGap()) .addGap(8, 8, 8))
); );
org.openide.awt.Mnemonics.setLocalizedText(cbUseCentralRepo, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.cbUseCentralRepo.text")); // NOI18N
cbUseCentralRepo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseCentralRepoActionPerformed(evt);
}
});
bnImportDatabase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/centralrepository/images/import16.png"))); // NOI18N bnImportDatabase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/centralrepository/images/import16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnImportDatabase, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnImportDatabase.label")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(bnImportDatabase, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnImportDatabase.label")); // NOI18N
bnImportDatabase.setActionCommand(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnImportDatabase.actionCommand")); // NOI18N bnImportDatabase.setActionCommand(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnImportDatabase.actionCommand")); // NOI18N
@ -160,6 +180,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
} }
}); });
pnTagManagement.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnTagManagement.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
pnTagManagement.setPreferredSize(new java.awt.Dimension(674, 97));
org.openide.awt.Mnemonics.setLocalizedText(bnManageTags, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(bnManageTags, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.text")); // NOI18N
bnManageTags.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.toolTipText")); // NOI18N bnManageTags.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.toolTipText")); // NOI18N
bnManageTags.setActionCommand(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.actionCommand")); // NOI18N bnManageTags.setActionCommand(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.actionCommand")); // NOI18N
@ -169,6 +192,57 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
} }
}); });
manageTagsScrollPane.setBorder(null);
manageTagsTextArea.setEditable(false);
manageTagsTextArea.setBackground(new java.awt.Color(240, 240, 240));
manageTagsTextArea.setColumns(20);
manageTagsTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
manageTagsTextArea.setLineWrap(true);
manageTagsTextArea.setRows(2);
manageTagsTextArea.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.manageTagsTextArea.text")); // NOI18N
manageTagsTextArea.setToolTipText("");
manageTagsTextArea.setWrapStyleWord(true);
manageTagsTextArea.setBorder(null);
manageTagsScrollPane.setViewportView(manageTagsTextArea);
javax.swing.GroupLayout pnTagManagementLayout = new javax.swing.GroupLayout(pnTagManagement);
pnTagManagement.setLayout(pnTagManagementLayout);
pnTagManagementLayout.setHorizontalGroup(
pnTagManagementLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnTagManagementLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnTagManagementLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnTagManagementLayout.createSequentialGroup()
.addComponent(bnManageTags)
.addGap(0, 555, Short.MAX_VALUE))
.addGroup(pnTagManagementLayout.createSequentialGroup()
.addComponent(manageTagsScrollPane)
.addContainerGap())))
);
pnTagManagementLayout.setVerticalGroup(
pnTagManagementLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnTagManagementLayout.createSequentialGroup()
.addGap(7, 7, 7)
.addComponent(manageTagsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnManageTags, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(8, 8, 8))
);
tbOops.setEditable(false);
tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
tbOops.setBorder(null);
tbOops.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tbOopsActionPerformed(evt);
}
});
pnCorrelationProperties.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
pnCorrelationProperties.setPreferredSize(new java.awt.Dimension(674, 93));
org.openide.awt.Mnemonics.setLocalizedText(bnManageTypes, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageProperties.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(bnManageTypes, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageProperties.text")); // NOI18N
bnManageTypes.addActionListener(new java.awt.event.ActionListener() { bnManageTypes.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -176,41 +250,44 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
} }
}); });
javax.swing.GroupLayout pnDatabaseContentButtonsLayout = new javax.swing.GroupLayout(pnDatabaseContentButtons); correlationPropertiesScrollPane.setBorder(null);
pnDatabaseContentButtons.setLayout(pnDatabaseContentButtonsLayout);
pnDatabaseContentButtonsLayout.setHorizontalGroup( correlationPropertiesTextArea.setEditable(false);
pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) correlationPropertiesTextArea.setBackground(new java.awt.Color(240, 240, 240));
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup() correlationPropertiesTextArea.setColumns(20);
correlationPropertiesTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
correlationPropertiesTextArea.setLineWrap(true);
correlationPropertiesTextArea.setRows(2);
correlationPropertiesTextArea.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.correlationPropertiesTextArea.text")); // NOI18N
correlationPropertiesTextArea.setToolTipText("");
correlationPropertiesTextArea.setWrapStyleWord(true);
correlationPropertiesTextArea.setBorder(null);
correlationPropertiesScrollPane.setViewportView(correlationPropertiesTextArea);
javax.swing.GroupLayout pnCorrelationPropertiesLayout = new javax.swing.GroupLayout(pnCorrelationProperties);
pnCorrelationProperties.setLayout(pnCorrelationPropertiesLayout);
pnCorrelationPropertiesLayout.setHorizontalGroup(
pnCorrelationPropertiesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnCorrelationPropertiesLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(bnImportDatabase) .addGroup(pnCorrelationPropertiesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 642, Short.MAX_VALUE)
.addGroup(pnCorrelationPropertiesLayout.createSequentialGroup()
.addComponent(bnManageTypes)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
pnCorrelationPropertiesLayout.setVerticalGroup(
pnCorrelationPropertiesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnCorrelationPropertiesLayout.createSequentialGroup()
.addGap(7, 7, 7)
.addComponent(correlationPropertiesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnManageTags)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnManageTypes) .addComponent(bnManageTypes)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(8, 8, 8))
);
pnDatabaseContentButtonsLayout.setVerticalGroup(
pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnImportDatabase)
.addComponent(bnManageTags, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnManageTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(34, 34, 34))
); );
tbOops.setEditable(false); org.openide.awt.Mnemonics.setLocalizedText(lbCentralRepository, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbCentralRepository.text")); // NOI18N
tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
tbOops.setBorder(null);
org.openide.awt.Mnemonics.setLocalizedText(cbUseCentralRepo, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.cbUseCentralRepo.text")); // NOI18N
cbUseCentralRepo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseCentralRepoActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
@ -219,26 +296,39 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(tbOops, javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(tbOops, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(cbUseCentralRepo, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lbCentralRepository, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, Short.MAX_VALUE))) .addComponent(pnCorrelationProperties, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap()) .addComponent(pnTagManagement, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(cbUseCentralRepo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnImportDatabase, javax.swing.GroupLayout.Alignment.LEADING))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())))
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(lbCentralRepository)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cbUseCentralRepo) .addComponent(cbUseCentralRepo)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(pnTagManagement, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGap(0, 0, 0)
.addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(bnImportDatabase))
.addContainerGap())
); );
pnTagManagement.getAccessibleContext().setAccessibleName("");
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void bnImportDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnImportDatabaseActionPerformed private void bnImportDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnImportDatabaseActionPerformed
@ -276,6 +366,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_cbUseCentralRepoActionPerformed }//GEN-LAST:event_cbUseCentralRepoActionPerformed
private void tbOopsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbOopsActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_tbOopsActionPerformed
@Override @Override
@Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."}) @Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."})
public void load() { public void load() {
@ -398,7 +492,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private void enableDatabaseConfigureButton(Boolean enable) { private void enableDatabaseConfigureButton(Boolean enable) {
boolean ingestRunning = IngestManager.getInstance().isIngestRunning(); boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
pnDatabaseConfiguration.setEnabled(enable && !ingestRunning); pnDatabaseConfiguration.setEnabled(enable && !ingestRunning);
pnDatabaseContentButtons.setEnabled(enable && !ingestRunning);
bnDbConfigure.setEnabled(enable && !ingestRunning); bnDbConfigure.setEnabled(enable && !ingestRunning);
lbDbLocationLabel.setEnabled(enable && !ingestRunning); lbDbLocationLabel.setEnabled(enable && !ingestRunning);
lbDbLocationValue.setEnabled(enable && !ingestRunning); lbDbLocationValue.setEnabled(enable && !ingestRunning);
@ -418,10 +511,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
* @return True * @return True
*/ */
private boolean enableButtonSubComponents(Boolean enable) { private boolean enableButtonSubComponents(Boolean enable) {
boolean ingestRunning = IngestManager.getInstance().isIngestRunning(); boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
pnCorrelationProperties.setEnabled(enable && !ingestRunning);
pnTagManagement.setEnabled(enable && !ingestRunning);
bnManageTypes.setEnabled(enable && !ingestRunning); bnManageTypes.setEnabled(enable && !ingestRunning);
bnImportDatabase.setEnabled(enable && !ingestRunning); bnImportDatabase.setEnabled(enable && !ingestRunning);
bnManageTags.setEnabled(enable && !ingestRunning); bnManageTags.setEnabled(enable && !ingestRunning);
manageTagsTextArea.setEnabled(enable && !ingestRunning);
correlationPropertiesTextArea.setEnabled(enable && !ingestRunning);
return true; return true;
} }
@ -431,14 +528,20 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private javax.swing.JButton bnManageTags; private javax.swing.JButton bnManageTags;
private javax.swing.JButton bnManageTypes; private javax.swing.JButton bnManageTypes;
private javax.swing.JCheckBox cbUseCentralRepo; private javax.swing.JCheckBox cbUseCentralRepo;
private javax.swing.JScrollPane correlationPropertiesScrollPane;
private javax.swing.JTextArea correlationPropertiesTextArea;
private javax.swing.JLabel lbCentralRepository;
private javax.swing.JLabel lbDbLocationLabel; private javax.swing.JLabel lbDbLocationLabel;
private javax.swing.JLabel lbDbLocationValue; private javax.swing.JLabel lbDbLocationValue;
private javax.swing.JLabel lbDbNameLabel; private javax.swing.JLabel lbDbNameLabel;
private javax.swing.JLabel lbDbNameValue; private javax.swing.JLabel lbDbNameValue;
private javax.swing.JLabel lbDbPlatformTypeLabel; private javax.swing.JLabel lbDbPlatformTypeLabel;
private javax.swing.JLabel lbDbPlatformValue; private javax.swing.JLabel lbDbPlatformValue;
private javax.swing.JScrollPane manageTagsScrollPane;
private javax.swing.JTextArea manageTagsTextArea;
private javax.swing.JPanel pnCorrelationProperties;
private javax.swing.JPanel pnDatabaseConfiguration; private javax.swing.JPanel pnDatabaseConfiguration;
private javax.swing.JPanel pnDatabaseContentButtons; private javax.swing.JPanel pnTagManagement;
private javax.swing.JTextField tbOops; private javax.swing.JTextField tbOops;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -587,7 +587,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
this.progress = ProgressHandle.createHandle(Bundle.ImportHashDatabaseDialog_ImportHashDatabaseWorker_displayName()); this.progress = ProgressHandle.createHandle(Bundle.ImportHashDatabaseDialog_ImportHashDatabaseWorker_displayName());
if (!EamDb.isEnabled()) { if (!EamDb.isEnabled()) {
throw new EamDbException("Central Repository database is not enabled."); // NON-NLS throw new EamDbException("Central repository database is not enabled."); // NON-NLS
} }
} }

View File

@ -249,7 +249,7 @@ final class ManageCorrelationPropertiesDialog extends javax.swing.JDialog {
try { try {
dbManager = EamDb.getInstance(); dbManager = EamDb.getInstance();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database.", ex); LOGGER.log(Level.SEVERE, "Failed to connect to central repository database.", ex);
lbWarningMsg.setText(Bundle.ManageCorrelationPropertiesDialog_okbutton_failure()); lbWarningMsg.setText(Bundle.ManageCorrelationPropertiesDialog_okbutton_failure());
return; return;
} }

View File

@ -31,17 +31,18 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="0" pref="223" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="okButton" linkSize="1" min="-2" max="-2" attributes="0"/> <Component id="okButton" linkSize="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/> <Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Group type="103" groupAlignment="1" attributes="0">
<Component id="jScrollPane1" pref="357" max="32767" attributes="0"/> <Component id="helpScrollPane" alignment="0" max="32767" attributes="0"/>
<Component id="lbWarnings" max="32767" attributes="0"/> <Component id="tagScrollArea" alignment="0" pref="328" max="32767" attributes="0"/>
<Component id="lbWarnings" alignment="0" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -51,16 +52,18 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="335" max="-2" attributes="0"/> <Component id="helpScrollPane" min="-2" pref="42" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="lbWarnings" pref="16" max="32767" attributes="0"/> <Component id="tagScrollArea" pref="341" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="lbWarnings" min="-2" pref="18" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -86,7 +89,7 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1"> <Container class="javax.swing.JScrollPane" name="tagScrollArea">
<AuxValues> <AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues> </AuxValues>
@ -97,8 +100,8 @@
<Properties> <Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="2" rowCount="0"> <Table columnCount="2" rowCount="0">
<Column editable="false" title="Tag" type="java.lang.Object"/> <Column editable="false" title="" type="java.lang.Object"/>
<Column editable="true" title="Implies Known Bad" type="java.lang.Boolean"/> <Column editable="true" title="" type="java.lang.Boolean"/>
</Table> </Table>
</Property> </Property>
</Properties> </Properties>
@ -107,5 +110,38 @@
</Container> </Container>
<Component class="javax.swing.JLabel" name="lbWarnings"> <Component class="javax.swing.JLabel" name="lbWarnings">
</Component> </Component>
<Container class="javax.swing.JScrollPane" name="helpScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="helpTextArea">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="0"/>
</Property>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="3"/>
<Property name="wrapStyleWord" type="boolean" value="true"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -60,25 +60,34 @@ final class ManageTagsDialog extends javax.swing.JDialog {
* and add it to the set of hash databases used to classify files as * and add it to the set of hash databases used to classify files as
* unknown, known, or known bad. * unknown, known, or known bad.
*/ */
@Messages({"ManageTagDialog.title=Manage Tags"}) @Messages({"ManageTagDialog.title=Manage Tags",
"ManageTagDialog.tagInfo.text=Select the tags that cause files and results to be recorded in the central repository. Additional tags can be created in the Tags options panel."})
ManageTagsDialog() { ManageTagsDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(), super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.ManageTagDialog_title(), Bundle.ManageTagDialog_title(),
true); // NON-NLS true); // NON-NLS
initComponents(); initComponents();
customizeComponents(); customizeComponents();
setupHelpTextArea();
display(); display();
} }
@Messages({"ManageTagsDialog.init.failedConnection.msg=Cannot connect to Central Repository.",
"ManageTagsDialog.init.failedGettingTags.msg=Unable to retrieve list of tags."}) @Messages({"ManageTagsDialog.init.failedConnection.msg=Cannot connect to central cepository.",
"ManageTagsDialog.init.failedGettingTags.msg=Unable to retrieve list of tags.",
"ManageTagsDialog.tagColumn.header.text=Tags",
"ManageTagsDialog.notableColumn.header.text=Notable"})
private void setupHelpTextArea() {
helpTextArea.setText(Bundle.ManageTagDialog_tagInfo_text());
}
private void customizeComponents() { private void customizeComponents() {
lbWarnings.setText(""); lbWarnings.setText("");
EamDb dbManager; EamDb dbManager;
try { try {
dbManager = EamDb.getInstance(); dbManager = EamDb.getInstance();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database."); LOGGER.log(Level.SEVERE, "Failed to connect to central repository database.");
lbWarnings.setText(Bundle.ManageTagsDialog_init_failedConnection_msg()); lbWarnings.setText(Bundle.ManageTagsDialog_init_failedConnection_msg());
return; return;
} }
@ -99,6 +108,7 @@ final class ManageTagsDialog extends javax.swing.JDialog {
Collections.sort(tagNames); Collections.sort(tagNames);
DefaultTableModel model = (DefaultTableModel) tblTagNames.getModel(); DefaultTableModel model = (DefaultTableModel) tblTagNames.getModel();
model.setColumnIdentifiers(new String[] {Bundle.ManageTagsDialog_tagColumn_header_text(), Bundle.ManageTagsDialog_notableColumn_header_text()});
for (String tagName : tagNames) { for (String tagName : tagNames) {
boolean enabled = badTags.contains(tagName); boolean enabled = badTags.contains(tagName);
model.addRow(new Object[]{tagName, enabled}); model.addRow(new Object[]{tagName, enabled});
@ -125,9 +135,11 @@ final class ManageTagsDialog extends javax.swing.JDialog {
buttonGroup1 = new javax.swing.ButtonGroup(); buttonGroup1 = new javax.swing.ButtonGroup();
okButton = new javax.swing.JButton(); okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane(); tagScrollArea = new javax.swing.JScrollPane();
tblTagNames = new javax.swing.JTable(); tblTagNames = new javax.swing.JTable();
lbWarnings = new javax.swing.JLabel(); lbWarnings = new javax.swing.JLabel();
helpScrollPane = new javax.swing.JScrollPane();
helpTextArea = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
@ -150,7 +162,7 @@ final class ManageTagsDialog extends javax.swing.JDialog {
}, },
new String [] { new String [] {
"Tag", "Implies Known Bad" "", ""
} }
) { ) {
Class[] types = new Class [] { Class[] types = new Class [] {
@ -168,7 +180,20 @@ final class ManageTagsDialog extends javax.swing.JDialog {
return canEdit [columnIndex]; return canEdit [columnIndex];
} }
}); });
jScrollPane1.setViewportView(tblTagNames); tagScrollArea.setViewportView(tblTagNames);
helpScrollPane.setBorder(null);
helpTextArea.setEditable(false);
helpTextArea.setBackground(new java.awt.Color(240, 240, 240));
helpTextArea.setColumns(20);
helpTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
helpTextArea.setLineWrap(true);
helpTextArea.setRows(3);
helpTextArea.setWrapStyleWord(true);
helpTextArea.setBorder(null);
helpTextArea.setFocusable(false);
helpScrollPane.setViewportView(helpTextArea);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
@ -178,15 +203,16 @@ final class ManageTagsDialog extends javax.swing.JDialog {
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(0, 223, Short.MAX_VALUE) .addGap(0, 0, Short.MAX_VALUE)
.addComponent(okButton) .addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)) .addComponent(cancelButton))
.addGroup(layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE) .addComponent(helpScrollPane, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbWarnings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(tagScrollArea, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 328, Short.MAX_VALUE)
.addGap(0, 0, Short.MAX_VALUE))) .addComponent(lbWarnings, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(2, 2, 2)))
.addContainerGap()) .addContainerGap())
); );
@ -196,9 +222,11 @@ final class ManageTagsDialog extends javax.swing.JDialog {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 335, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(helpScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGap(0, 0, 0)
.addComponent(lbWarnings, javax.swing.GroupLayout.DEFAULT_SIZE, 16, Short.MAX_VALUE) .addComponent(tagScrollArea, javax.swing.GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lbWarnings, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(okButton) .addComponent(okButton)
@ -237,7 +265,7 @@ final class ManageTagsDialog extends javax.swing.JDialog {
dbManager.setBadTags(badTags); dbManager.setBadTags(badTags);
dbManager.saveSettings(); dbManager.saveSettings();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database."); // NON-NLS LOGGER.log(Level.SEVERE, "Failed to connect to central repository database."); // NON-NLS
lbWarnings.setText(Bundle.ManageTagsDialog_init_failedConnection_msg()); lbWarnings.setText(Bundle.ManageTagsDialog_init_failedConnection_msg());
return false; return false;
} }
@ -249,9 +277,9 @@ final class ManageTagsDialog extends javax.swing.JDialog {
* any existing tagged items (in the current case only) in the central repo. * any existing tagged items (in the current case only) in the central repo.
*/ */
public class CheckBoxModelListener implements TableModelListener { public class CheckBoxModelListener implements TableModelListener {
@Messages({"ManageTagsDialog.updateCurrentCase.msg=Mark as known bad any files/artifacts in the current case that have this tag?", @Messages({"ManageTagsDialog.updateCurrentCase.msg=Mark as known bad any files/results in the current case that have this tag?",
"ManageTagsDialog.updateCurrentCase.title=Update current case?", "ManageTagsDialog.updateCurrentCase.title=Update current case?",
"ManageTagsDialog.updateCurrentCase.error=Error updating existing Central Repository entries"}) "ManageTagsDialog.updateCurrentCase.error=Error updating existing central repository entries"})
javax.swing.JDialog dialog; javax.swing.JDialog dialog;
public CheckBoxModelListener(javax.swing.JDialog dialog){ public CheckBoxModelListener(javax.swing.JDialog dialog){
@ -331,9 +359,11 @@ final class ManageTagsDialog extends javax.swing.JDialog {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup buttonGroup1; private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JButton cancelButton; private javax.swing.JButton cancelButton;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane helpScrollPane;
private javax.swing.JTextArea helpTextArea;
private javax.swing.JLabel lbWarnings; private javax.swing.JLabel lbWarnings;
private javax.swing.JButton okButton; private javax.swing.JButton okButton;
private javax.swing.JScrollPane tagScrollArea;
private javax.swing.JTable tblTagNames; private javax.swing.JTable tblTagNames;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -19,27 +19,16 @@
package org.sleuthkit.autopsy.corecomponents; package org.sleuthkit.autopsy.corecomponents;
import java.awt.Insets; import java.awt.Insets;
import java.io.File;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException; import javax.swing.UnsupportedLookAndFeelException;
import org.netbeans.spi.sendopts.OptionProcessor;
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI; import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
import org.openide.modules.ModuleInstall; import org.openide.modules.ModuleInstall;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
import org.sleuthkit.autopsy.casemodule.OpenFromArguments;
import org.sleuthkit.autopsy.casemodule.StartupWindowProvider; import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@ -66,33 +55,11 @@ public class Installer extends ModuleInstall {
@Override @Override
public void restored() { public void restored() {
super.restored(); super.restored();
setLookAndFeel(); setLookAndFeel();
UIManager.put("ViewTabDisplayerUI", "org.sleuthkit.autopsy.corecomponents.NoTabsTabDisplayerUI"); UIManager.put("ViewTabDisplayerUI", "org.sleuthkit.autopsy.corecomponents.NoTabsTabDisplayerUI");
UIManager.put(DefaultTabbedContainerUI.KEY_VIEW_CONTENT_BORDER, BorderFactory.createEmptyBorder()); UIManager.put(DefaultTabbedContainerUI.KEY_VIEW_CONTENT_BORDER, BorderFactory.createEmptyBorder());
UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0));
/*
* Open the case if a case metadata file was double-clicked. This only
* works if the user has associated files with ".aut" extensions with
* Autopsy.
*/
WindowManager.getDefault().invokeWhenUIReady(() -> { WindowManager.getDefault().invokeWhenUIReady(() -> {
Collection<? extends OptionProcessor> processors = Lookup.getDefault().lookupAll(OptionProcessor.class);
for (OptionProcessor processor : processors) {
if (processor instanceof OpenFromArguments) {
OpenFromArguments argsProcessor = (OpenFromArguments) processor;
final String caseFile = argsProcessor.getDefaultArg();
if (caseFile != null && !caseFile.isEmpty() && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
try {
Case.openAsCurrentCase(caseFile);
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseFile), ex); //NON-NLS
}
return;
}
}
}
StartupWindowProvider.getInstance().open(); StartupWindowProvider.getInstance().open();
}); });
} }

View File

@ -1143,7 +1143,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
} }
tableModel.setRowCount(0); tableModel.setRowCount(0);
for (AutoIngestJob job : jobs) { for (AutoIngestJob job : jobs) {
AutoIngestJob.StageDetails status = job.getStageDetails(); AutoIngestJob.StageDetails status = job.getProcessingStageDetails();
tableModel.addRow(new Object[]{ tableModel.addRow(new Object[]{
job.getManifest().getCaseName(), // CASE job.getManifest().getCaseName(), // CASE
job.getManifest().getDataSourcePath().getFileName(), // DATA_SOURCE job.getManifest().getDataSourcePath().getFileName(), // DATA_SOURCE
@ -1152,7 +1152,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
job.getProcessingStageStartDate(), // STARTED_TIME job.getProcessingStageStartDate(), // STARTED_TIME
job.getCompletedDate(), // COMPLETED_TIME job.getCompletedDate(), // COMPLETED_TIME
status.getDescription(), // ACTIVITY status.getDescription(), // ACTIVITY
job.getErrorsOccurred(), // STATUS job.getErrorsOccurred(), // STATUS
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME ((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB
@ -1701,7 +1701,7 @@ job.getErrorsOccurred(), // STATUS
* *
* @param evt The button click event. * @param evt The button click event.
*/ */
@Messages({"AutoIngestControlPanel.casePrioritization.errorMessage=An error occurred when prioritizing the case. Some or all jobs may not have been prioritized."}) @Messages({"AutoIngestControlPanel.casePrioritization.errorMessage=An error occurred when prioritizing the case. Some or all jobs may not have been prioritized."})
private void bnPrioritizeCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeCaseActionPerformed private void bnPrioritizeCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeCaseActionPerformed
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
@ -1759,8 +1759,8 @@ job.getErrorsOccurred(), // STATUS
options[0]); options[0]);
} }
}//GEN-LAST:event_bnShowCaseLogActionPerformed }//GEN-LAST:event_bnShowCaseLogActionPerformed
@Messages({"AutoIngestControlPanel.jobPrioritization.errorMessage=An error occurred when prioritizing the job."}) @Messages({"AutoIngestControlPanel.jobPrioritization.errorMessage=An error occurred when prioritizing the job."})
private void bnPrioritizeJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeJobActionPerformed private void bnPrioritizeJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeJobActionPerformed
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

View File

@ -18,6 +18,7 @@
*/ */
package org.sleuthkit.autopsy.experimental.autoingest; package org.sleuthkit.autopsy.experimental.autoingest;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.awt.Cursor; import java.awt.Cursor;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.nio.file.Path; import java.nio.file.Path;
@ -44,6 +45,8 @@ import org.sleuthkit.autopsy.core.ServicesMonitor;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestMonitor.JobsSnapshot; import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestMonitor.JobsSnapshot;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** /**
* A dashboard for monitoring an automated ingest cluster. * A dashboard for monitoring an automated ingest cluster.
@ -55,28 +58,30 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
private static final int GENERIC_COL_MAX_WIDTH = 2000; private static final int GENERIC_COL_MAX_WIDTH = 2000;
private static final int PENDING_TABLE_COL_PREFERRED_WIDTH = 280; private static final int PENDING_TABLE_COL_PREFERRED_WIDTH = 280;
private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175; private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175;
private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250; private static final int STAGE_TIME_COL_MIN_WIDTH = 250;
private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450; private static final int STAGE_TIME_COL_MAX_WIDTH = 450;
private static final int TIME_COL_MIN_WIDTH = 30; private static final int TIME_COL_MIN_WIDTH = 30;
private static final int TIME_COL_MAX_WIDTH = 250; private static final int TIME_COL_MAX_WIDTH = 250;
private static final int TIME_COL_PREFERRED_WIDTH = 140; private static final int TIME_COL_PREFERRED_WIDTH = 140;
private static final int NAME_COL_MIN_WIDTH = 100; private static final int NAME_COL_MIN_WIDTH = 100;
private static final int NAME_COL_MAX_WIDTH = 250; private static final int NAME_COL_MAX_WIDTH = 250;
private static final int NAME_COL_PREFERRED_WIDTH = 140; private static final int NAME_COL_PREFERRED_WIDTH = 140;
private static final int ACTIVITY_COL_MIN_WIDTH = 70; private static final int STAGE_COL_MIN_WIDTH = 70;
private static final int ACTIVITY_COL_MAX_WIDTH = 2000; private static final int STAGE_COL_MAX_WIDTH = 2000;
private static final int ACTIVITY_COL_PREFERRED_WIDTH = 300; private static final int STAGE_COL_PREFERRED_WIDTH = 300;
private static final int STATUS_COL_MIN_WIDTH = 55; private static final int STATUS_COL_MIN_WIDTH = 55;
private static final int STATUS_COL_MAX_WIDTH = 250; private static final int STATUS_COL_MAX_WIDTH = 250;
private static final int STATUS_COL_PREFERRED_WIDTH = 55; private static final int STATUS_COL_PREFERRED_WIDTH = 55;
private static final int COMPLETED_TIME_COL_MIN_WIDTH = 30; private static final int COMPLETED_TIME_COL_MIN_WIDTH = 30;
private static final int COMPLETED_TIME_COL_MAX_WIDTH = 2000; private static final int COMPLETED_TIME_COL_MAX_WIDTH = 2000;
private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280; private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280;
private static final String UPDATE_TASKS_THREAD_NAME = "AID-update-tasks-%d";
private static final Logger logger = Logger.getLogger(AutoIngestDashboard.class.getName()); private static final Logger logger = Logger.getLogger(AutoIngestDashboard.class.getName());
private final DefaultTableModel pendingTableModel; private final DefaultTableModel pendingTableModel;
private final DefaultTableModel runningTableModel; private final DefaultTableModel runningTableModel;
private final DefaultTableModel completedTableModel; private final DefaultTableModel completedTableModel;
private AutoIngestMonitor autoIngestMonitor; private AutoIngestMonitor autoIngestMonitor;
private ExecutorService updateExecutor;
/** /**
* Creates a dashboard for monitoring an automated ingest cluster. * Creates a dashboard for monitoring an automated ingest cluster.
@ -213,6 +218,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader())); pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader())); pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.JOB.getColumnHeader()));
/* /*
* Set up a column to display the cases associated with the jobs. * Set up a column to display the cases associated with the jobs.
@ -275,6 +281,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.JOB.getColumnHeader()));
/* /*
* Set up a column to display the cases associated with the jobs. * Set up a column to display the cases associated with the jobs.
@ -311,10 +318,10 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
* jobs. * jobs.
*/ */
column = runningTable.getColumn(JobsTableModelColumns.STAGE.getColumnHeader()); column = runningTable.getColumn(JobsTableModelColumns.STAGE.getColumnHeader());
column.setMinWidth(ACTIVITY_COL_MIN_WIDTH); column.setMinWidth(STAGE_COL_MIN_WIDTH);
column.setMaxWidth(ACTIVITY_COL_MAX_WIDTH); column.setMaxWidth(STAGE_COL_MAX_WIDTH);
column.setPreferredWidth(ACTIVITY_COL_PREFERRED_WIDTH); column.setPreferredWidth(STAGE_COL_PREFERRED_WIDTH);
column.setWidth(ACTIVITY_COL_PREFERRED_WIDTH); column.setWidth(STAGE_COL_PREFERRED_WIDTH);
/* /*
* Set up a column to display the ingest activity times associated with * Set up a column to display the ingest activity times associated with
@ -323,9 +330,9 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
column = runningTable.getColumn(JobsTableModelColumns.STAGE_TIME.getColumnHeader()); column = runningTable.getColumn(JobsTableModelColumns.STAGE_TIME.getColumnHeader());
column.setCellRenderer(new DurationCellRenderer()); column.setCellRenderer(new DurationCellRenderer());
column.setMinWidth(GENERIC_COL_MIN_WIDTH); column.setMinWidth(GENERIC_COL_MIN_WIDTH);
column.setMaxWidth(ACTIVITY_TIME_COL_MAX_WIDTH); column.setMaxWidth(STAGE_TIME_COL_MAX_WIDTH);
column.setPreferredWidth(ACTIVITY_TIME_COL_MIN_WIDTH); column.setPreferredWidth(STAGE_TIME_COL_MIN_WIDTH);
column.setWidth(ACTIVITY_TIME_COL_MIN_WIDTH); column.setWidth(STAGE_TIME_COL_MIN_WIDTH);
/* /*
* Prevent sorting when a column header is clicked. * Prevent sorting when a column header is clicked.
@ -348,6 +355,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader()));
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader())); completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.JOB.getColumnHeader()));
/* /*
* Set up a column to display the cases associated with the jobs. * Set up a column to display the cases associated with the jobs.
@ -419,12 +427,20 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
autoIngestMonitor = new AutoIngestMonitor(); autoIngestMonitor = new AutoIngestMonitor();
autoIngestMonitor.addObserver(this); autoIngestMonitor.addObserver(this);
autoIngestMonitor.startUp(); autoIngestMonitor.startUp();
updateExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(UPDATE_TASKS_THREAD_NAME).build());
updateExecutor.submit(new UpdateJobsSnapshotTask());
} }
@Override @Override
public void update(Observable observable, Object argument) { public void update(Observable observable, Object arg) {
JobsSnapshot jobsSnapshot = (JobsSnapshot) argument; /*
EventQueue.invokeLater(new RefreshComponentsTask(jobsSnapshot)); * By creating a task to get the latest jobs snapshot, the possibility
* of queuing a refresh task for the EDT with snaphot rendered stale by
* the handling of a user prioritization action, etc. on the EDT is
* avoided. This is why the snapshot pushed ny the auto ingest jobs
* monitor is ignored.
*/
updateExecutor.submit(new UpdateJobsSnapshotTask());
} }
/** /**
@ -438,7 +454,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
List<AutoIngestJob> runningJobs = jobsSnapshot.getRunningJobs(); List<AutoIngestJob> runningJobs = jobsSnapshot.getRunningJobs();
List<AutoIngestJob> completedJobs = jobsSnapshot.getCompletedJobs(); List<AutoIngestJob> completedJobs = jobsSnapshot.getCompletedJobs();
pendingJobs.sort(new AutoIngestJob.PriorityComparator()); pendingJobs.sort(new AutoIngestJob.PriorityComparator());
runningJobs.sort(new AutoIngestJob.CaseNameAndProcessingHostComparator());
completedJobs.sort(new AutoIngestJob.ReverseCompletedDateComparator()); completedJobs.sort(new AutoIngestJob.ReverseCompletedDateComparator());
refreshTable(pendingJobs, pendingTable, pendingTableModel); refreshTable(pendingJobs, pendingTable, pendingTableModel);
refreshTable(runningJobs, runningTable, runningTableModel); refreshTable(runningJobs, runningTable, runningTableModel);
@ -459,24 +474,19 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
Path currentRow = getSelectedEntry(table, tableModel); Path currentRow = getSelectedEntry(table, tableModel);
tableModel.setRowCount(0); tableModel.setRowCount(0);
for (AutoIngestJob job : jobs) { for (AutoIngestJob job : jobs) {
if (job.getVersion() < 1) { AutoIngestJob.StageDetails status = job.getProcessingStageDetails();
// Ignore version '0' nodes since they don't carry enough
// data to populate the table.
continue;
}
AutoIngestJob.StageDetails status = job.getStageDetails();
tableModel.addRow(new Object[]{ tableModel.addRow(new Object[]{
job.getManifest().getCaseName(), // CASE job.getManifest().getCaseName(), // CASE
job.getManifest().getDataSourcePath().getFileName(), job.getProcessingHostName(), // HOST_NAME job.getManifest().getDataSourcePath().getFileName(), job.getProcessingHostName(), // HOST_NAME
job.getManifest().getDateFileCreated(), // CREATED_TIME job.getManifest().getDateFileCreated(), // CREATED_TIME
job.getProcessingStageStartDate(), // STARTED_TIME job.getProcessingStageStartDate(), // STARTED_TIME
job.getCompletedDate(), // COMPLETED_TIME job.getCompletedDate(), // COMPLETED_TIME
status.getDescription(), // ACTIVITY status.getDescription(), // STAGE
job.getErrorsOccurred(), // STATUS job.getErrorsOccurred(), // STATUS
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME ((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // STAGE_TIME
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
job.getManifest().getFilePath() // MANIFEST_FILE_PATH job.getManifest().getFilePath(), // MANIFEST_FILE_PATH
//DLG: Put job object in the table job
}); });
} }
setSelectedEntry(table, tableModel, currentRow); setSelectedEntry(table, tableModel, currentRow);
@ -542,7 +552,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
*/ */
private enum JobsTableModelColumns { private enum JobsTableModelColumns {
// DLG: Go through the bundle.properties file and delete any unused key-value pairs.
CASE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Case")), CASE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Case")),
DATA_SOURCE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ImageFolder")), DATA_SOURCE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ImageFolder")),
HOST_NAME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.HostName")), HOST_NAME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.HostName")),
@ -553,8 +562,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
STAGE_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime")), STAGE_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime")),
STATUS(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Status")), STATUS(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Status")),
CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder")), CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder")),
MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath")); //DLG:, MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath")),
//DLG: JOB(""); JOB(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Job"));
private final String header; private final String header;
@ -566,15 +575,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
return header; return header;
} }
/*
* DLG: We need to add the AutoIngestJob object for the row to the
* table. As a model you can look in AutoIngestControlPanel to see how a
* boolean is stored in a hidden IS_LOCAL_JOB column and do something
* similar for the job. Once youy hjave done that, you can change the
* button event handler for the Prioritize button to make it pass the
* AutoIngestJob to the AutoIngestMonitor instead of the manifest file
* path.
*/
private static final String[] headers = { private static final String[] headers = {
CASE.getColumnHeader(), CASE.getColumnHeader(),
DATA_SOURCE.getColumnHeader(), DATA_SOURCE.getColumnHeader(),
@ -586,11 +586,28 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
STATUS.getColumnHeader(), STATUS.getColumnHeader(),
STAGE_TIME.getColumnHeader(), STAGE_TIME.getColumnHeader(),
CASE_DIRECTORY_PATH.getColumnHeader(), CASE_DIRECTORY_PATH.getColumnHeader(),
MANIFEST_FILE_PATH.getColumnHeader() //DLG: , MANIFEST_FILE_PATH.getColumnHeader(),
//DLG: JOB.getColumnHeader() JOB.getColumnHeader()
}; };
}; };
/**
* A task that gets the latest auto ingest jobs snapshot from the autop
* ingest monitor and queues a components refresh task for execution in the
* EDT.
*/
private class UpdateJobsSnapshotTask implements Runnable {
/**
* @inheritDoc
*/
@Override
public void run() {
JobsSnapshot jobsSnapshot = AutoIngestDashboard.this.autoIngestMonitor.getJobsSnapshot();
EventQueue.invokeLater(new RefreshComponentsTask(jobsSnapshot));
}
}
/** /**
* A task that refreshes the UI components on this panel to reflect a * A task that refreshes the UI components on this panel to reflect a
* snapshot of the pending, running and completed auto ingest jobs lists of * snapshot of the pending, running and completed auto ingest jobs lists of
@ -835,13 +852,13 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
private void prioritizeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prioritizeButtonActionPerformed private void prioritizeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prioritizeButtonActionPerformed
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
Path manifestFilePath = (Path) (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal())); AutoIngestJob job = (AutoIngestJob) (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.JOB.ordinal()));
JobsSnapshot jobsSnapshot; JobsSnapshot jobsSnapshot;
try { try {
jobsSnapshot = autoIngestMonitor.prioritizeJob(manifestFilePath); jobsSnapshot = autoIngestMonitor.prioritizeJob(job);
refreshTables(jobsSnapshot); refreshTables(jobsSnapshot);
} catch (AutoIngestMonitor.AutoIngestMonitorException ex) { } catch (AutoIngestMonitor.AutoIngestMonitorException ex) {
String errorMessage = String.format(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.PrioritizeError"), manifestFilePath); String errorMessage = String.format(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.PrioritizeError"), job.getManifest().getFilePath());
logger.log(Level.SEVERE, errorMessage, ex); logger.log(Level.SEVERE, errorMessage, ex);
MessageNotifyUtil.Message.error(errorMessage); MessageNotifyUtil.Message.error(errorMessage);
} }

View File

@ -50,10 +50,6 @@ public final class AutoIngestDashboardTopComponent extends TopComponent {
@Messages({ @Messages({
"AutoIngestDashboardTopComponent.exceptionMessage.failedToCreateDashboard=Failed to create Auto Ingest Dashboard.",}) "AutoIngestDashboardTopComponent.exceptionMessage.failedToCreateDashboard=Failed to create Auto Ingest Dashboard.",})
public static void openTopComponent() { public static void openTopComponent() {
/*
* DLG: Please make the top component initial size big enough to show
* the whole dashboard.
*/
final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID); final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
if (tc != null) { if (tc != null) {
topComponentInitialized = true; topComponentInitialized = true;
@ -67,7 +63,7 @@ public final class AutoIngestDashboardTopComponent extends TopComponent {
try { try {
dashboard = AutoIngestDashboard.createDashboard(); dashboard = AutoIngestDashboard.createDashboard();
tc.add(dashboard); tc.add(dashboard);
dashboard.setSize(992, 744); dashboard.setSize(dashboard.getPreferredSize());
if (tc.isOpened() == false) { if (tc.isOpened() == false) {
tc.open(); tc.open();
} }

View File

@ -34,8 +34,8 @@ import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.autopsy.ingest.IngestJob; import org.sleuthkit.autopsy.ingest.IngestJob;
/** /**
* An automated ingest job for a manifest. The manifest specifies a co-located * An automated ingest job, which is an ingest job performed by the automated
* data source and a case to which the data source is to be added. * ingest service.
*/ */
@ThreadSafe @ThreadSafe
public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable { public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
@ -44,9 +44,13 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
private static final int CURRENT_VERSION = 1; private static final int CURRENT_VERSION = 1;
private static final int DEFAULT_PRIORITY = 0; private static final int DEFAULT_PRIORITY = 0;
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName(); private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
private final int version;
/*
* Version 0 fields.
*/
private final Manifest manifest; private final Manifest manifest;
private final String nodeName; @GuardedBy("this")
private String nodeName;
@GuardedBy("this") @GuardedBy("this")
private String caseDirectoryPath; private String caseDirectoryPath;
@GuardedBy("this") @GuardedBy("this")
@ -56,8 +60,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
@GuardedBy("this") @GuardedBy("this")
private Date stageStartDate; private Date stageStartDate;
@GuardedBy("this") @GuardedBy("this")
private StageDetails stageDetails;
@GuardedBy("this")
transient private DataSourceProcessor dataSourceProcessor; transient private DataSourceProcessor dataSourceProcessor;
@GuardedBy("this") @GuardedBy("this")
transient private IngestJob ingestJob; transient private IngestJob ingestJob;
@ -69,96 +71,116 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
private Date completedDate; private Date completedDate;
@GuardedBy("this") @GuardedBy("this")
private boolean errorsOccurred; private boolean errorsOccurred;
/*
* Version 1 fields.
*/
private final int version; // For possible future use.
@GuardedBy("this") @GuardedBy("this")
private ProcessingStatus processingStatus; private ProcessingStatus processingStatus;
@GuardedBy("this") @GuardedBy("this")
private int numberOfCrashes; private int numberOfCrashes;
@GuardedBy("this")
private StageDetails stageDetails;
/** /**
* Constructs a new automated ingest job for a manifest. All job state not * Constructs a new automated ingest job. All job state not specified in the
* specified in the manifest is set to the default state for a new job. * job manifest is set to the default state for a new job.
* *
* @param manifest The manifest. * @param manifest The manifest for an automated ingest job.
*/ */
AutoIngestJob(Manifest manifest) { AutoIngestJob(Manifest manifest) {
this.version = CURRENT_VERSION; /*
* Version 0 fields.
*/
this.manifest = manifest; this.manifest = manifest;
this.nodeName = AutoIngestJob.LOCAL_HOST_NAME; this.nodeName = "";
this.caseDirectoryPath = ""; this.caseDirectoryPath = "";
this.priority = DEFAULT_PRIORITY; this.priority = DEFAULT_PRIORITY;
this.stage = Stage.PENDING; this.stage = Stage.PENDING;
this.stageStartDate = manifest.getDateFileCreated(); this.stageStartDate = manifest.getDateFileCreated();
this.stageDetails = this.getStageDetails();
this.dataSourceProcessor = null; this.dataSourceProcessor = null;
this.ingestJob = null; this.ingestJob = null;
this.cancelled = false; this.cancelled = false;
this.completed = false; this.completed = false;
this.completedDate = new Date(0); this.completedDate = new Date(0);
this.errorsOccurred = false; this.errorsOccurred = false;
/*
* Version 1 fields.
*/
this.version = CURRENT_VERSION;
this.processingStatus = ProcessingStatus.PENDING; this.processingStatus = ProcessingStatus.PENDING;
this.numberOfCrashes = 0; this.numberOfCrashes = 0;
this.stageDetails = this.getProcessingStageDetails();
} }
/** /**
* Constructs an automated ingest job for a manifest. The manifest specifies * Constructs an automated ingest job using the coordination service node
* a co-located data source and a case to which the data source is to be * data for the job.
* added.
* *
* Note: Manifest objects will be phased out and no longer be part of the * @param nodeData The coordination service node data for an automated
* AutoIngestJob class. * ingest job.
*
* @param nodeData The node data.
*/ */
AutoIngestJob(AutoIngestJobNodeData nodeData) { AutoIngestJob(AutoIngestJobNodeData nodeData) {
this.version = nodeData.getVersion(); /*
* Version 0 fields.
*/
this.manifest = new Manifest(nodeData.getManifestFilePath(), nodeData.getManifestFileDate(), nodeData.getCaseName(), nodeData.getDeviceId(), nodeData.getDataSourcePath(), Collections.emptyMap()); this.manifest = new Manifest(nodeData.getManifestFilePath(), nodeData.getManifestFileDate(), nodeData.getCaseName(), nodeData.getDeviceId(), nodeData.getDataSourcePath(), Collections.emptyMap());
this.nodeName = nodeData.getProcessingHostName(); this.nodeName = nodeData.getProcessingHostName();
this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString(); this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString();
this.priority = nodeData.getPriority(); this.priority = nodeData.getPriority();
this.stage = nodeData.getProcessingStage(); this.stage = nodeData.getProcessingStage();
this.stageStartDate = nodeData.getProcessingStageStartDate(); this.stageStartDate = nodeData.getProcessingStageStartDate();
this.stageDetails = this.getStageDetails(); this.dataSourceProcessor = null; // Transient data not in node data.
this.dataSourceProcessor = null; this.ingestJob = null; // Transient data not in node data.
this.ingestJob = null; this.cancelled = false; // Transient data not in node data.
this.cancelled = false; this.completed = false; // Transient data not in node data.
this.completed = false;
this.completedDate = nodeData.getCompletedDate(); this.completedDate = nodeData.getCompletedDate();
this.errorsOccurred = nodeData.getErrorsOccurred(); this.errorsOccurred = nodeData.getErrorsOccurred();
/*
* Version 1 fields.
*/
this.version = CURRENT_VERSION;
this.processingStatus = nodeData.getProcessingStatus(); this.processingStatus = nodeData.getProcessingStatus();
this.numberOfCrashes = nodeData.getNumberOfCrashes(); this.numberOfCrashes = nodeData.getNumberOfCrashes();
this.stageDetails = this.getProcessingStageDetails();
} }
/** /**
* Gets the auto ingest job manifest. * Gets the job manifest.
* *
* @return The manifest. * @return The job manifest.
*/ */
Manifest getManifest() { Manifest getManifest() {
return this.manifest; return this.manifest;
} }
/** /**
* Sets the path to the case directory of the case associated with this job. * Sets the path to the case directory for the job.
* *
* @param caseDirectoryPath The path to the case directory. * @param caseDirectoryPath The path to the case directory. Can be the empty
* path if the case directory has not been created
* yet.
*/ */
synchronized void setCaseDirectoryPath(Path caseDirectoryPath) { synchronized void setCaseDirectoryPath(Path caseDirectoryPath) {
this.caseDirectoryPath = caseDirectoryPath.toString(); if (null != caseDirectoryPath) {
this.caseDirectoryPath = caseDirectoryPath.toString();
} else {
this.caseDirectoryPath = "";
}
} }
/** /**
* Gets the path to the case directory of the case associated with this job, * Gets the path to the case directory for job, may be the empty path if the
* may be null. * case directory has not been created yet.
* *
* @return The case directory path or null if the case directory has not * @return The case directory path. Will be the empty path if the case
* been created yet. * directory has not been created yet.
*/ */
synchronized Path getCaseDirectoryPath() { synchronized Path getCaseDirectoryPath() {
if (!caseDirectoryPath.isEmpty()) { return Paths.get(caseDirectoryPath);
return Paths.get(caseDirectoryPath);
} else {
return null;
}
} }
/** /**
@ -181,7 +203,13 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
return this.priority; return this.priority;
} }
synchronized void setStage(Stage newStage) { /**
* Sets the processing stage of the job. The start date/time for the stage
* is set when the stage is set.
*
* @param newStage The processing stage.
*/
synchronized void setProcessingStage(Stage newStage) {
if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newStage) { if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newStage) {
return; return;
} }
@ -189,15 +217,35 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
this.stageStartDate = Date.from(Instant.now()); this.stageStartDate = Date.from(Instant.now());
} }
/**
* Gets the processing stage of the job.
*
* @return The processing stage.
*/
synchronized Stage getProcessingStage() { synchronized Stage getProcessingStage() {
return this.stage; return this.stage;
} }
/**
* Gets the date/time the current processing stage of the job started.
*
* @return The current processing stage start date/time.
*/
synchronized Date getProcessingStageStartDate() { synchronized Date getProcessingStageStartDate() {
return new Date(this.stageStartDate.getTime()); return new Date(this.stageStartDate.getTime());
} }
synchronized StageDetails getStageDetails() { /**
* Gets any available details associated with the current processing stage
* of the job, e.g., the currently running data source level ingest module,
* an ingest module in the process of being cancelled, etc. If no additional
* details are available, the stage details will be the same as the
* processing stage.
*
* @return A stage details object consisting of a descrition and associated
* date/time.
*/
synchronized StageDetails getProcessingStageDetails() {
String description; String description;
Date startDate; Date startDate;
if (Stage.CANCELLING != this.stage && null != this.ingestJob) { if (Stage.CANCELLING != this.stage && null != this.ingestJob) {
@ -235,24 +283,43 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
return this.stageDetails; return this.stageDetails;
} }
synchronized void setStageDetails(StageDetails stageDetails) { /**
this.stageDetails = stageDetails; * Sets the data source processor for the job. Used for job cancellation.
} *
* @param dataSourceProcessor A data source processor for the job.
*/
synchronized void setDataSourceProcessor(DataSourceProcessor dataSourceProcessor) { synchronized void setDataSourceProcessor(DataSourceProcessor dataSourceProcessor) {
this.dataSourceProcessor = dataSourceProcessor; this.dataSourceProcessor = dataSourceProcessor;
} }
/**
* Sets the ingest job for the auto ingest job. Used for obtaining
* processing stage details, cancelling the currently running data source
* ingest module, and cancelling the job.
*
* @param ingestJob The ingest job for the auto ingest job.
*/
synchronized void setIngestJob(IngestJob ingestJob) { synchronized void setIngestJob(IngestJob ingestJob) {
this.ingestJob = ingestJob; this.ingestJob = ingestJob;
} }
/**
* Gets the ingest job for the auto ingest job.
*
* @return The ingest job, may be null.
*
* TODO (JIRA-3059): Provide an AutoIngestJob ingest module cancellation API
* instead.
*/
synchronized IngestJob getIngestJob() { synchronized IngestJob getIngestJob() {
return this.ingestJob; return this.ingestJob;
} }
/**
* Cancels the job.
*/
synchronized void cancel() { synchronized void cancel() {
setStage(Stage.CANCELLING); setProcessingStage(Stage.CANCELLING);
cancelled = true; cancelled = true;
errorsOccurred = true; errorsOccurred = true;
if (null != dataSourceProcessor) { if (null != dataSourceProcessor) {
@ -263,15 +330,33 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
} }
} }
/**
* Indicates whether or not the job has been cancelled. This is transient
* state used by the auto ingest manager that is not saved as coordination
* service node data for the job.
*
* @return True or false.
*/
synchronized boolean isCanceled() { synchronized boolean isCanceled() {
return cancelled; return cancelled;
} }
/**
* Marks the job as completed. This is transient state used by the auto
* ingest manager that is not saved as coordination service node data for
* the job.
*/
synchronized void setCompleted() { synchronized void setCompleted() {
setStage(Stage.COMPLETED); setProcessingStage(Stage.COMPLETED);
completed = true; completed = true;
} }
/**
* Indicates whether or not the job has been completed. This is transient
* state that is not saved as coordination service node data for the job.
*
* @return True or false.
*/
synchronized boolean isCompleted() { synchronized boolean isCompleted() {
return completed; return completed;
} }
@ -314,55 +399,108 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
return this.errorsOccurred; return this.errorsOccurred;
} }
/**
* Gets the processing host name for this job.
*
* @return The processing host name.
*/
synchronized String getProcessingHostName() { synchronized String getProcessingHostName() {
return nodeName; return nodeName;
} }
int getVersion() { /**
return this.version; * Sets the processing host name for this job.
*
* @param processingHostName The processing host name.
*/
synchronized void setProcessingHostName(String processingHostName) {
this.nodeName = processingHostName;
} }
/**
* Gets the processing status of the job.
*
* @return The processing status.
*/
synchronized ProcessingStatus getProcessingStatus() { synchronized ProcessingStatus getProcessingStatus() {
return this.processingStatus; return this.processingStatus;
} }
/**
* Sets the processing status of the job.
*
* @param processingStatus The processing status.
*/
synchronized void setProcessingStatus(ProcessingStatus processingStatus) { synchronized void setProcessingStatus(ProcessingStatus processingStatus) {
this.processingStatus = processingStatus; this.processingStatus = processingStatus;
} }
/**
* Gets the number of time this job has "crashed" during processing.
*
* @return The number of crashes.
*/
synchronized int getNumberOfCrashes() { synchronized int getNumberOfCrashes() {
return this.numberOfCrashes; return this.numberOfCrashes;
} }
/**
* Sets the number of time this job has "crashed" during processing.
*
* @param numberOfCrashes The number of crashes.
*/
synchronized void setNumberOfCrashes(int numberOfCrashes) { synchronized void setNumberOfCrashes(int numberOfCrashes) {
this.numberOfCrashes = numberOfCrashes; this.numberOfCrashes = numberOfCrashes;
} }
/**
* Indicates whether some other job is "equal to" this job. Two jobs are
* equal if they have the same manifest file path.
*
* @param otherJob The job to which this job is to be compared.
*
* @return True or false.
*/
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object otherJob) {
if (!(obj instanceof AutoIngestJob)) { if (!(otherJob instanceof AutoIngestJob)) {
return false; return false;
} }
if (obj == this) { if (otherJob == this) {
return true; return true;
} }
return this.getManifest().getFilePath().equals(((AutoIngestJob) obj).getManifest().getFilePath()); return this.getManifest().getFilePath().equals(((AutoIngestJob) otherJob).getManifest().getFilePath());
}
@Override
public int hashCode() {
int hash = 71 * (Objects.hashCode(this.caseDirectoryPath));
return hash;
}
@Override
public int compareTo(AutoIngestJob o) {
return -this.getManifest().getDateFileCreated().compareTo(o.getManifest().getDateFileCreated());
} }
/** /**
* Custom comparator that allows us to sort List<AutoIngestJob> on reverse * Returns a hash code value for the job. The hash code is derived from the
* chronological date modified (descending) * manifest file path.
*
* @return The hash code.
*/
@Override
public int hashCode() {
int hash = 71 * (Objects.hashCode(this.getManifest().getFilePath()));
return hash;
}
/**
* Compares one job to another in a way that orders jobs by manifest
* creation date.
*
* @param otherJob The job to which this job is to be compared.
*
* @return A negative integer, zero, or a positive integer as this job is
* less than, equal to, or greater than the specified job.
*/
@Override
public int compareTo(AutoIngestJob otherJob) {
return -this.getManifest().getDateFileCreated().compareTo(otherJob.getManifest().getDateFileCreated());
}
/**
* Comparator that supports doing a descending sort of jobs based on job
* completion date.
*/ */
static class ReverseCompletedDateComparator implements Comparator<AutoIngestJob> { static class ReverseCompletedDateComparator implements Comparator<AutoIngestJob> {
@ -374,7 +512,8 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
} }
/** /**
* Comparator that sorts auto ingest jobs by priority in descending order. * Comparator that supports doing a descending sort of jobs based on job
* priority.
*/ */
public static class PriorityComparator implements Comparator<AutoIngestJob> { public static class PriorityComparator implements Comparator<AutoIngestJob> {
@ -386,27 +525,26 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
} }
/** /**
* Custom comparator that allows us to sort List<AutoIngestJob> on case name * Comparator that supports doing an alphabetical sort of jobs based on a
* alphabetically except for jobs for the current host, which are placed at * combination of case name and processing host.
* the top of the list.
*/ */
static class CaseNameAndProcessingHostComparator implements Comparator<AutoIngestJob> { static class CaseNameAndProcessingHostComparator implements Comparator<AutoIngestJob> {
@Override @Override
public int compare(AutoIngestJob o1, AutoIngestJob o2) { public int compare(AutoIngestJob aJob, AutoIngestJob anotherJob) {
if (o1.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) { if (aJob.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
return -1; // o1 is for current case, float to top return -1; // aJob is for this, float to top
} else if (o2.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) { } else if (anotherJob.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
return 1; // o2 is for current case, float to top return 1; // anotherJob is for this, float to top
} else { } else {
return o1.getManifest().getCaseName().compareToIgnoreCase(o2.getManifest().getCaseName()); return aJob.getManifest().getCaseName().compareToIgnoreCase(anotherJob.getManifest().getCaseName());
} }
} }
} }
/** /**
* Processing status for the auto ingest job for the manifest. * Processing statuses for an auto ingest job.
*/ */
enum ProcessingStatus { enum ProcessingStatus {
PENDING, PENDING,
@ -415,6 +553,9 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
DELETED DELETED
} }
/**
* Processing stages for an auto ingest job.
*/
enum Stage { enum Stage {
PENDING("Pending"), PENDING("Pending"),
@ -443,6 +584,9 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
} }
/**
* Processing stage details for an auto ingest job.
*/
@Immutable @Immutable
static final class StageDetails implements Serializable { static final class StageDetails implements Serializable {

View File

@ -32,8 +32,22 @@ import javax.lang.model.type.TypeKind;
final class AutoIngestJobNodeData { final class AutoIngestJobNodeData {
private static final int CURRENT_VERSION = 1; private static final int CURRENT_VERSION = 1;
private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131629;
private static final int DEFAULT_PRIORITY = 0; private static final int DEFAULT_PRIORITY = 0;
/*
* This number is the sum of each piece of data, based on it's type. For the
* types boolean, int, and long, values 1, 4, and 8 will be added
* respectively. For String objects, the length of the string, plus either a
* byte or short respesenting the length of the string, will be added.
*
* This field is used to set the size of the buffer during the byte array
* creation in the 'toArray()' method. Since the final size of the array
* isn't immediately known at the time of creation, this number is used to
* create an array as large as could possibly be needed to store all the
* data. This avoids the need to continuously enlarge the buffer. Once the
* buffer has all the necessary data, it will be resized as appropriate.
*/
private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131629;
/* /*
* Version 0 fields. * Version 0 fields.
@ -48,16 +62,16 @@ final class AutoIngestJobNodeData {
* Version 1 fields. * Version 1 fields.
*/ */
private int version; private int version;
private String manifestFilePath; private String manifestFilePath; // 'short' length used in byte array
private long manifestFileDate; private long manifestFileDate;
private String caseName; private String caseName; // 'byte' length used in byte array
private String deviceId; private String deviceId; // 'byte' length used in byte array
private String dataSourcePath; private String dataSourcePath; // 'short' length used in byte array
private String caseDirectoryPath; private String caseDirectoryPath; // 'short' length used in byte array
private String processingHostName; private String processingHostName; // 'short' length used in byte array
private byte processingStage; private byte processingStage;
private long processingStageStartDate; private long processingStageStartDate;
private String processingStageDetailsDescription; private String processingStageDetailsDescription; // 'byte' length used in byte array
private long processingStageDetailsStartDate; private long processingStageDetailsStartDate;
/** /**
@ -84,7 +98,7 @@ final class AutoIngestJobNodeData {
setProcessingHostName(job.getProcessingHostName()); setProcessingHostName(job.getProcessingHostName());
setProcessingStage(job.getProcessingStage()); setProcessingStage(job.getProcessingStage());
setProcessingStageStartDate(job.getProcessingStageStartDate()); setProcessingStageStartDate(job.getProcessingStageStartDate());
setProcessingStageDetails(job.getStageDetails()); setProcessingStageDetails(job.getProcessingStageDetails());
} }
/** /**
@ -107,7 +121,7 @@ final class AutoIngestJobNodeData {
this.numberOfCrashes = 0; this.numberOfCrashes = 0;
this.completedDate = 0L; this.completedDate = 0L;
this.errorsOccurred = false; this.errorsOccurred = false;
this.version = CURRENT_VERSION; this.version = 0;
this.manifestFilePath = ""; this.manifestFilePath = "";
this.manifestFileDate = 0L; this.manifestFileDate = 0L;
this.caseName = ""; this.caseName = "";
@ -151,7 +165,7 @@ final class AutoIngestJobNodeData {
this.processingStage = buffer.get(); this.processingStage = buffer.get();
this.processingStageStartDate = buffer.getLong(); this.processingStageStartDate = buffer.getLong();
this.processingStageDetailsDescription = getStringFromBuffer(buffer, TypeKind.BYTE); this.processingStageDetailsDescription = getStringFromBuffer(buffer, TypeKind.BYTE);
this.processingStageDetailsStartDate = buffer.getLong();; this.processingStageDetailsStartDate = buffer.getLong();
this.processingHostName = getStringFromBuffer(buffer, TypeKind.SHORT); this.processingHostName = getStringFromBuffer(buffer, TypeKind.SHORT);
} }
@ -318,14 +332,14 @@ final class AutoIngestJobNodeData {
/** /**
* Gets the path to the case directory of the case associated with the job. * Gets the path to the case directory of the case associated with the job.
* *
* @return The case directory path or null if the case directory has not * @return The case directory path or an empty string path if the case
* been created yet. * directory has not been created yet.
*/ */
synchronized Path getCaseDirectoryPath() { synchronized Path getCaseDirectoryPath() {
if (!caseDirectoryPath.isEmpty()) { if (!caseDirectoryPath.isEmpty()) {
return Paths.get(caseDirectoryPath); return Paths.get(caseDirectoryPath);
} else { } else {
return null; return Paths.get("");
} }
} }
@ -517,7 +531,16 @@ final class AutoIngestJobNodeData {
return array; return array;
} }
// DGL: Document what is going on here and how the max buffer sie constant is calculated. /**
* This method retrieves a string from a given buffer. Depending on the type
* specified, either a 'byte' or a 'short' will first be read out of the
* buffer which gives the length of the string so it can be properly parsed.
*
* @param buffer The buffer from which the string will be read.
* @param lengthType The size of the length data.
*
* @return The string read from the buffer.
*/
private String getStringFromBuffer(ByteBuffer buffer, TypeKind lengthType) { private String getStringFromBuffer(ByteBuffer buffer, TypeKind lengthType) {
int length = 0; int length = 0;
String output = ""; String output = "";
@ -540,7 +563,16 @@ final class AutoIngestJobNodeData {
return output; return output;
} }
// DGL: Document what is going on here and how the max buffer sie constant is calculated. /**
* This method puts a given string into a given buffer. Depending on the
* type specified, either a 'byte' or a 'short' will be inserted prior to
* the string which gives the length of the string so it can be properly
* parsed.
*
* @param stringValue The string to write to the buffer.
* @param buffer The buffer to which the string will be written.
* @param lengthType The size of the length data.
*/
private void putStringIntoBuffer(String stringValue, ByteBuffer buffer, TypeKind lengthType) { private void putStringIntoBuffer(String stringValue, ByteBuffer buffer, TypeKind lengthType) {
switch (lengthType) { switch (lengthType) {
case BYTE: case BYTE:

View File

@ -647,10 +647,10 @@ public final class AutoIngestManager extends Observable implements PropertyChang
} }
/* /*
* Add the job to the pending jobs queue and update the coordinatino * Add the job to the pending jobs queue and update the coordination
* service node data for the job. * service node data for the job.
*/ */
if (null != completedJob && null != completedJob.getCaseDirectoryPath()) { if (null != completedJob && !completedJob.getCaseDirectoryPath().toString().isEmpty()) {
try { try {
completedJob.setErrorsOccurred(false); completedJob.setErrorsOccurred(false);
completedJob.setCompletedDate(new Date(0)); completedJob.setCompletedDate(new Date(0));
@ -849,7 +849,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (null != ingestJob) { if (null != ingestJob) {
IngestJob.DataSourceIngestModuleHandle moduleHandle = ingestJob.getSnapshot().runningDataSourceIngestModule(); IngestJob.DataSourceIngestModuleHandle moduleHandle = ingestJob.getSnapshot().runningDataSourceIngestModule();
if (null != moduleHandle) { if (null != moduleHandle) {
currentJob.setStage(AutoIngestJob.Stage.CANCELLING_MODULE); currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE);
moduleHandle.cancel(); moduleHandle.cancel();
SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()}); SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()});
} }
@ -1117,7 +1117,9 @@ public final class AutoIngestManager extends Observable implements PropertyChang
AutoIngestJob job = new AutoIngestJob(manifest); AutoIngestJob job = new AutoIngestJob(manifest);
job.setPriority(nodeData.getPriority()); job.setPriority(nodeData.getPriority());
Path caseDirectory = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); Path caseDirectory = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
job.setCaseDirectoryPath(caseDirectory); if (null != caseDirectory) {
job.setCaseDirectoryPath(caseDirectory);
}
newPendingJobsList.add(job); newPendingJobsList.add(job);
/* /*
@ -1295,7 +1297,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
AutoIngestJob job = new AutoIngestJob(manifest); AutoIngestJob job = new AutoIngestJob(manifest);
job.setCaseDirectoryPath(caseDirectoryPath); job.setCaseDirectoryPath(caseDirectoryPath);
job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED); job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED);
job.setStage(AutoIngestJob.Stage.COMPLETED); job.setProcessingStage(AutoIngestJob.Stage.COMPLETED);
job.setCompletedDate(nodeData.getCompletedDate()); job.setCompletedDate(nodeData.getCompletedDate());
job.setErrorsOccurred(true); job.setErrorsOccurred(true);
newCompletedJobsList.add(new AutoIngestJob(nodeData)); newCompletedJobsList.add(new AutoIngestJob(nodeData));
@ -1864,10 +1866,11 @@ public final class AutoIngestManager extends Observable implements PropertyChang
*/ */
private void processJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestAlertFileException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, AutoIngestJobNodeData.InvalidDataException { private void processJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestAlertFileException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, AutoIngestJobNodeData.InvalidDataException {
Path manifestPath = currentJob.getManifest().getFilePath(); Path manifestPath = currentJob.getManifest().getFilePath();
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING);
updateCoordinationServiceNode(currentJob);
SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.STARTING); currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING);
currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING);
currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME);
updateCoordinationServiceNode(currentJob);
setChanged(); setChanged();
notifyObservers(Event.JOB_STARTED); notifyObservers(Event.JOB_STARTED);
eventPublisher.publishRemotely(new AutoIngestJobStartedEvent(currentJob)); eventPublisher.publishRemotely(new AutoIngestJobStartedEvent(currentJob));
@ -1890,6 +1893,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
// The job may get retried // The job may get retried
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PENDING); currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PENDING);
} }
currentJob.setProcessingHostName("");
updateCoordinationServiceNode(currentJob); updateCoordinationServiceNode(currentJob);
boolean retry = (!currentJob.isCanceled() && !currentJob.isCompleted()); boolean retry = (!currentJob.isCanceled() && !currentJob.isCompleted());
@ -1986,7 +1990,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (AutoIngestUserPreferences.getSharedConfigEnabled()) { if (AutoIngestUserPreferences.getSharedConfigEnabled()) {
Path manifestPath = currentJob.getManifest().getFilePath(); Path manifestPath = currentJob.getManifest().getFilePath();
SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG); currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG);
new SharedConfiguration().downloadConfiguration(); new SharedConfiguration().downloadConfiguration();
} }
} }
@ -2004,7 +2008,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException { private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException {
Path manifestPath = currentJob.getManifest().getFilePath(); Path manifestPath = currentJob.getManifest().getFilePath();
SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.CHECKING_SERVICES); currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES);
if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) { if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) {
throw new DatabaseServerDownException("Case database server is down"); throw new DatabaseServerDownException("Case database server is down");
} }
@ -2051,7 +2055,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
String caseName = manifest.getCaseName(); String caseName = manifest.getCaseName();
SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()}); SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
currentJob.setStage(AutoIngestJob.Stage.OPENING_CASE); currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE);
/* /*
* Acquire and hold a case name lock so that only one node at as * Acquire and hold a case name lock so that only one node at as
* time can scan the output directory at a time. This prevents * time can scan the output directory at a time. This prevents
@ -2164,7 +2168,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
DataSource dataSource = identifyDataSource(caseForJob); DataSource dataSource = identifyDataSource(caseForJob);
if (null == dataSource) { if (null == dataSource) {
currentJob.setStage(AutoIngestJob.Stage.COMPLETED); currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED);
return; return;
} }
@ -2174,7 +2178,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
runDataSourceProcessor(caseForJob, dataSource); runDataSourceProcessor(caseForJob, dataSource);
if (dataSource.getContent().isEmpty()) { if (dataSource.getContent().isEmpty()) {
currentJob.setStage(AutoIngestJob.Stage.COMPLETED); currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED);
return; return;
} }
@ -2219,7 +2223,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath); SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE); currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE);
Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
Path dataSourcePath = manifest.getDataSourcePath(); Path dataSourcePath = manifest.getDataSourcePath();
@ -2255,7 +2259,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath); SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE); currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE);
UUID taskId = UUID.randomUUID(); UUID taskId = UUID.randomUUID();
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId); DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId);
DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor(); DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor();
@ -2420,7 +2424,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath); SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE); currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE);
Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
IngestJobEventListener ingestJobEventListener = new IngestJobEventListener(); IngestJobEventListener ingestJobEventListener = new IngestJobEventListener();
@ -2456,7 +2460,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
} }
jobLogger.logAnalysisCompleted(); jobLogger.logAnalysisCompleted();
} else { } else {
currentJob.setStage(AutoIngestJob.Stage.CANCELLING); currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING);
currentJob.setErrorsOccurred(true); currentJob.setErrorsOccurred(true);
AutoIngestAlertFile.create(caseDirectoryPath); // Do this first, it is more important than the case log AutoIngestAlertFile.create(caseDirectoryPath); // Do this first, it is more important than the case log
jobLogger.logAnalysisCancelled(); jobLogger.logAnalysisCancelled();
@ -2519,7 +2523,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest(); Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath(); Path manifestPath = manifest.getFilePath();
SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath); SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath);
currentJob.setStage(AutoIngestJob.Stage.EXPORTING_FILES); currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES);
Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
try { try {
@ -2770,9 +2774,10 @@ public final class AutoIngestManager extends Observable implements PropertyChang
try { try {
synchronized (jobsLock) { synchronized (jobsLock) {
if (currentJob != null) { if (currentJob != null) {
currentJob.getStageDetails(); currentJob.getProcessingStageDetails();
setChanged(); setChanged();
notifyObservers(Event.JOB_STATUS_UPDATED); notifyObservers(Event.JOB_STATUS_UPDATED);
updateCoordinationServiceNode(currentJob);
eventPublisher.publishRemotely(new AutoIngestJobStatusEvent(currentJob)); eventPublisher.publishRemotely(new AutoIngestJobStatusEvent(currentJob));
} }

View File

@ -19,13 +19,10 @@
package org.sleuthkit.autopsy.experimental.autoingest; package org.sleuthkit.autopsy.experimental.autoingest;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.awt.Cursor;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Observable; import java.util.Observable;
@ -34,7 +31,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.GuardedBy;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@ -143,8 +139,6 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/ */
private void handleJobStartedEvent(AutoIngestJobStartedEvent event) { private void handleJobStartedEvent(AutoIngestJobStartedEvent event) {
synchronized (jobsLock) { synchronized (jobsLock) {
// DLG: TEST! Remove job from pending queue, if present
// DLG: TEST! Add job to running jobs list
jobsSnapshot.removePendingJob(event.getJob()); jobsSnapshot.removePendingJob(event.getJob());
jobsSnapshot.addOrReplaceRunningJob(event.getJob()); jobsSnapshot.addOrReplaceRunningJob(event.getJob());
setChanged(); setChanged();
@ -159,8 +153,12 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/ */
private void handleJobStatusEvent(AutoIngestJobStatusEvent event) { private void handleJobStatusEvent(AutoIngestJobStatusEvent event) {
synchronized (jobsLock) { synchronized (jobsLock) {
// DLG: TEST! Replace job in running list with job from event /*
jobsSnapshot.addOrReplaceRunningJob(event.getJob()); * Currently this event is only published for running jobs.
*/
AutoIngestJob job = event.getJob();
jobsSnapshot.removePendingJob(job);
jobsSnapshot.addOrReplaceRunningJob(job);
setChanged(); setChanged();
notifyObservers(jobsSnapshot); notifyObservers(jobsSnapshot);
} }
@ -173,10 +171,10 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/ */
private void handleJobCompletedEvent(AutoIngestJobCompletedEvent event) { private void handleJobCompletedEvent(AutoIngestJobCompletedEvent event) {
synchronized (jobsLock) { synchronized (jobsLock) {
// DLG: TEST! Remove job from event from running list, if present AutoIngestJob job = event.getJob();
// DLG: TEST! Add job to completed list jobsSnapshot.removePendingJob(job);
jobsSnapshot.removeRunningJob(event.getJob()); jobsSnapshot.removeRunningJob(job);
jobsSnapshot.addOrReplaceCompletedJob(event.getJob()); jobsSnapshot.addOrReplaceCompletedJob(job);
setChanged(); setChanged();
notifyObservers(jobsSnapshot); notifyObservers(jobsSnapshot);
} }
@ -241,6 +239,13 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
for (String node : nodeList) { for (String node : nodeList) {
try { try {
AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node)); AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node));
if (nodeData.getVersion() < 1) {
/*
* Ignore version '0' nodes that have not been
* "upgraded" since they don't carry enough data.
*/
continue;
}
AutoIngestJob job = new AutoIngestJob(nodeData); AutoIngestJob job = new AutoIngestJob(nodeData);
ProcessingStatus processingStatus = nodeData.getProcessingStatus(); ProcessingStatus processingStatus = nodeData.getProcessingStatus();
switch (processingStatus) { switch (processingStatus) {
@ -275,9 +280,9 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
/** /**
* Bumps the priority of an auto ingest job. * Bumps the priority of an auto ingest job.
* *
* @param manifestPath The manifest file path for the job to be prioritized. * @param job The job to be prioritized.
*/ */
JobsSnapshot prioritizeJob(Path manifestFilePath) throws AutoIngestMonitorException { JobsSnapshot prioritizeJob(AutoIngestJob job) throws AutoIngestMonitorException {
int highestPriority = 0; int highestPriority = 0;
AutoIngestJob prioritizedJob = null; AutoIngestJob prioritizedJob = null;
synchronized (jobsLock) { synchronized (jobsLock) {
@ -285,11 +290,11 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
* Get the highest known priority and make sure the job is still in * Get the highest known priority and make sure the job is still in
* the pending jobs queue. * the pending jobs queue.
*/ */
for (AutoIngestJob job : jobsSnapshot.getPendingJobs()) { for (AutoIngestJob pendingJob : jobsSnapshot.getPendingJobs()) {
if (job.getPriority() > highestPriority) { if (pendingJob.getPriority() > highestPriority) {
highestPriority = job.getPriority(); highestPriority = pendingJob.getPriority();
} }
if (job.getManifest().getFilePath().equals(manifestFilePath)) { if (pendingJob.equals(job)) {
prioritizedJob = job; prioritizedJob = job;
} }
} }
@ -300,27 +305,25 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/ */
if (null != prioritizedJob) { if (null != prioritizedJob) {
++highestPriority; ++highestPriority;
String manifestNodePath = prioritizedJob.getManifest().getFilePath().toString(); String manifestNodePath = job.getManifest().getFilePath().toString();
try { try {
AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath)); AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath));
nodeData.setPriority(highestPriority); nodeData.setPriority(highestPriority);
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, nodeData.toArray()); coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, nodeData.toArray());
} catch (AutoIngestJobNodeData.InvalidDataException | CoordinationServiceException | InterruptedException ex) { } catch (AutoIngestJobNodeData.InvalidDataException | CoordinationServiceException | InterruptedException ex) {
throw new AutoIngestMonitorException("Error bumping priority for job " + prioritizedJob.toString(), ex); throw new AutoIngestMonitorException("Error bumping priority for job " + job.toString(), ex);
} }
prioritizedJob.setPriority(highestPriority); prioritizedJob.setPriority(highestPriority);
}
/* /*
* Publish a prioritization event. * Publish a prioritization event.
*/ */
if (null != prioritizedJob) { final String caseName = job.getManifest().getCaseName();
final String caseName = prioritizedJob.getManifest().getCaseName();
new Thread(() -> { new Thread(() -> {
eventPublisher.publishRemotely(new AutoIngestCasePrioritizedEvent(LOCAL_HOST_NAME, caseName)); eventPublisher.publishRemotely(new AutoIngestCasePrioritizedEvent(LOCAL_HOST_NAME, caseName));
}).start(); }).start();
}
}
return jobsSnapshot; return jobsSnapshot;
} }
} }
@ -344,7 +347,7 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
synchronized (jobsLock) { synchronized (jobsLock) {
jobsSnapshot = newJobsSnapshot; jobsSnapshot = newJobsSnapshot;
setChanged(); setChanged();
notifyObservers(jobsSnapshot); notifyObservers(null);
} }
} }
} }

View File

@ -11,45 +11,16 @@ AutoIngestDashboard.JobsTableModel.ColumnHeader.CompletedTime=Job Completed
AutoIngestDashboard.JobsTableModel.ColumnHeader.Stage=Stage AutoIngestDashboard.JobsTableModel.ColumnHeader.Stage=Stage
AutoIngestDashboard.JobsTableModel.ColumnHeader.Status=Status AutoIngestDashboard.JobsTableModel.ColumnHeader.Status=Status
AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path
AutoIngestDashboard.bnResume.text=Resume
AutoIngestDashboard.bnPause.confirmHeader=Are you sure you want to pause?
AutoIngestDashboard.bnPause.warningText=Pause will occur after the current job completes processing. This could take a long time. Continue?
AutoIngestDashboard.bnPause.toolTipTextResume=Resume processing of Pending Jobs
AutoIngestDashboard.bnPause.pausing=Pausing after current job completes...
AutoIngestDashboard.Cancelling=Cancelling...
AutoIngestDashboard.pendingTable.toolTipText=The Pending table displays the order upcoming Jobs will be processed with the top of the list first AutoIngestDashboard.pendingTable.toolTipText=The Pending table displays the order upcoming Jobs will be processed with the top of the list first
AutoIngestDashboard.runningTable.toolTipText=The Running table displays the currently running Job and information about it AutoIngestDashboard.runningTable.toolTipText=The Running table displays the currently running Job and information about it
AutoIngestDashboard.completedTable.toolTipText=The Completed table shows all Jobs that have been processed already AutoIngestDashboard.completedTable.toolTipText=The Completed table shows all Jobs that have been processed already
AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime=Time in Stage AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime=Time in Stage
AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder=Case Folder AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder=Case
AutoIngestDashboard.JobsTableModel.ColumnHeader.LocalJob= Local Job? AutoIngestDashboard.JobsTableModel.ColumnHeader.Job=Job
AutoIngestDashboard.DeletionFailed=Deletion failed for job
AutoIngestDashboard.ShowLogFailed.Title=Unable to display case log
AutoIngestDashboard.ShowLogFailed.Message=Case log file does not exist
AutoIngestDashboard.bnPrioritizeCase.toolTipText=Move all images associated with a case to top of Pending queue.
AutoIngestDashboard.ExitConsequences=This will cancel any currently running job on this host. Exiting while a job is running potentially leaves the case in an inconsistent or corrupted state.
AutoIngestDashboard.ExitingStatus=Exiting...
AutoIngestDashboard.OK=OK
AutoIngestDashboard.Cancel=Cancel
AutoIngestDashboard.AutoIngestStartupFailed.Message=Failed to start automated ingest.\nPlease see auto ingest system log for details.
AutoIngestDashboard.AutoIngestStartupFailed.Title=Automated Ingest Error
AutoIngestDashboard.AutoIngestStartupError=Failed to start automated ingest. Verify Multi-user Settings.
AutoIngestDashboard.AutoIngestStartupWarning.Title=Automated Ingest Warning
AutoIngestDashboard.AutoIngestStartupWarning.Message=Failed to establish remote communications with other automated ingest nodes.\nAuto ingest dashboard will only be able to display local ingest job events.\nPlease verify Multi-User settings (Options->Multi-User). See application log for details.
AutoIngestDashboard.UpdatingSharedConfig=Updating shared configuration
AutoIngestDashboard.SharedConfigurationDisabled=Shared configuration disabled
AutoIngestDashboard.EnableConfigurationSettings=Enable shared configuration from the options panel before uploading
AutoIngestDashboard.ErrorUploadingConfiguration=Error uploading configuration
AutoIngestDashboard.UploadSuccessTitle=Success
AutoIngestDashboard.UploadSuccess=Shared configuration successfully uploaded
AutoIngestDashboard.UploadFailedTitle=Failed
AutoIngestDashboard.ConfigLocked=The shared configuration directory is locked because upload from another node is in progress. \nIf this is an error, you can unlock the directory and then retry the upload.
AutoIngestDashboard.ConfigLockedTitle=Configuration directory locked
AutoIngestDashboard.tbServicesStatusMessage.Message=Case databases {0}, keyword search {1}, coordination {2}, messaging {3} AutoIngestDashboard.tbServicesStatusMessage.Message=Case databases {0}, keyword search {1}, coordination {2}, messaging {3}
AutoIngestDashboard.tbServicesStatusMessage.Message.Up=up AutoIngestDashboard.tbServicesStatusMessage.Message.Up=up
AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down
AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown=unknown AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown=unknown
AutoIngestDashboard.PauseDueToSystemError=Paused due to system error, please consult the auto ingest system log
ConfirmationDialog.DoNotDelete=Do not delete ConfirmationDialog.DoNotDelete=Do not delete
ConfirmationDialog.Delete=Permanently delete ConfirmationDialog.Delete=Permanently delete
ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case
@ -260,7 +231,6 @@ FileExporterSettingsPanel.BrowseReportTooltip_1=Browse for the Reports Folder
FileExporterSettingsPanel.NewRuleTooltip_1=Clear the rule editor to begin a new rule FileExporterSettingsPanel.NewRuleTooltip_1=Clear the rule editor to begin a new rule
FileExporterSettingsPanel.DeleteTooltip_1=Delete the selected rule FileExporterSettingsPanel.DeleteTooltip_1=Delete the selected rule
FileExporterSettingsPanel.SaveTooltip_1=Save the current rule FileExporterSettingsPanel.SaveTooltip_1=Save the current rule
AutoIngestDashboard.bnPrioritizeFolder.label=<AutoIngestDashboard.bnPrioritizeJob.text>
AutoIngestCasePanel.rbDays.text=Days AutoIngestCasePanel.rbDays.text=Days
AutoIngestCasePanel.rbWeeks.text=Weeks AutoIngestCasePanel.rbWeeks.text=Weeks
AutoIngestCasePanel.rbMonths.text=Months AutoIngestCasePanel.rbMonths.text=Months

View File

@ -42,7 +42,7 @@ public final class Manifest implements Serializable {
this.dateFileCreated = dateFileCreated; this.dateFileCreated = dateFileCreated;
this.caseName = caseName; this.caseName = caseName;
this.deviceId = deviceId; this.deviceId = deviceId;
if (dataSourcePath != null) { if (null != dataSourcePath) {
this.dataSourcePath = dataSourcePath.toString(); this.dataSourcePath = dataSourcePath.toString();
} else { } else {
this.dataSourcePath = ""; this.dataSourcePath = "";
@ -55,7 +55,7 @@ public final class Manifest implements Serializable {
} }
public Date getDateFileCreated() { public Date getDateFileCreated() {
return this.dateFileCreated; return new Date(this.dateFileCreated.getTime());
} }
public String getCaseName() { public String getCaseName() {

View File

@ -3,7 +3,7 @@
<name unique="dashboard"/> <name unique="dashboard"/>
<kind type="editor"/> <kind type="editor"/>
<state type="separated"/> <state type="separated"/>
<bounds x="76" y="68" width="996" height="672"/> <bounds x="76" y="68" width="1005" height="750"/>
<frame state="0"/> <frame state="0"/>
<empty-behavior permanent="false"/> <empty-behavior permanent="false"/>

View File

@ -778,26 +778,26 @@ public class SharedConfiguration {
} }
/** /**
* Upload Central Repository settings. * Upload central repository settings.
* *
* @param remoteFolder Shared settings folder * @param remoteFolder Shared settings folder
* *
* @throws SharedConfigurationException * @throws SharedConfigurationException
*/ */
private void uploadCentralRepositorySettings(File remoteFolder) throws SharedConfigurationException { private void uploadCentralRepositorySettings(File remoteFolder) throws SharedConfigurationException {
publishTask("Uploading Central Repository configuration"); publishTask("Uploading central repository configuration");
copyToRemoteFolder(CENTRAL_REPOSITORY_PROPERTIES_FILE, moduleDirPath, remoteFolder, true); copyToRemoteFolder(CENTRAL_REPOSITORY_PROPERTIES_FILE, moduleDirPath, remoteFolder, true);
} }
/** /**
* Download Central Repository settings. * Download central repository settings.
* *
* @param remoteFolder Shared settings folder * @param remoteFolder Shared settings folder
* *
* @throws SharedConfigurationException * @throws SharedConfigurationException
*/ */
private void downloadCentralRepositorySettings(File remoteFolder) throws SharedConfigurationException { private void downloadCentralRepositorySettings(File remoteFolder) throws SharedConfigurationException {
publishTask("Downloading Central Repository configuration"); publishTask("Downloading central repository configuration");
copyToLocalFolder(CENTRAL_REPOSITORY_PROPERTIES_FILE, moduleDirPath, remoteFolder, true); copyToLocalFolder(CENTRAL_REPOSITORY_PROPERTIES_FILE, moduleDirPath, remoteFolder, true);
} }

View File

@ -1,52 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.imagegallery.actions;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import java.util.logging.Level;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
@ActionID(
category = "Help",
id = "org.sleuthkit.autopsy.imagegallery.actions.OpenHelpAction"
)
@ActionRegistration(
displayName = "#CTL_OpenHelpAction"
)
@ActionReference(path = "Menu/Help", position = 350)
@Messages("CTL_OpenHelpAction=Image / Video Gallery Help")
public final class OpenHelpAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().browse(URI.create("http://sleuthkit.org/autopsy/docs/user-docs/4.4.1/image_gallery_page.html")); //NON-NLS
} catch (IOException ex) {
Logger.getLogger(OpenHelpAction.class.getName()).log(Level.SEVERE, "failed to open help page", ex); //NON-NLS
}
}
}

View File

@ -136,7 +136,15 @@ public class Toolbar extends ToolBar {
tagGroupMenuButton.setText(followUpGroupAction.getText()); tagGroupMenuButton.setText(followUpGroupAction.getText());
tagGroupMenuButton.setGraphic(followUpGroupAction.getGraphic()); tagGroupMenuButton.setGraphic(followUpGroupAction.getGraphic());
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Could create follow up tag menu item", ex); //NON-NLS /*
* The problem appears to be a timing issue where a case is closed
* before this initialization is completed, which It appears to be
* harmless, so we are temporarily changing this log message to a
* WARNING.
*
* TODO (JIRA-3010): SEVERE error logged by image Gallery UI
*/
LOGGER.log(Level.WARNING, "Could not create Follow Up tag menu item", ex); //NON-NLS
} }
tagGroupMenuButton.showingProperty().addListener(showing -> { tagGroupMenuButton.showingProperty().addListener(showing -> {
if (tagGroupMenuButton.isShowing()) { if (tagGroupMenuButton.isShowing()) {

View File

@ -265,7 +265,6 @@
<unzip src="${nbdist.dir}/${app.name}-${app.version}.zip" dest="${nbdist.dir}/${app.name}-installer"/> <unzip src="${nbdist.dir}/${app.name}-${app.version}.zip" dest="${nbdist.dir}/${app.name}-installer"/>
<!-- Disable the Experimental module by default for the installed version --> <!-- Disable the Experimental module by default for the installed version -->
<replace file="${nbdist.dir}/${app.name}-installer/autopsy/config/modules/org-sleuthkit-autopsy-experimental.xml" token="&lt;param name=&quot;enabled&quot;&gt;true&lt;/param&gt;" value="&lt;param name=&quot;enabled&quot;&gt;false&lt;/param&gt;"/> <replace file="${nbdist.dir}/${app.name}-installer/autopsy/config/modules/org-sleuthkit-autopsy-experimental.xml" token="&lt;param name=&quot;enabled&quot;&gt;true&lt;/param&gt;" value="&lt;param name=&quot;enabled&quot;&gt;false&lt;/param&gt;"/>
<replace file="${nbdist.dir}/${app.name}-installer/autopsy/config/modules/org-sleuthkit-autopsy-centralrepository.xml" token="&lt;param name=&quot;enabled&quot;&gt;true&lt;/param&gt;" value="&lt;param name=&quot;enabled&quot;&gt;false&lt;/param&gt;"/>
<echo file="${nbdist.dir}/${app.name}-installer/autopsy/.lastModified" message="" /> <echo file="${nbdist.dir}/${app.name}-installer/autopsy/.lastModified" message="" />
<antcall target="build-installer-${os.family}" /> <antcall target="build-installer-${os.family}" />
</target> </target>