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 REPORTS_FOLDER = "Reports"; //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 long EXECUTOR_AWAIT_TIMEOUT_SECS = 5;
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;
/**
* Handle editing details of cases within the Central Repository
* Handle editing details of cases within the central repository
*/
public class EamCaseEditDetailsDialog extends JDialog {
@ -531,14 +531,14 @@ public class EamCaseEditDetailsDialog extends JDialog {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
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;
}
try {
dbManager.updateCase(eamCase);
} 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 {
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
*/
@ServiceProvider(service = DataContentViewer.class, position = 8)
@Messages({"DataContentViewerOtherCases.title=Other Data Sources",
"DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other data sources.",})
@Messages({"DataContentViewerOtherCases.title=Other Occurrences",
"DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",})
public class DataContentViewerOtherCases extends javax.swing.JPanel implements DataContentViewer {
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
*
* @return A collection of Central Repository artifacts to display
* @return A collection of central repository artifacts to display
*/
private Collection<EamArtifact> getArtifactsFromCorrelatableAttributes(Node node) {
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
* given Central Repository artifact.
* given central repository artifact.
*
* @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
* them to Central Repository Artifact Instancess.
* Get the global file instances matching the given eamArtifact and convert
* them to central repository artifact instancess.
*
* @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
*/
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.
*/
@Messages({"DataContentViewerOtherCases.table.isempty=There are no associated artifacts or files from other cases to display.",
"DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file; likely missing MD5 hash."})
@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."})
private void populateTable(Node node) {
String dataSourceName = getDataSourceNameFromNode(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
*/
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 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
* lowercase letters, numbers, and '_' characters.
* @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
* 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 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
* lowercase letters, numbers, and '_' characters.
* @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"})
private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List<String> caseDisplayNames) {
@ -200,9 +201,9 @@ public class IngestEventsListener {
String MODULE_NAME = Bundle.IngestEventsListener_ingestmodule_name();
BlackboardArtifact tifArtifact = af.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
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,
"Previous Case: " + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
tifArtifact.addAttribute(att);
tifArtifact.addAttribute(att2);
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 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 {
private final static Logger LOGGER = Logger.getLogger(IngestModule.class.getName());
@ -187,7 +188,7 @@ class IngestModule implements FileIngestModule {
// see ArtifactManagerTimeTester for details
@Messages({
"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
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
if((Case.getCurrentCase().getCaseType() == Case.CaseType.MULTI_USER_CASE)
&& (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.SQLITE)){
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
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
}
jobId = context.getJobId();
eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName());
@ -230,8 +231,8 @@ class IngestModule implements FileIngestModule {
try {
dbManager = EamDb.getInstance();
} catch (EamDbException ex) {
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
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
}
try {
@ -289,9 +290,9 @@ class IngestModule implements FileIngestModule {
String MODULE_NAME = IngestModuleFactory.getModuleName();
BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
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,
"Previous Case: " + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
Bundle.IngestModule_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
tifArtifact.addAttribute(att);
tifArtifact.addAttribute(att2);
@ -319,7 +320,7 @@ class IngestModule implements FileIngestModule {
String MODULE_NAME = IngestModuleFactory.getModuleName();
BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.IngestModule_prevcases_text());
Bundle.IngestModule_prevCaseComment_text());
tifArtifact.addAttribute(att);
try {

View File

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

View File

@ -59,7 +59,7 @@ public class EamDbSettingsDialog extends JDialog {
*/
@Messages({"EamDbSettingsDialog.title.text=Central Repository Database Configuration",
"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"})
public EamDbSettingsDialog() {
@ -94,7 +94,7 @@ public class EamDbSettingsDialog extends JDialog {
@Override
public String getDescription() {
return "Directories and Central Repository databases";
return "Directories and central repository databases";
}
});
cbDatabaseType.setSelectedItem(selectedPlatform);
@ -419,7 +419,7 @@ public class EamDbSettingsDialog extends JDialog {
Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(),
Bundle.EamDbSettingsDialog_okButton_createDbError_title(),
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;
}
break;
@ -440,7 +440,7 @@ public class EamDbSettingsDialog extends JDialog {
Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(),
Bundle.EamDbSettingsDialog_okButton_createDbError_title(),
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;
}
break;
@ -459,7 +459,7 @@ public class EamDbSettingsDialog extends JDialog {
@Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.",
"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.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",

View File

@ -19,32 +19,46 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnDatabaseContentButtons" max="32767" attributes="0"/>
<Component id="tbOops" alignment="1" max="32767" attributes="0"/>
<Component id="pnDatabaseConfiguration" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="cbUseCentralRepo" min="-2" pref="186" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lbCentralRepository" alignment="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>
<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">
<Component id="lbCentralRepository" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbUseCentralRepo" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="pnDatabaseConfiguration" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="pnDatabaseConfiguration" min="-2" pref="119" 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"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnDatabaseContentButtons" min="-2" pref="50" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -66,26 +80,26 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" 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="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">
<Component id="lbDbPlatformTypeLabel" 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"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbDbPlatformValue" alignment="0" min="-2" pref="711" max="-2" attributes="0"/>
<Component id="lbDbNameValue" alignment="1" min="-2" pref="711" max="-2" attributes="0"/>
</Group>
<Component id="lbDbLocationValue" alignment="1" min="-2" pref="711" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lbDbNameValue" alignment="0" max="32767" attributes="0"/>
<Component id="lbDbPlatformValue" max="32767" attributes="0"/>
<Component id="lbDbLocationValue" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Component id="bnDbConfigure" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -107,9 +121,9 @@
<Component id="lbDbLocationLabel" max="32767" attributes="0"/>
<Component id="lbDbLocationValue" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="11" max="32767" attributes="0"/>
<EmptySpace max="32767" 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>
</DimensionLayout>
@ -154,53 +168,81 @@
</Component>
</SubComponents>
</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>
<DimensionLayout dim="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"/>
<Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnManageTags" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="bnManageTags" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="555" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="manageTagsScrollPane" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnImportDatabase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnManageTags" alignment="3" min="-2" pref="25" max="-2" attributes="0"/>
<Component id="bnManageTypes" alignment="3" min="-2" pref="25" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="34" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<Component id="manageTagsScrollPane" min="-2" pref="31" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnManageTags" min="-2" pref="25" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<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">
<Properties>
<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"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnManageTypes">
<Container class="javax.swing.JScrollPane" name="manageTagsScrollPane">
<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 name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnManageTypesActionPerformed"/>
</Events>
</Component>
<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="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>
</Container>
<Component class="javax.swing.JTextField" name="tbOops">
@ -244,16 +312,108 @@
<Border info="null"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbOopsActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbUseCentralRepo">
<Container class="javax.swing.JPanel" name="pnCorrelationProperties">
<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 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.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>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseCentralRepoActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View File

@ -56,7 +56,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
}
@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() {
setName(Bundle.GlobalSettingsPanel_title());
@ -86,12 +93,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
lbDbPlatformValue = new javax.swing.JLabel();
lbDbNameValue = 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();
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
@ -117,19 +130,19 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
.addComponent(bnDbConfigure)
.addContainerGap())
.addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
.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(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))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbDbPlatformValue, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE))
.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))
.addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.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.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
);
pnDatabaseConfigurationLayout.setVerticalGroup(
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)
.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))
.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)
.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
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
@ -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
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
@ -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
bnManageTypes.addActionListener(new java.awt.event.ActionListener() {
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);
pnDatabaseContentButtons.setLayout(pnDatabaseContentButtonsLayout);
pnDatabaseContentButtonsLayout.setHorizontalGroup(
pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup()
correlationPropertiesScrollPane.setBorder(null);
correlationPropertiesTextArea.setEditable(false);
correlationPropertiesTextArea.setBackground(new java.awt.Color(240, 240, 240));
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()
.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)
.addComponent(bnManageTags)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnManageTypes)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
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))
.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);
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);
}
});
org.openide.awt.Mnemonics.setLocalizedText(lbCentralRepository, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbCentralRepository.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@ -219,26 +296,39 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.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(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(cbUseCentralRepo, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lbCentralRepository, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.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.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(lbCentralRepository)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.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)
.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)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGap(0, 0, 0)
.addComponent(bnImportDatabase))
);
pnTagManagement.getAccessibleContext().setAccessibleName("");
}// </editor-fold>//GEN-END:initComponents
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);
}//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
@Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."})
public void load() {
@ -398,7 +492,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private void enableDatabaseConfigureButton(Boolean enable) {
boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
pnDatabaseConfiguration.setEnabled(enable && !ingestRunning);
pnDatabaseContentButtons.setEnabled(enable && !ingestRunning);
bnDbConfigure.setEnabled(enable && !ingestRunning);
lbDbLocationLabel.setEnabled(enable && !ingestRunning);
lbDbLocationValue.setEnabled(enable && !ingestRunning);
@ -419,9 +512,13 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
*/
private boolean enableButtonSubComponents(Boolean enable) {
boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
pnCorrelationProperties.setEnabled(enable && !ingestRunning);
pnTagManagement.setEnabled(enable && !ingestRunning);
bnManageTypes.setEnabled(enable && !ingestRunning);
bnImportDatabase.setEnabled(enable && !ingestRunning);
bnManageTags.setEnabled(enable && !ingestRunning);
manageTagsTextArea.setEnabled(enable && !ingestRunning);
correlationPropertiesTextArea.setEnabled(enable && !ingestRunning);
return true;
}
@ -431,14 +528,20 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private javax.swing.JButton bnManageTags;
private javax.swing.JButton bnManageTypes;
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 lbDbLocationValue;
private javax.swing.JLabel lbDbNameLabel;
private javax.swing.JLabel lbDbNameValue;
private javax.swing.JLabel lbDbPlatformTypeLabel;
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 pnDatabaseContentButtons;
private javax.swing.JPanel pnTagManagement;
private javax.swing.JTextField tbOops;
// 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());
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 {
dbManager = EamDb.getInstance();
} 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());
return;
}

