mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
modified travis for reduced verbosity and added appveyor.yml
This commit is contained in:
parent
3c652a20f3
commit
9e04d08280
12
.travis.yml
12
.travis.yml
@ -14,9 +14,13 @@ install:
|
|||||||
- sudo apt-get install testdisk
|
- sudo apt-get install testdisk
|
||||||
- cd sleuthkit/sleuthkit
|
- cd sleuthkit/sleuthkit
|
||||||
- sh install-sleuthkit.sh
|
- sh install-sleuthkit.sh
|
||||||
script:
|
script:
|
||||||
|
- set -e
|
||||||
|
- echo "building autopsy..." && echo -en 'travis_fold:start:script.build\\r'
|
||||||
- cd $TRAVIS_BUILD_DIR/
|
- cd $TRAVIS_BUILD_DIR/
|
||||||
- ant build
|
- ant -q build
|
||||||
|
- echo -en 'travis_fold:end:script.build\\r'
|
||||||
|
- echo "testing autopsy..." && echo -en 'travis_fold:start:script.tests\\r'
|
||||||
- cd Core/
|
- cd Core/
|
||||||
- xvfb-run ant test
|
- xvfb-run ant -q test
|
||||||
|
- echo -en 'travis_fold:end:script.tests\\r'
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
<copy file="${thirdparty.dir}/LICENSE-2.0.txt" todir="${ext.dir}" />
|
<copy file="${thirdparty.dir}/LICENSE-2.0.txt" todir="${ext.dir}" />
|
||||||
|
|
||||||
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
|
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
|
||||||
<ivy:resolve/>
|
<ivy:resolve log="quiet"/>
|
||||||
<ivy:retrieve conf="core" pattern="${ext.dir}/[artifact]-[revision](-[classifier]).[ext]" />
|
<ivy:retrieve conf="core" pattern="${ext.dir}/[artifact]-[revision](-[classifier]).[ext]" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||||
import org.sleuthkit.datamodel.IngestModuleInfo;
|
import org.sleuthkit.datamodel.IngestModuleInfo;
|
||||||
|
@ -90,7 +90,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
|
|
||||||
PreparedStatement preparedStatement = null;
|
PreparedStatement preparedStatement = null;
|
||||||
String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)";
|
String sql = "INSERT INTO db_info (name, value) VALUES (?, ?) "
|
||||||
|
+ getConflictClause();
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
preparedStatement.setString(1, name);
|
preparedStatement.setString(1, name);
|
||||||
@ -189,7 +190,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
|
String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
|
||||||
+ "examiner_name, examiner_email, examiner_phone, notes) "
|
+ "examiner_name, examiner_email, examiner_phone, notes) "
|
||||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
|
||||||
|
+ getConflictClause();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
@ -425,7 +427,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
PreparedStatement preparedStatement = null;
|
PreparedStatement preparedStatement = null;
|
||||||
|
|
||||||
String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?)";
|
String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) "
|
||||||
|
+ getConflictClause();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql);
|
preparedStatement = conn.prepareStatement(sql);
|
||||||
@ -549,7 +552,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
sql.append(tableName);
|
sql.append(tableName);
|
||||||
sql.append("(case_id, data_source_id, value, file_path, known_status, comment) ");
|
sql.append("(case_id, data_source_id, value, file_path, known_status, comment) ");
|
||||||
sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), ");
|
sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), ");
|
||||||
sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?)");
|
sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) ");
|
||||||
|
sql.append(getConflictClause());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql.toString());
|
preparedStatement = conn.prepareStatement(sql.toString());
|
||||||
@ -1535,7 +1539,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
Connection conn = connect();
|
Connection conn = connect();
|
||||||
ResultSet generatedKeys = null;
|
ResultSet generatedKeys = null;
|
||||||
PreparedStatement preparedStatement = null;
|
PreparedStatement preparedStatement = null;
|
||||||
String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?)";
|
String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
|
||||||
|
+ getConflictClause();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||||
@ -1741,7 +1746,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
PreparedStatement preparedStatement1 = null;
|
PreparedStatement preparedStatement1 = null;
|
||||||
PreparedStatement preparedStatement2 = null;
|
PreparedStatement preparedStatement2 = null;
|
||||||
ResultSet resultSet = null;
|
ResultSet resultSet = null;
|
||||||
String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
|
||||||
|
+ getConflictClause();
|
||||||
String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
|
String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -1873,7 +1879,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
|
|
||||||
PreparedStatement preparedStatement = null;
|
PreparedStatement preparedStatement = null;
|
||||||
|
|
||||||
String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?)";
|
String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
|
||||||
|
+ getConflictClause();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(correlationType)));
|
preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(correlationType)));
|
||||||
@ -2044,9 +2051,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
String querySql;
|
String querySql;
|
||||||
// if we have a known ID, use it, if not (is -1) let the db assign it.
|
// if we have a known ID, use it, if not (is -1) let the db assign it.
|
||||||
if (-1 == newType.getId()) {
|
if (-1 == newType.getId()) {
|
||||||
insertSql = "INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?)";
|
insertSql = "INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
|
||||||
} else {
|
} else {
|
||||||
insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
|
insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
|
||||||
}
|
}
|
||||||
querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
|
querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
|
||||||
|
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import org.openide.util.Utilities;
|
||||||
|
import org.openide.util.actions.Presenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for actions that act on the selected AccountDeviceInstanceKeys.
|
||||||
|
* getPopupPresenter() provides a JMenuItem that works (i.e., has an icon) in
|
||||||
|
* custom context menus and also in the Netbeans Explorer views.
|
||||||
|
*/
|
||||||
|
abstract class AbstractCVTAction extends AbstractAction implements Presenter.Popup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the selected accounts that will be acted upon.
|
||||||
|
*
|
||||||
|
* @return The selected accounts
|
||||||
|
*/
|
||||||
|
Collection<? extends AccountDeviceInstanceKey> getSelectedAccounts() {
|
||||||
|
return Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JMenuItem getPopupPresenter() {
|
||||||
|
JMenuItem presenter = new JMenuItem(this);
|
||||||
|
presenter.setText(getActionDisplayName());
|
||||||
|
presenter.setIcon(getIcon());
|
||||||
|
return presenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name/text of the action as displayed in a menu.
|
||||||
|
*
|
||||||
|
* @return The diaplay name of this action
|
||||||
|
*/
|
||||||
|
abstract String getActionDisplayName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The icon to use for this icon.
|
||||||
|
*
|
||||||
|
* @return An ImageIcon used to represent this action.
|
||||||
|
*/
|
||||||
|
abstract ImageIcon getIcon();
|
||||||
|
}
|
@ -18,17 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.communications;
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import javax.swing.AbstractAction;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.Utilities;
|
|
||||||
import org.openide.util.lookup.Lookups;
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
@ -102,58 +98,8 @@ final class AccountDeviceInstanceNode extends AbstractNode {
|
|||||||
@Override
|
@Override
|
||||||
public Action[] getActions(boolean context) {
|
public Action[] getActions(boolean context) {
|
||||||
ArrayList<Action> actions = new ArrayList<>(Arrays.asList(super.getActions(context)));
|
ArrayList<Action> actions = new ArrayList<>(Arrays.asList(super.getActions(context)));
|
||||||
// actions.add(PinAccountsAction.getInstance());
|
actions.add(PinAccountsAction.getInstance());
|
||||||
// actions.add(ResetAndPinAccountsAction.getInstance());
|
actions.add(ResetAndPinAccountsAction.getInstance());
|
||||||
return actions.toArray(new Action[actions.size()]);
|
return actions.toArray(new Action[actions.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Action that pins the selected AccountDeviceInstances to the
|
|
||||||
* visualization.
|
|
||||||
*/
|
|
||||||
static private class PinAccountsAction extends AbstractAction {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private final static PinAccountsAction instance = new PinAccountsAction();
|
|
||||||
|
|
||||||
private static PinAccountsAction getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PinAccountsAction() {
|
|
||||||
super("Add Account(s) to Visualization");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
Collection<? extends AccountDeviceInstanceKey> lookupAll =
|
|
||||||
Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class);
|
|
||||||
CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(lookupAll, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Action that pins the selected AccountDeviceInstances to the
|
|
||||||
* visualization.
|
|
||||||
*/
|
|
||||||
static private class ResetAndPinAccountsAction extends AbstractAction {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private final static ResetAndPinAccountsAction instance = new ResetAndPinAccountsAction();
|
|
||||||
|
|
||||||
private static ResetAndPinAccountsAction getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResetAndPinAccountsAction() {
|
|
||||||
super("Visualize Account(s)");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
Collection<? extends AccountDeviceInstanceKey> lookupAll =
|
|
||||||
Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class);
|
|
||||||
CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(lookupAll, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2017-18 Basis Technology Corp.
|
* Copyright 2017-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,9 +21,9 @@ package org.sleuthkit.autopsy.communications;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import org.openide.nodes.ChildFactory;
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||||
|
@ -20,9 +20,6 @@ CVTTopComponent.vizPanel.TabConstraints.tabTitle=Visualize
|
|||||||
CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=Browse
|
CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=Browse
|
||||||
CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=Visualize
|
CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=Visualize
|
||||||
CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=Visualize
|
CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=Visualize
|
||||||
VisualizationPanel.jButton6.text=Hierarchy
|
|
||||||
VisualizationPanel.jButton7.text=Circle
|
|
||||||
VisualizationPanel.jButton8.text=Organic
|
|
||||||
VisualizationPanel.fitGraphButton.text=
|
VisualizationPanel.fitGraphButton.text=
|
||||||
VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||||
VisualizationPanel.jLabel1.text=Layouts:
|
VisualizationPanel.jLabel1.text=Layouts:
|
||||||
@ -36,11 +33,8 @@ VisualizationPanel.zoomInButton.toolTipText=Zoom in
|
|||||||
VisualizationPanel.zoomInButton.text=
|
VisualizationPanel.zoomInButton.text=
|
||||||
VisualizationPanel.zoomOutButton.toolTipText=Zoom out
|
VisualizationPanel.zoomOutButton.toolTipText=Zoom out
|
||||||
VisualizationPanel.zoomOutButton.text=
|
VisualizationPanel.zoomOutButton.text=
|
||||||
# To change this license header, choose License Headers in Project Properties.
|
|
||||||
# To change this template file, choose Tools | Templates
|
|
||||||
# and open the template in the editor.
|
|
||||||
VisualizationPanel.circleLayoutButton.text=Circle
|
VisualizationPanel.circleLayoutButton.text=Circle
|
||||||
VisualizationPanel.organicLayoutButton.text=Organic
|
VisualizationPanel.organicLayoutButton.text=Organic
|
||||||
VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic
|
VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic
|
||||||
VisualizationPanel.hierarchyLayoutButton.text=Hierarchy
|
VisualizationPanel.hierarchyLayoutButton.text=Hierarchical
|
||||||
VisualizationPanel.clearVizButton.text_1=Clear Viz.
|
VisualizationPanel.clearVizButton.text_1=Clear Viz.
|
||||||
|
@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.communications;
|
|||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
|
||||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +78,7 @@ final class CVTEvents {
|
|||||||
return accountDeviceInstances;
|
return accountDeviceInstances;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnpinAccountsEvent(Set<AccountDeviceInstanceKey> accountDeviceInstances) {
|
UnpinAccountsEvent(Collection<? extends AccountDeviceInstanceKey> accountDeviceInstances) {
|
||||||
this.accountDeviceInstances = ImmutableSet.copyOf(accountDeviceInstances);
|
this.accountDeviceInstances = ImmutableSet.copyOf(accountDeviceInstances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<NonVisualComponents>
|
|
||||||
<Component class="org.sleuthkit.autopsy.communications.VisualizationPanel" name="vizPanel">
|
|
||||||
</Component>
|
|
||||||
</NonVisualComponents>
|
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
@ -72,6 +68,20 @@
|
|||||||
</Constraint>
|
</Constraint>
|
||||||
</Constraints>
|
</Constraints>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="org.sleuthkit.autopsy.communications.VisualizationPanel" name="vizPanel">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||||
|
<JTabbedPaneConstraints tabName="Visualize">
|
||||||
|
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="CVTTopComponent.vizPanel.TabConstraints.tabTitle_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="tabIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
|
<Image iconType="3" name="/org/sleuthkit/autopsy/communications/images/emblem-web.png"/>
|
||||||
|
</Property>
|
||||||
|
</JTabbedPaneConstraints>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
<Component class="org.sleuthkit.autopsy.communications.FiltersPanel" name="filtersPane">
|
<Component class="org.sleuthkit.autopsy.communications.FiltersPanel" name="filtersPane">
|
||||||
|
@ -71,7 +71,7 @@ public final class CVTTopComponent extends TopComponent {
|
|||||||
* via an Eventbus
|
* via an Eventbus
|
||||||
*/
|
*/
|
||||||
CVTEvents.getCVTEventBus().register(this);
|
CVTEvents.getCVTEventBus().register(this);
|
||||||
// CVTEvents.getCVTEventBus().register(vizPanel);
|
CVTEvents.getCVTEventBus().register(vizPanel);
|
||||||
CVTEvents.getCVTEventBus().register(accountsBrowser);
|
CVTEvents.getCVTEventBus().register(accountsBrowser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +88,14 @@ public final class CVTTopComponent extends TopComponent {
|
|||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
vizPanel = new VisualizationPanel();
|
|
||||||
browseVisualizeTabPane = new JTabbedPane();
|
browseVisualizeTabPane = new JTabbedPane();
|
||||||
accountsBrowser = new AccountsBrowser();
|
accountsBrowser = new AccountsBrowser();
|
||||||
|
vizPanel = new VisualizationPanel();
|
||||||
filtersPane = new FiltersPanel();
|
filtersPane = new FiltersPanel();
|
||||||
|
|
||||||
browseVisualizeTabPane.setFont(new Font("Tahoma", 0, 18)); // NOI18N
|
browseVisualizeTabPane.setFont(new Font("Tahoma", 0, 18)); // NOI18N
|
||||||
browseVisualizeTabPane.addTab(NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1"), new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N
|
browseVisualizeTabPane.addTab(NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1"), new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N
|
||||||
|
browseVisualizeTabPane.addTab(NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.vizPanel.TabConstraints.tabTitle_1"), new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), vizPanel); // NOI18N
|
||||||
|
|
||||||
filtersPane.setMinimumSize(new Dimension(256, 495));
|
filtersPane.setMinimumSize(new Dimension(256, 495));
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ public final class CVTTopComponent extends TopComponent {
|
|||||||
.addGap(6, 6, 6)
|
.addGap(6, 6, 6)
|
||||||
.addComponent(filtersPane, GroupLayout.PREFERRED_SIZE, 265, GroupLayout.PREFERRED_SIZE)
|
.addComponent(filtersPane, GroupLayout.PREFERRED_SIZE, 265, GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(browseVisualizeTabPane, GroupLayout.DEFAULT_SIZE, 786, Short.MAX_VALUE)
|
.addComponent(browseVisualizeTabPane, GroupLayout.PREFERRED_SIZE, 786, Short.MAX_VALUE)
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
|
@ -25,7 +25,6 @@ import com.google.common.collect.MultimapBuilder;
|
|||||||
import com.mxgraph.model.mxCell;
|
import com.mxgraph.model.mxCell;
|
||||||
import com.mxgraph.model.mxICell;
|
import com.mxgraph.model.mxICell;
|
||||||
import com.mxgraph.util.mxConstants;
|
import com.mxgraph.util.mxConstants;
|
||||||
import com.mxgraph.view.mxCellState;
|
|
||||||
import com.mxgraph.view.mxGraph;
|
import com.mxgraph.view.mxGraph;
|
||||||
import com.mxgraph.view.mxStylesheet;
|
import com.mxgraph.view.mxStylesheet;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -84,17 +83,19 @@ final class CommunicationsGraph extends mxGraph {
|
|||||||
mxStylesheet.getDefaultEdgeStyle().put(mxConstants.STYLE_STARTARROW, mxConstants.NONE);
|
mxStylesheet.getDefaultEdgeStyle().put(mxConstants.STYLE_STARTARROW, mxConstants.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map from type specific account identifier to mxCell(vertex). */
|
/** Map from type specific account identifier to mxCell(vertex). */
|
||||||
private final Map<String, mxCell> nodeMap = new HashMap<>();
|
private final Map<String, mxCell> nodeMap = new HashMap<>();
|
||||||
|
|
||||||
/* Map from relationship source (Content) to mxCell (edge). */
|
/** Map from relationship source (Content) to mxCell (edge). */
|
||||||
private final Multimap<Content, mxCell> edgeMap = MultimapBuilder.hashKeys().hashSetValues().build();
|
private final Multimap<Content, mxCell> edgeMap = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||||
private final LockedVertexModel lockedVertexModel;
|
private final LockedVertexModel lockedVertexModel;
|
||||||
|
|
||||||
private final PinnedAccountModel pinnedAccountModel;
|
private final PinnedAccountModel pinnedAccountModel;
|
||||||
|
|
||||||
CommunicationsGraph() {
|
CommunicationsGraph(PinnedAccountModel pinnedAccountModel, LockedVertexModel lockedVertexModel) {
|
||||||
super(mxStylesheet);
|
super(mxStylesheet);
|
||||||
|
this.pinnedAccountModel = pinnedAccountModel;
|
||||||
|
this.lockedVertexModel = lockedVertexModel;
|
||||||
//set fixed properties of graph.
|
//set fixed properties of graph.
|
||||||
setAutoSizeCells(true);
|
setAutoSizeCells(true);
|
||||||
setCellsCloneable(false);
|
setCellsCloneable(false);
|
||||||
@ -113,21 +114,6 @@ final class CommunicationsGraph extends mxGraph {
|
|||||||
setKeepEdgesInBackground(true);
|
setKeepEdgesInBackground(true);
|
||||||
setResetEdgesOnMove(true);
|
setResetEdgesOnMove(true);
|
||||||
setHtmlLabels(true);
|
setHtmlLabels(true);
|
||||||
|
|
||||||
lockedVertexModel = new LockedVertexModel();
|
|
||||||
lockedVertexModel.registerhandler((LockedVertexModel.VertexLockEvent event) -> {
|
|
||||||
if (event.isVertexLocked()) {
|
|
||||||
getView().clear(event.getVertex(), true, true);
|
|
||||||
getView().validate();
|
|
||||||
} else {
|
|
||||||
final mxCellState state = getView().getState(event.getVertex(), true);
|
|
||||||
getView().updateLabel(state);
|
|
||||||
getView().updateLabelBounds(state);
|
|
||||||
getView().updateBoundingBox(state);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
pinnedAccountModel = new PinnedAccountModel(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,20 +241,20 @@ final class CommunicationsGraph extends mxGraph {
|
|||||||
*/
|
*/
|
||||||
private class RebuildWorker extends SwingWorker<Void, Void> {
|
private class RebuildWorker extends SwingWorker<Void, Void> {
|
||||||
|
|
||||||
private final ProgressIndicator progress;
|
private final ProgressIndicator progressIndicator;
|
||||||
private final CommunicationsManager commsManager;
|
private final CommunicationsManager commsManager;
|
||||||
private final CommunicationsFilter currentFilter;
|
private final CommunicationsFilter currentFilter;
|
||||||
|
|
||||||
RebuildWorker(ProgressIndicator progress, CommunicationsManager commsManager, CommunicationsFilter currentFilter) {
|
RebuildWorker(ProgressIndicator progress, CommunicationsManager commsManager, CommunicationsFilter currentFilter) {
|
||||||
this.progress = progress;
|
this.progressIndicator = progress;
|
||||||
this.currentFilter = currentFilter;
|
this.currentFilter = currentFilter;
|
||||||
this.commsManager = commsManager;
|
this.commsManager = commsManager;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground() throws Exception {
|
protected Void doInBackground() {
|
||||||
progress.start("Loading accounts");
|
progressIndicator.start("Loading accounts");
|
||||||
int progressCounter = 0;
|
int progressCounter = 0;
|
||||||
try {
|
try {
|
||||||
/**
|
/**
|
||||||
@ -279,18 +265,18 @@ final class CommunicationsGraph extends mxGraph {
|
|||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final List<AccountDeviceInstance> relatedAccountDeviceInstances =
|
//get accounts related to pinned account
|
||||||
commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter);
|
final List<AccountDeviceInstance> relatedAccountDeviceInstances
|
||||||
|
= commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter);
|
||||||
relatedAccounts.put(adiKey.getAccountDeviceInstance(), adiKey);
|
relatedAccounts.put(adiKey.getAccountDeviceInstance(), adiKey);
|
||||||
getOrCreateVertex(adiKey);
|
getOrCreateVertex(adiKey);
|
||||||
|
|
||||||
//get accounts related to pinned account
|
|
||||||
for (final AccountDeviceInstance relatedADI : relatedAccountDeviceInstances) {
|
for (final AccountDeviceInstance relatedADI : relatedAccountDeviceInstances) {
|
||||||
final long adiRelationshipsCount = commsManager.getRelationshipSourcesCount(relatedADI, currentFilter);
|
final long adiRelationshipsCount = commsManager.getRelationshipSourcesCount(relatedADI, currentFilter);
|
||||||
final AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, currentFilter, adiRelationshipsCount);
|
final AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, currentFilter, adiRelationshipsCount);
|
||||||
relatedAccounts.put(relatedADI, relatedADIKey); //store related accounts
|
relatedAccounts.put(relatedADI, relatedADIKey); //store related accounts
|
||||||
}
|
}
|
||||||
progress.progress(++progressCounter);
|
progressIndicator.progress(++progressCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<AccountDeviceInstance> accounts = relatedAccounts.keySet();
|
Set<AccountDeviceInstance> accounts = relatedAccounts.keySet();
|
||||||
@ -298,19 +284,24 @@ final class CommunicationsGraph extends mxGraph {
|
|||||||
Map<AccountPair, Long> relationshipCounts = commsManager.getRelationshipCountsPairwise(accounts, currentFilter);
|
Map<AccountPair, Long> relationshipCounts = commsManager.getRelationshipCountsPairwise(accounts, currentFilter);
|
||||||
|
|
||||||
int total = relationshipCounts.size();
|
int total = relationshipCounts.size();
|
||||||
int k = 0;
|
int progress = 0;
|
||||||
progress.switchToDeterminate("", 0, total);
|
String progressText = "";
|
||||||
|
progressIndicator.switchToDeterminate("", 0, total);
|
||||||
for (Map.Entry<AccountPair, Long> entry : relationshipCounts.entrySet()) {
|
for (Map.Entry<AccountPair, Long> entry : relationshipCounts.entrySet()) {
|
||||||
Long count = entry.getValue();
|
Long count = entry.getValue();
|
||||||
AccountPair relationshipKey = entry.getKey();
|
AccountPair relationshipKey = entry.getKey();
|
||||||
AccountDeviceInstanceKey account1 = relatedAccounts.get(relationshipKey.getFirst());
|
AccountDeviceInstanceKey account1 = relatedAccounts.get(relationshipKey.getFirst());
|
||||||
AccountDeviceInstanceKey account2 = relatedAccounts.get(relationshipKey.getSecond());
|
AccountDeviceInstanceKey account2 = relatedAccounts.get(relationshipKey.getSecond());
|
||||||
mxCell addEdge = addOrUpdateEdge(count, account1, account2);
|
|
||||||
progress.progress(addEdge.getId(), k++);
|
if (pinnedAccountModel.isAccountPinned(account1)
|
||||||
|
|| pinnedAccountModel.isAccountPinned(account2)) {
|
||||||
|
mxCell addEdge = addOrUpdateEdge(count, account1, account2);
|
||||||
|
progressText = addEdge.getId();
|
||||||
|
}
|
||||||
|
progressIndicator.progress(progressText, progress++);
|
||||||
}
|
}
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
logger.log(Level.SEVERE, "Error", tskCoreException);
|
logger.log(Level.SEVERE, "Error", tskCoreException);
|
||||||
} finally {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -326,7 +317,7 @@ final class CommunicationsGraph extends mxGraph {
|
|||||||
} catch (CancellationException ex) {
|
} catch (CancellationException ex) {
|
||||||
logger.log(Level.INFO, "Graph visualization cancelled");
|
logger.log(Level.INFO, "Graph visualization cancelled");
|
||||||
} finally {
|
} finally {
|
||||||
progress.finish();
|
progressIndicator.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2018 Basis Technology Corp.
|
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sleuthkit.autopsy.communications;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface EventHandler<T> {
|
|
||||||
|
|
||||||
void handle(T event);
|
|
||||||
}
|
|
@ -18,20 +18,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.communications;
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.mxgraph.model.mxCell;
|
import com.mxgraph.model.mxCell;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class LockedVertexModel {
|
/**
|
||||||
|
* Model of which vertices in a graph are locked ( not moveable by layout
|
||||||
void registerhandler(EventHandler<VertexLockEvent> handler) {
|
* algorithms).
|
||||||
eventBus.register(handler);
|
*
|
||||||
}
|
*/
|
||||||
|
final class LockedVertexModel {
|
||||||
void unregisterhandler(EventHandler<VertexLockEvent> handler) {
|
|
||||||
eventBus.unregister(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final EventBus eventBus = new EventBus();
|
private final EventBus eventBus = new EventBus();
|
||||||
|
|
||||||
@ -42,30 +41,34 @@ class LockedVertexModel {
|
|||||||
*/
|
*/
|
||||||
private final Set<mxCell> lockedVertices = new HashSet<>();
|
private final Set<mxCell> lockedVertices = new HashSet<>();
|
||||||
|
|
||||||
LockedVertexModel() {
|
void registerhandler(Object handler) {
|
||||||
|
eventBus.register(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregisterhandler(Object handler) {
|
||||||
|
eventBus.unregister(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock the given vertex so that applying a layout algorithm doesn't move
|
* Lock the given vertices so that applying a layout algorithm doesn't move
|
||||||
* it. The user can still manually position the vertex.
|
* them. The user can still manually position the vertices.
|
||||||
*
|
*
|
||||||
* @param vertex The vertex to lock.
|
* @param vertex The vertex to lock.
|
||||||
*/
|
*/
|
||||||
void lockVertex(mxCell vertex) {
|
void lock(Collection<mxCell> vertices) {
|
||||||
lockedVertices.add(vertex);
|
lockedVertices.addAll(vertices);
|
||||||
eventBus.post(new VertexLockEvent(vertex, true));
|
eventBus.post(new VertexLockEvent(true, vertices));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock the given vertex so that applying a layout algorithm can move it.
|
* Unlock the given vertices so that applying a layout algorithm can move
|
||||||
|
* them.
|
||||||
*
|
*
|
||||||
* @param vertex The vertex to unlock.
|
* @param vertex The vertex to unlock.
|
||||||
*/
|
*/
|
||||||
void unlockVertex(mxCell vertex) {
|
void unlock(Collection<mxCell> vertices) {
|
||||||
lockedVertices.remove(vertex);
|
lockedVertices.removeAll(vertices);
|
||||||
eventBus.post(new VertexLockEvent(vertex, false));
|
eventBus.post(new VertexLockEvent(false, vertices));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isVertexLocked(mxCell vertex) {
|
boolean isVertexLocked(mxCell vertex) {
|
||||||
@ -77,21 +80,36 @@ class LockedVertexModel {
|
|||||||
lockedVertices.clear();
|
lockedVertices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class VertexLockEvent {
|
boolean isEmpty() {
|
||||||
|
return lockedVertices.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
private final mxCell vertex;
|
/**
|
||||||
|
* Event that represents a change in the locked state of one or more
|
||||||
|
* vertices.
|
||||||
|
*/
|
||||||
|
final static class VertexLockEvent {
|
||||||
|
|
||||||
public mxCell getVertex() {
|
private final boolean locked;
|
||||||
return vertex;
|
private final Set<mxCell> vertices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The vertices whose locked state has changed.
|
||||||
|
*/
|
||||||
|
public Set<mxCell> getVertices() {
|
||||||
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVertexLocked() {
|
/**
|
||||||
|
* @return True if the vertices are locked, False if the vertices are
|
||||||
|
* unlocked.
|
||||||
|
*/
|
||||||
|
public boolean isLocked() {
|
||||||
return locked;
|
return locked;
|
||||||
}
|
}
|
||||||
private final boolean locked;
|
|
||||||
|
|
||||||
VertexLockEvent(mxCell vertex, boolean locked) {
|
VertexLockEvent(boolean locked, Collection< mxCell> vertices) {
|
||||||
this.vertex = vertex;
|
this.vertices = ImmutableSet.copyOf(vertices);
|
||||||
this.locked = locked;
|
this.locked = locked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
|||||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The right hand side of the CVT. Has a DataResultPanel to show a listing of
|
* The right hand side of the CVT. Has a DataResultPanel to show a listing of
|
||||||
@ -151,10 +150,10 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
|||||||
//Use lookup here?
|
//Use lookup here?
|
||||||
final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) selectedNodes[0];
|
final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) selectedNodes[0];
|
||||||
|
|
||||||
final Set<AccountDeviceInstance> accountDeviceInstances = new HashSet<>();
|
final Set<AccountDeviceInstanceKey> accountDeviceInstances = new HashSet<>();
|
||||||
for (final Node n : selectedNodes) {
|
for (final Node n : selectedNodes) {
|
||||||
//Use lookup here?
|
//Use lookup here?
|
||||||
accountDeviceInstances.add(((AccountDeviceInstanceNode) n).getAccountDeviceInstance());
|
accountDeviceInstances.add(((AccountDeviceInstanceNode) n).getAccountDeviceInstanceKey());
|
||||||
}
|
}
|
||||||
return SelectionNode.createFromAccounts(accountDeviceInstances, adiNode.getFilter(), adiNode.getCommsManager());
|
return SelectionNode.createFromAccounts(accountDeviceInstances, adiNode.getFilter(), adiNode.getCommsManager());
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import org.openide.util.ImageUtilities;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that pins the AccountDevicesIntanceKeys in the ActionsGlobalContext to
|
||||||
|
* the visualizaion
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({"PinAccountsAction.pluralText=Add Selected Accounts to Visualization",
|
||||||
|
"PinAccountsAction.singularText=Add Selected Account to Visualization"})
|
||||||
|
final class PinAccountsAction extends AbstractCVTAction {
|
||||||
|
|
||||||
|
static private final ImageIcon ICON = ImageUtilities.loadImageIcon(
|
||||||
|
"/org/sleuthkit/autopsy/communications/images/marker--plus.png", false);
|
||||||
|
private static final String SINGULAR_TEXT = Bundle.PinAccountsAction_singularText();
|
||||||
|
private static final String PLURAL_TEXT = Bundle.PinAccountsAction_pluralText();
|
||||||
|
|
||||||
|
private static final PinAccountsAction instance = new PinAccountsAction();
|
||||||
|
|
||||||
|
static PinAccountsAction getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(getSelectedAccounts(), false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getActionDisplayName() {
|
||||||
|
return getSelectedAccounts().size() > 1 ? PLURAL_TEXT : SINGULAR_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ImageIcon getIcon() {
|
||||||
|
return ICON;
|
||||||
|
}
|
||||||
|
}
|
@ -19,22 +19,31 @@
|
|||||||
package org.sleuthkit.autopsy.communications;
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model of what accounts are pinned to a visualization.
|
||||||
|
*/
|
||||||
class PinnedAccountModel {
|
class PinnedAccountModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of AccountDeviceInstanceKeys that are 'Pinned' to this graph. Pinned
|
* Set of AccountDeviceInstanceKeys that are 'Pinned' to the graph. Pinned
|
||||||
* accounts are shown regardless of filters, and accounts that are related
|
* accounts are shown regardless of filters, and accounts that are related
|
||||||
* to pinned accounts and pass the filters are show. Pinning accounts is the
|
* to pinned accounts and pass the filters are show. Pinning accounts is the
|
||||||
* primary way to populate the graph.
|
* primary way to populate the graph.
|
||||||
*/
|
*/
|
||||||
private final Set<AccountDeviceInstanceKey> pinnedAccountDevices = new HashSet<>();
|
private final Set<AccountDeviceInstanceKey> pinnedAccountDevices = new HashSet<>();
|
||||||
private final CommunicationsGraph graph;
|
|
||||||
|
|
||||||
PinnedAccountModel(CommunicationsGraph graph) {
|
private final EventBus eventBus = new EventBus();
|
||||||
this.graph = graph;
|
|
||||||
|
void registerhandler(Object handler) {
|
||||||
|
eventBus.register(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregisterhandler(Object handler) {
|
||||||
|
eventBus.unregister(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAccountPinned(AccountDeviceInstanceKey account) {
|
boolean isAccountPinned(AccountDeviceInstanceKey account) {
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import org.openide.util.ImageUtilities;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that clears any pinned accounts and pins the AcountDevicesInstanceKeys
|
||||||
|
* in the ActionsGlobalContext to the visualization.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages(value = {"ResetAndPinAccountsAction.singularText=Visualize Only Selected Account",
|
||||||
|
"ResetAndPinAccountsAction.pluralText=Visualize Only Selected Accounts"})
|
||||||
|
final class ResetAndPinAccountsAction extends AbstractCVTAction {
|
||||||
|
|
||||||
|
private static final ImageIcon ICON = ImageUtilities.loadImageIcon(
|
||||||
|
"/org/sleuthkit/autopsy/communications/images/marker--pin.png", false);
|
||||||
|
private static final String SINGULAR_TEXT = Bundle.ResetAndPinAccountsAction_singularText();
|
||||||
|
private static final String PLURAL_TEXT = Bundle.ResetAndPinAccountsAction_pluralText();
|
||||||
|
|
||||||
|
private static final ResetAndPinAccountsAction instance = new ResetAndPinAccountsAction();
|
||||||
|
|
||||||
|
static ResetAndPinAccountsAction getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(getSelectedAccounts(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getActionDisplayName() {
|
||||||
|
return getSelectedAccounts().size() > 1 ? PLURAL_TEXT : SINGULAR_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ImageIcon getIcon() {
|
||||||
|
return ICON;
|
||||||
|
}
|
||||||
|
}
|
@ -24,10 +24,13 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.ChildFactory;
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -44,23 +47,27 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
*/
|
*/
|
||||||
final class SelectionNode extends AbstractNode {
|
final class SelectionNode extends AbstractNode {
|
||||||
|
|
||||||
private SelectionNode(Children children) {
|
private SelectionNode(Children children, Lookup lookup) {
|
||||||
super(children);
|
super(children, lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SelectionNode createFromAccountsAndRelationships(
|
static SelectionNode createFromAccountsAndRelationships(
|
||||||
Set<Content> edgeRelationshipArtifacts,
|
Set<Content> edgeRelationshipArtifacts,
|
||||||
Set<AccountDeviceInstance> accountDeviceInstances,
|
Set<AccountDeviceInstanceKey> accountDeviceInstanceKeys,
|
||||||
CommunicationsFilter filter,
|
CommunicationsFilter filter,
|
||||||
CommunicationsManager commsManager) {
|
CommunicationsManager commsManager) {
|
||||||
|
|
||||||
|
Set<AccountDeviceInstance> accountDeviceInstances = accountDeviceInstanceKeys.stream()
|
||||||
|
.map(AccountDeviceInstanceKey::getAccountDeviceInstance)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
SelectionNode node = new SelectionNode(Children.create(
|
SelectionNode node = new SelectionNode(Children.create(
|
||||||
new RelationshipChildren(
|
new RelationshipChildren(
|
||||||
edgeRelationshipArtifacts,
|
edgeRelationshipArtifacts,
|
||||||
accountDeviceInstances,
|
accountDeviceInstances,
|
||||||
commsManager,
|
commsManager,
|
||||||
filter),
|
filter),
|
||||||
true));
|
true), Lookups.fixed(accountDeviceInstanceKeys.toArray()));
|
||||||
|
|
||||||
//This is not good for internationalization!!!
|
//This is not good for internationalization!!!
|
||||||
String name = "";
|
String name = "";
|
||||||
@ -82,7 +89,7 @@ final class SelectionNode extends AbstractNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SelectionNode createFromAccounts(
|
static SelectionNode createFromAccounts(
|
||||||
Set<AccountDeviceInstance> accountDeviceInstances,
|
Set<AccountDeviceInstanceKey> accountDeviceInstances,
|
||||||
CommunicationsFilter filter,
|
CommunicationsFilter filter,
|
||||||
CommunicationsManager commsManager) {
|
CommunicationsManager commsManager) {
|
||||||
|
|
||||||
@ -122,9 +129,9 @@ final class SelectionNode extends AbstractNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node createNodeForKey(Content t) {
|
protected Node createNodeForKey(Content content) {
|
||||||
if (t instanceof BlackboardArtifact) {
|
if (content instanceof BlackboardArtifact) {
|
||||||
return new RelationshipNode((BlackboardArtifact) t);
|
return new RelationshipNode((BlackboardArtifact) content);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException("Cannot create a RelationshipNode for non BlackboardArtifact content.");
|
throw new UnsupportedOperationException("Cannot create a RelationshipNode for non BlackboardArtifact content.");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.communications;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import org.openide.util.ImageUtilities;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that unpins the AcccountDeviceInstanceKeys in the ActionsGlobalContext
|
||||||
|
* form the visualization.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({"UnpinAccountsAction.pluralText=Remove Selected Accounts",
|
||||||
|
"UnpinAccountsAction.singularText=Remove Selected Account"})
|
||||||
|
final class UnpinAccountsAction extends AbstractCVTAction {
|
||||||
|
|
||||||
|
static final private ImageIcon ICON = ImageUtilities.loadImageIcon(
|
||||||
|
"/org/sleuthkit/autopsy/communications/images/marker--minus.png", false);
|
||||||
|
private static final String SINGULAR_TEXT = Bundle.UnpinAccountsAction_singularText();
|
||||||
|
private static final String PLURAL_TEXT = Bundle.UnpinAccountsAction_pluralText();
|
||||||
|
|
||||||
|
private static final UnpinAccountsAction instance = new UnpinAccountsAction();
|
||||||
|
|
||||||
|
static UnpinAccountsAction getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent event) {
|
||||||
|
CVTEvents.getCVTEventBus().post(new CVTEvents.UnpinAccountsEvent(getSelectedAccounts()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getActionDisplayName() {
|
||||||
|
return getSelectedAccounts().size() > 1 ? PLURAL_TEXT : SINGULAR_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ImageIcon getIcon() {
|
||||||
|
return ICON;
|
||||||
|
}
|
||||||
|
}
|
@ -68,15 +68,15 @@
|
|||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JTextArea" name="jTextArea1">
|
<Component class="javax.swing.JTextArea" name="jTextArea1">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
<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="columns" type="int" value="20"/>
|
||||||
<Property name="lineWrap" type="boolean" value="true"/>
|
<Property name="lineWrap" type="boolean" value="true"/>
|
||||||
<Property name="rows" type="int" value="5"/>
|
<Property name="rows" type="int" value="5"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.jTextArea1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.jTextArea1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
|
||||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
@ -166,9 +166,6 @@
|
|||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hierarchyLayoutButtonActionPerformed"/>
|
|
||||||
</Events>
|
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="fastOrganicLayoutButton">
|
<Component class="javax.swing.JButton" name="fastOrganicLayoutButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -179,9 +176,6 @@
|
|||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fastOrganicLayoutButtonActionPerformed"/>
|
|
||||||
</Events>
|
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="organicLayoutButton">
|
<Component class="javax.swing.JButton" name="organicLayoutButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -192,9 +186,6 @@
|
|||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="organicLayoutButtonActionPerformed"/>
|
|
||||||
</Events>
|
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="circleLayoutButton">
|
<Component class="javax.swing.JButton" name="circleLayoutButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -205,9 +196,6 @@
|
|||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="circleLayoutButtonActionPerformed"/>
|
|
||||||
</Events>
|
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JToolBar$Separator" name="jSeparator1">
|
<Component class="javax.swing.JToolBar$Separator" name="jSeparator1">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -222,11 +210,11 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomOutButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomOutButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="focusable" type="boolean" value="false"/>
|
|
||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomOutButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomOutButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="focusable" type="boolean" value="false"/>
|
||||||
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
@ -241,11 +229,11 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomInButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomInButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="focusable" type="boolean" value="false"/>
|
|
||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomInButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomInButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="focusable" type="boolean" value="false"/>
|
||||||
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
@ -260,11 +248,11 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomActualButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomActualButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="focusable" type="boolean" value="false"/>
|
|
||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomActualButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomActualButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="focusable" type="boolean" value="false"/>
|
||||||
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
@ -279,11 +267,11 @@
|
|||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.fitZoomButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.fitZoomButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="focusable" type="boolean" value="false"/>
|
|
||||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.fitZoomButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.fitZoomButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property name="focusable" type="boolean" value="false"/>
|
||||||
|
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
|
@ -28,7 +28,6 @@ import com.mxgraph.model.mxCell;
|
|||||||
import com.mxgraph.model.mxICell;
|
import com.mxgraph.model.mxICell;
|
||||||
import com.mxgraph.swing.handler.mxRubberband;
|
import com.mxgraph.swing.handler.mxRubberband;
|
||||||
import com.mxgraph.swing.mxGraphComponent;
|
import com.mxgraph.swing.mxGraphComponent;
|
||||||
import com.mxgraph.swing.util.mxMorphing;
|
|
||||||
import com.mxgraph.util.mxEvent;
|
import com.mxgraph.util.mxEvent;
|
||||||
import com.mxgraph.util.mxEventObject;
|
import com.mxgraph.util.mxEventObject;
|
||||||
import com.mxgraph.util.mxEventSource;
|
import com.mxgraph.util.mxEventSource;
|
||||||
@ -36,11 +35,14 @@ import com.mxgraph.util.mxPoint;
|
|||||||
import com.mxgraph.util.mxRectangle;
|
import com.mxgraph.util.mxRectangle;
|
||||||
import com.mxgraph.util.mxUndoManager;
|
import com.mxgraph.util.mxUndoManager;
|
||||||
import com.mxgraph.util.mxUndoableEdit;
|
import com.mxgraph.util.mxUndoableEdit;
|
||||||
|
import com.mxgraph.view.mxCellState;
|
||||||
import com.mxgraph.view.mxGraph;
|
import com.mxgraph.view.mxGraph;
|
||||||
|
import com.mxgraph.view.mxGraphView;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
@ -51,18 +53,23 @@ import java.beans.PropertyChangeEvent;
|
|||||||
import java.beans.PropertyVetoException;
|
import java.beans.PropertyVetoException;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import static java.util.Collections.singleton;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JSplitPane;
|
import javax.swing.JSplitPane;
|
||||||
@ -80,12 +87,11 @@ import org.openide.util.Lookup;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ProxyLookup;
|
import org.openide.util.lookup.ProxyLookup;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
|
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
|
||||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
|
||||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
@ -101,23 +107,17 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* CVTTopComponent when this tab is active allowing for context sensitive
|
* CVTTopComponent when this tab is active allowing for context sensitive
|
||||||
* actions to work correctly.
|
* actions to work correctly.
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages("VisualizationPanel.cancelButton.text=Cancel")
|
|
||||||
final public class VisualizationPanel extends JPanel implements Lookup.Provider {
|
final public class VisualizationPanel extends JPanel implements Lookup.Provider {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(VisualizationPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(VisualizationPanel.class.getName());
|
||||||
private static final String BASE_IMAGE_PATH = "/org/sleuthkit/autopsy/communications/images";
|
private static final String BASE_IMAGE_PATH = "/org/sleuthkit/autopsy/communications/images";
|
||||||
static final private ImageIcon pinIcon
|
|
||||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--pin.png"));
|
|
||||||
static final private ImageIcon addPinIcon
|
|
||||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--plus.png"));
|
|
||||||
static final private ImageIcon unpinIcon
|
|
||||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--minus.png"));
|
|
||||||
static final private ImageIcon unlockIcon
|
static final private ImageIcon unlockIcon
|
||||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_unlocked.png"));
|
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_unlocked.png"));
|
||||||
static final private ImageIcon lockIcon
|
static final private ImageIcon lockIcon
|
||||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_locked.png"));
|
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_locked.png"));
|
||||||
|
|
||||||
|
@NbBundle.Messages("VisualizationPanel.cancelButton.text=Cancel")
|
||||||
private static final String CANCEL = Bundle.VisualizationPanel_cancelButton_text();
|
private static final String CANCEL = Bundle.VisualizationPanel_cancelButton_text();
|
||||||
|
|
||||||
private final ExplorerManager vizEM = new ExplorerManager();
|
private final ExplorerManager vizEM = new ExplorerManager();
|
||||||
@ -132,27 +132,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
private final CommunicationsGraph graph;
|
private final CommunicationsGraph graph;
|
||||||
|
|
||||||
private final mxUndoManager undoManager = new mxUndoManager();
|
private final mxUndoManager undoManager = new mxUndoManager();
|
||||||
private final mxRubberband rubberband;
|
private final mxRubberband rubberband; //NOPMD We keep a referenec as insurance to prevent garbage collection
|
||||||
private final mxFastOrganicLayout fastOrganicLayout;
|
|
||||||
private final mxCircleLayout circleLayout;
|
|
||||||
private final mxOrganicLayout organicLayout;
|
|
||||||
private final mxHierarchicalLayout hierarchicalLayout;
|
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
private SwingWorker<?, ?> worker;
|
private SwingWorker<?, ?> worker;
|
||||||
private final PinnedAccountModel pinnedAccountModel;
|
private final PinnedAccountModel pinnedAccountModel = new PinnedAccountModel();
|
||||||
private final LockedVertexModel lockedVertexModel;
|
private final LockedVertexModel lockedVertexModel = new LockedVertexModel();
|
||||||
|
|
||||||
|
private final Map<NamedGraphLayout, JButton> layoutButtons = new HashMap<>();
|
||||||
|
private NamedGraphLayout currentLayout;
|
||||||
|
|
||||||
public VisualizationPanel() {
|
public VisualizationPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
graph = new CommunicationsGraph();
|
|
||||||
pinnedAccountModel = graph.getPinnedAccountModel();
|
|
||||||
lockedVertexModel = graph.getLockedVertexModel();
|
|
||||||
|
|
||||||
fastOrganicLayout = new mxFastOrganicLayoutImpl(graph);
|
graph = new CommunicationsGraph(pinnedAccountModel, lockedVertexModel);
|
||||||
circleLayout = new mxCircleLayoutImpl(graph);
|
|
||||||
organicLayout = new mxOrganicLayoutImpl(graph);
|
|
||||||
hierarchicalLayout = new mxHierarchicalLayoutImpl(graph);
|
|
||||||
|
|
||||||
graphComponent = new mxGraphComponent(graph);
|
graphComponent = new mxGraphComponent(graph);
|
||||||
graphComponent.setAutoExtend(true);
|
graphComponent.setAutoExtend(true);
|
||||||
@ -166,123 +159,90 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
graphComponent.setBackground(Color.WHITE);
|
graphComponent.setBackground(Color.WHITE);
|
||||||
borderLayoutPanel.add(graphComponent, BorderLayout.CENTER);
|
borderLayoutPanel.add(graphComponent, BorderLayout.CENTER);
|
||||||
|
|
||||||
//install rubber band selection handler
|
//install rubber band other handlers
|
||||||
rubberband = new mxRubberband(graphComponent);
|
rubberband = new mxRubberband(graphComponent);
|
||||||
|
|
||||||
|
lockedVertexModel.registerhandler(this);
|
||||||
|
|
||||||
final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt)
|
final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt)
|
||||||
-> zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale()));
|
-> zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale()));
|
||||||
graph.getView().addListener(mxEvent.SCALE, scaleListener);
|
graph.getView().addListener(mxEvent.SCALE, scaleListener);
|
||||||
graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, scaleListener);
|
graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, scaleListener);
|
||||||
|
|
||||||
graphComponent.getGraphControl().addMouseWheelListener(new MouseAdapter() {
|
final GraphMouseListener graphMouseListener = new GraphMouseListener();
|
||||||
/**
|
graphComponent.getGraphControl().addMouseWheelListener(graphMouseListener);
|
||||||
* Translate mouse wheel events into zooming.
|
graphComponent.getGraphControl().addMouseListener(graphMouseListener);
|
||||||
*
|
|
||||||
* @param event The MouseWheelEvent
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void mouseWheelMoved(final MouseWheelEvent event) {
|
|
||||||
super.mouseWheelMoved(event);
|
|
||||||
if (event.getPreciseWheelRotation() > 0) {
|
|
||||||
graphComponent.zoomIn();
|
|
||||||
} else if (event.getPreciseWheelRotation() < 0) {
|
|
||||||
graphComponent.zoomOut();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
graphComponent.getGraphControl().addMouseListener(new MouseAdapter() {
|
|
||||||
/**
|
|
||||||
* Right click handler: show context menu.
|
|
||||||
*
|
|
||||||
* @param event The MouseEvent
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(final MouseEvent event) {
|
|
||||||
super.mouseClicked(event);
|
|
||||||
if (SwingUtilities.isRightMouseButton(event)) {
|
|
||||||
final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY());
|
|
||||||
if (cellAt != null && cellAt.isVertex()) {
|
|
||||||
final JPopupMenu jPopupMenu = new JPopupMenu();
|
|
||||||
final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue();
|
|
||||||
|
|
||||||
if (lockedVertexModel.isVertexLocked(cellAt)) {
|
|
||||||
jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock " + cellAt.getId(), unlockIcon) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent event) {
|
|
||||||
lockedVertexModel.unlockVertex(cellAt);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
jPopupMenu.add(new JMenuItem(new AbstractAction("Lock " + cellAt.getId(), lockIcon) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent event) {
|
|
||||||
lockedVertexModel.lockVertex(cellAt);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (pinnedAccountModel.isAccountPinned(adiKey)) {
|
|
||||||
jPopupMenu.add(new JMenuItem(new AbstractAction("Unpin " + cellAt.getId(), unpinIcon) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent event) {
|
|
||||||
handleUnPinEvent(new CVTEvents.UnpinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue())));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
jPopupMenu.add(new JMenuItem(new AbstractAction("Pin " + cellAt.getId(), addPinIcon) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent event) {
|
|
||||||
handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), false));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
jPopupMenu.add(new JMenuItem(new AbstractAction("Pin only " + cellAt.getId(), pinIcon) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent event) {
|
|
||||||
handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), true));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM);
|
final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM);
|
||||||
|
|
||||||
splitPane.setRightComponent(messageBrowser);
|
splitPane.setRightComponent(messageBrowser);
|
||||||
|
|
||||||
proxyLookup = new ProxyLookup(
|
proxyLookup = new ProxyLookup(
|
||||||
messageBrowser.getLookup(),
|
ExplorerUtils.createLookup(vizEM, getActionMap()),
|
||||||
ExplorerUtils.createLookup(vizEM, getActionMap()));
|
messageBrowser.getLookup()
|
||||||
|
);
|
||||||
|
|
||||||
//feed selection to explorermanager
|
//feed selection to explorermanager
|
||||||
graph.getSelectionModel().addListener(null, new SelectionListener());
|
graph.getSelectionModel().addListener(mxEvent.CHANGE, new SelectionListener());
|
||||||
final mxEventSource.mxIEventListener undoListener = (Object sender, mxEventObject evt)
|
final mxEventSource.mxIEventListener undoListener = (Object sender, mxEventObject evt)
|
||||||
-> undoManager.undoableEditHappened((mxUndoableEdit) evt.getProperty("edit"));
|
-> undoManager.undoableEditHappened((mxUndoableEdit) evt.getProperty("edit"));
|
||||||
|
|
||||||
graph.getModel().addListener(mxEvent.UNDO, undoListener);
|
graph.getModel().addListener(mxEvent.UNDO, undoListener);
|
||||||
graph.getView().addListener(mxEvent.UNDO, undoListener);
|
graph.getView().addListener(mxEvent.UNDO, undoListener);
|
||||||
|
|
||||||
|
FastOrganicLayoutImpl fastOrganicLayout = new FastOrganicLayoutImpl(graph);
|
||||||
|
CircleLayoutImpl circleLayout = new CircleLayoutImpl(graph);
|
||||||
|
OrganicLayoutImpl organicLayout = new OrganicLayoutImpl(graph);
|
||||||
|
organicLayout.setMaxIterations(10);
|
||||||
|
HierarchicalLayoutImpl hierarchyLayout = new HierarchicalLayoutImpl(graph);
|
||||||
|
|
||||||
|
//local method to configure layout buttons
|
||||||
|
BiConsumer<JButton, NamedGraphLayout> configure = (layoutButton, layout) -> {
|
||||||
|
layoutButtons.put(layout, layoutButton);
|
||||||
|
layoutButton.addActionListener(event -> applyLayout(layout));
|
||||||
|
};
|
||||||
|
//configure layout buttons.
|
||||||
|
configure.accept(circleLayoutButton, circleLayout);
|
||||||
|
configure.accept(organicLayoutButton, organicLayout);
|
||||||
|
configure.accept(fastOrganicLayoutButton, fastOrganicLayout);
|
||||||
|
configure.accept(hierarchyLayoutButton, hierarchyLayout);
|
||||||
|
|
||||||
|
applyLayout(fastOrganicLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param layoutButton the value of layoutButton
|
||||||
|
* @param layout the value of layout
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public Lookup getLookup() {
|
public Lookup getLookup() {
|
||||||
return proxyLookup;
|
return proxyLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
void handleUnPinEvent(final CVTEvents.UnpinAccountsEvent pinEvent) {
|
void handle(LockedVertexModel.VertexLockEvent event) {
|
||||||
|
final Set<mxCell> vertices = event.getVertices();
|
||||||
|
mxGraphView view = graph.getView();
|
||||||
|
vertices.forEach(vertex -> {
|
||||||
|
final mxCellState state = view.getState(vertex, true);
|
||||||
|
view.updateLabel(state);
|
||||||
|
view.updateLabelBounds(state);
|
||||||
|
view.updateBoundingBox(state);
|
||||||
|
graphComponent.redraw(state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
void handle(final CVTEvents.UnpinAccountsEvent pinEvent) {
|
||||||
graph.getModel().beginUpdate();
|
graph.getModel().beginUpdate();
|
||||||
pinnedAccountModel.unpinAccount(pinEvent.getAccountDeviceInstances());
|
pinnedAccountModel.unpinAccount(pinEvent.getAccountDeviceInstances());
|
||||||
graph.clear();
|
graph.clear();
|
||||||
rebuildGraph();
|
rebuildGraph();
|
||||||
// Updates the display
|
// Updates the display
|
||||||
graph.getModel().endUpdate();
|
graph.getModel().endUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
void handlePinEvent(final CVTEvents.PinAccountsEvent pinEvent) {
|
void handle(final CVTEvents.PinAccountsEvent pinEvent) {
|
||||||
graph.getModel().beginUpdate();
|
graph.getModel().beginUpdate();
|
||||||
if (pinEvent.isReplace()) {
|
if (pinEvent.isReplace()) {
|
||||||
graph.resetGraph();
|
graph.resetGraph();
|
||||||
@ -291,19 +251,16 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
rebuildGraph();
|
rebuildGraph();
|
||||||
// Updates the display
|
// Updates the display
|
||||||
graph.getModel().endUpdate();
|
graph.getModel().endUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
void handleFilterEvent(final CVTEvents.FilterChangeEvent filterChangeEvent) {
|
void handle(final CVTEvents.FilterChangeEvent filterChangeEvent) {
|
||||||
|
|
||||||
graph.getModel().beginUpdate();
|
graph.getModel().beginUpdate();
|
||||||
graph.clear();
|
graph.clear();
|
||||||
currentFilter = filterChangeEvent.getNewFilter();
|
currentFilter = filterChangeEvent.getNewFilter();
|
||||||
rebuildGraph();
|
rebuildGraph();
|
||||||
// Updates the display
|
// Updates the display
|
||||||
graph.getModel().endUpdate();
|
graph.getModel().endUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||||
@ -328,19 +285,12 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
if (worker.isCancelled()) {
|
if (worker.isCancelled()) {
|
||||||
graph.resetGraph();
|
graph.resetGraph();
|
||||||
rebuildGraph();
|
rebuildGraph();
|
||||||
} else if (graph.getModel().getChildCount(graph.getDefaultParent()) < 64) {
|
|
||||||
applyOrganicLayout(10);
|
|
||||||
} else {
|
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
"Too many accounts, layout aborted.",
|
|
||||||
"Autopsy",
|
|
||||||
JOptionPane.WARNING_MESSAGE);
|
|
||||||
}
|
}
|
||||||
|
applyLayout(currentLayout);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
worker.execute();
|
worker.execute();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +307,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
logger.log(Level.SEVERE, "Can't get CommunicationsManager when there is no case open.", ex);
|
logger.log(Level.SEVERE, "Can't get CommunicationsManager when there is no case open.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Case.addEventTypeSubscriber(EnumSet.of(CURRENT_CASE), evt -> {
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), evt -> {
|
||||||
graph.getModel().beginUpdate();
|
graph.getModel().beginUpdate();
|
||||||
try {
|
try {
|
||||||
graph.resetGraph();
|
graph.resetGraph();
|
||||||
@ -374,15 +324,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
logger.log(Level.SEVERE, "Error getting CommunicationsManager for the current case.", ex);
|
logger.log(Level.SEVERE, "Error getting CommunicationsManager for the current case.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeNotify() {
|
|
||||||
super.removeNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -419,11 +363,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
|
|
||||||
borderLayoutPanel.setLayout(new BorderLayout());
|
borderLayoutPanel.setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
jTextArea1.setBackground(new Color(240, 240, 240));
|
||||||
jTextArea1.setColumns(20);
|
jTextArea1.setColumns(20);
|
||||||
jTextArea1.setLineWrap(true);
|
jTextArea1.setLineWrap(true);
|
||||||
jTextArea1.setRows(5);
|
jTextArea1.setRows(5);
|
||||||
jTextArea1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextArea1.text")); // NOI18N
|
jTextArea1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextArea1.text")); // NOI18N
|
||||||
jTextArea1.setBackground(new Color(240, 240, 240));
|
|
||||||
|
|
||||||
GroupLayout placeHolderPanelLayout = new GroupLayout(placeHolderPanel);
|
GroupLayout placeHolderPanelLayout = new GroupLayout(placeHolderPanel);
|
||||||
placeHolderPanel.setLayout(placeHolderPanelLayout);
|
placeHolderPanel.setLayout(placeHolderPanelLayout);
|
||||||
@ -448,49 +392,29 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
hierarchyLayoutButton.setFocusable(false);
|
hierarchyLayoutButton.setFocusable(false);
|
||||||
hierarchyLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
hierarchyLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
hierarchyLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
hierarchyLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
hierarchyLayoutButton.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent evt) {
|
|
||||||
hierarchyLayoutButtonActionPerformed(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fastOrganicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fastOrganicLayoutButton.text")); // NOI18N
|
fastOrganicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fastOrganicLayoutButton.text")); // NOI18N
|
||||||
fastOrganicLayoutButton.setFocusable(false);
|
fastOrganicLayoutButton.setFocusable(false);
|
||||||
fastOrganicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
fastOrganicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
fastOrganicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
fastOrganicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
fastOrganicLayoutButton.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent evt) {
|
|
||||||
fastOrganicLayoutButtonActionPerformed(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
organicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.organicLayoutButton.text")); // NOI18N
|
organicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.organicLayoutButton.text")); // NOI18N
|
||||||
organicLayoutButton.setFocusable(false);
|
organicLayoutButton.setFocusable(false);
|
||||||
organicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
organicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
organicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
organicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
organicLayoutButton.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent evt) {
|
|
||||||
organicLayoutButtonActionPerformed(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
circleLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.circleLayoutButton.text")); // NOI18N
|
circleLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.circleLayoutButton.text")); // NOI18N
|
||||||
circleLayoutButton.setFocusable(false);
|
circleLayoutButton.setFocusable(false);
|
||||||
circleLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
circleLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
circleLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
circleLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
circleLayoutButton.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent evt) {
|
|
||||||
circleLayoutButtonActionPerformed(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
jSeparator1.setOrientation(SwingConstants.VERTICAL);
|
jSeparator1.setOrientation(SwingConstants.VERTICAL);
|
||||||
|
|
||||||
zoomOutButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-out-red.png"))); // NOI18N
|
zoomOutButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-out-red.png"))); // NOI18N
|
||||||
zoomOutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.text")); // NOI18N
|
zoomOutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.text")); // NOI18N
|
||||||
|
zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N
|
||||||
zoomOutButton.setFocusable(false);
|
zoomOutButton.setFocusable(false);
|
||||||
zoomOutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
zoomOutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N
|
|
||||||
zoomOutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
zoomOutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
zoomOutButton.addActionListener(new ActionListener() {
|
zoomOutButton.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
@ -500,9 +424,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
|
|
||||||
zoomInButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-in-green.png"))); // NOI18N
|
zoomInButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-in-green.png"))); // NOI18N
|
||||||
zoomInButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.text")); // NOI18N
|
zoomInButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.text")); // NOI18N
|
||||||
|
zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N
|
||||||
zoomInButton.setFocusable(false);
|
zoomInButton.setFocusable(false);
|
||||||
zoomInButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
zoomInButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N
|
|
||||||
zoomInButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
zoomInButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
zoomInButton.addActionListener(new ActionListener() {
|
zoomInButton.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
@ -512,9 +436,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
|
|
||||||
zoomActualButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-actual.png"))); // NOI18N
|
zoomActualButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-actual.png"))); // NOI18N
|
||||||
zoomActualButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.text")); // NOI18N
|
zoomActualButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.text")); // NOI18N
|
||||||
|
zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N
|
||||||
zoomActualButton.setFocusable(false);
|
zoomActualButton.setFocusable(false);
|
||||||
zoomActualButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
zoomActualButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N
|
|
||||||
zoomActualButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
zoomActualButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
zoomActualButton.addActionListener(new ActionListener() {
|
zoomActualButton.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
@ -524,9 +448,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
|
|
||||||
fitZoomButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-fit.png"))); // NOI18N
|
fitZoomButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-fit.png"))); // NOI18N
|
||||||
fitZoomButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.text")); // NOI18N
|
fitZoomButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.text")); // NOI18N
|
||||||
|
fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N
|
||||||
fitZoomButton.setFocusable(false);
|
fitZoomButton.setFocusable(false);
|
||||||
fitZoomButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
fitZoomButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N
|
|
||||||
fitZoomButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
fitZoomButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||||
fitZoomButton.addActionListener(new ActionListener() {
|
fitZoomButton.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
@ -626,21 +550,55 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
graphComponent.zoomOut();
|
graphComponent.zoomOut();
|
||||||
}//GEN-LAST:event_zoomOutButtonActionPerformed
|
}//GEN-LAST:event_zoomOutButtonActionPerformed
|
||||||
|
|
||||||
private void circleLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_circleLayoutButtonActionPerformed
|
/**
|
||||||
morph(circleLayout);
|
* Apply the given layout. The given layout becomes the current layout. The
|
||||||
}//GEN-LAST:event_circleLayoutButtonActionPerformed
|
* layout is computed in the background.
|
||||||
|
*
|
||||||
|
* @param layout The layout to apply.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({"VisualizationPanel.computingLayout=Computing Layout",
|
||||||
|
"# {0} - layout name",
|
||||||
|
"VisualizationPanel.layoutFailWithLockedVertices.text={0} layout failed with locked vertices. Unlock some vertices or try a different layout.",
|
||||||
|
"# {0} - layout name",
|
||||||
|
"VisualizationPanel.layoutFail.text={0} layout failed. Try a different layout."})
|
||||||
|
private void applyLayout(NamedGraphLayout layout) {
|
||||||
|
currentLayout = layout;
|
||||||
|
layoutButtons.forEach((layoutKey, button)
|
||||||
|
-> button.setFont(button.getFont().deriveFont(layoutKey == layout ? Font.BOLD : Font.PLAIN)));
|
||||||
|
|
||||||
private void organicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_organicLayoutButtonActionPerformed
|
ModalDialogProgressIndicator progressIndicator = new ModalDialogProgressIndicator(windowAncestor, Bundle.VisualizationPanel_computingLayout());
|
||||||
applyOrganicLayout(10);
|
progressIndicator.start(Bundle.VisualizationPanel_computingLayout());
|
||||||
}//GEN-LAST:event_organicLayoutButtonActionPerformed
|
|
||||||
|
|
||||||
private void fastOrganicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_fastOrganicLayoutButtonActionPerformed
|
new SwingWorker<Void, Void>() {
|
||||||
morph(fastOrganicLayout);
|
@Override
|
||||||
}//GEN-LAST:event_fastOrganicLayoutButtonActionPerformed
|
protected Void doInBackground() {
|
||||||
|
graph.getModel().beginUpdate();
|
||||||
|
try {
|
||||||
|
layout.execute(graph.getDefaultParent());
|
||||||
|
fitGraph();
|
||||||
|
} finally {
|
||||||
|
graph.getModel().endUpdate();
|
||||||
|
progressIndicator.finish();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void hierarchyLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_hierarchyLayoutButtonActionPerformed
|
@Override
|
||||||
morph(hierarchicalLayout);
|
protected void done() {
|
||||||
}//GEN-LAST:event_hierarchyLayoutButtonActionPerformed
|
try {
|
||||||
|
get();
|
||||||
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
logger.log(Level.WARNING, "CVT graph layout failed.", ex);
|
||||||
|
if (lockedVertexModel.isEmpty()) {
|
||||||
|
MessageNotifyUtil.Message.error(Bundle.VisualizationPanel_layoutFail_text(layout.getDisplayName()));
|
||||||
|
} else {
|
||||||
|
MessageNotifyUtil.Message.error(Bundle.VisualizationPanel_layoutFailWithLockedVertices_text(layout.getDisplayName()));
|
||||||
|
}
|
||||||
|
undoManager.undo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
|
||||||
private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed
|
private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed
|
||||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
@ -651,14 +609,8 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
// Updates the display
|
// Updates the display
|
||||||
graph.getModel().endUpdate();
|
graph.getModel().endUpdate();
|
||||||
setCursor(Cursor.getDefaultCursor());
|
setCursor(Cursor.getDefaultCursor());
|
||||||
|
|
||||||
}//GEN-LAST:event_clearVizButtonActionPerformed
|
}//GEN-LAST:event_clearVizButtonActionPerformed
|
||||||
|
|
||||||
private void applyOrganicLayout(int iterations) {
|
|
||||||
organicLayout.setMaxIterations(iterations);
|
|
||||||
morph(organicLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fitGraph() {
|
private void fitGraph() {
|
||||||
graphComponent.zoomTo(1, true);
|
graphComponent.zoomTo(1, true);
|
||||||
mxPoint translate = graph.getView().getTranslate();
|
mxPoint translate = graph.getView().getTranslate();
|
||||||
@ -681,57 +633,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
|
|
||||||
final Dimension size = graphComponent.getSize();
|
final Dimension size = graphComponent.getSize();
|
||||||
final double widthFactor = size.getWidth() / boundsForCells.getWidth();
|
final double widthFactor = size.getWidth() / boundsForCells.getWidth();
|
||||||
|
final double heightFactor = size.getHeight() / boundsForCells.getHeight();
|
||||||
|
|
||||||
graphComponent.zoom(widthFactor);
|
graphComponent.zoom((heightFactor + widthFactor) / 2.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void morph(mxIGraphLayout layout) {
|
|
||||||
// layout using morphing
|
|
||||||
graph.getModel().beginUpdate();
|
|
||||||
|
|
||||||
CancelationListener cancelationListener = new CancelationListener();
|
|
||||||
ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, "Computing layout", new String[]{CANCEL}, CANCEL, cancelationListener);
|
|
||||||
SwingWorker<Void, Void> morphWorker = new SwingWorker<Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground() {
|
|
||||||
progress.start("Computing layout");
|
|
||||||
layout.execute(graph.getDefaultParent());
|
|
||||||
if (isCancelled()) {
|
|
||||||
progress.finish();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
mxMorphing morph = new mxMorphing(graphComponent, 20, 1.2, 20) {
|
|
||||||
@Override
|
|
||||||
public void updateAnimation() {
|
|
||||||
fireEvent(new mxEventObject(mxEvent.EXECUTE));
|
|
||||||
super.updateAnimation(); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
morph.addListener(mxEvent.EXECUTE, (Object sender, mxEventObject evt) -> {
|
|
||||||
if (isCancelled()) {
|
|
||||||
morph.stopAnimation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
morph.addListener(mxEvent.DONE, (Object sender, mxEventObject event) -> {
|
|
||||||
graph.getModel().endUpdate();
|
|
||||||
if (isCancelled()) {
|
|
||||||
undoManager.undo();
|
|
||||||
} else {
|
|
||||||
fitGraph();
|
|
||||||
}
|
|
||||||
progress.finish();
|
|
||||||
});
|
|
||||||
|
|
||||||
morph.startAnimation();
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cancelationListener.configure(morphWorker, progress);
|
|
||||||
morphWorker.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private JPanel borderLayoutPanel;
|
private JPanel borderLayoutPanel;
|
||||||
@ -755,6 +661,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
private JButton zoomOutButton;
|
private JButton zoomOutButton;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens to graph selection model and updates ExplorerManager to reflect
|
||||||
|
* changes in selection.
|
||||||
|
*/
|
||||||
final private class SelectionListener implements mxEventSource.mxIEventListener {
|
final private class SelectionListener implements mxEventSource.mxIEventListener {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -766,7 +676,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
if (selectionCells.length > 0) {
|
if (selectionCells.length > 0) {
|
||||||
mxICell[] selectedCells = Arrays.asList(selectionCells).toArray(new mxCell[selectionCells.length]);
|
mxICell[] selectedCells = Arrays.asList(selectionCells).toArray(new mxCell[selectionCells.length]);
|
||||||
HashSet<Content> relationshipSources = new HashSet<>();
|
HashSet<Content> relationshipSources = new HashSet<>();
|
||||||
HashSet<AccountDeviceInstance> adis = new HashSet<>();
|
HashSet<AccountDeviceInstanceKey> adis = new HashSet<>();
|
||||||
for (mxICell cell : selectedCells) {
|
for (mxICell cell : selectedCells) {
|
||||||
if (cell.isEdge()) {
|
if (cell.isEdge()) {
|
||||||
mxICell source = (mxICell) graph.getModel().getTerminal(cell, true);
|
mxICell source = (mxICell) graph.getModel().getTerminal(cell, true);
|
||||||
@ -783,7 +693,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
logger.log(Level.SEVERE, " Error getting relationsips....", tskCoreException);
|
logger.log(Level.SEVERE, " Error getting relationsips....", tskCoreException);
|
||||||
}
|
}
|
||||||
} else if (cell.isVertex()) {
|
} else if (cell.isVertex()) {
|
||||||
adis.add(((AccountDeviceInstanceKey) cell.getValue()).getAccountDeviceInstance());
|
adis.add((AccountDeviceInstanceKey) cell.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,9 +709,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final private class mxFastOrganicLayoutImpl extends mxFastOrganicLayout {
|
/**
|
||||||
|
* Extend mxIGraphLayout with a getDisplayName method,
|
||||||
|
*/
|
||||||
|
private interface NamedGraphLayout extends mxIGraphLayout {
|
||||||
|
|
||||||
mxFastOrganicLayoutImpl(mxGraph graph) {
|
String getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of mxFastOrganicLayout that ignores locked vertices.
|
||||||
|
*/
|
||||||
|
final private class FastOrganicLayoutImpl extends mxFastOrganicLayout implements NamedGraphLayout {
|
||||||
|
|
||||||
|
FastOrganicLayoutImpl(mxGraph graph) {
|
||||||
super(graph);
|
super(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,18 +733,26 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public mxRectangle setVertexLocation(Object vertex, double x, double y) {
|
public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names
|
||||||
if (isVertexIgnored(vertex)) {
|
if (isVertexIgnored(vertex)) {
|
||||||
return getVertexBounds(vertex);
|
return getVertexBounds(vertex);
|
||||||
} else {
|
} else {
|
||||||
return super.setVertexLocation(vertex, x, y);
|
return super.setVertexLocation(vertex, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return "Fast Organic";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final private class mxCircleLayoutImpl extends mxCircleLayout {
|
/**
|
||||||
|
* Extension of mxCircleLayout that ignores locked vertices.
|
||||||
|
*/
|
||||||
|
final private class CircleLayoutImpl extends mxCircleLayout implements NamedGraphLayout {
|
||||||
|
|
||||||
mxCircleLayoutImpl(mxGraph graph) {
|
CircleLayoutImpl(mxGraph graph) {
|
||||||
super(graph);
|
super(graph);
|
||||||
setResetEdges(true);
|
setResetEdges(true);
|
||||||
}
|
}
|
||||||
@ -835,18 +764,26 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public mxRectangle setVertexLocation(Object vertex, double x, double y) {
|
public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names
|
||||||
if (isVertexIgnored(vertex)) {
|
if (isVertexIgnored(vertex)) {
|
||||||
return getVertexBounds(vertex);
|
return getVertexBounds(vertex);
|
||||||
} else {
|
} else {
|
||||||
return super.setVertexLocation(vertex, x, y);
|
return super.setVertexLocation(vertex, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return "Circle";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final private class mxOrganicLayoutImpl extends mxOrganicLayout {
|
/**
|
||||||
|
* Extension of mxOrganicLayout that ignores locked vertices.
|
||||||
|
*/
|
||||||
|
final private class OrganicLayoutImpl extends mxOrganicLayout implements NamedGraphLayout {
|
||||||
|
|
||||||
mxOrganicLayoutImpl(mxGraph graph) {
|
OrganicLayoutImpl(mxGraph graph) {
|
||||||
super(graph);
|
super(graph);
|
||||||
setResetEdges(true);
|
setResetEdges(true);
|
||||||
}
|
}
|
||||||
@ -858,18 +795,26 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public mxRectangle setVertexLocation(Object vertex, double x, double y) {
|
public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names
|
||||||
if (isVertexIgnored(vertex)) {
|
if (isVertexIgnored(vertex)) {
|
||||||
return getVertexBounds(vertex);
|
return getVertexBounds(vertex);
|
||||||
} else {
|
} else {
|
||||||
return super.setVertexLocation(vertex, x, y);
|
return super.setVertexLocation(vertex, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return "Organic";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final private class mxHierarchicalLayoutImpl extends mxHierarchicalLayout {
|
/**
|
||||||
|
* Extension of mxHierarchicalLayout that ignores locked vertices.
|
||||||
|
*/
|
||||||
|
final private class HierarchicalLayoutImpl extends mxHierarchicalLayout implements NamedGraphLayout {
|
||||||
|
|
||||||
mxHierarchicalLayoutImpl(mxGraph graph) {
|
HierarchicalLayoutImpl(mxGraph graph) {
|
||||||
super(graph);
|
super(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,15 +825,24 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public mxRectangle setVertexLocation(Object vertex, double x, double y) {
|
public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names
|
||||||
if (isVertexIgnored(vertex)) {
|
if (isVertexIgnored(vertex)) {
|
||||||
return getVertexBounds(vertex);
|
return getVertexBounds(vertex);
|
||||||
} else {
|
} else {
|
||||||
return super.setVertexLocation(vertex, x, y);
|
return super.setVertexLocation(vertex, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return "Hierarchical";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that closses the given ModalDialogProgressIndicator and cancels
|
||||||
|
* the future.
|
||||||
|
*/
|
||||||
private class CancelationListener implements ActionListener {
|
private class CancelationListener implements ActionListener {
|
||||||
|
|
||||||
private Future<?> cancellable;
|
private Future<?> cancellable;
|
||||||
@ -905,6 +859,108 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
|||||||
cancellable.cancel(true);
|
cancellable.cancel(true);
|
||||||
progress.finish();
|
progress.finish();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mouse Adapter for the graphComponent. Handles wheel zooming and context
|
||||||
|
* menus.
|
||||||
|
*/
|
||||||
|
private class GraphMouseListener extends MouseAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate mouse wheel events into zooming.
|
||||||
|
*
|
||||||
|
* @param event The MouseWheelEvent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(final MouseWheelEvent event) {
|
||||||
|
super.mouseWheelMoved(event);
|
||||||
|
if (event.getPreciseWheelRotation() < 0) {
|
||||||
|
graphComponent.zoomIn();
|
||||||
|
} else if (event.getPreciseWheelRotation() > 0) {
|
||||||
|
graphComponent.zoomOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Right click handler: show context menu.
|
||||||
|
*
|
||||||
|
* @param event The MouseEvent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(final MouseEvent event) {
|
||||||
|
super.mouseClicked(event);
|
||||||
|
if (SwingUtilities.isRightMouseButton(event)) {
|
||||||
|
final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY());
|
||||||
|
if (cellAt != null && cellAt.isVertex()) {
|
||||||
|
final JPopupMenu jPopupMenu = new JPopupMenu();
|
||||||
|
final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue();
|
||||||
|
|
||||||
|
Set<mxCell> selectedVertices
|
||||||
|
= Stream.of(graph.getSelectionModel().getCells())
|
||||||
|
.map(mxCell.class::cast)
|
||||||
|
.filter(mxCell::isVertex)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (lockedVertexModel.isVertexLocked(cellAt)) {
|
||||||
|
jPopupMenu.add(new JMenuItem(new UnlockAction(selectedVertices)));
|
||||||
|
} else {
|
||||||
|
jPopupMenu.add(new JMenuItem(new LockAction(selectedVertices)));
|
||||||
|
}
|
||||||
|
if (pinnedAccountModel.isAccountPinned(adiKey)) {
|
||||||
|
jPopupMenu.add(UnpinAccountsAction.getInstance().getPopupPresenter());
|
||||||
|
} else {
|
||||||
|
jPopupMenu.add(PinAccountsAction.getInstance().getPopupPresenter());
|
||||||
|
jPopupMenu.add(ResetAndPinAccountsAction.getInstance().getPopupPresenter());
|
||||||
|
}
|
||||||
|
jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that un-locks the selected vertices.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"VisualizationPanel.unlockAction.singularText=Unlock Selected Account",
|
||||||
|
"VisualizationPanel.unlockAction.pluralText=Unlock Selected Accounts",})
|
||||||
|
private final class UnlockAction extends AbstractAction {
|
||||||
|
|
||||||
|
private final Set<mxCell> selectedVertices;
|
||||||
|
|
||||||
|
UnlockAction(Set<mxCell> selectedVertices) {
|
||||||
|
super(selectedVertices.size() > 1 ? Bundle.VisualizationPanel_unlockAction_pluralText() : Bundle.VisualizationPanel_unlockAction_singularText(),
|
||||||
|
unlockIcon);
|
||||||
|
this.selectedVertices = selectedVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
|
||||||
|
public void actionPerformed(final ActionEvent event) {
|
||||||
|
lockedVertexModel.unlock(selectedVertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that locks the selected vertices.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"VisualizationPanel.lockAction.singularText=Lock Selected Account",
|
||||||
|
"VisualizationPanel.lockAction.pluralText=Lock Selected Accounts"})
|
||||||
|
private final class LockAction extends AbstractAction {
|
||||||
|
|
||||||
|
private final Set<mxCell> selectedVertices;
|
||||||
|
|
||||||
|
LockAction(Set<mxCell> selectedVertices) {
|
||||||
|
super(selectedVertices.size() > 1 ? Bundle.VisualizationPanel_lockAction_pluralText() : Bundle.VisualizationPanel_lockAction_singularText(),
|
||||||
|
lockIcon);
|
||||||
|
this.selectedVertices = selectedVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent event) {
|
||||||
|
lockedVertexModel.lock(selectedVertices);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,8 +25,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import org.apache.curator.RetryPolicy;
|
import org.apache.curator.RetryPolicy;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,12 +25,12 @@ import java.io.IOException;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import org.apache.commons.csv.CSVFormat;
|
import org.apache.commons.csv.CSVFormat;
|
||||||
import org.apache.commons.csv.CSVParser;
|
import org.apache.commons.csv.CSVParser;
|
||||||
import org.apache.commons.csv.CSVRecord;
|
import org.apache.commons.csv.CSVRecord;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.datamodel.accounts.BINRange;
|
import org.sleuthkit.autopsy.datamodel.accounts.BINRange;
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ public class CreditCards {
|
|||||||
Optional<String> getScheme();
|
Optional<String> getScheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(CreditCards.class.getName());
|
private static final Logger logger = Logger.getLogger(CreditCards.class.getName());
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,12 +166,12 @@ public class CreditCards {
|
|||||||
binRanges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), binRange);
|
binRanges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), binRange);
|
||||||
|
|
||||||
} catch (NumberFormatException numberFormatException) {
|
} catch (NumberFormatException numberFormatException) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to parse BIN range: " + record.toString(), numberFormatException); //NON-NLS
|
logger.log(Level.WARNING, "Failed to parse BIN range: " + record.toString(), numberFormatException); //NON-NLS
|
||||||
}
|
}
|
||||||
binsLoaded = true;
|
binsLoaded = true;
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to load BIN ranges form ranges.csv", ex); //NON-NLS
|
logger.log(Level.WARNING, "Failed to load BIN ranges form ranges.csv", ex); //NON-NLS
|
||||||
MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified.");
|
MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -60,6 +59,7 @@ import org.openide.util.lookup.Lookups;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.datamodel.AutopsyItemVisitor;
|
import org.sleuthkit.autopsy.datamodel.AutopsyItemVisitor;
|
||||||
import org.sleuthkit.autopsy.datamodel.AutopsyVisitableItem;
|
import org.sleuthkit.autopsy.datamodel.AutopsyVisitableItem;
|
||||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||||
@ -408,6 +408,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void addNotify() {
|
protected void addNotify() {
|
||||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||||
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,6 +416,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void removeNotify() {
|
protected void removeNotify() {
|
||||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||||
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.removeNotify();
|
super.removeNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,6 +571,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void addNotify() {
|
protected void addNotify() {
|
||||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||||
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,6 +579,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void removeNotify() {
|
protected void removeNotify() {
|
||||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||||
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.removeNotify();
|
super.removeNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,6 +695,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void addNotify() {
|
protected void addNotify() {
|
||||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||||
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,6 +703,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void removeNotify() {
|
protected void removeNotify() {
|
||||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||||
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.removeNotify();
|
super.removeNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,6 +907,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void addNotify() {
|
protected void addNotify() {
|
||||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||||
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,6 +915,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
|||||||
protected void removeNotify() {
|
protected void removeNotify() {
|
||||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||||
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||||
super.removeNotify();
|
super.removeNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2017 Basis Technology Corp.
|
* Copyright 2017-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,17 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.directorytree;
|
package org.sleuthkit.autopsy.directorytree;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.Volume;
|
import org.sleuthkit.datamodel.Volume;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.directorytree;
|
|||||||
|
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.FileSystem;
|
import org.sleuthkit.datamodel.FileSystem;
|
||||||
import org.sleuthkit.datamodel.Volume;
|
import org.sleuthkit.datamodel.Volume;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
@ -20,10 +20,10 @@ package org.sleuthkit.autopsy.directorytree;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
@ -27,7 +27,6 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.DefaultComboBoxModel;
|
import javax.swing.DefaultComboBoxModel;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
@ -45,6 +44,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
|
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSetDefsPanel;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSetDefsPanel;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSetPanel;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSetPanel;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2018 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -38,15 +38,20 @@ import org.sleuthkit.autopsy.events.AutopsyEvent;
|
|||||||
/**
|
/**
|
||||||
* Monitors disk space and memory and cancels ingest if disk space runs low.
|
* Monitors disk space and memory and cancels ingest if disk space runs low.
|
||||||
* <p>
|
* <p>
|
||||||
* Note: This should be a singleton and currently is used as such, with the
|
* Note: This should be a singleton and currently is used as such, with the only
|
||||||
* only instance residing in the IngestManager class.
|
* instance residing in the IngestManager class.
|
||||||
*/
|
*/
|
||||||
public final class IngestMonitor {
|
public final class IngestMonitor {
|
||||||
|
|
||||||
public static final int DISK_FREE_SPACE_UNKNOWN = -1;
|
public static final int DISK_FREE_SPACE_UNKNOWN = -1;
|
||||||
private static final int INITIAL_INTERVAL_MS = 60000; //1 min.
|
private static final int INITIAL_INTERVAL_MS = 60000; //1 min.
|
||||||
private static final int MAX_LOG_FILES = 3;
|
private static final int MAX_LOG_FILES = 3;
|
||||||
private static final java.util.logging.Logger MONITOR_LOGGER = java.util.logging.Logger.getLogger("monitor"); //NON-NLS
|
|
||||||
|
/*
|
||||||
|
* The monitorLogger used the standard Java Logger type for compact logs
|
||||||
|
* without the stack trace.
|
||||||
|
*/
|
||||||
|
private static final java.util.logging.Logger monitorLogger = java.util.logging.Logger.getLogger("monitor"); //NON-NLS
|
||||||
private final Logger logger = Logger.getLogger(IngestMonitor.class.getName());
|
private final Logger logger = Logger.getLogger(IngestMonitor.class.getName());
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private MonitorTimerAction timerAction;
|
private MonitorTimerAction timerAction;
|
||||||
@ -63,8 +68,8 @@ public final class IngestMonitor {
|
|||||||
FileHandler monitorLogHandler = new FileHandler(PlatformUtil.getUserDirectory().getAbsolutePath() + "/var/log/monitor.log", 0, MAX_LOG_FILES); //NON-NLS
|
FileHandler monitorLogHandler = new FileHandler(PlatformUtil.getUserDirectory().getAbsolutePath() + "/var/log/monitor.log", 0, MAX_LOG_FILES); //NON-NLS
|
||||||
monitorLogHandler.setFormatter(new SimpleFormatter());
|
monitorLogHandler.setFormatter(new SimpleFormatter());
|
||||||
monitorLogHandler.setEncoding(PlatformUtil.getLogFileEncoding());
|
monitorLogHandler.setEncoding(PlatformUtil.getLogFileEncoding());
|
||||||
MONITOR_LOGGER.setUseParentHandlers(false);
|
monitorLogger.setUseParentHandlers(false);
|
||||||
MONITOR_LOGGER.addHandler(monitorLogHandler);
|
monitorLogger.addHandler(monitorLogHandler);
|
||||||
} catch (IOException | SecurityException ex) {
|
} catch (IOException | SecurityException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to create memory usage logger", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to create memory usage logger", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
@ -202,7 +207,7 @@ public final class IngestMonitor {
|
|||||||
IngestServices.getInstance().postMessage(IngestMessage.createManagerErrorMessage(
|
IngestServices.getInstance().postMessage(IngestMessage.createManagerErrorMessage(
|
||||||
NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.title", diskPath),
|
NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.title", diskPath),
|
||||||
NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.msg", diskPath)));
|
NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.msg", diskPath)));
|
||||||
MONITOR_LOGGER.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS
|
monitorLogger.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS
|
||||||
logger.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS
|
logger.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,12 +216,13 @@ public final class IngestMonitor {
|
|||||||
* Writes current message usage to the memory usage log.
|
* Writes current message usage to the memory usage log.
|
||||||
*/
|
*/
|
||||||
private void logMemoryUsage() {
|
private void logMemoryUsage() {
|
||||||
MONITOR_LOGGER.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
|
monitorLogger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes current disk space usage of the drive where case dir resides to log.
|
* Writes current disk space usage of the drive where case dir resides
|
||||||
*/
|
* to log.
|
||||||
|
*/
|
||||||
private void logDiskSpaceUsage() {
|
private void logDiskSpaceUsage() {
|
||||||
final long freeSpace = root.getFreeSpace();
|
final long freeSpace = root.getFreeSpace();
|
||||||
logger.log(Level.INFO, "Available disk space on drive where case dir resides is {0} (bytes)", freeSpace); //NON-NLS
|
logger.log(Level.INFO, "Available disk space on drive where case dir resides is {0} (bytes)", freeSpace); //NON-NLS
|
||||||
@ -253,18 +259,17 @@ public final class IngestMonitor {
|
|||||||
private long getFreeSpace() throws SecurityException {
|
private long getFreeSpace() throws SecurityException {
|
||||||
// always return "UNKNOWN", see note below
|
// always return "UNKNOWN", see note below
|
||||||
return DISK_FREE_SPACE_UNKNOWN;
|
return DISK_FREE_SPACE_UNKNOWN;
|
||||||
|
|
||||||
/* NOTE: use and accuracy of this code for network drives needs to be investigated and validated
|
/*
|
||||||
final long freeSpace = root.getFreeSpace();
|
* NOTE: use and accuracy of this code for network drives needs to
|
||||||
if (0 == freeSpace) {
|
* be investigated and validated final long freeSpace =
|
||||||
// Check for a network drive, some network filesystems always
|
* root.getFreeSpace(); if (0 == freeSpace) { // Check for a network
|
||||||
// return zero.
|
* drive, some network filesystems always // return zero. final
|
||||||
final String monitoredPath = root.getAbsolutePath();
|
* String monitoredPath = root.getAbsolutePath(); if
|
||||||
if (monitoredPath.startsWith("\\\\") || monitoredPath.startsWith("//")) {
|
* (monitoredPath.startsWith("\\\\") ||
|
||||||
return DISK_FREE_SPACE_UNKNOWN;
|
* monitoredPath.startsWith("//")) { return DISK_FREE_SPACE_UNKNOWN;
|
||||||
}
|
* } } return freeSpace;
|
||||||
}
|
*/
|
||||||
return freeSpace;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import static junit.framework.Assert.assertFalse;
|
import static junit.framework.Assert.assertFalse;
|
||||||
import junit.framework.TestCase;
|
|
||||||
import org.netbeans.junit.NbModuleSuite;
|
import org.netbeans.junit.NbModuleSuite;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||||
@ -48,6 +47,7 @@ import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ExtensionCon
|
|||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.FullNameCondition;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.FullNameCondition;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition;
|
||||||
|
import org.sleuthkit.autopsy.modules.photoreccarver.PhotoRecCarverIngestModuleFactory;
|
||||||
import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner;
|
import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner;
|
||||||
import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner.ProcessorCallback;
|
import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner.ProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.testutils.IngestJobRunner;
|
import org.sleuthkit.autopsy.testutils.IngestJobRunner;
|
||||||
@ -84,7 +84,7 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
Assert.fail(ex);
|
Assert.fail(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertFalse("Unable to delete existing test directory", CASE_DIRECTORY_PATH.toFile().exists());
|
assertFalse("Unable to delete existing test directory",CASE_DIRECTORY_PATH.toFile().exists());
|
||||||
|
|
||||||
// Create the test directory
|
// Create the test directory
|
||||||
CASE_DIRECTORY_PATH.toFile().mkdirs();
|
CASE_DIRECTORY_PATH.toFile().mkdirs();
|
||||||
@ -133,11 +133,13 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
HashMap<String, Rule> rule = new HashMap<>();
|
HashMap<String, Rule> rule = new HashMap<>();
|
||||||
rule.put("Rule", new Rule("testFileType", null, new MetaTypeCondition(MetaTypeCondition.Type.FILES), new ParentPathCondition("dir1"), null, null, null));
|
rule.put("Rule", new Rule("testFileType", null, new MetaTypeCondition(MetaTypeCondition.Type.FILES), new ParentPathCondition("dir1"), null, null, null));
|
||||||
//Filter for dir1 and no unallocated space
|
//Filter for dir1 and no unallocated space
|
||||||
FilesSet Files_Dirs_Unalloc_Ingest_Filter = new FilesSet("Filter", "Filter to find all files in dir1.", false, true, rule);
|
FilesSet dirFilter = new FilesSet("Filter", "Filter to find all files in dir1.", false, true, rule);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Case openCase = Case.getOpenCase();
|
Case openCase = Case.getOpenCase();
|
||||||
runIngestJob(openCase.getDataSources(), Files_Dirs_Unalloc_Ingest_Filter);
|
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
||||||
|
templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory()));
|
||||||
|
runIngestJob(openCase.getDataSources(), templates, dirFilter);
|
||||||
FileManager fileManager = openCase.getServices().getFileManager();
|
FileManager fileManager = openCase.getServices().getFileManager();
|
||||||
List<AbstractFile> results = fileManager.findFiles("file.jpg", "dir1");
|
List<AbstractFile> results = fileManager.findFiles("file.jpg", "dir1");
|
||||||
String mimeType = results.get(0).getMIMEType();
|
String mimeType = results.get(0).getMIMEType();
|
||||||
@ -171,7 +173,9 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Case openCase = Case.getOpenCase();
|
Case openCase = Case.getOpenCase();
|
||||||
runIngestJob(openCase.getDataSources(), filesExtDirsFilter);
|
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
||||||
|
templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory()));
|
||||||
|
runIngestJob(openCase.getDataSources(), templates, filesExtDirsFilter);
|
||||||
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
List<AbstractFile> results = fileManager.findFiles("%%");
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
assertEquals(62, results.size());
|
assertEquals(62, results.size());
|
||||||
@ -200,7 +204,9 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Case openCase = Case.getOpenCase();
|
Case openCase = Case.getOpenCase();
|
||||||
runIngestJob(openCase.getDataSources(), filesExtDirsFilter);
|
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
||||||
|
templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory()));
|
||||||
|
runIngestJob(openCase.getDataSources(), templates, filesExtDirsFilter);
|
||||||
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
List<AbstractFile> results = fileManager.findFiles("%%");
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
assertEquals(62, results.size());
|
assertEquals(62, results.size());
|
||||||
@ -236,7 +242,10 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Case openCase = Case.getOpenCase();
|
Case openCase = Case.getOpenCase();
|
||||||
runIngestJob(openCase.getDataSources(), fullNameFilter);
|
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
||||||
|
templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory()));
|
||||||
|
|
||||||
|
runIngestJob(openCase.getDataSources(), templates, fullNameFilter);
|
||||||
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
List<AbstractFile> results = fileManager.findFiles("%%");
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
assertEquals(62, results.size());
|
assertEquals(62, results.size());
|
||||||
@ -255,13 +264,80 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
Assert.fail(ex);
|
Assert.fail(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void runIngestJob(List<Content> datasources, FilesSet filter) {
|
|
||||||
FileTypeIdModuleFactory factory = new FileTypeIdModuleFactory();
|
public void testCarvingWithExtRuleAndUnallocSpace() {
|
||||||
IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings();
|
HashMap<String, Rule> rules = new HashMap<>();
|
||||||
IngestModuleTemplate template = new IngestModuleTemplate(factory, settings);
|
rules.put("rule1", new Rule("FindJpgExtention", new ExtensionCondition("jpg"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null));
|
||||||
template.setEnabled(true);
|
rules.put("rule2", new Rule("FindGifExtention", new ExtensionCondition("gif"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null));
|
||||||
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
|
||||||
templates.add(template);
|
//Build the filter to find files with .jpg and .gif extension and unallocated space
|
||||||
|
FilesSet extensionFilter = new FilesSet("Filter", "Filter to files with .jpg and .gif extension.", false, false, rules);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Case openCase = Case.getOpenCase();
|
||||||
|
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
||||||
|
templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory()));
|
||||||
|
templates.add(getIngestModuleTemplate(new PhotoRecCarverIngestModuleFactory()));
|
||||||
|
runIngestJob(openCase.getDataSources(), templates, extensionFilter);
|
||||||
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
|
assertEquals(70, results.size());
|
||||||
|
int carvedJpgGifFiles = 0;
|
||||||
|
for (AbstractFile file : results) {
|
||||||
|
if (file.getNameExtension().equalsIgnoreCase("jpg") || file.getNameExtension().equalsIgnoreCase("gif")) { //Unalloc file and .jpg files in dir1, dir2, $CarvedFiles, root directory should have MIME type
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
|
|
||||||
|
if (file.getParentPath().equalsIgnoreCase("/$CarvedFiles/")) {
|
||||||
|
carvedJpgGifFiles++;
|
||||||
|
}
|
||||||
|
} else if (file.getName().startsWith("Unalloc_")) {
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
|
} else { //All other files should not have MIME type.
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Make sure we have carved jpg/gif files
|
||||||
|
assertEquals(2, carvedJpgGifFiles);
|
||||||
|
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCarvingNoUnallocatedSpace() {
|
||||||
|
HashMap<String, Rule> rules = new HashMap<>();
|
||||||
|
rules.put("rule1", new Rule("FindJpgExtention", new ExtensionCondition("jpg"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null));
|
||||||
|
rules.put("rule2", new Rule("FindGifExtention", new ExtensionCondition("gif"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null));
|
||||||
|
|
||||||
|
//Build the filter to find files with .jpg and .gif extension
|
||||||
|
FilesSet extensionFilter = new FilesSet("Filter", "Filter to files with .jpg and .gif extension.", false, true, rules);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Case openCase = Case.getOpenCase();
|
||||||
|
ArrayList<IngestModuleTemplate> templates = new ArrayList<>();
|
||||||
|
templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory()));
|
||||||
|
templates.add(getIngestModuleTemplate(new PhotoRecCarverIngestModuleFactory()));
|
||||||
|
IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, extensionFilter);
|
||||||
|
try {
|
||||||
|
List<IngestModuleError> errs = IngestJobRunner.runIngestJob(openCase.getDataSources(), ingestJobSettings);
|
||||||
|
//Ingest fails because Carving wants unallocated space
|
||||||
|
assertEquals(1, errs.size());
|
||||||
|
assertEquals("PhotoRec Carver", errs.get(0).getModuleDisplayName());
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex);
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runIngestJob(List<Content> datasources, ArrayList<IngestModuleTemplate> templates, FilesSet filter) {
|
||||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, filter);
|
IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, filter);
|
||||||
try {
|
try {
|
||||||
List<IngestModuleError> errs = IngestJobRunner.runIngestJob(datasources, ingestJobSettings);
|
List<IngestModuleError> errs = IngestJobRunner.runIngestJob(datasources, ingestJobSettings);
|
||||||
@ -275,4 +351,10 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IngestModuleTemplate getIngestModuleTemplate(IngestModuleFactoryAdapter factory) {
|
||||||
|
IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings();
|
||||||
|
IngestModuleTemplate template = new IngestModuleTemplate(factory, settings);
|
||||||
|
template.setEnabled(true);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<target name="get-deps" description="retrieve dependencies using ivy" depends="init-ivy,build-native-libs">
|
<target name="get-deps" description="retrieve dependencies using ivy" depends="init-ivy,build-native-libs">
|
||||||
<ivy:settings file="ivysettings.xml" />
|
<ivy:settings file="ivysettings.xml" />
|
||||||
<ivy:resolve/>
|
<ivy:resolve log="quiet"/>
|
||||||
<ivy:retrieve pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
|
<ivy:retrieve pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<target name="resolve">
|
<target name="resolve">
|
||||||
<ivy:settings file="ivysettings.xml" />
|
<ivy:settings file="ivysettings.xml" />
|
||||||
<ivy:resolve file="ivy.xml" conf="experimental"/>
|
<ivy:resolve file="ivy.xml" conf="experimental" log="quiet"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="retrieve-experimental" depends="resolve">
|
<target name="retrieve-experimental" depends="resolve">
|
||||||
|
@ -43,7 +43,6 @@ import java.io.File;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
@ -60,6 +59,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
@ -141,7 +141,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280;
|
private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280;
|
||||||
private static final String UPDATE_TASKS_THREAD_NAME = "AID-update-tasks-%d";
|
private static final String UPDATE_TASKS_THREAD_NAME = "AID-update-tasks-%d";
|
||||||
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
|
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
|
||||||
private static final Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger();
|
private static final Logger sysLogger = AutoIngestSystemLogger.getLogger();
|
||||||
private static AutoIngestControlPanel instance;
|
private static AutoIngestControlPanel instance;
|
||||||
private final DefaultTableModel pendingTableModel;
|
private final DefaultTableModel pendingTableModel;
|
||||||
private final DefaultTableModel runningTableModel;
|
private final DefaultTableModel runningTableModel;
|
||||||
@ -333,7 +333,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
serviceStatus = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Down");
|
serviceStatus = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Down");
|
||||||
}
|
}
|
||||||
} catch (ServicesMonitor.ServicesMonitorException ex) {
|
} catch (ServicesMonitor.ServicesMonitorException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Dashboard error getting service status for %s", service), ex);
|
sysLogger.log(Level.SEVERE, String.format("Dashboard error getting service status for %s", service), ex);
|
||||||
}
|
}
|
||||||
return serviceStatus;
|
return serviceStatus;
|
||||||
}
|
}
|
||||||
@ -687,7 +687,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
manager.startUp();
|
manager.startUp();
|
||||||
autoIngestStarted = true;
|
autoIngestStarted = true;
|
||||||
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Dashboard error starting up auto ingest", ex);
|
sysLogger.log(Level.SEVERE, "Dashboard error starting up auto ingest", ex);
|
||||||
tbStatusMessage.setText(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.AutoIngestStartupError"));
|
tbStatusMessage.setText(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.AutoIngestStartupError"));
|
||||||
manager = null;
|
manager = null;
|
||||||
|
|
||||||
@ -712,7 +712,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
status = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Up");
|
status = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Up");
|
||||||
} else if (status.equals(ServicesMonitor.ServiceStatus.DOWN.toString())) {
|
} else if (status.equals(ServicesMonitor.ServiceStatus.DOWN.toString())) {
|
||||||
status = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Down");
|
status = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Down");
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Connection to {0} is down", serviceDisplayName); //NON-NLS
|
sysLogger.log(Level.SEVERE, "Connection to {0} is down", serviceDisplayName); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the status update is for an existing service who's status hasn't changed - do nothing.
|
// if the status update is for an existing service who's status hasn't changed - do nothing.
|
||||||
@ -1187,7 +1187,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
job.getPriority()}); // PRIORITY
|
job.getPriority()}); // PRIORITY
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Dashboard error refreshing table", ex);
|
sysLogger.log(Level.SEVERE, "Dashboard error refreshing table", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1823,7 +1823,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
try {
|
try {
|
||||||
manager.prioritizeCase(caseName);
|
manager.prioritizeCase(caseName);
|
||||||
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Error prioritizing a case", ex);
|
sysLogger.log(Level.SEVERE, "Error prioritizing a case", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_casePrioritization());
|
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_casePrioritization());
|
||||||
}
|
}
|
||||||
refreshTables();
|
refreshTables();
|
||||||
@ -1862,7 +1862,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Dashboard error attempting to display case auto ingest log", ex);
|
sysLogger.log(Level.SEVERE, "Dashboard error attempting to display case auto ingest log", ex);
|
||||||
Object[] options = {org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "DisplayLogDialog.okay")};
|
Object[] options = {org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "DisplayLogDialog.okay")};
|
||||||
JOptionPane.showOptionDialog(this,
|
JOptionPane.showOptionDialog(this,
|
||||||
org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "DisplayLogDialog.cannotFindLog"),
|
org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "DisplayLogDialog.cannotFindLog"),
|
||||||
@ -1883,7 +1883,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
try {
|
try {
|
||||||
manager.prioritizeJob(manifestFilePath);
|
manager.prioritizeJob(manifestFilePath);
|
||||||
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Error prioritizing a job", ex);
|
sysLogger.log(Level.SEVERE, "Error prioritizing a job", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_jobPrioritization());
|
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_jobPrioritization());
|
||||||
}
|
}
|
||||||
refreshTables();
|
refreshTables();
|
||||||
@ -1930,7 +1930,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
try {
|
try {
|
||||||
manager.deprioritizeCase(caseName);
|
manager.deprioritizeCase(caseName);
|
||||||
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Error deprioritizing a case", ex);
|
sysLogger.log(Level.SEVERE, "Error deprioritizing a case", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_caseDeprioritization());
|
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_caseDeprioritization());
|
||||||
}
|
}
|
||||||
refreshTables();
|
refreshTables();
|
||||||
@ -1949,7 +1949,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
|
|||||||
try {
|
try {
|
||||||
manager.deprioritizeJob(manifestFilePath);
|
manager.deprioritizeJob(manifestFilePath);
|
||||||
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
} catch (AutoIngestManager.AutoIngestManagerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Error deprioritizing a job", ex);
|
sysLogger.log(Level.SEVERE, "Error deprioritizing a job", ex);
|
||||||
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_jobDeprioritization());
|
MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_jobDeprioritization());
|
||||||
}
|
}
|
||||||
refreshTables();
|
refreshTables();
|
||||||
|
@ -76,6 +76,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
||||||
import static org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
|
import static org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||||
@ -137,7 +138,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private static final String JOB_STATUS_PUBLISHING_THREAD_NAME = "AIM-job-status-event-publisher-%d";
|
private static final String JOB_STATUS_PUBLISHING_THREAD_NAME = "AIM-job-status-event-publisher-%d";
|
||||||
private static final long MAX_MISSED_JOB_STATUS_UPDATES = 10;
|
private static final long MAX_MISSED_JOB_STATUS_UPDATES = 10;
|
||||||
private static final int DEFAULT_PRIORITY = 0;
|
private static final int DEFAULT_PRIORITY = 0;
|
||||||
private static final java.util.logging.Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger();
|
private static final Logger sysLogger = AutoIngestSystemLogger.getLogger();
|
||||||
private static AutoIngestManager instance;
|
private static AutoIngestManager instance;
|
||||||
private final AutopsyEventPublisher eventPublisher;
|
private final AutopsyEventPublisher eventPublisher;
|
||||||
private final Object scanMonitor;
|
private final Object scanMonitor;
|
||||||
@ -184,7 +185,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* designated input directory tree.
|
* designated input directory tree.
|
||||||
*/
|
*/
|
||||||
private AutoIngestManager() {
|
private AutoIngestManager() {
|
||||||
SYS_LOGGER.log(Level.INFO, "Initializing auto ingest");
|
sysLogger.log(Level.INFO, "Initializing auto ingest");
|
||||||
state = State.IDLE;
|
state = State.IDLE;
|
||||||
eventPublisher = new AutopsyEventPublisher();
|
eventPublisher = new AutopsyEventPublisher();
|
||||||
scanMonitor = new Object();
|
scanMonitor = new Object();
|
||||||
@ -200,9 +201,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
completedJobs = new ArrayList<>();
|
completedJobs = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
RuntimeProperties.setRunningWithGUI(false);
|
RuntimeProperties.setRunningWithGUI(false);
|
||||||
SYS_LOGGER.log(Level.INFO, "Set running with desktop GUI runtime property to false");
|
sysLogger.log(Level.INFO, "Set running with desktop GUI runtime property to false");
|
||||||
} catch (RuntimeProperties.RuntimePropertiesException ex) {
|
} catch (RuntimeProperties.RuntimePropertiesException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Failed to set running with desktop GUI runtime property to false", ex);
|
sysLogger.log(Level.SEVERE, "Failed to set running with desktop GUI runtime property to false", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +214,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* ingest.
|
* ingest.
|
||||||
*/
|
*/
|
||||||
void startUp() throws AutoIngestManagerException {
|
void startUp() throws AutoIngestManagerException {
|
||||||
SYS_LOGGER.log(Level.INFO, "Auto ingest starting");
|
sysLogger.log(Level.INFO, "Auto ingest starting");
|
||||||
try {
|
try {
|
||||||
coordinationService = CoordinationService.getInstance();
|
coordinationService = CoordinationService.getInstance();
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
@ -221,9 +222,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
eventPublisher.openRemoteEventChannel(EVENT_CHANNEL_NAME);
|
eventPublisher.openRemoteEventChannel(EVENT_CHANNEL_NAME);
|
||||||
SYS_LOGGER.log(Level.INFO, "Opened auto ingest event channel");
|
sysLogger.log(Level.INFO, "Opened auto ingest event channel");
|
||||||
} catch (AutopsyEventException ex) {
|
} catch (AutopsyEventException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Failed to open auto ingest event channel", ex);
|
sysLogger.log(Level.SEVERE, "Failed to open auto ingest event channel", ex);
|
||||||
throw new AutoIngestManagerException("Failed to open auto ingest event channel", ex);
|
throw new AutoIngestManagerException("Failed to open auto ingest event channel", ex);
|
||||||
}
|
}
|
||||||
rootInputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeImageFolder());
|
rootInputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeImageFolder());
|
||||||
@ -396,7 +397,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
if (State.RUNNING != state) {
|
if (State.RUNNING != state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Auto ingest shutting down");
|
sysLogger.log(Level.INFO, "Auto ingest shutting down");
|
||||||
state = State.SHUTTING_DOWN;
|
state = State.SHUTTING_DOWN;
|
||||||
try {
|
try {
|
||||||
eventPublisher.removeSubscriber(EVENT_LIST, instance);
|
eventPublisher.removeSubscriber(EVENT_LIST, instance);
|
||||||
@ -406,9 +407,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
cleanupJobs();
|
cleanupJobs();
|
||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Auto ingest interrupted during shut down", ex);
|
sysLogger.log(Level.SEVERE, "Auto ingest interrupted during shut down", ex);
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Auto ingest shut down");
|
sysLogger.log(Level.INFO, "Auto ingest shut down");
|
||||||
state = State.IDLE;
|
state = State.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,10 +421,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
inputScanSchedulingExecutor.shutdownNow();
|
inputScanSchedulingExecutor.shutdownNow();
|
||||||
inputScanExecutor.shutdownNow();
|
inputScanExecutor.shutdownNow();
|
||||||
while (!inputScanSchedulingExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
|
while (!inputScanSchedulingExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
|
||||||
SYS_LOGGER.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan scheduling executor to shut down, continuing to wait"); //NON-NLS
|
sysLogger.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan scheduling executor to shut down, continuing to wait"); //NON-NLS
|
||||||
}
|
}
|
||||||
while (!inputScanExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
|
while (!inputScanExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
|
||||||
SYS_LOGGER.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan executor to shut down, continuing to wait"); //NON-NLS
|
sysLogger.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan executor to shut down, continuing to wait"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,7 +440,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
jobProcessingExecutor.shutdown();
|
jobProcessingExecutor.shutdown();
|
||||||
}
|
}
|
||||||
while (!jobProcessingExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
|
while (!jobProcessingExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
|
||||||
SYS_LOGGER.log(Level.WARNING, "Auto ingest waited at least thirty seconds for job processing executor to shut down, continuing to wait"); //NON-NLS
|
sysLogger.log(Level.WARNING, "Auto ingest waited at least thirty seconds for job processing executor to shut down, continuing to wait"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,11 +507,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
if (State.RUNNING != state) {
|
if (State.RUNNING != state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory);
|
sysLogger.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory);
|
||||||
InputDirScanner scanner = new InputDirScanner();
|
InputDirScanner scanner = new InputDirScanner();
|
||||||
|
|
||||||
scanner.scan();
|
scanner.scan();
|
||||||
SYS_LOGGER.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory);
|
sysLogger.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -772,10 +773,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
updateCoordinationServiceManifestNode(completedJob);
|
updateCoordinationServiceManifestNode(completedJob);
|
||||||
pendingJobs.add(completedJob);
|
pendingJobs.add(completedJob);
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Coordination service error while reprocessing %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Coordination service error while reprocessing %s", manifestPath), ex);
|
||||||
completedJobs.add(completedJob);
|
completedJobs.add(completedJob);
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Unexpected interrupt while updating coordination service node data for {0}", manifestPath);
|
sysLogger.log(Level.SEVERE, "Unexpected interrupt while updating coordination service node data for {0}", manifestPath);
|
||||||
completedJobs.add(completedJob);
|
completedJobs.add(completedJob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -811,7 +812,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
metaData = new CaseMetadata(caseMetaDataFilePath);
|
metaData = new CaseMetadata(caseMetaDataFilePath);
|
||||||
} catch (CaseMetadata.CaseMetadataException ex) {
|
} catch (CaseMetadata.CaseMetadataException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to get case metadata file %s for case %s at %s", caseMetaDataFilePath, caseName, caseDirectoryPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Failed to get case metadata file %s for case %s at %s", caseMetaDataFilePath, caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,7 +823,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
scanner.scan();
|
scanner.scan();
|
||||||
Set<Path> manifestPaths = casesToManifests.get(caseName);
|
Set<Path> manifestPaths = casesToManifests.get(caseName);
|
||||||
if (null == manifestPaths) {
|
if (null == manifestPaths) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("No manifest paths found for case %s at %s", caseName, caseDirectoryPath));
|
sysLogger.log(Level.SEVERE, String.format("No manifest paths found for case %s at %s", caseName, caseDirectoryPath));
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,7 +841,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to acquire manifest lock for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to acquire manifest lock for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -851,7 +852,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
Case.deleteCase(metaData);
|
Case.deleteCase(metaData);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to physically delete case %s at %s", caseName, caseDirectoryPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Failed to physically delete case %s at %s", caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,10 +866,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
deletedJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.DELETED);
|
deletedJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.DELETED);
|
||||||
this.updateCoordinationServiceManifestNode(deletedJob);
|
this.updateCoordinationServiceManifestNode(deletedJob);
|
||||||
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
|
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
|
||||||
SYS_LOGGER.log(Level.WARNING, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
|
sysLogger.log(Level.WARNING, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
|
||||||
return CaseDeletionResult.PARTIALLY_DELETED;
|
return CaseDeletionResult.PARTIALLY_DELETED;
|
||||||
} catch (InterruptedException | CoordinationServiceException ex) {
|
} catch (InterruptedException | CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set delete flag on manifest data for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to set delete flag on manifest data for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.PARTIALLY_DELETED;
|
return CaseDeletionResult.PARTIALLY_DELETED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -895,7 +896,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
lock.release();
|
lock.release();
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to release manifest file lock when deleting case %s at %s", caseName, caseDirectoryPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Failed to release manifest file lock when deleting case %s at %s", caseName, caseDirectoryPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -944,7 +945,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
synchronized (jobsLock) {
|
synchronized (jobsLock) {
|
||||||
if (null != currentJob) {
|
if (null != currentJob) {
|
||||||
currentJob.cancel();
|
currentJob.cancel();
|
||||||
SYS_LOGGER.log(Level.INFO, "Cancelling automated ingest for manifest {0}", currentJob.getManifest().getFilePath());
|
sysLogger.log(Level.INFO, "Cancelling automated ingest for manifest {0}", currentJob.getManifest().getFilePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,7 +966,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
if (null != moduleHandle) {
|
if (null != moduleHandle) {
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE, Date.from(Instant.now()));
|
||||||
moduleHandle.cancel();
|
moduleHandle.cancel();
|
||||||
SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()});
|
sysLogger.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1015,7 +1016,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* input directory scan task executor.
|
* input directory scan task executor.
|
||||||
*/
|
*/
|
||||||
private InputDirScanSchedulingTask() {
|
private InputDirScanSchedulingTask() {
|
||||||
SYS_LOGGER.log(Level.INFO, "Periodic input scan scheduling task started");
|
sysLogger.log(Level.INFO, "Periodic input scan scheduling task started");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1045,10 +1046,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory);
|
sysLogger.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory);
|
||||||
InputDirScanner scanner = new InputDirScanner();
|
InputDirScanner scanner = new InputDirScanner();
|
||||||
scanner.scan();
|
scanner.scan();
|
||||||
SYS_LOGGER.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory);
|
sysLogger.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory);
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(Event.INPUT_SCAN_COMPLETED);
|
notifyObservers(Event.INPUT_SCAN_COMPLETED);
|
||||||
return null;
|
return null;
|
||||||
@ -1090,7 +1091,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* uncaught exceptions will propagate up to the calling
|
* uncaught exceptions will propagate up to the calling
|
||||||
* thread and may stop it from running.
|
* thread and may stop it from running.
|
||||||
*/
|
*/
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error scanning the input directory %s", rootInputDirectory), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error scanning the input directory %s", rootInputDirectory), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized (scanMonitor) {
|
synchronized (scanMonitor) {
|
||||||
@ -1151,7 +1152,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
manifest = parser.parse(filePath);
|
manifest = parser.parse(filePath);
|
||||||
break;
|
break;
|
||||||
} catch (ManifestFileParserException ex) {
|
} catch (ManifestFileParserException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to parse %s with parser %s", filePath, parser.getClass().getCanonicalName()), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to parse %s with parser %s", filePath, parser.getClass().getCanonicalName()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
@ -1205,21 +1206,21 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Unknown ManifestNodeData.ProcessingStatus");
|
sysLogger.log(Level.SEVERE, "Unknown ManifestNodeData.ProcessingStatus");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
|
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
addNewPendingJob(manifest);
|
addNewPendingJob(manifest);
|
||||||
} catch (AutoIngestJobException ex) {
|
} catch (AutoIngestJobException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Invalid manifest data for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Invalid manifest data for %s", manifestPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error transmitting node data for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error transmitting node data for %s", manifestPath), ex);
|
||||||
return CONTINUE;
|
return CONTINUE;
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
@ -1231,7 +1232,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
// Catch all unhandled and unexpected exceptions. Otherwise one bad file
|
// Catch all unhandled and unexpected exceptions. Otherwise one bad file
|
||||||
// can stop the entire input folder scanning. Given that the exception is unexpected,
|
// can stop the entire input folder scanning. Given that the exception is unexpected,
|
||||||
// I'm hesitant to add logging which requires accessing or de-referencing data.
|
// I'm hesitant to add logging which requires accessing or de-referencing data.
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Unexpected exception in file visitor", ex);
|
sysLogger.log(Level.SEVERE, "Unexpected exception in file visitor", ex);
|
||||||
return CONTINUE;
|
return CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,7 +1289,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
updateCoordinationServiceManifestNode(job);
|
updateCoordinationServiceManifestNode(job);
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Path caseDirectory = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
|
Path caseDirectory = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
|
||||||
@ -1330,7 +1331,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
newPendingJobsList.add(job);
|
newPendingJobsList.add(job);
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,7 +1362,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
String manifestPath = manifest.getFilePath().toString();
|
String manifestPath = manifest.getFilePath().toString();
|
||||||
try (Lock manifestLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.MANIFESTS, manifestPath)) {
|
try (Lock manifestLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.MANIFESTS, manifestPath)) {
|
||||||
if (null != manifestLock) {
|
if (null != manifestLock) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Attempting crash recovery for {0}", manifestPath);
|
sysLogger.log(Level.SEVERE, "Attempting crash recovery for {0}", manifestPath);
|
||||||
try {
|
try {
|
||||||
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
|
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
|
||||||
|
|
||||||
@ -1386,7 +1387,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
} catch (CaseNodeData.InvalidDataException ex) {
|
} catch (CaseNodeData.InvalidDataException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to get case node data for %s", caseDirectoryPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to get case node data for %s", caseDirectoryPath), ex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
job.setErrorsOccurred(false);
|
job.setErrorsOccurred(false);
|
||||||
@ -1398,7 +1399,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryWithRetry();
|
new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryWithRetry();
|
||||||
} catch (AutoIngestJobLoggerException ex) {
|
} catch (AutoIngestJobLoggerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1407,7 +1408,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryNoRetry();
|
new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryNoRetry();
|
||||||
} catch (AutoIngestJobLoggerException ex) {
|
} catch (AutoIngestJobLoggerException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1419,7 +1420,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
updateCoordinationServiceManifestNode(job);
|
updateCoordinationServiceManifestNode(job);
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifestPath), ex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1435,12 +1436,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
manifestLock.release();
|
manifestLock.release();
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to release exclusive lock for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to release exclusive lock for %s", manifestPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to get exclusive lock for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to get exclusive lock for %s", manifestPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1495,13 +1496,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
updateCoordinationServiceManifestNode(job);
|
updateCoordinationServiceManifestNode(job);
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newCompletedJobsList.add(job);
|
newCompletedJobsList.add(job);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SYS_LOGGER.log(Level.WARNING, String.format("Job completed for %s, but cannot find case directory, ignoring job", nodeData.getManifestFilePath()));
|
sysLogger.log(Level.WARNING, String.format("Job completed for %s, but cannot find case directory, ignoring job", nodeData.getManifestFilePath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1522,7 +1523,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFileFailed(Path file, IOException ex) throws IOException {
|
public FileVisitResult visitFileFailed(Path file, IOException ex) throws IOException {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error while visiting %s during input directories scan", file.toString()), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error while visiting %s during input directories scan", file.toString()), ex);
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
return TERMINATE;
|
return TERMINATE;
|
||||||
}
|
}
|
||||||
@ -1607,7 +1608,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing task started");
|
sysLogger.log(Level.INFO, "Job processing task started");
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
if (jobProcessingTaskFuture.isCancelled()) {
|
if (jobProcessingTaskFuture.isCancelled()) {
|
||||||
@ -1650,14 +1651,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
} else {
|
} else {
|
||||||
errorState = ErrorState.UNEXPECTED_EXCEPTION;
|
errorState = ErrorState.UNEXPECTED_EXCEPTION;
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Auto ingest system error", ex);
|
sysLogger.log(Level.SEVERE, "Auto ingest system error", ex);
|
||||||
pauseForSystemError();
|
pauseForSystemError();
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing task stopped");
|
sysLogger.log(Level.INFO, "Job processing task stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1666,7 +1667,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
private void requestPause() {
|
private void requestPause() {
|
||||||
synchronized (pauseLock) {
|
synchronized (pauseLock) {
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing pause requested");
|
sysLogger.log(Level.INFO, "Job processing pause requested");
|
||||||
pauseRequested = true;
|
pauseRequested = true;
|
||||||
if (waitingForInputScan) {
|
if (waitingForInputScan) {
|
||||||
/*
|
/*
|
||||||
@ -1689,7 +1690,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
private void requestResume() {
|
private void requestResume() {
|
||||||
synchronized (pauseLock) {
|
synchronized (pauseLock) {
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing resume requested");
|
sysLogger.log(Level.INFO, "Job processing resume requested");
|
||||||
pauseRequested = false;
|
pauseRequested = false;
|
||||||
if (waitingForInputScan) {
|
if (waitingForInputScan) {
|
||||||
/*
|
/*
|
||||||
@ -1719,12 +1720,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private void pauseIfRequested() throws InterruptedException {
|
private void pauseIfRequested() throws InterruptedException {
|
||||||
synchronized (pauseLock) {
|
synchronized (pauseLock) {
|
||||||
if (pauseRequested) {
|
if (pauseRequested) {
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing paused by request");
|
sysLogger.log(Level.INFO, "Job processing paused by request");
|
||||||
pauseRequested = false;
|
pauseRequested = false;
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(Event.PAUSED_BY_REQUEST);
|
notifyObservers(Event.PAUSED_BY_REQUEST);
|
||||||
pauseLock.wait();
|
pauseLock.wait();
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing resumed after pause request");
|
sysLogger.log(Level.INFO, "Job processing resumed after pause request");
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(Event.RESUMED);
|
notifyObservers(Event.RESUMED);
|
||||||
}
|
}
|
||||||
@ -1740,12 +1741,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
private void pauseForSystemError() throws InterruptedException {
|
private void pauseForSystemError() throws InterruptedException {
|
||||||
synchronized (pauseLock) {
|
synchronized (pauseLock) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Job processing paused for system error");
|
sysLogger.log(Level.SEVERE, "Job processing paused for system error");
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(Event.PAUSED_FOR_SYSTEM_ERROR);
|
notifyObservers(Event.PAUSED_FOR_SYSTEM_ERROR);
|
||||||
pauseLock.wait();
|
pauseLock.wait();
|
||||||
errorState = ErrorState.NONE;
|
errorState = ErrorState.NONE;
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing resumed after system error");
|
sysLogger.log(Level.INFO, "Job processing resumed after system error");
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(Event.RESUMED);
|
notifyObservers(Event.RESUMED);
|
||||||
}
|
}
|
||||||
@ -1775,11 +1776,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
waitingForInputScan = true;
|
waitingForInputScan = true;
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing waiting for input scan completion");
|
sysLogger.log(Level.INFO, "Job processing waiting for input scan completion");
|
||||||
synchronized (scanMonitor) {
|
synchronized (scanMonitor) {
|
||||||
scanMonitor.wait();
|
scanMonitor.wait();
|
||||||
}
|
}
|
||||||
SYS_LOGGER.log(Level.INFO, "Job processing finished wait for input scan completion");
|
sysLogger.log(Level.INFO, "Job processing finished wait for input scan completion");
|
||||||
synchronized (pauseLock) {
|
synchronized (pauseLock) {
|
||||||
waitingForInputScan = false;
|
waitingForInputScan = false;
|
||||||
pauseIfRequested();
|
pauseIfRequested();
|
||||||
@ -1845,7 +1846,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* job.
|
* job.
|
||||||
*/
|
*/
|
||||||
private void processJobs() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, AutoIngestJobNodeData.InvalidDataException, CaseNodeData.InvalidDataException, JobMetricsCollectionException {
|
private void processJobs() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, AutoIngestJobNodeData.InvalidDataException, CaseNodeData.InvalidDataException, JobMetricsCollectionException {
|
||||||
SYS_LOGGER.log(Level.INFO, "Started processing pending jobs queue");
|
sysLogger.log(Level.INFO, "Started processing pending jobs queue");
|
||||||
Lock manifestLock = JobProcessingTask.this.dequeueAndLockNextJob();
|
Lock manifestLock = JobProcessingTask.this.dequeueAndLockNextJob();
|
||||||
while (null != manifestLock) {
|
while (null != manifestLock) {
|
||||||
try {
|
try {
|
||||||
@ -1895,20 +1896,20 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* while reading the lock data
|
* while reading the lock data
|
||||||
*/
|
*/
|
||||||
private Lock dequeueAndLockNextJob() throws CoordinationServiceException, InterruptedException {
|
private Lock dequeueAndLockNextJob() throws CoordinationServiceException, InterruptedException {
|
||||||
SYS_LOGGER.log(Level.INFO, "Checking pending jobs queue for ready job, enforcing max jobs per case");
|
sysLogger.log(Level.INFO, "Checking pending jobs queue for ready job, enforcing max jobs per case");
|
||||||
Lock manifestLock;
|
Lock manifestLock;
|
||||||
synchronized (jobsLock) {
|
synchronized (jobsLock) {
|
||||||
manifestLock = dequeueAndLockNextJob(true);
|
manifestLock = dequeueAndLockNextJob(true);
|
||||||
if (null != manifestLock) {
|
if (null != manifestLock) {
|
||||||
SYS_LOGGER.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath());
|
sysLogger.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath());
|
||||||
} else {
|
} else {
|
||||||
SYS_LOGGER.log(Level.INFO, "No ready job");
|
sysLogger.log(Level.INFO, "No ready job");
|
||||||
SYS_LOGGER.log(Level.INFO, "Checking pending jobs queue for ready job, not enforcing max jobs per case");
|
sysLogger.log(Level.INFO, "Checking pending jobs queue for ready job, not enforcing max jobs per case");
|
||||||
manifestLock = dequeueAndLockNextJob(false);
|
manifestLock = dequeueAndLockNextJob(false);
|
||||||
if (null != manifestLock) {
|
if (null != manifestLock) {
|
||||||
SYS_LOGGER.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath());
|
sysLogger.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath());
|
||||||
} else {
|
} else {
|
||||||
SYS_LOGGER.log(Level.INFO, "No ready job");
|
sysLogger.log(Level.INFO, "No ready job");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1980,7 +1981,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
currentJob = job;
|
currentJob = job;
|
||||||
break;
|
break;
|
||||||
} catch (AutoIngestJobNodeData.InvalidDataException ex) {
|
} catch (AutoIngestJobNodeData.InvalidDataException ex) {
|
||||||
SYS_LOGGER.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex); // JCTODO: Is this right?
|
sysLogger.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex); // JCTODO: Is this right?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2047,7 +2048,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
private void processJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, CaseNodeData.InvalidDataException, JobMetricsCollectionException {
|
private void processJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, CaseNodeData.InvalidDataException, JobMetricsCollectionException {
|
||||||
Path manifestPath = currentJob.getManifest().getFilePath();
|
Path manifestPath = currentJob.getManifest().getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath);
|
sysLogger.log(Level.INFO, "Started processing of {0}", manifestPath);
|
||||||
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING);
|
currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING, Date.from(Instant.now()));
|
||||||
currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME);
|
currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME);
|
||||||
@ -2078,7 +2079,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
updateCoordinationServiceManifestNode(currentJob);
|
updateCoordinationServiceManifestNode(currentJob);
|
||||||
|
|
||||||
boolean retry = (!currentJob.isCanceled() && !currentJob.isCompleted());
|
boolean retry = (!currentJob.isCanceled() && !currentJob.isCompleted());
|
||||||
SYS_LOGGER.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry});
|
sysLogger.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry});
|
||||||
if (currentJob.isCanceled()) {
|
if (currentJob.isCanceled()) {
|
||||||
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
||||||
if (null != caseDirectoryPath) {
|
if (null != caseDirectoryPath) {
|
||||||
@ -2173,7 +2174,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private void updateConfiguration() throws SharedConfigurationException, InterruptedException {
|
private void updateConfiguration() throws SharedConfigurationException, InterruptedException {
|
||||||
if (AutoIngestUserPreferences.getSharedConfigEnabled()) {
|
if (AutoIngestUserPreferences.getSharedConfigEnabled()) {
|
||||||
Path manifestPath = currentJob.getManifest().getFilePath();
|
Path manifestPath = currentJob.getManifest().getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath);
|
sysLogger.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now()));
|
||||||
new SharedConfiguration().downloadConfiguration();
|
new SharedConfiguration().downloadConfiguration();
|
||||||
}
|
}
|
||||||
@ -2191,7 +2192,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException {
|
private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException {
|
||||||
Path manifestPath = currentJob.getManifest().getFilePath();
|
Path manifestPath = currentJob.getManifest().getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath);
|
sysLogger.log(Level.INFO, "Checking services availability for {0}", manifestPath);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES, Date.from(Instant.now()));
|
||||||
if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) {
|
if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) {
|
||||||
throw new DatabaseServerDownException("Case database server is down");
|
throw new DatabaseServerDownException("Case database server is down");
|
||||||
@ -2238,7 +2239,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private Case openCase() throws CoordinationServiceException, CaseManagementException, InterruptedException {
|
private Case openCase() throws CoordinationServiceException, CaseManagementException, InterruptedException {
|
||||||
Manifest manifest = currentJob.getManifest();
|
Manifest manifest = currentJob.getManifest();
|
||||||
String caseName = manifest.getCaseName();
|
String caseName = manifest.getCaseName();
|
||||||
SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
|
sysLogger.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE, Date.from(Instant.now()));
|
||||||
/*
|
/*
|
||||||
* Acquire and hold a case name lock so that only one node at as
|
* Acquire and hold a case name lock so that only one node at as
|
||||||
@ -2272,7 +2273,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
}
|
}
|
||||||
currentJob.setCaseDirectoryPath(caseDirectoryPath);
|
currentJob.setCaseDirectoryPath(caseDirectoryPath);
|
||||||
Case caseForJob = Case.getOpenCase();
|
Case caseForJob = Case.getOpenCase();
|
||||||
SYS_LOGGER.log(Level.INFO, "Opened case {0} for {1}", new Object[]{caseForJob.getName(), manifest.getFilePath()});
|
sysLogger.log(Level.INFO, "Opened case {0} for {1}", new Object[]{caseForJob.getName(), manifest.getFilePath()});
|
||||||
return caseForJob;
|
return caseForJob;
|
||||||
|
|
||||||
} catch (KeywordSearchModuleException ex) {
|
} catch (KeywordSearchModuleException ex) {
|
||||||
@ -2417,14 +2418,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private AutoIngestDataSource identifyDataSource() throws AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
private AutoIngestDataSource identifyDataSource() throws AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
||||||
Manifest manifest = currentJob.getManifest();
|
Manifest manifest = currentJob.getManifest();
|
||||||
Path manifestPath = manifest.getFilePath();
|
Path manifestPath = manifest.getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath);
|
sysLogger.log(Level.INFO, "Identifying data source for {0} ", manifestPath);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE, Date.from(Instant.now()));
|
||||||
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
||||||
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
|
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
|
||||||
Path dataSourcePath = manifest.getDataSourcePath();
|
Path dataSourcePath = manifest.getDataSourcePath();
|
||||||
File dataSource = dataSourcePath.toFile();
|
File dataSource = dataSourcePath.toFile();
|
||||||
if (!dataSource.exists()) {
|
if (!dataSource.exists()) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Missing data source for {0}", manifestPath);
|
sysLogger.log(Level.SEVERE, "Missing data source for {0}", manifestPath);
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
jobLogger.logMissingDataSource();
|
jobLogger.logMissingDataSource();
|
||||||
@ -2451,7 +2452,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private void runDataSourceProcessor(Case caseForJob, AutoIngestDataSource dataSource) throws InterruptedException, AutoIngestJobLoggerException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
private void runDataSourceProcessor(Case caseForJob, AutoIngestDataSource dataSource) throws InterruptedException, AutoIngestJobLoggerException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
||||||
Manifest manifest = currentJob.getManifest();
|
Manifest manifest = currentJob.getManifest();
|
||||||
Path manifestPath = manifest.getFilePath();
|
Path manifestPath = manifest.getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath);
|
sysLogger.log(Level.INFO, "Adding data source for {0} ", manifestPath);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE, Date.from(Instant.now()));
|
||||||
DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor();
|
DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor();
|
||||||
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
||||||
@ -2463,7 +2464,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath());
|
validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath());
|
||||||
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
|
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath());
|
sysLogger.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath());
|
||||||
// rethrow the exception. It will get caught & handled upstream and will result in AIM auto-pause.
|
// rethrow the exception. It will get caught & handled upstream and will result in AIM auto-pause.
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
@ -2474,7 +2475,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
jobLogger.logFailedToIdentifyDataSource();
|
jobLogger.logFailedToIdentifyDataSource();
|
||||||
SYS_LOGGER.log(Level.WARNING, "Unsupported data source {0} for {1}", new Object[]{dataSource.getPath(), manifestPath}); // NON-NLS
|
sysLogger.log(Level.WARNING, "Unsupported data source {0} for {1}", new Object[]{dataSource.getPath(), manifestPath}); // NON-NLS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2486,7 +2487,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId, ingestLock);
|
DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId, ingestLock);
|
||||||
caseForJob.notifyAddingDataSource(taskId);
|
caseForJob.notifyAddingDataSource(taskId);
|
||||||
jobLogger.logDataSourceProcessorSelected(selectedProcessor.getDataSourceType());
|
jobLogger.logDataSourceProcessorSelected(selectedProcessor.getDataSourceType());
|
||||||
SYS_LOGGER.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()});
|
sysLogger.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()});
|
||||||
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
|
selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack);
|
||||||
ingestLock.wait();
|
ingestLock.wait();
|
||||||
|
|
||||||
@ -2504,7 +2505,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If we get to this point, none of the processors were successful
|
// If we get to this point, none of the processors were successful
|
||||||
SYS_LOGGER.log(Level.SEVERE, "All data source processors failed to process {0}", dataSource.getPath());
|
sysLogger.log(Level.SEVERE, "All data source processors failed to process {0}", dataSource.getPath());
|
||||||
jobLogger.logFailedToAddDataSource();
|
jobLogger.logFailedToAddDataSource();
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
@ -2547,7 +2548,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
|
|
||||||
case NONCRITICAL_ERRORS:
|
case NONCRITICAL_ERRORS:
|
||||||
for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) {
|
for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) {
|
||||||
SYS_LOGGER.log(Level.WARNING, "Non-critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage});
|
sysLogger.log(Level.WARNING, "Non-critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage});
|
||||||
}
|
}
|
||||||
jobLogger.logDataSourceAdded();
|
jobLogger.logDataSourceAdded();
|
||||||
if (dataSource.getContent().isEmpty()) {
|
if (dataSource.getContent().isEmpty()) {
|
||||||
@ -2557,7 +2558,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
|
|
||||||
case CRITICAL_ERRORS:
|
case CRITICAL_ERRORS:
|
||||||
for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) {
|
for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage});
|
sysLogger.log(Level.SEVERE, "Critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage});
|
||||||
}
|
}
|
||||||
jobLogger.logFailedToAddDataSource();
|
jobLogger.logFailedToAddDataSource();
|
||||||
break;
|
break;
|
||||||
@ -2570,7 +2571,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* AutoIngestJob and calling cancel on the DSP, if not null, in
|
* AutoIngestJob and calling cancel on the DSP, if not null, in
|
||||||
* cancelCurrentJob.
|
* cancelCurrentJob.
|
||||||
*/
|
*/
|
||||||
SYS_LOGGER.log(Level.WARNING, "Cancellation while waiting for data source processor for {0}", manifestPath);
|
sysLogger.log(Level.WARNING, "Cancellation while waiting for data source processor for {0}", manifestPath);
|
||||||
jobLogger.logDataSourceProcessorCancelled();
|
jobLogger.logDataSourceProcessorCancelled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2595,7 +2596,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private void analyze(AutoIngestDataSource dataSource) throws AnalysisStartupException, AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
private void analyze(AutoIngestDataSource dataSource) throws AnalysisStartupException, AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
||||||
Manifest manifest = currentJob.getManifest();
|
Manifest manifest = currentJob.getManifest();
|
||||||
Path manifestPath = manifest.getFilePath();
|
Path manifestPath = manifest.getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath);
|
sysLogger.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE, Date.from(Instant.now()));
|
||||||
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
||||||
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
|
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
|
||||||
@ -2616,17 +2617,17 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
* is shutting down.
|
* is shutting down.
|
||||||
*/
|
*/
|
||||||
ingestLock.wait();
|
ingestLock.wait();
|
||||||
SYS_LOGGER.log(Level.INFO, "Finished ingest modules analysis for {0} ", manifestPath);
|
sysLogger.log(Level.INFO, "Finished ingest modules analysis for {0} ", manifestPath);
|
||||||
IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot();
|
IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot();
|
||||||
for (IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot : jobSnapshot.getDataSourceSnapshots()) {
|
for (IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot : jobSnapshot.getDataSourceSnapshots()) {
|
||||||
if (!snapshot.isCancelled()) {
|
if (!snapshot.isCancelled()) {
|
||||||
List<String> cancelledModules = snapshot.getCancelledDataSourceIngestModules();
|
List<String> cancelledModules = snapshot.getCancelledDataSourceIngestModules();
|
||||||
if (!cancelledModules.isEmpty()) {
|
if (!cancelledModules.isEmpty()) {
|
||||||
SYS_LOGGER.log(Level.WARNING, String.format("Ingest module(s) cancelled for %s", manifestPath));
|
sysLogger.log(Level.WARNING, String.format("Ingest module(s) cancelled for %s", manifestPath));
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
for (String module : snapshot.getCancelledDataSourceIngestModules()) {
|
for (String module : snapshot.getCancelledDataSourceIngestModules()) {
|
||||||
SYS_LOGGER.log(Level.WARNING, String.format("%s ingest module cancelled for %s", module, manifestPath));
|
sysLogger.log(Level.WARNING, String.format("%s ingest module cancelled for %s", module, manifestPath));
|
||||||
jobLogger.logIngestModuleCancelled(module);
|
jobLogger.logIngestModuleCancelled(module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2644,14 +2645,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
}
|
}
|
||||||
} else if (!ingestJobStartResult.getModuleErrors().isEmpty()) {
|
} else if (!ingestJobStartResult.getModuleErrors().isEmpty()) {
|
||||||
for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) {
|
for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable());
|
sysLogger.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable());
|
||||||
}
|
}
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
jobLogger.logIngestModuleStartupErrors();
|
jobLogger.logIngestModuleStartupErrors();
|
||||||
throw new AnalysisStartupException(String.format("Error(s) during ingest module startup for %s", manifestPath));
|
throw new AnalysisStartupException(String.format("Error(s) during ingest module startup for %s", manifestPath));
|
||||||
} else {
|
} else {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException());
|
sysLogger.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException());
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
jobLogger.logAnalysisStartupError();
|
jobLogger.logAnalysisStartupError();
|
||||||
@ -2659,7 +2660,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (String warning : settingsWarnings) {
|
for (String warning : settingsWarnings) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Ingest job settings error for {0}: {1}", new Object[]{manifestPath, warning});
|
sysLogger.log(Level.SEVERE, "Ingest job settings error for {0}: {1}", new Object[]{manifestPath, warning});
|
||||||
}
|
}
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
@ -2732,7 +2733,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private void exportFiles(AutoIngestDataSource dataSource) throws FileExportException, AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
private void exportFiles(AutoIngestDataSource dataSource) throws FileExportException, AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException {
|
||||||
Manifest manifest = currentJob.getManifest();
|
Manifest manifest = currentJob.getManifest();
|
||||||
Path manifestPath = manifest.getFilePath();
|
Path manifestPath = manifest.getFilePath();
|
||||||
SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath);
|
sysLogger.log(Level.INFO, "Exporting files for {0}", manifestPath);
|
||||||
currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES, Date.from(Instant.now()));
|
currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES, Date.from(Instant.now()));
|
||||||
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
Path caseDirectoryPath = currentJob.getCaseDirectoryPath();
|
||||||
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
|
AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath);
|
||||||
@ -2743,7 +2744,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
jobLogger.logFileExportCompleted();
|
jobLogger.logFileExportCompleted();
|
||||||
}
|
}
|
||||||
} catch (FileExportException ex) {
|
} catch (FileExportException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error doing file export for %s", manifestPath), ex);
|
sysLogger.log(Level.SEVERE, String.format("Error doing file export for %s", manifestPath), ex);
|
||||||
currentJob.setErrorsOccurred(true);
|
currentJob.setErrorsOccurred(true);
|
||||||
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
setCaseNodeDataErrorsOccurred(caseDirectoryPath);
|
||||||
jobLogger.logFileExportError();
|
jobLogger.logFileExportError();
|
||||||
@ -2916,7 +2917,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
private final long MAX_SECONDS_WITHOUT_UPDATE = JOB_STATUS_EVENT_INTERVAL_SECONDS * MAX_MISSED_JOB_STATUS_UPDATES;
|
private final long MAX_SECONDS_WITHOUT_UPDATE = JOB_STATUS_EVENT_INTERVAL_SECONDS * MAX_MISSED_JOB_STATUS_UPDATES;
|
||||||
|
|
||||||
private PeriodicJobStatusEventTask() {
|
private PeriodicJobStatusEventTask() {
|
||||||
SYS_LOGGER.log(Level.INFO, "Periodic status publishing task started");
|
sysLogger.log(Level.INFO, "Periodic status publishing task started");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2949,7 +2950,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
try {
|
try {
|
||||||
StatusDatabaseLogger.logToStatusDatabase(message, isError);
|
StatusDatabaseLogger.logToStatusDatabase(message, isError);
|
||||||
} catch (SQLException | UserPreferencesException ex) {
|
} catch (SQLException | UserPreferencesException ex) {
|
||||||
SYS_LOGGER.log(Level.WARNING, "Failed to update status database", ex);
|
sysLogger.log(Level.WARNING, "Failed to update status database", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2975,7 +2976,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "Unexpected exception in PeriodicJobStatusEventTask", ex); //NON-NLS
|
sysLogger.log(Level.SEVERE, "Unexpected exception in PeriodicJobStatusEventTask", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 Basis Technology Corp.
|
* Copyright 2015-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,8 +25,8 @@ import java.sql.Timestamp;
|
|||||||
import java.util.logging.FileHandler;
|
import java.util.logging.FileHandler;
|
||||||
import java.util.logging.Formatter;
|
import java.util.logging.Formatter;
|
||||||
import java.util.logging.LogRecord;
|
import java.util.logging.LogRecord;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,7 +37,7 @@ final class AutoIngestSystemLogger {
|
|||||||
|
|
||||||
private static final int LOG_SIZE = 50000000; // In bytes, zero is unlimited, set to roughly 10mb currently
|
private static final int LOG_SIZE = 50000000; // In bytes, zero is unlimited, set to roughly 10mb currently
|
||||||
private static final int LOG_FILE_COUNT = 10;
|
private static final int LOG_FILE_COUNT = 10;
|
||||||
private static final Logger LOGGER = Logger.getLogger("AutoIngest"); //NON-NLS
|
private static final Logger logger = Logger.getLogger("AutoIngest"); //NON-NLS
|
||||||
private static final String NEWLINE = System.lineSeparator();
|
private static final String NEWLINE = System.lineSeparator();
|
||||||
@GuardedBy("AutoIngestSystemLogger")
|
@GuardedBy("AutoIngestSystemLogger")
|
||||||
private static boolean configured;
|
private static boolean configured;
|
||||||
@ -74,14 +74,14 @@ final class AutoIngestSystemLogger {
|
|||||||
+ stackTrace;
|
+ stackTrace;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
LOGGER.addHandler(fileHandler);
|
logger.addHandler(fileHandler);
|
||||||
LOGGER.setUseParentHandlers(false);
|
logger.setUseParentHandlers(false);
|
||||||
} catch (SecurityException | IOException ex) {
|
} catch (SecurityException | IOException ex) {
|
||||||
throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS
|
throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
configured = true;
|
configured = true;
|
||||||
}
|
}
|
||||||
return LOGGER;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 Basis Technology Corp.
|
* Copyright 2015-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -26,6 +26,7 @@ import java.sql.Statement;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
||||||
|
|
||||||
@ -33,72 +34,79 @@ import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreference
|
|||||||
* Write auto-ingest status updates to a database.
|
* Write auto-ingest status updates to a database.
|
||||||
*/
|
*/
|
||||||
public class StatusDatabaseLogger {
|
public class StatusDatabaseLogger {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log the current status to the database using the database
|
* Log the current status to the database using the database parameters
|
||||||
* parameters saved in AutoIngestUserPreferences.
|
* saved in AutoIngestUserPreferences.
|
||||||
* @param message Current status message
|
*
|
||||||
* @param isError true if we're in an error state, false otherwise
|
* @param message Current status message
|
||||||
* @throws SQLException
|
* @param isError true if we're in an error state, false otherwise
|
||||||
|
*
|
||||||
|
* @throws SQLException If a SQL data access error occurs.
|
||||||
|
* @throws UserPreferencesException If there's an issue reading the user
|
||||||
|
* preferences.
|
||||||
*/
|
*/
|
||||||
public static void logToStatusDatabase(String message, boolean isError) throws SQLException, UserPreferencesException{
|
public static void logToStatusDatabase(String message, boolean isError) throws SQLException, UserPreferencesException {
|
||||||
|
|
||||||
try{
|
try {
|
||||||
Class.forName("org.postgresql.Driver");
|
Class.forName("org.postgresql.Driver");
|
||||||
} catch (ClassNotFoundException ex){
|
} catch (ClassNotFoundException ex) {
|
||||||
java.util.logging.Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger();
|
Logger sysLogger = AutoIngestSystemLogger.getLogger();
|
||||||
SYS_LOGGER.log(Level.WARNING, "Error loading postgresql driver", ex);
|
sysLogger.log(Level.WARNING, "Error loading postgresql driver", ex);
|
||||||
}
|
}
|
||||||
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://"
|
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://"
|
||||||
+ AutoIngestUserPreferences.getLoggingDatabaseHostnameOrIP()
|
+ AutoIngestUserPreferences.getLoggingDatabaseHostnameOrIP()
|
||||||
+ ":" + AutoIngestUserPreferences.getLoggingPort()
|
+ ":" + AutoIngestUserPreferences.getLoggingPort()
|
||||||
+ "/" + AutoIngestUserPreferences.getLoggingDatabaseName(),
|
+ "/" + AutoIngestUserPreferences.getLoggingDatabaseName(),
|
||||||
AutoIngestUserPreferences.getLoggingUsername(),
|
AutoIngestUserPreferences.getLoggingUsername(),
|
||||||
AutoIngestUserPreferences.getLoggingPassword());
|
AutoIngestUserPreferences.getLoggingPassword());
|
||||||
Statement statement = connection.createStatement();) {
|
Statement statement = connection.createStatement();) {
|
||||||
|
|
||||||
logToStatusDatabase(statement, message, isError);
|
logToStatusDatabase(statement, message, isError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log the current status to the database using an already
|
* Log the current status to the database using an already configured
|
||||||
* configured Statement.
|
* Statement.
|
||||||
|
*
|
||||||
* @param statement SQL statement (must have already been created)
|
* @param statement SQL statement (must have already been created)
|
||||||
* @param message Current status message
|
* @param message Current status message
|
||||||
* @param isError true if we're in an error state, false otherwise
|
* @param isError true if we're in an error state, false otherwise
|
||||||
* @throws SQLException
|
*
|
||||||
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public static void logToStatusDatabase(Statement statement, String message, boolean isError) throws SQLException{
|
public static void logToStatusDatabase(Statement statement, String message, boolean isError) throws SQLException {
|
||||||
if((statement == null) || statement.isClosed()){
|
if ((statement == null) || statement.isClosed()) {
|
||||||
throw new SQLException("SQL Statement is null/closed");
|
throw new SQLException("SQL Statement is null/closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
if(isError){
|
if (isError) {
|
||||||
status = 1;
|
status = 1;
|
||||||
} else {
|
} else {
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
|
String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format( new java.util.Date());
|
||||||
|
|
||||||
String checkForPreviousEntry = "SELECT * FROM statusUpdates WHERE tool='" + UserPreferences.getAppName() + "' AND " +
|
String checkForPreviousEntry = "SELECT * FROM statusUpdates WHERE tool='" + UserPreferences.getAppName() + "' AND "
|
||||||
"node='" + NetworkUtils.getLocalHostName() + "'";
|
+ "node='" + NetworkUtils.getLocalHostName() + "'";
|
||||||
|
|
||||||
ResultSet resultSet = statement.executeQuery(checkForPreviousEntry);
|
ResultSet resultSet = statement.executeQuery(checkForPreviousEntry);
|
||||||
String logMessage;
|
String logMessage;
|
||||||
if(resultSet.next()){
|
if (resultSet.next()) {
|
||||||
logMessage = "UPDATE statusUpdates SET reportTime='" + timestamp +
|
logMessage = "UPDATE statusUpdates SET reportTime='" + timestamp
|
||||||
"', message='" + message + "', status=" + status
|
+ "', message='" + message + "', status=" + status
|
||||||
+ " WHERE tool='" + UserPreferences.getAppName() + "' AND node='" + NetworkUtils.getLocalHostName() + "'";
|
+ " WHERE tool='" + UserPreferences.getAppName() + "' AND node='" + NetworkUtils.getLocalHostName() + "'";
|
||||||
} else {
|
} else {
|
||||||
logMessage = "INSERT INTO statusUpdates (tool, node, reportTime, message, status) " +
|
logMessage = "INSERT INTO statusUpdates (tool, node, reportTime, message, status) "
|
||||||
"VALUES ('" + UserPreferences.getAppName()
|
+ "VALUES ('" + UserPreferences.getAppName()
|
||||||
+ "', '" + NetworkUtils.getLocalHostName() +
|
+ "', '" + NetworkUtils.getLocalHostName()
|
||||||
"', '" +
|
+ "', '"
|
||||||
timestamp + "', '" + message + "', '" + status + "')";
|
+ timestamp + "', '" + message + "', '" + status + "')";
|
||||||
|
|
||||||
}
|
}
|
||||||
statement.execute(logMessage);
|
statement.execute(logMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,6 @@ class VolatilityProcessor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
String pluginToRun = pluginsToRun.get(i);
|
String pluginToRun = pluginsToRun.get(i);
|
||||||
progressMonitor.setProgressText(Bundle.VolatilityProcessor_progressMessage_runningImageInfo(pluginToRun));
|
|
||||||
runVolatilityPlugin(pluginToRun);
|
runVolatilityPlugin(pluginToRun);
|
||||||
progressMonitor.setProgress(i);
|
progressMonitor.setProgress(i);
|
||||||
}
|
}
|
||||||
@ -172,6 +171,8 @@ class VolatilityProcessor {
|
|||||||
"VolatilityProcessor_exceptionMessage_errorIndexingOutput=Error indexing output for {0} plugin"
|
"VolatilityProcessor_exceptionMessage_errorIndexingOutput=Error indexing output for {0} plugin"
|
||||||
})
|
})
|
||||||
private void runVolatilityPlugin(String pluginToRun) throws VolatilityProcessorException {
|
private void runVolatilityPlugin(String pluginToRun) throws VolatilityProcessorException {
|
||||||
|
progressMonitor.setProgressText("Running module " + pluginToRun);
|
||||||
|
|
||||||
List<String> commandLine = new ArrayList<>();
|
List<String> commandLine = new ArrayList<>();
|
||||||
commandLine.add("\"" + executableFile + "\""); //NON-NLS
|
commandLine.add("\"" + executableFile + "\""); //NON-NLS
|
||||||
File memoryImage = new File(memoryImagePath);
|
File memoryImage = new File(memoryImagePath);
|
||||||
@ -314,6 +315,8 @@ class VolatilityProcessor {
|
|||||||
|
|
||||||
String filePath = volfile.getParent();
|
String filePath = volfile.getParent();
|
||||||
|
|
||||||
|
logger.log(Level.INFO, "Looking up file " + fileName + " at path " + filePath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<AbstractFile> resolvedFiles;
|
List<AbstractFile> resolvedFiles;
|
||||||
if (filePath == null) {
|
if (filePath == null) {
|
||||||
@ -333,12 +336,13 @@ class VolatilityProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileName += ".%"; //NON-NLS
|
fileName += ".%"; //NON-NLS
|
||||||
|
logger.log(Level.INFO, "Looking up file (extension wildcard) " + fileName + " at path " + filePath);
|
||||||
|
|
||||||
if (filePath == null) {
|
if (filePath == null) {
|
||||||
resolvedFiles = fileManager.findFiles(fileName); //NON-NLS
|
resolvedFiles = fileManager.findFiles(fileName); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
resolvedFiles = fileManager.findFiles(fileName, filePath); //NON-NLS
|
resolvedFiles = fileManager.findFiles(fileName, filePath); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedFiles.isEmpty()) {
|
if (resolvedFiles.isEmpty()) {
|
||||||
@ -387,6 +391,7 @@ class VolatilityProcessor {
|
|||||||
* @param pluginOutputFile File that contains the output to parse.
|
* @param pluginOutputFile File that contains the output to parse.
|
||||||
*/
|
*/
|
||||||
private void createArtifactsFromPluginOutput(String pluginName, File pluginOutputFile) throws VolatilityProcessorException {
|
private void createArtifactsFromPluginOutput(String pluginName, File pluginOutputFile) throws VolatilityProcessorException {
|
||||||
|
progressMonitor.setProgressText("Parsing module " + pluginName);
|
||||||
Set<String> fileSet = null;
|
Set<String> fileSet = null;
|
||||||
switch (pluginName) {
|
switch (pluginName) {
|
||||||
case "dlllist": //NON-NLS
|
case "dlllist": //NON-NLS
|
||||||
@ -421,6 +426,7 @@ class VolatilityProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fileSet != null && !fileSet.isEmpty()) {
|
if (fileSet != null && !fileSet.isEmpty()) {
|
||||||
|
progressMonitor.setProgressText("Flagging files from module " + pluginName);
|
||||||
flagFiles(fileSet, pluginName);
|
flagFiles(fileSet, pluginName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<target name="get-deps" depends="init-ivy, get-solr-deployment">
|
<target name="get-deps" depends="init-ivy, get-solr-deployment">
|
||||||
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
|
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
|
||||||
<ivy:resolve/>
|
<ivy:resolve log="quiet"/>
|
||||||
<ivy:retrieve conf="autopsy" pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
|
<ivy:retrieve conf="autopsy" pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
|
||||||
<ivy:retrieve conf="solr-war" pattern="${basedir}/release/solr/webapps/solr.war" />
|
<ivy:retrieve conf="solr-war" pattern="${basedir}/release/solr/webapps/solr.war" />
|
||||||
<ivy:retrieve conf="start-solr" pattern="${basedir}/release/solr/start.jar" />
|
<ivy:retrieve conf="start-solr" pattern="${basedir}/release/solr/start.jar" />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -23,10 +23,10 @@ import java.beans.PropertyChangeSupport;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.FileHandler;
|
import java.util.logging.FileHandler;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.logging.SimpleFormatter;
|
import java.util.logging.SimpleFormatter;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
|
||||||
@ -39,8 +39,8 @@ public class KeywordSearch {
|
|||||||
private static Server server;
|
private static Server server;
|
||||||
//we want a custom java.util.logging.Logger here for a reason
|
//we want a custom java.util.logging.Logger here for a reason
|
||||||
//a separate logger from framework logs
|
//a separate logger from framework logs
|
||||||
private static final Logger TIKA_LOGGER = Logger.getLogger("Tika"); //NON-NLS
|
private static final java.util.logging.Logger tikaLogger = java.util.logging.Logger.getLogger("Tika"); //NON-NLS
|
||||||
private static final org.sleuthkit.autopsy.coreutils.Logger logger = org.sleuthkit.autopsy.coreutils.Logger.getLogger(Case.class.getName());
|
private static final Logger logger = Logger.getLogger(Case.class.getName());
|
||||||
|
|
||||||
// @@@ We should move this into TskData (or somewhere) because we are using
|
// @@@ We should move this into TskData (or somewhere) because we are using
|
||||||
// this value in the results tree to display substring differently from regexp (KeywordHit.java)
|
// this value in the results tree to display substring differently from regexp (KeywordHit.java)
|
||||||
@ -70,9 +70,9 @@ public class KeywordSearch {
|
|||||||
0, MAX_TIKA_LOG_FILES);
|
0, MAX_TIKA_LOG_FILES);
|
||||||
tikaLogHandler.setFormatter(new SimpleFormatter());
|
tikaLogHandler.setFormatter(new SimpleFormatter());
|
||||||
tikaLogHandler.setEncoding(PlatformUtil.getLogFileEncoding());
|
tikaLogHandler.setEncoding(PlatformUtil.getLogFileEncoding());
|
||||||
TIKA_LOGGER.addHandler(tikaLogHandler);
|
tikaLogger.addHandler(tikaLogHandler);
|
||||||
//do not forward to the parent autopsy logger
|
//do not forward to the parent autopsy logger
|
||||||
TIKA_LOGGER.setUseParentHandlers(false);
|
tikaLogger.setUseParentHandlers(false);
|
||||||
} catch (IOException | SecurityException ex) {
|
} catch (IOException | SecurityException ex) {
|
||||||
logger.log(Level.SEVERE, "Error setting up tika logging", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Error setting up tika logging", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
@ -83,8 +83,8 @@ public class KeywordSearch {
|
|||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Logger getTikaLogger() {
|
static java.util.logging.Logger getTikaLogger() {
|
||||||
return TIKA_LOGGER;
|
return tikaLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addNumIndexedFilesChangeListener(PropertyChangeListener l) {
|
public static void addNumIndexedFilesChangeListener(PropertyChangeListener l) {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<target name="get-deps" depends="init-ivy,get-thirdparty-tools">
|
<target name="get-deps" depends="init-ivy,get-thirdparty-tools">
|
||||||
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
|
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
|
||||||
<ivy:resolve/>
|
<ivy:resolve log="quiet"/>
|
||||||
<ivy:retrieve conf="recent-activity" pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
|
<ivy:retrieve conf="recent-activity" pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -41,7 +41,7 @@ import org.netbeans.junit.NbModuleSuite;
|
|||||||
public class RegressionTest extends TestCase {
|
public class RegressionTest extends TestCase {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(RegressionTest.class.getName());
|
private static final Logger logger = Logger.getLogger(RegressionTest.class.getName());
|
||||||
private static AutopsyTestCases autopsyTests = new AutopsyTestCases(Boolean.parseBoolean(System.getProperty("isMultiUser")));
|
private static final AutopsyTestCases autopsyTests = new AutopsyTestCases(Boolean.parseBoolean(System.getProperty("isMultiUser")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor required by JUnit
|
* Constructor required by JUnit
|
||||||
|
51
appveyor.yml
Normal file
51
appveyor.yml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
version: 4.6.0.{build}
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- C:\Users\appveyor\.ant -> appveyor.yml
|
||||||
|
- C:\Users\appveyor\.ivy2 -> appveyor.yml
|
||||||
|
- C:\ProgramData\chocolatey\bin -> appveyor.yml
|
||||||
|
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
image: Visual Studio 2015
|
||||||
|
platform: x64
|
||||||
|
init:
|
||||||
|
- ps: choco install ant --ignore-dependencies
|
||||||
|
- ps: $env:Path="C:\Program Files\Java\jdk1.8.0\bin;$($env:Path);C:\ProgramData\chocolatey\lib\ant"
|
||||||
|
- set PATH=C:\Python36-x64\';%PATH%
|
||||||
|
environment:
|
||||||
|
global:
|
||||||
|
TSK_HOME: "C:\\sleuthkit"
|
||||||
|
LIBVHDI_HOME: "C:\\libvhdi_64bit"
|
||||||
|
LIBVMDK_HOME: "C:\\libvmdk_64bit\\libvmdk"
|
||||||
|
LIBEWF_HOME: "C:\\libewf_64bit"
|
||||||
|
POSTGRESQL_HOME_64: "C:\\Program Files\\PostgreSQL\\9.5"
|
||||||
|
JDK_HOME: C:\Program Files\Java\jdk1.8.0
|
||||||
|
PYTHON: "C:\\Python36-x64"
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ps: pushd C:\
|
||||||
|
- git clone https://github.com/sleuthkit/sleuthkit
|
||||||
|
- ps: popd
|
||||||
|
services:
|
||||||
|
- postgresql95
|
||||||
|
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cd %TSK_HOME%
|
||||||
|
- python setupLibs.py
|
||||||
|
- python win32\updateBuildLibs.py -m
|
||||||
|
- ps: pushd bindings/java
|
||||||
|
- ps: ant -version
|
||||||
|
- cmd: ant dist-PostgreSQL
|
||||||
|
- ps: popd
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%
|
||||||
|
- cmd: ant -q build
|
||||||
|
- cd Core
|
||||||
|
- cmd: ant -q test
|
||||||
|
- cd ..
|
||||||
|
|
||||||
|
test: off
|
Loading…
x
Reference in New Issue
Block a user