View File

@ -31,17 +31,18 @@
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" 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"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jScrollPane1" pref="357" max="32767" attributes="0"/>
<Component id="lbWarnings" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="helpScrollPane" alignment="0" 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>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@ -51,16 +52,18 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="335" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbWarnings" pref="16" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="helpScrollPane" min="-2" pref="42" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="tagScrollArea" pref="341" max="32767" 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">
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -86,7 +89,7 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Container class="javax.swing.JScrollPane" name="tagScrollArea">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
@ -97,8 +100,8 @@
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="2" rowCount="0">
<Column editable="false" title="Tag" type="java.lang.Object"/>
<Column editable="true" title="Implies Known Bad" type="java.lang.Boolean"/>
<Column editable="false" title="" type="java.lang.Object"/>
<Column editable="true" title="" type="java.lang.Boolean"/>
</Table>
</Property>
</Properties>
@ -107,5 +110,38 @@
</Container>
<Component class="javax.swing.JLabel" name="lbWarnings">
</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>
</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
* 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() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.ManageTagDialog_title(),
true); // NON-NLS
initComponents();
customizeComponents();
setupHelpTextArea();
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() {
lbWarnings.setText("");
EamDb dbManager;
try {
dbManager = EamDb.getInstance();
} 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());
return;
}
@ -99,6 +108,7 @@ final class ManageTagsDialog extends javax.swing.JDialog {
Collections.sort(tagNames);
DefaultTableModel model = (DefaultTableModel) tblTagNames.getModel();
model.setColumnIdentifiers(new String[] {Bundle.ManageTagsDialog_tagColumn_header_text(), Bundle.ManageTagsDialog_notableColumn_header_text()});
for (String tagName : tagNames) {
boolean enabled = badTags.contains(tagName);
model.addRow(new Object[]{tagName, enabled});
@ -125,9 +135,11 @@ final class ManageTagsDialog extends javax.swing.JDialog {
buttonGroup1 = new javax.swing.ButtonGroup();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
tagScrollArea = new javax.swing.JScrollPane();
tblTagNames = new javax.swing.JTable();
lbWarnings = new javax.swing.JLabel();
helpScrollPane = new javax.swing.JScrollPane();
helpTextArea = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
@ -150,7 +162,7 @@ final class ManageTagsDialog extends javax.swing.JDialog {
},
new String [] {
"Tag", "Implies Known Bad"
"", ""
}
) {
Class[] types = new Class [] {
@ -168,7 +180,20 @@ final class ManageTagsDialog extends javax.swing.JDialog {
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());
getContentPane().setLayout(layout);
@ -178,15 +203,16 @@ final class ManageTagsDialog extends javax.swing.JDialog {
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 223, Short.MAX_VALUE)
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
.addComponent(lbWarnings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(0, 0, Short.MAX_VALUE)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(helpScrollPane, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tagScrollArea, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 328, 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())
);
@ -196,9 +222,11 @@ final class ManageTagsDialog extends javax.swing.JDialog {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 335, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbWarnings, javax.swing.GroupLayout.DEFAULT_SIZE, 16, Short.MAX_VALUE)
.addComponent(helpScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.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)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(okButton)
@ -237,7 +265,7 @@ final class ManageTagsDialog extends javax.swing.JDialog {
dbManager.setBadTags(badTags);
dbManager.saveSettings();
} 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());
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.
*/
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.error=Error updating existing Central Repository entries"})
"ManageTagsDialog.updateCurrentCase.error=Error updating existing central repository entries"})
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
private javax.swing.ButtonGroup buttonGroup1;
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.JButton okButton;
private javax.swing.JScrollPane tagScrollArea;
private javax.swing.JTable tblTagNames;
// End of variables declaration//GEN-END:variables
}

View File

@ -19,27 +19,16 @@
package org.sleuthkit.autopsy.corecomponents;
import java.awt.Insets;
import java.io.File;
import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import javax.swing.BorderFactory;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
import org.netbeans.spi.sendopts.OptionProcessor;
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
import org.openide.modules.ModuleInstall;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
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.coreutils.Logger;
@ -66,33 +55,11 @@ public class Installer extends ModuleInstall {
@Override
public void restored() {
super.restored();
setLookAndFeel();
UIManager.put("ViewTabDisplayerUI", "org.sleuthkit.autopsy.corecomponents.NoTabsTabDisplayerUI");
UIManager.put(DefaultTabbedContainerUI.KEY_VIEW_CONTENT_BORDER, BorderFactory.createEmptyBorder());
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(() -> {
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();
});
}

View File

@ -1143,7 +1143,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
}
tableModel.setRowCount(0);
for (AutoIngestJob job : jobs) {
AutoIngestJob.StageDetails status = job.getStageDetails();
AutoIngestJob.StageDetails status = job.getProcessingStageDetails();
tableModel.addRow(new Object[]{
job.getManifest().getCaseName(), // CASE
job.getManifest().getDataSourcePath().getFileName(), // DATA_SOURCE
@ -1152,7 +1152,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
job.getProcessingStageStartDate(), // STARTED_TIME
job.getCompletedDate(), // COMPLETED_TIME
status.getDescription(), // ACTIVITY
job.getErrorsOccurred(), // STATUS
job.getErrorsOccurred(), // STATUS
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.experimental.autoingest;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.awt.Cursor;
import java.awt.EventQueue;
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.MessageNotifyUtil;
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.
@ -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 PENDING_TABLE_COL_PREFERRED_WIDTH = 280;
private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175;
private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250;
private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450;
private static final int STAGE_TIME_COL_MIN_WIDTH = 250;
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_MAX_WIDTH = 250;
private static final int TIME_COL_PREFERRED_WIDTH = 140;
private static final int NAME_COL_MIN_WIDTH = 100;
private static final int NAME_COL_MAX_WIDTH = 250;
private static final int NAME_COL_PREFERRED_WIDTH = 140;
private static final int ACTIVITY_COL_MIN_WIDTH = 70;
private static final int ACTIVITY_COL_MAX_WIDTH = 2000;
private static final int ACTIVITY_COL_PREFERRED_WIDTH = 300;
private static final int STAGE_COL_MIN_WIDTH = 70;
private static final int STAGE_COL_MAX_WIDTH = 2000;
private static final int STAGE_COL_PREFERRED_WIDTH = 300;
private static final int STATUS_COL_MIN_WIDTH = 55;
private static final int STATUS_COL_MAX_WIDTH = 250;
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_MAX_WIDTH = 2000;
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 final DefaultTableModel pendingTableModel;
private final DefaultTableModel runningTableModel;
private final DefaultTableModel completedTableModel;
private AutoIngestMonitor autoIngestMonitor;
private ExecutorService updateExecutor;
/**
* 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.STATUS.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.
@ -275,6 +281,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_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.
@ -311,10 +318,10 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
* jobs.
*/
column = runningTable.getColumn(JobsTableModelColumns.STAGE.getColumnHeader());
column.setMinWidth(ACTIVITY_COL_MIN_WIDTH);
column.setMaxWidth(ACTIVITY_COL_MAX_WIDTH);
column.setPreferredWidth(ACTIVITY_COL_PREFERRED_WIDTH);
column.setWidth(ACTIVITY_COL_PREFERRED_WIDTH);
column.setMinWidth(STAGE_COL_MIN_WIDTH);
column.setMaxWidth(STAGE_COL_MAX_WIDTH);
column.setPreferredWidth(STAGE_COL_PREFERRED_WIDTH);
column.setWidth(STAGE_COL_PREFERRED_WIDTH);
/*
* 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.setCellRenderer(new DurationCellRenderer());
column.setMinWidth(GENERIC_COL_MIN_WIDTH);
column.setMaxWidth(ACTIVITY_TIME_COL_MAX_WIDTH);
column.setPreferredWidth(ACTIVITY_TIME_COL_MIN_WIDTH);
column.setWidth(ACTIVITY_TIME_COL_MIN_WIDTH);
column.setMaxWidth(STAGE_TIME_COL_MAX_WIDTH);
column.setPreferredWidth(STAGE_TIME_COL_MIN_WIDTH);
column.setWidth(STAGE_TIME_COL_MIN_WIDTH);
/*
* 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.CASE_DIRECTORY_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.
@ -419,12 +427,20 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
autoIngestMonitor = new AutoIngestMonitor();
autoIngestMonitor.addObserver(this);
autoIngestMonitor.startUp();
updateExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(UPDATE_TASKS_THREAD_NAME).build());
updateExecutor.submit(new UpdateJobsSnapshotTask());
}
@Override
public void update(Observable observable, Object argument) {
JobsSnapshot jobsSnapshot = (JobsSnapshot) argument;
EventQueue.invokeLater(new RefreshComponentsTask(jobsSnapshot));
public void update(Observable observable, Object arg) {
/*
* 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> completedJobs = jobsSnapshot.getCompletedJobs();
pendingJobs.sort(new AutoIngestJob.PriorityComparator());
runningJobs.sort(new AutoIngestJob.CaseNameAndProcessingHostComparator());
completedJobs.sort(new AutoIngestJob.ReverseCompletedDateComparator());
refreshTable(pendingJobs, pendingTable, pendingTableModel);
refreshTable(runningJobs, runningTable, runningTableModel);
@ -459,24 +474,19 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
Path currentRow = getSelectedEntry(table, tableModel);
tableModel.setRowCount(0);
for (AutoIngestJob job : jobs) {
if (job.getVersion() < 1) {
// Ignore version '0' nodes since they don't carry enough
// data to populate the table.
continue;
}
AutoIngestJob.StageDetails status = job.getStageDetails();
AutoIngestJob.StageDetails status = job.getProcessingStageDetails();
tableModel.addRow(new Object[]{
job.getManifest().getCaseName(), // CASE
job.getManifest().getDataSourcePath().getFileName(), job.getProcessingHostName(), // HOST_NAME
job.getManifest().getDateFileCreated(), // CREATED_TIME
job.getProcessingStageStartDate(), // STARTED_TIME
job.getCompletedDate(), // COMPLETED_TIME
status.getDescription(), // ACTIVITY
status.getDescription(), // STAGE
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.getManifest().getFilePath() // MANIFEST_FILE_PATH
//DLG: Put job object in the table
job.getManifest().getFilePath(), // MANIFEST_FILE_PATH
job
});
}
setSelectedEntry(table, tableModel, currentRow);
@ -542,7 +552,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
*/
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")),
DATA_SOURCE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ImageFolder")),
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")),
STATUS(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Status")),
CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder")),
MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath")); //DLG:,
//DLG: JOB("");
MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath")),
JOB(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Job"));
private final String header;
@ -566,15 +575,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
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 = {
CASE.getColumnHeader(),
DATA_SOURCE.getColumnHeader(),
@ -586,11 +586,28 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
STATUS.getColumnHeader(),
STAGE_TIME.getColumnHeader(),
CASE_DIRECTORY_PATH.getColumnHeader(),
MANIFEST_FILE_PATH.getColumnHeader() //DLG: ,
//DLG: JOB.getColumnHeader()
MANIFEST_FILE_PATH.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
* 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
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
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;
try {
jobsSnapshot = autoIngestMonitor.prioritizeJob(manifestFilePath);
jobsSnapshot = autoIngestMonitor.prioritizeJob(job);
refreshTables(jobsSnapshot);
} 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);
MessageNotifyUtil.Message.error(errorMessage);
}

View File

@ -50,10 +50,6 @@ public final class AutoIngestDashboardTopComponent extends TopComponent {
@Messages({
"AutoIngestDashboardTopComponent.exceptionMessage.failedToCreateDashboard=Failed to create Auto Ingest Dashboard.",})
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);
if (tc != null) {
topComponentInitialized = true;
@ -67,7 +63,7 @@ public final class AutoIngestDashboardTopComponent extends TopComponent {
try {
dashboard = AutoIngestDashboard.createDashboard();
tc.add(dashboard);
dashboard.setSize(992, 744);
dashboard.setSize(dashboard.getPreferredSize());
if (tc.isOpened() == false) {
tc.open();
}

View File

@ -34,8 +34,8 @@ import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.autopsy.ingest.IngestJob;
/**
* An automated ingest job for a manifest. The manifest specifies a co-located
* data source and a case to which the data source is to be added.
* An automated ingest job, which is an ingest job performed by the automated
* ingest service.
*/
@ThreadSafe
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 DEFAULT_PRIORITY = 0;
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
private final int version;
/*
* Version 0 fields.
*/
private final Manifest manifest;
private final String nodeName;
@GuardedBy("this")
private String nodeName;
@GuardedBy("this")
private String caseDirectoryPath;
@GuardedBy("this")
@ -56,8 +60,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
@GuardedBy("this")
private Date stageStartDate;
@GuardedBy("this")
private StageDetails stageDetails;
@GuardedBy("this")
transient private DataSourceProcessor dataSourceProcessor;
@GuardedBy("this")
transient private IngestJob ingestJob;
@ -69,96 +71,116 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
private Date completedDate;
@GuardedBy("this")
private boolean errorsOccurred;
/*
* Version 1 fields.
*/
private final int version; // For possible future use.
@GuardedBy("this")
private ProcessingStatus processingStatus;
@GuardedBy("this")
private int numberOfCrashes;
@GuardedBy("this")
private StageDetails stageDetails;
/**
* Constructs a new automated ingest job for a manifest. All job state not
* specified in the manifest is set to the default state for a new job.
* Constructs a new automated ingest job. All job state not specified in the
* 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) {
this.version = CURRENT_VERSION;
/*
* Version 0 fields.
*/
this.manifest = manifest;
this.nodeName = AutoIngestJob.LOCAL_HOST_NAME;
this.nodeName = "";
this.caseDirectoryPath = "";
this.priority = DEFAULT_PRIORITY;
this.stage = Stage.PENDING;
this.stageStartDate = manifest.getDateFileCreated();
this.stageDetails = this.getStageDetails();
this.dataSourceProcessor = null;
this.ingestJob = null;
this.cancelled = false;
this.completed = false;
this.completedDate = new Date(0);
this.errorsOccurred = false;
/*
* Version 1 fields.
*/
this.version = CURRENT_VERSION;
this.processingStatus = ProcessingStatus.PENDING;
this.numberOfCrashes = 0;
this.stageDetails = this.getProcessingStageDetails();
}
/**
* Constructs an automated ingest job for a manifest. The manifest specifies
* a co-located data source and a case to which the data source is to be
* added.
* Constructs an automated ingest job using the coordination service node
* data for the job.
*
* Note: Manifest objects will be phased out and no longer be part of the
* AutoIngestJob class.
*
* @param nodeData The node data.
* @param nodeData The coordination service node data for an automated
* ingest job.
*/
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.nodeName = nodeData.getProcessingHostName();
this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString();
this.priority = nodeData.getPriority();
this.stage = nodeData.getProcessingStage();
this.stageStartDate = nodeData.getProcessingStageStartDate();
this.stageDetails = this.getStageDetails();
this.dataSourceProcessor = null;
this.ingestJob = null;
this.cancelled = false;
this.completed = false;
this.dataSourceProcessor = null; // Transient data not in node data.
this.ingestJob = null; // Transient data not in node data.
this.cancelled = false; // Transient data not in node data.
this.completed = false; // Transient data not in node data.
this.completedDate = nodeData.getCompletedDate();
this.errorsOccurred = nodeData.getErrorsOccurred();
/*
* Version 1 fields.
*/
this.version = CURRENT_VERSION;
this.processingStatus = nodeData.getProcessingStatus();
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() {
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) {
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,
* may be null.
* Gets the path to the case directory for job, may be the empty path if the
* case directory has not been created yet.
*
* @return The case directory path or null if the case directory has not
* been created yet.
* @return The case directory path. Will be the empty path if the case
* directory has not been created yet.
*/
synchronized Path getCaseDirectoryPath() {
if (!caseDirectoryPath.isEmpty()) {
return Paths.get(caseDirectoryPath);
} else {
return null;
}
return Paths.get(caseDirectoryPath);
}
/**
@ -181,7 +203,13 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
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) {
return;
}
@ -189,15 +217,35 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
this.stageStartDate = Date.from(Instant.now());
}
/**
* Gets the processing stage of the job.
*
* @return The processing stage.
*/
synchronized Stage getProcessingStage() {
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() {
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;
Date startDate;
if (Stage.CANCELLING != this.stage && null != this.ingestJob) {
@ -235,24 +283,43 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
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) {
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) {
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() {
return this.ingestJob;
}
/**
* Cancels the job.
*/
synchronized void cancel() {
setStage(Stage.CANCELLING);
setProcessingStage(Stage.CANCELLING);
cancelled = true;
errorsOccurred = true;
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() {
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() {
setStage(Stage.COMPLETED);
setProcessingStage(Stage.COMPLETED);
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() {
return completed;
}
@ -314,55 +399,108 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
return this.errorsOccurred;
}
/**
* Gets the processing host name for this job.
*
* @return The processing host name.
*/
synchronized String getProcessingHostName() {
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() {
return this.processingStatus;
}
/**
* Sets the processing status of the job.
*
* @param processingStatus The processing status.
*/
synchronized void setProcessingStatus(ProcessingStatus processingStatus) {
this.processingStatus = processingStatus;
}
/**
* Gets the number of time this job has "crashed" during processing.
*
* @return The number of crashes.
*/
synchronized int getNumberOfCrashes() {
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) {
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
public boolean equals(Object obj) {
if (!(obj instanceof AutoIngestJob)) {
public boolean equals(Object otherJob) {
if (!(otherJob instanceof AutoIngestJob)) {
return false;
}
if (obj == this) {
if (otherJob == this) {
return true;
}
return this.getManifest().getFilePath().equals(((AutoIngestJob) obj).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());
return this.getManifest().getFilePath().equals(((AutoIngestJob) otherJob).getManifest().getFilePath());
}
/**
* Custom comparator that allows us to sort List<AutoIngestJob> on reverse
* chronological date modified (descending)
* Returns a hash code value for the job. The hash code is derived from the
* 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> {
@ -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> {
@ -386,27 +525,26 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
}
/**
* Custom comparator that allows us to sort List<AutoIngestJob> on case name
* alphabetically except for jobs for the current host, which are placed at
* the top of the list.
* Comparator that supports doing an alphabetical sort of jobs based on a
* combination of case name and processing host.
*/
static class CaseNameAndProcessingHostComparator implements Comparator<AutoIngestJob> {
@Override
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
if (o1.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
return -1; // o1 is for current case, float to top
} else if (o2.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
return 1; // o2 is for current case, float to top
public int compare(AutoIngestJob aJob, AutoIngestJob anotherJob) {
if (aJob.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
return -1; // aJob is for this, float to top
} else if (anotherJob.getProcessingHostName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
return 1; // anotherJob is for this, float to top
} 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 {
PENDING,
@ -415,6 +553,9 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
DELETED
}
/**
* Processing stages for an auto ingest job.
*/
enum Stage {
PENDING("Pending"),
@ -443,6 +584,9 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
}
/**
* Processing stage details for an auto ingest job.
*/
@Immutable
static final class StageDetails implements Serializable {

View File

@ -32,9 +32,23 @@ import javax.lang.model.type.TypeKind;
final class AutoIngestJobNodeData {
private static final int CURRENT_VERSION = 1;
private static final int MAX_POSSIBLE_NODE_DATA_SIZE = 131629;
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.
*/
@ -48,16 +62,16 @@ final class AutoIngestJobNodeData {
* Version 1 fields.
*/
private int version;
private String manifestFilePath;
private String manifestFilePath; // 'short' length used in byte array
private long manifestFileDate;
private String caseName;
private String deviceId;
private String dataSourcePath;
private String caseDirectoryPath;
private String processingHostName;
private String caseName; // 'byte' length used in byte array
private String deviceId; // 'byte' length used in byte array
private String dataSourcePath; // 'short' length used in byte array
private String caseDirectoryPath; // 'short' length used in byte array
private String processingHostName; // 'short' length used in byte array
private byte processingStage;
private long processingStageStartDate;
private String processingStageDetailsDescription;
private String processingStageDetailsDescription; // 'byte' length used in byte array
private long processingStageDetailsStartDate;
/**
@ -84,7 +98,7 @@ final class AutoIngestJobNodeData {
setProcessingHostName(job.getProcessingHostName());
setProcessingStage(job.getProcessingStage());
setProcessingStageStartDate(job.getProcessingStageStartDate());
setProcessingStageDetails(job.getStageDetails());
setProcessingStageDetails(job.getProcessingStageDetails());
}
/**
@ -107,7 +121,7 @@ final class AutoIngestJobNodeData {
this.numberOfCrashes = 0;
this.completedDate = 0L;
this.errorsOccurred = false;
this.version = CURRENT_VERSION;
this.version = 0;
this.manifestFilePath = "";
this.manifestFileDate = 0L;
this.caseName = "";
@ -151,7 +165,7 @@ final class AutoIngestJobNodeData {
this.processingStage = buffer.get();
this.processingStageStartDate = buffer.getLong();
this.processingStageDetailsDescription = getStringFromBuffer(buffer, TypeKind.BYTE);
this.processingStageDetailsStartDate = buffer.getLong();;
this.processingStageDetailsStartDate = buffer.getLong();
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.
*
* @return The case directory path or null if the case directory has not
* been created yet.
* @return The case directory path or an empty string path if the case
* directory has not been created yet.
*/
synchronized Path getCaseDirectoryPath() {
if (!caseDirectoryPath.isEmpty()) {
return Paths.get(caseDirectoryPath);
} else {
return null;
return Paths.get("");
}
}
@ -517,7 +531,16 @@ final class AutoIngestJobNodeData {
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) {
int length = 0;
String output = "";
@ -540,7 +563,16 @@ final class AutoIngestJobNodeData {
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) {
switch (lengthType) {
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.
*/
if (null != completedJob && null != completedJob.getCaseDirectoryPath()) {
if (null != completedJob && !completedJob.getCaseDirectoryPath().toString().isEmpty()) {
try {
completedJob.setErrorsOccurred(false);
completedJob.setCompletedDate(new Date(0));
@ -849,7 +849,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (null != ingestJob) {
IngestJob.DataSourceIngestModuleHandle moduleHandle = ingestJob.getSnapshot().runningDataSourceIngestModule();
if (null != moduleHandle) {
currentJob.setStage(AutoIngestJob.Stage.CANCELLING_MODULE);
currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE);
moduleHandle.cancel();
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);
job.setPriority(nodeData.getPriority());
Path caseDirectory = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
job.setCaseDirectoryPath(caseDirectory);
if (null != caseDirectory) {
job.setCaseDirectoryPath(caseDirectory);
}
newPendingJobsList.add(job);
/*
@ -1295,7 +1297,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
AutoIngestJob job = new AutoIngestJob(manifest);
job.setCaseDirectoryPath(caseDirectoryPath);
job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED);
job.setStage(AutoIngestJob.Stage.COMPLETED);
job.setProcessingStage(AutoIngestJob.Stage.COMPLETED);
job.setCompletedDate(nodeData.getCompletedDate());
job.setErrorsOccurred(true);
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 {
Path manifestPath = currentJob.getManifest().getFilePath();
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING);
updateCoordinationServiceNode(currentJob);
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();
notifyObservers(Event.JOB_STARTED);
eventPublisher.publishRemotely(new AutoIngestJobStartedEvent(currentJob));
@ -1890,6 +1893,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
// The job may get retried
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PENDING);
}
currentJob.setProcessingHostName("");
updateCoordinationServiceNode(currentJob);
boolean retry = (!currentJob.isCanceled() && !currentJob.isCompleted());
@ -1986,7 +1990,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (AutoIngestUserPreferences.getSharedConfigEnabled()) {
Path manifestPath = currentJob.getManifest().getFilePath();
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();
}
}
@ -2004,7 +2008,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException {
Path manifestPath = currentJob.getManifest().getFilePath();
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())) {
throw new DatabaseServerDownException("Case database server is down");
}
@ -2051,7 +2055,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest();
String caseName = manifest.getCaseName();
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
* 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);
if (null == dataSource) {
currentJob.setStage(AutoIngestJob.Stage.COMPLETED);
currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED);
return;
}
@ -2174,7 +2178,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
runDataSourceProcessor(caseForJob, dataSource);
if (dataSource.getContent().isEmpty()) {
currentJob.setStage(AutoIngestJob.Stage.COMPLETED);
currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED);
return;
}
@ -2219,7 +2223,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath();
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();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
Path dataSourcePath = manifest.getDataSourcePath();
@ -2255,7 +2259,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath();
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();
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId);
DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor();
@ -2420,7 +2424,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath();
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();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
IngestJobEventListener ingestJobEventListener = new IngestJobEventListener();
@ -2456,7 +2460,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
jobLogger.logAnalysisCompleted();
} else {
currentJob.setStage(AutoIngestJob.Stage.CANCELLING);
currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING);
currentJob.setErrorsOccurred(true);
AutoIngestAlertFile.create(caseDirectoryPath); // Do this first, it is more important than the case log
jobLogger.logAnalysisCancelled();
@ -2519,7 +2523,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Manifest manifest = currentJob.getManifest();
Path manifestPath = manifest.getFilePath();
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();
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
try {
@ -2770,9 +2774,10 @@ public final class AutoIngestManager extends Observable implements PropertyChang
try {
synchronized (jobsLock) {
if (currentJob != null) {
currentJob.getStageDetails();
currentJob.getProcessingStageDetails();
setChanged();
notifyObservers(Event.JOB_STATUS_UPDATED);
updateCoordinationServiceNode(currentJob);
eventPublisher.publishRemotely(new AutoIngestJobStatusEvent(currentJob));
}

View File

@ -19,13 +19,10 @@
package org.sleuthkit.autopsy.experimental.autoingest;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.awt.Cursor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Observable;
@ -34,7 +31,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.annotation.concurrent.GuardedBy;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -143,8 +139,6 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/
private void handleJobStartedEvent(AutoIngestJobStartedEvent event) {
synchronized (jobsLock) {
// DLG: TEST! Remove job from pending queue, if present
// DLG: TEST! Add job to running jobs list
jobsSnapshot.removePendingJob(event.getJob());
jobsSnapshot.addOrReplaceRunningJob(event.getJob());
setChanged();
@ -159,8 +153,12 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/
private void handleJobStatusEvent(AutoIngestJobStatusEvent event) {
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();
notifyObservers(jobsSnapshot);
}
@ -173,10 +171,10 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/
private void handleJobCompletedEvent(AutoIngestJobCompletedEvent event) {
synchronized (jobsLock) {
// DLG: TEST! Remove job from event from running list, if present
// DLG: TEST! Add job to completed list
jobsSnapshot.removeRunningJob(event.getJob());
jobsSnapshot.addOrReplaceCompletedJob(event.getJob());
AutoIngestJob job = event.getJob();
jobsSnapshot.removePendingJob(job);
jobsSnapshot.removeRunningJob(job);
jobsSnapshot.addOrReplaceCompletedJob(job);
setChanged();
notifyObservers(jobsSnapshot);
}
@ -241,6 +239,13 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
for (String node : nodeList) {
try {
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);
ProcessingStatus processingStatus = nodeData.getProcessingStatus();
switch (processingStatus) {
@ -275,9 +280,9 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
/**
* 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;
AutoIngestJob prioritizedJob = null;
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
* the pending jobs queue.
*/
for (AutoIngestJob job : jobsSnapshot.getPendingJobs()) {
if (job.getPriority() > highestPriority) {
highestPriority = job.getPriority();
for (AutoIngestJob pendingJob : jobsSnapshot.getPendingJobs()) {
if (pendingJob.getPriority() > highestPriority) {
highestPriority = pendingJob.getPriority();
}
if (job.getManifest().getFilePath().equals(manifestFilePath)) {
if (pendingJob.equals(job)) {
prioritizedJob = job;
}
}
@ -300,27 +305,25 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
*/
if (null != prioritizedJob) {
++highestPriority;
String manifestNodePath = prioritizedJob.getManifest().getFilePath().toString();
String manifestNodePath = job.getManifest().getFilePath().toString();
try {
AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath));
nodeData.setPriority(highestPriority);
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, nodeData.toArray());
} 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);
}
/*
* Publish a prioritization event.
*/
if (null != prioritizedJob) {
final String caseName = prioritizedJob.getManifest().getCaseName();
/*
* Publish a prioritization event.
*/
final String caseName = job.getManifest().getCaseName();
new Thread(() -> {
eventPublisher.publishRemotely(new AutoIngestCasePrioritizedEvent(LOCAL_HOST_NAME, caseName));
}).start();
}
}
return jobsSnapshot;
}
}
@ -344,7 +347,7 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
synchronized (jobsLock) {
jobsSnapshot = newJobsSnapshot;
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.Status=Status
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.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.JobsTableModel.ColumnHeader.StageTime=Time in Stage
AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder=Case Folder
AutoIngestDashboard.JobsTableModel.ColumnHeader.LocalJob= Local 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.JobsTableModel.ColumnHeader.CaseFolder=Case
AutoIngestDashboard.JobsTableModel.ColumnHeader.Job=Job
AutoIngestDashboard.tbServicesStatusMessage.Message=Case databases {0}, keyword search {1}, coordination {2}, messaging {3}
AutoIngestDashboard.tbServicesStatusMessage.Message.Up=up
AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down
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.Delete=Permanently delete
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.DeleteTooltip_1=Delete the selected rule
FileExporterSettingsPanel.SaveTooltip_1=Save the current rule
AutoIngestDashboard.bnPrioritizeFolder.label=<AutoIngestDashboard.bnPrioritizeJob.text>
AutoIngestCasePanel.rbDays.text=Days
AutoIngestCasePanel.rbWeeks.text=Weeks
AutoIngestCasePanel.rbMonths.text=Months

View File

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

View File

@ -3,7 +3,7 @@
<name unique="dashboard"/>
<kind type="editor"/>
<state type="separated"/>
<bounds x="76" y="68" width="996" height="672"/>
<bounds x="76" y="68" width="1005" height="750"/>
<frame state="0"/>
<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
*
* @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);
}
/**
* Download Central Repository settings.
* Download central repository settings.
*
* @param remoteFolder Shared settings folder
*
* @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);
}

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.setGraphic(followUpGroupAction.getGraphic());
} 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 -> {
if (tagGroupMenuButton.isShowing()) {

View File

@ -265,7 +265,6 @@
<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 -->
<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="" />
<antcall target="build-installer-${os.family}" />
</target>