mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 07:56:16 +00:00
Merge branch 'develop' into 2988-fix-cc-viewer
This commit is contained in:
commit
f9ca7b55f2
@ -377,7 +377,9 @@ public class Case {
|
||||
*
|
||||
* @param eventNames The events the subscriber is interested in.
|
||||
* @param subscriber The subscriber (PropertyChangeListener) to add.
|
||||
* @deprecated Use addEventTypeSubscriber instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void addEventSubscriber(Set<String> eventNames, PropertyChangeListener subscriber) {
|
||||
eventPublisher.addSubscriber(eventNames, subscriber);
|
||||
}
|
||||
@ -385,9 +387,23 @@ public class Case {
|
||||
/**
|
||||
* Adds a subscriber to specific case events.
|
||||
*
|
||||
* @param eventName The event the subscriber is interested in.
|
||||
* @param eventTypes The events the subscriber is interested in.
|
||||
* @param subscriber The subscriber (PropertyChangeListener) to add.
|
||||
*/
|
||||
public static void addEventTypeSubscriber(Set<Events> eventTypes, PropertyChangeListener subscriber) {
|
||||
eventTypes.forEach((Events event) -> {
|
||||
eventPublisher.addSubscriber(event.toString(), subscriber);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subscriber to specific case events.
|
||||
*
|
||||
* @param eventName The event the subscriber is interested in.
|
||||
* @param subscriber The subscriber (PropertyChangeListener) to add.
|
||||
* @deprecated Use addEventTypeSubscriber instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void addEventSubscriber(String eventName, PropertyChangeListener subscriber) {
|
||||
eventPublisher.addSubscriber(eventName, subscriber);
|
||||
}
|
||||
@ -412,6 +428,18 @@ public class Case {
|
||||
eventPublisher.removeSubscriber(eventNames, subscriber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a subscriber to specific case events.
|
||||
*
|
||||
* @param eventTypes The events the subscriber is no longer interested in.
|
||||
* @param subscriber The subscriber (PropertyChangeListener) to remove.
|
||||
*/
|
||||
public static void removeEventTypeSubscriber(Set<Events> eventTypes, PropertyChangeListener subscriber) {
|
||||
eventTypes.forEach((Events event) -> {
|
||||
eventPublisher.removeSubscriber(event.toString(), subscriber);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a case display name is valid, i.e., does not include any
|
||||
* characters that cannot be used in file names.
|
||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.EnumSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.Action;
|
||||
@ -49,7 +50,7 @@ final class CaseDeleteAction extends CallableSystemAction {
|
||||
CaseDeleteAction() {
|
||||
putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction"));
|
||||
this.setEnabled(false);
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
setEnabled(null != evt.getNewValue() && UserPreferences.getMode() != UserPreferences.SelectedMode.REVIEW);
|
||||
});
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.EnumSet;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -42,7 +43,7 @@ final class CasePropertiesAction extends CallableSystemAction {
|
||||
CasePropertiesAction() {
|
||||
putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction"));
|
||||
this.setEnabled(false);
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
setEnabled(null != evt.getNewValue());
|
||||
});
|
||||
}
|
||||
|
@ -24,9 +24,8 @@ import java.beans.PropertyChangeListener;
|
||||
import java.io.Serializable;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -57,7 +56,8 @@ final class CollaborationMonitor {
|
||||
|
||||
private static final String EVENT_CHANNEL_NAME = "%s-Collaboration-Monitor-Events"; //NON-NLS
|
||||
private static final String COLLABORATION_MONITOR_EVENT = "COLLABORATION_MONITOR_EVENT"; //NON-NLS
|
||||
private static final Set<String> CASE_EVENTS_OF_INTEREST = new HashSet<>(Arrays.asList(new String[]{Case.Events.ADDING_DATA_SOURCE.toString(), Case.Events.DATA_SOURCE_ADDED.toString(), Case.Events.ADDING_DATA_SOURCE_FAILED.toString()}));
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.ADDING_DATA_SOURCE,
|
||||
Case.Events.DATA_SOURCE_ADDED, Case.Events.ADDING_DATA_SOURCE_FAILED);
|
||||
private static final int NUMBER_OF_PERIODIC_TASK_THREADS = 2;
|
||||
private static final String PERIODIC_TASK_THREAD_NAME = "collab-monitor-periodic-tasks-%d"; //NON-NLS
|
||||
private static final long HEARTBEAT_INTERVAL_MINUTES = 1;
|
||||
@ -113,7 +113,7 @@ final class CollaborationMonitor {
|
||||
*/
|
||||
localTasksManager = new LocalTasksManager();
|
||||
IngestManager.getInstance().addIngestJobEventListener(localTasksManager);
|
||||
Case.addEventSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager);
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager);
|
||||
|
||||
/**
|
||||
* Start periodic tasks that:
|
||||
@ -141,7 +141,7 @@ final class CollaborationMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
Case.removeEventSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, localTasksManager);
|
||||
IngestManager.getInstance().removeIngestJobEventListener(localTasksManager);
|
||||
|
||||
if (null != eventPublisher) {
|
||||
|
@ -35,6 +35,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import static java.util.Objects.nonNull;
|
||||
@ -153,7 +154,7 @@ public class ImageUtils {
|
||||
SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); //NON-NLS
|
||||
|
||||
//Clear the file map when the case changes, so we don't accidentaly get images from the old case.
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), evt -> cacheFileMap.clear());
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), evt -> cacheFileMap.clear());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,8 +21,10 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -53,6 +55,9 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
@NbBundle.Messages("AbstractAbstractFileNode.addFileProperty.desc=no description")
|
||||
private static final String NO_DESCR = AbstractAbstractFileNode_addFileProperty_desc();
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
|
||||
Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED);
|
||||
|
||||
/**
|
||||
* @param abstractFile file to wrap
|
||||
*/
|
||||
@ -67,13 +72,14 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
}
|
||||
}
|
||||
// Listen for case events so that we can detect when case is closed
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
// Listen for case events so that we can detect when the case is closed
|
||||
// or when tags are added.
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
@ -95,7 +101,11 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
|
||||
// If so, refresh our children.
|
||||
try {
|
||||
Children parentsChildren = getParentNode().getChildren();
|
||||
if (parentsChildren != null) {
|
||||
// We only want to refresh our parents children if we are in the
|
||||
// data sources branch of the tree. The parent nodes in other
|
||||
// branches of the tree (e.g. File Types and Deleted Files) do
|
||||
// not need to be refreshed.
|
||||
if (parentsChildren instanceof ContentChildren) {
|
||||
((ContentChildren) parentsChildren).refreshChildren();
|
||||
parentsChildren.getNodesCount();
|
||||
}
|
||||
|
@ -25,31 +25,29 @@ import java.beans.PropertyChangeListener;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.WeakListeners;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||
import static org.sleuthkit.autopsy.datamodel.DataModelActionsFactory.VIEW_IN_NEW_WINDOW;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked;
|
||||
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
|
||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -68,6 +66,11 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifact> {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(BlackboardArtifactNode.class.getName());
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED,
|
||||
Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED,
|
||||
Case.Events.CONTENT_TAG_ADDED,
|
||||
Case.Events.CONTENT_TAG_DELETED,
|
||||
Case.Events.CURRENT_CASE);
|
||||
|
||||
private static Cache<Long, Content> contentCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES).
|
||||
@ -128,8 +131,9 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct blackboard artifact node from an artifact and using provided
|
||||
* icon
|
||||
* Construct blackboard artifact node from an artifact, overriding the
|
||||
* standard icon with the one at the path provided.
|
||||
*
|
||||
*
|
||||
* @param artifact artifact to encapsulate
|
||||
* @param iconPath icon to use for the artifact
|
||||
@ -140,9 +144,9 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
this.artifact = artifact;
|
||||
|
||||
// Look for associated Content i.e. the source file for the artifact
|
||||
for (Content content : this.getLookup().lookupAll(Content.class)) {
|
||||
if ( (content != null) && (!(content instanceof BlackboardArtifact)) ){
|
||||
this.associated = content;
|
||||
for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
|
||||
if ((lookupContent != null) && (!(lookupContent instanceof BlackboardArtifact))) {
|
||||
this.associated = lookupContent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -150,7 +154,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
this.setName(Long.toString(artifact.getArtifactID()));
|
||||
this.setDisplayName();
|
||||
this.setIconBaseWithExtension(iconPath);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, WeakListeners.propertyChange(pcl, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,12 +164,11 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
* @param artifact artifact to encapsulate
|
||||
*/
|
||||
public BlackboardArtifactNode(BlackboardArtifact artifact) {
|
||||
|
||||
this(artifact, ExtractedContent.getIconFilePath(artifact.getArtifactTypeID()));
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
public BlackboardArtifact getArtifact() {
|
||||
@ -268,7 +271,6 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
return srcName;
|
||||
}
|
||||
|
||||
|
||||
@NbBundle.Messages({
|
||||
"BlackboardArtifactNode.createSheet.artifactType.displayName=Artifact Type",
|
||||
"BlackboardArtifactNode.createSheet.artifactType.name=Artifact Type",
|
||||
@ -476,11 +478,9 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()) {
|
||||
}
|
||||
else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
|
||||
addEmailMsgProperty (map, attribute);
|
||||
}
|
||||
else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||
} else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
|
||||
addEmailMsgProperty(map, attribute);
|
||||
} else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||
map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
|
||||
} else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
|
||||
&& attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
|
||||
@ -496,8 +496,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
value = value.substring(0, 512);
|
||||
}
|
||||
map.put(attribute.getAttributeType().getDisplayName(), value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
|
||||
}
|
||||
}
|
||||
@ -506,14 +505,14 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Fill map with EmailMsg properties, not all attributes are filled
|
||||
*
|
||||
* @param map map with preserved ordering, where property names/values
|
||||
* are put
|
||||
* @param attribute attribute to check/fill as property
|
||||
*/
|
||||
private void addEmailMsgProperty(Map<String, Object> map, BlackboardAttribute attribute ) {
|
||||
private void addEmailMsgProperty(Map<String, Object> map, BlackboardAttribute attribute) {
|
||||
|
||||
final int attributeTypeID = attribute.getAttributeType().getTypeID();
|
||||
|
||||
@ -523,23 +522,19 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID()
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()
|
||||
) {
|
||||
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()) {
|
||||
|
||||
// do nothing
|
||||
}
|
||||
else if (attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID()) {
|
||||
} else if (attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID()) {
|
||||
|
||||
String value = attribute.getDisplayString();
|
||||
if (value.length() > 160) {
|
||||
value = value.substring(0, 160) + "...";
|
||||
}
|
||||
map.put(attribute.getAttributeType().getDisplayName(), value);
|
||||
}
|
||||
else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||
} else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
|
||||
map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.Sheet;
|
||||
@ -88,13 +89,13 @@ public class DataSourcesNode extends DisplayableItemNode {
|
||||
|
||||
@Override
|
||||
protected void addNotify() {
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), pcl);
|
||||
reloadKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeNotify() {
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), pcl);
|
||||
currentKeys.clear();
|
||||
setKeys(Collections.<Content>emptySet());
|
||||
}
|
||||
|
@ -22,9 +22,11 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -173,24 +175,26 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
* Listens for case and ingest invest. Updates observers when events are
|
||||
* fired. Other nodes are listening to this for changes.
|
||||
*/
|
||||
private final class DeletedContentsChildrenObservable extends Observable {
|
||||
private static final class DeletedContentsChildrenObservable extends Observable {
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
|
||||
Case.Events.DATA_SOURCE_ADDED,
|
||||
Case.Events.CURRENT_CASE
|
||||
);
|
||||
|
||||
DeletedContentsChildrenObservable() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
deleteObservers();
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private final PropertyChangeListener pcl = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
|
||||
/**
|
||||
@ -235,7 +239,6 @@ public class DeletedContent implements AutopsyVisitableItem {
|
||||
}
|
||||
maxFilesDialogShown = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void update() {
|
||||
|
@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -285,7 +286,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
emailResults.update();
|
||||
emailResults.addObserver(this);
|
||||
}
|
||||
@ -294,7 +295,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
emailResults.deleteObserver(this);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@ -251,14 +252,14 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
typeNodeList.clear();
|
||||
}
|
||||
|
||||
@ -309,7 +310,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
||||
*/
|
||||
public class TypeNode extends DisplayableItemNode {
|
||||
|
||||
private BlackboardArtifact.Type type;
|
||||
private final BlackboardArtifact.Type type;
|
||||
private long childCount = 0;
|
||||
|
||||
TypeNode(BlackboardArtifact.Type type) {
|
||||
|
@ -22,9 +22,11 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
@ -169,32 +171,32 @@ public class FileSize implements AutopsyVisitableItem {
|
||||
* Listens for case and ingest invest. Updates observers when events are
|
||||
* fired. Size-based nodes are listening to this for changes.
|
||||
*/
|
||||
private final class FileSizeRootChildrenObservable extends Observable {
|
||||
private static final class FileSizeRootChildrenObservable extends Observable {
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE);
|
||||
|
||||
FileSizeRootChildrenObservable() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
deleteObservers();
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private final PropertyChangeListener pcl = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
|
||||
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
|
||||
/**
|
||||
* Checking for a current case is a stop gap measure
|
||||
* until a different way of handling the closing of
|
||||
* cases is worked out. Currently, remote events may be
|
||||
* received for a case that is already closed.
|
||||
* Checking for a current case is a stop gap measure until a
|
||||
* different way of handling the closing of cases is worked
|
||||
* out. Currently, remote events may be received for a case
|
||||
* that is already closed.
|
||||
*/
|
||||
try {
|
||||
// new file was added
|
||||
@ -210,10 +212,10 @@ public class FileSize implements AutopsyVisitableItem {
|
||||
|| eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|
||||
|| eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
|
||||
/**
|
||||
* Checking for a current case is a stop gap measure
|
||||
* until a different way of handling the closing of
|
||||
* cases is worked out. Currently, remote events may be
|
||||
* received for a case that is already closed.
|
||||
* Checking for a current case is a stop gap measure until a
|
||||
* different way of handling the closing of cases is worked
|
||||
* out. Currently, remote events may be received for a case
|
||||
* that is already closed.
|
||||
*/
|
||||
try {
|
||||
Case.getCurrentCase();
|
||||
@ -229,7 +231,6 @@ public class FileSize implements AutopsyVisitableItem {
|
||||
removeListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void update() {
|
||||
|
@ -21,10 +21,11 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.function.Function;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@ -39,8 +40,6 @@ import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesKey;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@ -75,9 +74,11 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
private class FileTypesByExtObservable extends Observable {
|
||||
|
||||
private final PropertyChangeListener pcl;
|
||||
private final Set<Case.Events> CASE_EVENTS_OF_INTEREST;
|
||||
|
||||
private FileTypesByExtObservable() {
|
||||
super();
|
||||
this.CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE);
|
||||
this.pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())
|
||||
@ -109,15 +110,14 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
deleteObservers();
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
|
@ -24,11 +24,13 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -44,7 +46,6 @@ import static org.sleuthkit.autopsy.core.UserPreferences.hideSlackFilesInViewsTr
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesKey;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@ -79,6 +80,8 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
*/
|
||||
private final PropertyChangeListener pcl;
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.DATA_SOURCE_ADDED, Case.Events.CURRENT_CASE);
|
||||
|
||||
/**
|
||||
* Create the base expression used as the where clause in the queries for
|
||||
* files by mime type. Filters out certain kinds of files and directories,
|
||||
@ -102,7 +105,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
private void removeListeners() {
|
||||
deleteObservers();
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,7 +178,7 @@ public final class FileTypesByMimeType extends Observable implements AutopsyVisi
|
||||
}
|
||||
};
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
populateHashMap();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -252,7 +253,7 @@ public class HashsetHits implements AutopsyVisitableItem {
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
hashsetResults.update();
|
||||
hashsetResults.addObserver(this);
|
||||
}
|
||||
@ -261,7 +262,7 @@ public class HashsetHits implements AutopsyVisitableItem {
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
hashsetResults.deleteObserver(this);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.Action;
|
||||
@ -79,12 +80,12 @@ public class ImageNode extends AbstractContentNode<Image> {
|
||||
// Listen for ingest events so that we can detect new added files (e.g. carved)
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
// Listen for case events so that we can detect when case is closed
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -188,9 +189,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
* nice methods for its startup and shutdown, so it seemed like a
|
||||
* cleaner place to register the property change listener.
|
||||
*/
|
||||
private final PropertyChangeListener pcl = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
|
||||
/**
|
||||
@ -240,14 +239,13 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
skCase = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
interestingResults.update();
|
||||
interestingResults.addObserver(this);
|
||||
}
|
||||
@ -256,7 +254,7 @@ public class InterestingHits implements AutopsyVisitableItem {
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
interestingResults.deleteObserver(this);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -455,7 +456,7 @@ public class KeywordHits implements AutopsyVisitableItem {
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
keywordResults.update();
|
||||
super.addNotify();
|
||||
}
|
||||
@ -464,7 +465,7 @@ public class KeywordHits implements AutopsyVisitableItem {
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
super.removeNotify();
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,9 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
@ -103,8 +105,10 @@ public final class Reports implements AutopsyVisitableItem {
|
||||
*/
|
||||
private static final class ReportNodeFactory extends ChildFactory<Report> {
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.REPORT_ADDED, Case.Events.REPORT_DELETED);
|
||||
|
||||
ReportNodeFactory() {
|
||||
Case.addPropertyChangeListener((PropertyChangeEvent evt) -> {
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
|
||||
String eventType = evt.getPropertyName();
|
||||
if (eventType.equals(Case.Events.REPORT_ADDED.toString()) || eventType.equals(Case.Events.REPORT_DELETED.toString())) {
|
||||
/**
|
||||
|
@ -21,9 +21,11 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
@ -118,6 +120,12 @@ public class Tags implements AutopsyVisitableItem {
|
||||
|
||||
private class TagNameNodeFactory extends ChildFactory.Detachable<TagName> implements Observer {
|
||||
|
||||
private final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED,
|
||||
Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED,
|
||||
Case.Events.CONTENT_TAG_ADDED,
|
||||
Case.Events.CONTENT_TAG_DELETED,
|
||||
Case.Events.CURRENT_CASE);
|
||||
|
||||
private final PropertyChangeListener pcl = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
@ -171,7 +179,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
tagResults.update();
|
||||
tagResults.addObserver(this);
|
||||
}
|
||||
@ -180,7 +188,7 @@ public class Tags implements AutopsyVisitableItem {
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, pcl);
|
||||
tagResults.deleteObserver(this);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Children;
|
||||
@ -72,12 +73,12 @@ public class VolumeNode extends AbstractContentNode<Volume> {
|
||||
// Listen for ingest events so that we can detect new added files (e.g. carved)
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
// Listen for case events so that we can detect when case is closed
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -32,6 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -311,7 +312,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
||||
protected void removeNotify() {
|
||||
IngestManager.getInstance().removeIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().removeIngestModuleEventListener(pcl);
|
||||
Case.removePropertyChangeListener(pcl);
|
||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
super.removeNotify();
|
||||
}
|
||||
|
||||
@ -319,7 +320,7 @@ final public class Accounts implements AutopsyVisitableItem {
|
||||
protected void addNotify() {
|
||||
IngestManager.getInstance().addIngestJobEventListener(pcl);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(pcl);
|
||||
Case.addPropertyChangeListener(pcl);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl);
|
||||
super.addNotify();
|
||||
refreshKeys();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.beans.PropertyVetoException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -151,7 +152,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
}
|
||||
}
|
||||
});
|
||||
Case.addEventSubscriber(new HashSet<>(Arrays.asList(Case.Events.CURRENT_CASE.toString(), Case.Events.DATA_SOURCE_ADDED.toString())), this);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_ADDED), this);
|
||||
this.em.addPropertyChangeListener(this);
|
||||
IngestManager.getInstance().addIngestJobEventListener(this);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(this);
|
||||
|
@ -56,3 +56,5 @@ SizeSearchPanel.sizeCompareComboBox.lessThan=less than
|
||||
MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected
|
||||
FileSearchPanel.searchButton.text=Search
|
||||
MimeTypePanel.mimeTypeCheckBox.text=MIME Type:
|
||||
HashSearchPanel.md5CheckBox.text=MD5:
|
||||
HashSearchPanel.emptyHashMsg.text=Must enter something for hash search.
|
@ -28,6 +28,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -53,6 +54,9 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
|
||||
private static final String SEPARATOR = "SEPARATOR"; //NON-NLS
|
||||
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
|
||||
Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED);
|
||||
|
||||
/**
|
||||
* New DateSearchFilter with the default panel
|
||||
*/
|
||||
@ -62,7 +66,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
|
||||
private DateSearchFilter(DateSearchPanel panel) {
|
||||
super(panel);
|
||||
Case.addPropertyChangeListener(this.new CasePropertyChangeListener());
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.EnumSet;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
@ -35,14 +35,10 @@ final class FileSearchAction extends CallableSystemAction implements FileSearchP
|
||||
FileSearchAction() {
|
||||
super();
|
||||
setEnabled(Case.isCaseOpen());
|
||||
Case.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
setEnabled(evt.getNewValue() != null);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,8 @@ class FileSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.knownStatus"), new KnownStatusSearchFilter()));
|
||||
|
||||
this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "HashSearchPanel.md5CheckBox.text"), new HashSearchFilter()));
|
||||
|
||||
for (FilterArea fa : this.filterAreas) {
|
||||
fa.setMaximumSize(new Dimension(Integer.MAX_VALUE, fa.getMinimumSize().height));
|
||||
fa.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
|
66
Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java
Executable file
66
Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java
Executable file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 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.filesearch;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class HashSearchFilter extends AbstractFileSearchFilter<HashSearchPanel> {
|
||||
|
||||
private static final String EMPTY_HASH_MESSAGE = NbBundle
|
||||
.getMessage(HashSearchFilter.class, "HashSearchPanel.emptyHashMsg.text");
|
||||
|
||||
public HashSearchFilter() {
|
||||
this(new HashSearchPanel());
|
||||
}
|
||||
|
||||
public HashSearchFilter(HashSearchPanel component) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.getComponent().getHashCheckBox().isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPredicate() throws FilterValidationException {
|
||||
String md5Hash = this.getComponent().getSearchTextField().getText();
|
||||
|
||||
if (md5Hash.isEmpty()) {
|
||||
throw new FilterValidationException(EMPTY_HASH_MESSAGE);
|
||||
}
|
||||
|
||||
return "md5 = '" + md5Hash.toLowerCase() + "'"; //NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActionListener(ActionListener l) {
|
||||
getComponent().addActionListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return !this.getComponent().getSearchTextField().getText().isEmpty();
|
||||
}
|
||||
}
|
101
Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.form
Executable file
101
Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.form
Executable file
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Container class="javax.swing.JPopupMenu" name="rightClickMenu">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="cutMenuItem">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.cutMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</MenuItem>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="copyMenuItem">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.copyMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</MenuItem>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="pasteMenuItem">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.pasteMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</MenuItem>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="selectAllMenuItem">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.selectAllMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</MenuItem>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="hashCheckBox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="searchTextField" min="-2" pref="247" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="hashCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="searchTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JCheckBox" name="hashCheckBox">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="false" component="hashCheckBox" property="font" relativeSize="false" size="11"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="HashSearchPanel.md5CheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hashCheckBoxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="searchTextField">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="false" component="searchTextField" property="font" relativeSize="false" size="11"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
175
Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.java
Executable file
175
Core/src/org/sleuthkit/autopsy/filesearch/HashSearchPanel.java
Executable file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2017 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.filesearch;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class HashSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates new form HashSearchPanel
|
||||
*/
|
||||
HashSearchPanel() {
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
setComponentsEnabled();
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
|
||||
searchTextField.setComponentPopupMenu(rightClickMenu);
|
||||
ActionListener actList = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JMenuItem jmi = (JMenuItem) e.getSource();
|
||||
if (jmi.equals(cutMenuItem)) {
|
||||
searchTextField.cut();
|
||||
} else if (jmi.equals(copyMenuItem)) {
|
||||
searchTextField.copy();
|
||||
} else if (jmi.equals(pasteMenuItem)) {
|
||||
searchTextField.paste();
|
||||
} else if (jmi.equals(selectAllMenuItem)) {
|
||||
searchTextField.selectAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
cutMenuItem.addActionListener(actList);
|
||||
copyMenuItem.addActionListener(actList);
|
||||
pasteMenuItem.addActionListener(actList);
|
||||
selectAllMenuItem.addActionListener(actList);
|
||||
this.searchTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
JCheckBox getHashCheckBox() {
|
||||
return hashCheckBox;
|
||||
}
|
||||
|
||||
JTextField getSearchTextField() {
|
||||
return searchTextField;
|
||||
}
|
||||
|
||||
void setComponentsEnabled() {
|
||||
boolean enabled = hashCheckBox.isSelected();
|
||||
this.searchTextField.setEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
rightClickMenu = new javax.swing.JPopupMenu();
|
||||
cutMenuItem = new javax.swing.JMenuItem();
|
||||
copyMenuItem = new javax.swing.JMenuItem();
|
||||
pasteMenuItem = new javax.swing.JMenuItem();
|
||||
selectAllMenuItem = new javax.swing.JMenuItem();
|
||||
hashCheckBox = new javax.swing.JCheckBox();
|
||||
searchTextField = new javax.swing.JTextField();
|
||||
|
||||
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.cutMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(cutMenuItem);
|
||||
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.copyMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(copyMenuItem);
|
||||
|
||||
pasteMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.pasteMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(pasteMenuItem);
|
||||
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "NameSearchPanel.selectAllMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(selectAllMenuItem);
|
||||
|
||||
hashCheckBox.setFont(hashCheckBox.getFont().deriveFont(hashCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||
hashCheckBox.setText(org.openide.util.NbBundle.getMessage(HashSearchPanel.class, "HashSearchPanel.md5CheckBox.text")); // NOI18N
|
||||
hashCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
hashCheckBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
searchTextField.setFont(searchTextField.getFont().deriveFont(searchTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(hashCheckBox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(hashCheckBox)
|
||||
.addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void hashCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hashCheckBoxActionPerformed
|
||||
setComponentsEnabled();
|
||||
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
|
||||
}//GEN-LAST:event_hashCheckBoxActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JMenuItem copyMenuItem;
|
||||
private javax.swing.JMenuItem cutMenuItem;
|
||||
private javax.swing.JCheckBox hashCheckBox;
|
||||
private javax.swing.JMenuItem pasteMenuItem;
|
||||
private javax.swing.JPopupMenu rightClickMenu;
|
||||
private javax.swing.JTextField searchTextField;
|
||||
private javax.swing.JMenuItem selectAllMenuItem;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
void addActionListener(ActionListener l) {
|
||||
searchTextField.addActionListener(l);
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -229,7 +230,7 @@ public class IngestManager {
|
||||
* opened/closed) events.
|
||||
*/
|
||||
private void subscribeToCaseEvents() {
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent event) -> {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent event) -> {
|
||||
if (event.getNewValue() != null) {
|
||||
handleCaseOpened();
|
||||
} else {
|
||||
|
@ -25,6 +25,7 @@ import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.EnumSet;
|
||||
import javax.swing.JButton;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.windows.Mode;
|
||||
@ -128,7 +129,7 @@ class IngestMessagesToolbar extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
Case.addPropertyChangeListener((PropertyChangeEvent evt) -> {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
setEnabled(evt.getNewValue() != null && RuntimeProperties.runningWithGUI());
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
@ -121,7 +122,7 @@ public final class IngestMonitor {
|
||||
|
||||
MonitorTimerAction() {
|
||||
findRootDirectoryForCurrentCase();
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
if (evt instanceof AutopsyEvent) {
|
||||
AutopsyEvent event = (AutopsyEvent) evt;
|
||||
if (AutopsyEvent.SourceType.LOCAL == event.getSourceType() && event.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
|
@ -23,7 +23,7 @@ import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.EnumSet;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
@ -43,14 +43,10 @@ class HashDbPanelSearchAction extends CallableSystemAction {
|
||||
HashDbPanelSearchAction() {
|
||||
super();
|
||||
setEnabled(Case.isCaseOpen());
|
||||
Case.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
setEnabled(evt.getNewValue() != null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
@ -81,7 +82,7 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
|
||||
|
||||
public ReportWizardAction() {
|
||||
setEnabled(false);
|
||||
Case.addPropertyChangeListener((PropertyChangeEvent evt) -> {
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
|
||||
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
Case newCase = (Case) evt.getNewValue();
|
||||
setEnabled(newCase != null && RuntimeProperties.runningWithGUI());
|
||||
|
@ -24,7 +24,7 @@
|
||||
Note there is no namespace collision with ver 3 -->
|
||||
<dependency conf="autopsy_core->*" org="commons-lang" name="commons-lang" rev="2.6"/>
|
||||
<dependency conf="autopsy_core->*" org="commons-logging" name="commons-logging" rev="1.1.2"/>
|
||||
<dependency conf="autopsy_core->*" org="commons-io" name="commons-io" rev="2.4"/>
|
||||
<dependency conf="autopsy_core->*" org="commons-io" name="commons-io" rev="2.5"/>
|
||||
<dependency conf="autopsy_core->*" org="log4j" name="log4j" rev="1.2.17"/>
|
||||
|
||||
<!-- <dependency conf="autopsy_core->*" org="org.jdom" name="jdom" rev="1.1.3"/> -->
|
||||
|
@ -10,6 +10,7 @@ file.reference.commons-codec-1.10.jar=release/modules/ext/commons-codec-1.10.jar
|
||||
file.reference.commons-collections4-4.1.jar=release/modules/ext/commons-collections4-4.1.jar
|
||||
file.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4.jar
|
||||
file.reference.commons-io-2.4.jar=release/modules/ext/commons-io-2.4.jar
|
||||
file.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5.jar
|
||||
file.reference.commons-lang-2.6.jar=release/modules/ext/commons-lang-2.6.jar
|
||||
file.reference.commons-lang3-3.0-javadoc.jar=release/modules/ext/commons-lang3-3.0-javadoc.jar
|
||||
file.reference.commons-lang3-3.0-sources.jar=release/modules/ext/commons-lang3-3.0-sources.jar
|
||||
@ -74,6 +75,7 @@ file.reference.xmlbeans-2.6.0.jar=release/modules/ext/xmlbeans-2.6.0.jar
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javadoc.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-javadoc.jar
|
||||
javadoc.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-javadoc.jar
|
||||
javadoc.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-javadoc.jar
|
||||
javadoc.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-javadoc.jar
|
||||
javadoc.reference.guava-19.0.jar=release/modules/ext/guava-19.0-javadoc.jar
|
||||
@ -82,6 +84,7 @@ javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-contro
|
||||
javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar
|
||||
nbm.needs.restart=true
|
||||
source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources.jar
|
||||
source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar
|
||||
source.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-sources.jar
|
||||
source.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-sources.jar
|
||||
source.reference.guava-19.0.jar=release/modules/ext/guava-19.0-sources.jar
|
||||
|
@ -699,18 +699,10 @@
|
||||
<runtime-relative-path>ext/sigar-1.6.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sigar-1.6.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xmlbeans-2.6.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xmlbeans-2.6.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-3.4.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-3.4.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-ooxml-schemas-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/gson-1.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/gson-1.4.jar</binary-origin>
|
||||
@ -731,6 +723,10 @@
|
||||
<runtime-relative-path>ext/imgscalr-lib-4.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imgscalr-lib-4.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/xmlbeans-2.6.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/xmlbeans-2.6.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/common-io-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/common-io-3.2.jar</binary-origin>
|
||||
@ -764,12 +760,12 @@
|
||||
<binary-origin>release/modules/ext/joda-time-2.4-javadoc.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jcalendarbutton-1.4.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jcalendarbutton-1.4.6.jar</binary-origin>
|
||||
<runtime-relative-path>ext/poi-excelant-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-excelant-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-ooxml-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-ooxml-3.15.jar</binary-origin>
|
||||
<runtime-relative-path>ext/jcalendarbutton-1.4.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jcalendarbutton-1.4.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imageio-psd-3.2.jar</runtime-relative-path>
|
||||
@ -779,18 +775,10 @@
|
||||
<runtime-relative-path>ext/stax-api-1.0.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/stax-api-1.0.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-collections4-4.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-collections4-4.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/servlet-api-2.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/servlet-api-2.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-excelant-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-excelant-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imageio-pcx-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imageio-pcx-3.2.jar</binary-origin>
|
||||
@ -827,10 +815,6 @@
|
||||
<runtime-relative-path>ext/geronimo-jms_1.1_spec-1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/geronimo-jms_1.1_spec-1.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-scratchpad-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-scratchpad-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/joda-time-2.4-sources.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/joda-time-2.4-sources.jar</binary-origin>
|
||||
@ -839,14 +823,26 @@
|
||||
<runtime-relative-path>ext/jfxtras-fxml-8.0-r4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-ooxml-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-ooxml-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/joda-time-2.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/joda-time-2.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-collections4-4.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-collections4-4.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-logging-1.1.2-javadoc.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-logging-1.1.2-javadoc.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-codec-1.10.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-codec-1.10.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-simple-1.6.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/slf4j-simple-1.6.1.jar</binary-origin>
|
||||
@ -855,6 +851,18 @@
|
||||
<runtime-relative-path>ext/guava-19.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/guava-19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-io-2.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-io-2.5.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-ooxml-schemas-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-scratchpad-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-scratchpad-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imageio-bmp-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imageio-bmp-3.2.jar</binary-origin>
|
||||
@ -879,10 +887,6 @@
|
||||
<runtime-relative-path>ext/ant-1.8.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/ant-1.8.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-codec-1.10.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-codec-1.10.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/javassist-3.12.1.GA.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/javassist-3.12.1.GA.jar</binary-origin>
|
||||
@ -895,14 +899,6 @@
|
||||
<runtime-relative-path>ext/commons-logging-1.1.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-logging-1.1.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-io-2.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-io-2.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/controlsfx-8.40.11.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/controlsfx-8.40.11.jar</binary-origin>
|
||||
@ -915,6 +911,10 @@
|
||||
<runtime-relative-path>ext/javaee-api-5.0-2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/javaee-api-5.0-2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/poi-3.15.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/poi-3.15.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/common-image-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/common-image-3.2.jar</binary-origin>
|
||||
|
@ -2646,8 +2646,6 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
||||
* back into hostNamesToRunningJobs as a result of
|
||||
* processing the job status update.
|
||||
*/
|
||||
SYS_LOGGER.log(Level.WARNING, "Auto ingest node {0} timed out while processing folder {1}",
|
||||
new Object[]{job.getNodeName(), job.getManifest().getFilePath().toString()});
|
||||
hostNamesToRunningJobs.remove(job.getNodeName());
|
||||
setChanged();
|
||||
notifyObservers(Event.JOB_COMPLETED);
|
||||
|
@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
*/
|
||||
final class AutoIngestSystemLogger {
|
||||
|
||||
private static final int LOG_SIZE = 10000000; // 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 Logger LOGGER = Logger.getLogger("AutoIngest"); //NON-NLS
|
||||
private static final String NEWLINE = System.lineSeparator();
|
||||
|
@ -23,6 +23,7 @@ import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.EnumSet;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
@ -76,7 +77,7 @@ class DropdownToolbar extends javax.swing.JPanel {
|
||||
private void customizeComponents() {
|
||||
searchSettingsChangeListener = new SearchSettingsChangeListener();
|
||||
KeywordSearch.getServer().addServerActionListener(searchSettingsChangeListener);
|
||||
Case.addPropertyChangeListener(searchSettingsChangeListener);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), searchSettingsChangeListener);
|
||||
|
||||
DropdownListSearchPanel listsPanel = DropdownListSearchPanel.getDefault();
|
||||
listsPanel.addSearchButtonActionListener((ActionEvent e) -> {
|
||||
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 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.keywordsearch;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
|
||||
/**
|
||||
* result of writing keyword search result to blackboard (cached artifact and
|
||||
* attributes) This is mainly to cache the attributes, so that we don't query
|
||||
* the DB to get them back again.
|
||||
*/
|
||||
class KeywordCachedArtifact {
|
||||
|
||||
private BlackboardArtifact artifact;
|
||||
private Map<Integer, BlackboardAttribute> attributes;
|
||||
|
||||
KeywordCachedArtifact(BlackboardArtifact artifact) {
|
||||
this.artifact = artifact;
|
||||
attributes = new HashMap<Integer, BlackboardAttribute>();
|
||||
}
|
||||
|
||||
BlackboardArtifact getArtifact() {
|
||||
return artifact;
|
||||
}
|
||||
|
||||
Collection<BlackboardAttribute> getAttributes() {
|
||||
return attributes.values();
|
||||
}
|
||||
|
||||
BlackboardAttribute getAttribute(Integer attrTypeID) {
|
||||
return attributes.get(attrTypeID);
|
||||
}
|
||||
|
||||
void add(BlackboardAttribute attribute) {
|
||||
attributes.put(attribute.getAttributeType().getTypeID(), attribute);
|
||||
}
|
||||
|
||||
void add(Collection<BlackboardAttribute> attributes) {
|
||||
for (BlackboardAttribute attr : attributes) {
|
||||
this.attributes.put(attr.getAttributeType().getTypeID(), attr);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,17 +18,18 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Stores the fact that file or an artifact associated with a file had a keyword
|
||||
* hit. All instances make both the document id of the Solr document where the
|
||||
* keyword was found and the file available to clients. Artifact keyword hits
|
||||
* also make the artifact available to clients.
|
||||
* keyword was found and the object Id available to clients. Artifact keyword
|
||||
* hits also make the artifact available to clients.
|
||||
*/
|
||||
class KeywordHit implements Comparable<KeywordHit> {
|
||||
|
||||
@ -36,7 +37,7 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
private final long solrObjectId;
|
||||
private final int chunkId;
|
||||
private final String snippet;
|
||||
private final Content content;
|
||||
private final long contentID;
|
||||
private final BlackboardArtifact artifact;
|
||||
private final String hit;
|
||||
|
||||
@ -44,14 +45,9 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
return hit;
|
||||
}
|
||||
|
||||
KeywordHit(String solrDocumentId, String snippet) throws TskCoreException {
|
||||
this(solrDocumentId, snippet, null);
|
||||
}
|
||||
|
||||
KeywordHit(String solrDocumentId, String snippet, String hit) throws TskCoreException {
|
||||
/**
|
||||
* Store the Solr document id.
|
||||
*/
|
||||
this.snippet = StringUtils.stripToEmpty(snippet);
|
||||
this.hit = hit;
|
||||
this.solrDocumentId = solrDocumentId;
|
||||
|
||||
/**
|
||||
@ -72,27 +68,19 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
this.chunkId = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the file associated with the keyword hit. If the high order
|
||||
* bit of the object id is set, the hit was for an artifact. In this
|
||||
* case, look up the artifact as well.
|
||||
/*
|
||||
* If the high order bit of the object id is set (ie, it is negative),
|
||||
* the hit was in an artifact, look up the artifact.
|
||||
*/
|
||||
SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase();
|
||||
long fileId;
|
||||
if (this.solrObjectId < 0) {
|
||||
SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase();
|
||||
this.artifact = caseDb.getBlackboardArtifact(this.solrObjectId);
|
||||
fileId = artifact.getObjectID();
|
||||
contentID = artifact.getObjectID();
|
||||
} else {
|
||||
//else the object id is for content.
|
||||
this.artifact = null;
|
||||
fileId = this.solrObjectId;
|
||||
contentID = this.solrObjectId;
|
||||
}
|
||||
this.content = caseDb.getContentById(fileId);
|
||||
|
||||
/**
|
||||
* Store the text snippet.
|
||||
*/
|
||||
this.snippet = snippet;
|
||||
this.hit = hit;
|
||||
}
|
||||
|
||||
String getSolrDocumentId() {
|
||||
@ -103,24 +91,20 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
return this.solrObjectId;
|
||||
}
|
||||
|
||||
boolean hasChunkId() {
|
||||
return this.chunkId != 0;
|
||||
}
|
||||
|
||||
int getChunkId() {
|
||||
return this.chunkId;
|
||||
}
|
||||
|
||||
boolean hasSnippet() {
|
||||
return !this.snippet.isEmpty();
|
||||
return StringUtils.isNotBlank(this.snippet);
|
||||
}
|
||||
|
||||
String getSnippet() {
|
||||
return this.snippet;
|
||||
}
|
||||
|
||||
Content getContent() {
|
||||
return this.content;
|
||||
long getContentID() {
|
||||
return this.contentID;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,7 +135,7 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
return false;
|
||||
}
|
||||
final KeywordHit other = (KeywordHit) obj;
|
||||
return (this.solrObjectId == other.solrObjectId && this.chunkId == other.chunkId);
|
||||
return this.compareTo(other) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -163,21 +147,8 @@ class KeywordHit implements Comparable<KeywordHit> {
|
||||
|
||||
@Override
|
||||
public int compareTo(KeywordHit o) {
|
||||
if (this.solrObjectId < o.solrObjectId) {
|
||||
// Out object id is less than the other object id
|
||||
return -1;
|
||||
} else if (this.solrObjectId == o.solrObjectId) {
|
||||
// Hits have same object id
|
||||
if (this.chunkId < o.chunkId) {
|
||||
// Our chunk id is lower than the other chunk id
|
||||
return -1;
|
||||
} else {
|
||||
// Our chunk id is either greater than or equal to the other chunk id
|
||||
return this.chunkId == o.chunkId ? 0 : 1;
|
||||
}
|
||||
} else {
|
||||
// Our object id is greater than the other object id
|
||||
return 1;
|
||||
}
|
||||
return Comparator.comparing(KeywordHit::getSolrObjectId)
|
||||
.thenComparing(KeywordHit::getChunkId)
|
||||
.compare(this, o);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* Interface for kewyord search queries.
|
||||
*/
|
||||
@ -36,9 +39,11 @@ interface KeywordSearchQuery {
|
||||
* execute query and return results without publishing them return results
|
||||
* for all matching terms
|
||||
*
|
||||
* @throws KeywordSearchModuleException error while executing Solr term query
|
||||
* @throws NoOpenCoreException if query failed due to server error, this
|
||||
* could be a notification to stop processing
|
||||
* @throws KeywordSearchModuleException error while executing Solr term
|
||||
* query
|
||||
* @throws NoOpenCoreException if query failed due to server error,
|
||||
* this could be a notification to stop
|
||||
* processing
|
||||
* @return
|
||||
*/
|
||||
QueryResults performQuery() throws KeywordSearchModuleException, NoOpenCoreException;
|
||||
@ -61,8 +66,6 @@ interface KeywordSearchQuery {
|
||||
/**
|
||||
* Modify the query string to be searched as a substring instead of a whole
|
||||
* word
|
||||
*
|
||||
* @param isSubstring
|
||||
*/
|
||||
void setSubstringQuery();
|
||||
|
||||
@ -97,6 +100,21 @@ interface KeywordSearchQuery {
|
||||
*/
|
||||
String getEscapedQueryString();
|
||||
|
||||
KeywordCachedArtifact writeSingleFileHitsToBlackBoard(Keyword keyword, KeywordHit hit, String snippet, String listName);
|
||||
|
||||
/**
|
||||
* Converts the keyword hits for a given search term into artifacts.
|
||||
*
|
||||
* @param content The Content object associated with the hit.
|
||||
* @param foundKeyword The keyword that was found by the search, this may be
|
||||
* different than the Keyword that was searched if, for
|
||||
* example, it was a RegexQuery.
|
||||
* @param hit The keyword hit.
|
||||
* @param snippet The document snippet that contains the hit.
|
||||
* @param listName The name of the keyword list that contained the
|
||||
* keyword for which the hit was found.
|
||||
*
|
||||
*
|
||||
* @return The newly created artifact or Null if there was a problem
|
||||
* creating it.
|
||||
*/
|
||||
BlackboardArtifact writeSingleFileHitsToBlackBoard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName);
|
||||
}
|
||||
|
@ -18,13 +18,10 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.TreeMultimap;
|
||||
import java.awt.EventQueue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -41,6 +38,7 @@ import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode;
|
||||
@ -50,12 +48,13 @@ import org.sleuthkit.autopsy.datamodel.KeyValue;
|
||||
import org.sleuthkit.autopsy.datamodel.KeyValueNode;
|
||||
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.KeyValueQueryContent;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Node factory that performs the keyword search and creates children nodes for
|
||||
@ -69,8 +68,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchResultFactory.class.getName());
|
||||
|
||||
//common properties (superset of all Node properties) to be displayed as columns
|
||||
static final List<String> COMMON_PROPERTIES
|
||||
= Stream.concat(
|
||||
static final List<String> COMMON_PROPERTIES =
|
||||
Stream.concat(
|
||||
Stream.of(
|
||||
TSK_KEYWORD,
|
||||
TSK_KEYWORD_REGEXP,
|
||||
@ -91,7 +90,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
* properties are displayed as columns (since we are doing lazy child Node
|
||||
* load we need to preinitialize properties when sending parent Node)
|
||||
*
|
||||
* @param toSet property set map for a Node
|
||||
* @param toPopulate property set map for a Node
|
||||
*/
|
||||
@Override
|
||||
protected boolean createKeys(List<KeyValueQueryContent> toPopulate) {
|
||||
@ -144,6 +143,13 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
MessageNotifyUtil.Notify.error(Bundle.KeywordSearchResultFactory_query_exception_msg() + queryRequest.getQueryString(), ex.getCause().getMessage());
|
||||
return false;
|
||||
}
|
||||
SleuthkitCase tskCase = null;
|
||||
try {
|
||||
tskCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
} catch (IllegalStateException ex) {
|
||||
logger.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS
|
||||
return false;
|
||||
}
|
||||
|
||||
int hitNumber = 0;
|
||||
List<KeyValueQueryContent> tempList = new ArrayList<>();
|
||||
@ -153,8 +159,20 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
* Get file properties.
|
||||
*/
|
||||
Map<String, Object> properties = new LinkedHashMap<>();
|
||||
Content content = hit.getContent();
|
||||
String contentName = content.getName();
|
||||
Content content = null;
|
||||
String contentName = "";
|
||||
try {
|
||||
content = tskCase.getContentById(hit.getContentID());
|
||||
if (content == null) {
|
||||
logger.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS
|
||||
return false;
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS
|
||||
return false;
|
||||
}
|
||||
|
||||
contentName = content.getName();
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFsContentNode.fillPropertyMap(properties, (AbstractFile) content);
|
||||
} else {
|
||||
@ -222,6 +240,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
|
||||
//wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization
|
||||
return new KeywordSearchFilterNode(hits, kvNode);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,9 +260,10 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
* practice
|
||||
*
|
||||
* @param name File name that has hit.
|
||||
* @param map Contains content metadata, snippets, etc. (property
|
||||
* map)
|
||||
* @param map Contains content metadata, snippets, etc.
|
||||
* (property map)
|
||||
* @param id User incremented ID
|
||||
* @param solrObjectId
|
||||
* @param content File that had the hit.
|
||||
* @param query Query used in search
|
||||
* @param hits Full set of search results (for all files! @@@)
|
||||
@ -278,13 +298,12 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
* worker for writing results to bb, with progress bar, cancellation, and
|
||||
* central registry of workers to be stopped when case is closed
|
||||
*/
|
||||
static class BlackboardResultWriter extends SwingWorker<Object, Void> {
|
||||
static class BlackboardResultWriter extends SwingWorker<Void, Void> {
|
||||
|
||||
private static final List<BlackboardResultWriter> writers = new ArrayList<>();
|
||||
private ProgressHandle progress;
|
||||
private final KeywordSearchQuery query;
|
||||
private final QueryResults hits;
|
||||
private Collection<BlackboardArtifact> newArtifacts = new ArrayList<>();
|
||||
private static final int QUERY_DISPLAY_LEN = 40;
|
||||
|
||||
BlackboardResultWriter(QueryResults hits, String listName) {
|
||||
@ -298,13 +317,13 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
protected Void doInBackground() throws Exception {
|
||||
registerWriter(this); //register (synchronized on class) outside of writerLock to prevent deadlock
|
||||
final String queryStr = query.getQueryString();
|
||||
final String queryDisp = queryStr.length() > QUERY_DISPLAY_LEN ? queryStr.substring(0, QUERY_DISPLAY_LEN - 1) + " ..." : queryStr;
|
||||
try {
|
||||
progress = ProgressHandle.createHandle(NbBundle.getMessage(this.getClass(), "KeywordSearchResultFactory.progress.saving", queryDisp), () -> BlackboardResultWriter.this.cancel(true));
|
||||
newArtifacts = hits.writeAllHitsToBlackBoard(progress, null, this, false);
|
||||
hits.writeAllHitsToBlackBoard(progress, null, this, false);
|
||||
} finally {
|
||||
finalizeWorker();
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
@ -40,6 +39,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
@ -192,15 +192,13 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
public BlackboardArtifact writeSingleFileHitsToBlackBoard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName();
|
||||
|
||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
BlackboardArtifact bba;
|
||||
KeywordCachedArtifact writeResult;
|
||||
try {
|
||||
bba = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
writeResult = new KeywordCachedArtifact(bba);
|
||||
bba = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
} catch (TskCoreException e) {
|
||||
logger.log(Level.WARNING, "Error adding bb artifact for keyword hit", e); //NON-NLS
|
||||
return null;
|
||||
@ -233,8 +231,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
|
||||
try {
|
||||
bba.addAttributes(attributes); //write out to bb
|
||||
writeResult.add(attributes);
|
||||
return writeResult;
|
||||
return bba;
|
||||
} catch (TskCoreException e) {
|
||||
logger.log(Level.WARNING, "Error adding bb attributes to artifact", e); //NON-NLS
|
||||
return null;
|
||||
|
@ -31,6 +31,7 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.aggregate.ProgressContributor;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||
@ -40,6 +41,8 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Stores the results from running a Solr query (which could contain multiple
|
||||
@ -60,8 +63,6 @@ class QueryResults {
|
||||
*/
|
||||
private final Map<Keyword, List<KeywordHit>> results = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
QueryResults(KeywordSearchQuery query) {
|
||||
this.keywordSearchQuery = query;
|
||||
}
|
||||
@ -70,8 +71,6 @@ class QueryResults {
|
||||
results.put(keyword, hits);
|
||||
}
|
||||
|
||||
|
||||
|
||||
KeywordSearchQuery getQuery() {
|
||||
return keywordSearchQuery;
|
||||
}
|
||||
@ -99,7 +98,7 @@ class QueryResults {
|
||||
*
|
||||
* @return The artifacts that were created.
|
||||
*/
|
||||
Collection<BlackboardArtifact> writeAllHitsToBlackBoard(ProgressHandle progress, ProgressContributor subProgress, SwingWorker<Object, Void> worker, boolean notifyInbox) {
|
||||
Collection<BlackboardArtifact> writeAllHitsToBlackBoard(ProgressHandle progress, ProgressContributor subProgress, SwingWorker<?, ?> worker, boolean notifyInbox) {
|
||||
final Collection<BlackboardArtifact> newArtifacts = new ArrayList<>();
|
||||
if (progress != null) {
|
||||
progress.start(getKeywords().size());
|
||||
@ -145,14 +144,26 @@ class QueryResults {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
KeywordCachedArtifact writeResult = keywordSearchQuery.writeSingleFileHitsToBlackBoard(keyword, hit, snippet, keywordSearchQuery.getKeywordList().getName());
|
||||
Content content = null;
|
||||
try {
|
||||
SleuthkitCase tskCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
content = tskCase.getContentById(hit.getContentID());
|
||||
} catch (TskCoreException | IllegalStateException tskCoreException) {
|
||||
logger.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", tskCoreException); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
BlackboardArtifact writeResult = keywordSearchQuery.writeSingleFileHitsToBlackBoard(content, keyword, hit, snippet, keywordSearchQuery.getKeywordList().getName());
|
||||
if (writeResult != null) {
|
||||
newArtifacts.add(writeResult.getArtifact());
|
||||
newArtifacts.add(writeResult);
|
||||
if (notifyInbox) {
|
||||
writeSingleFileInboxMessage(writeResult, hit.getContent());
|
||||
try {
|
||||
writeSingleFileInboxMessage(writeResult, content);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Error posting message to Ingest Inbox", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "BB artifact for keyword hit not written, file: {0}, hit: {1}", new Object[]{hit.getContent(), keyword.toString()}); //NON-NLS
|
||||
logger.log(Level.WARNING, "BB artifact for keyword hit not written, file: {0}, hit: {1}", new Object[]{content, keyword.toString()}); //NON-NLS
|
||||
}
|
||||
}
|
||||
++unitProgress;
|
||||
@ -181,7 +192,6 @@ class QueryResults {
|
||||
* SolrObjectID-ChunkID pairs.
|
||||
*/
|
||||
private Collection<KeywordHit> getOneHitPerObject(Keyword keyword) {
|
||||
|
||||
HashMap<Long, KeywordHit> hits = new HashMap<>();
|
||||
|
||||
// create a list of KeywordHits. KeywordHits with lowest chunkID is added the the list.
|
||||
@ -196,12 +206,16 @@ class QueryResults {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an ingest inbox message for given keyword in given file
|
||||
* Generate and post an ingest inbox message for the given keyword in the
|
||||
* given content.
|
||||
*
|
||||
* @param written
|
||||
* @param hitFile
|
||||
* @param artifact The keyword hit artifact.
|
||||
* @param hitContent The content that the hit is in.
|
||||
*
|
||||
* @throws TskCoreException If there is a problem generating or posting the
|
||||
* inbox message.
|
||||
*/
|
||||
private void writeSingleFileInboxMessage(KeywordCachedArtifact written, Content hitContent) {
|
||||
private void writeSingleFileInboxMessage(BlackboardArtifact artifact, Content hitContent) throws TskCoreException {
|
||||
StringBuilder subjectSb = new StringBuilder();
|
||||
StringBuilder detailsSb = new StringBuilder();
|
||||
|
||||
@ -210,24 +224,24 @@ class QueryResults {
|
||||
} else {
|
||||
subjectSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.kwHitLbl"));
|
||||
}
|
||||
|
||||
String uniqueKey = null;
|
||||
BlackboardAttribute attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID());
|
||||
BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD));
|
||||
if (attr != null) {
|
||||
final String keyword = attr.getValueString();
|
||||
subjectSb.append(keyword);
|
||||
uniqueKey = keyword.toLowerCase();
|
||||
}
|
||||
|
||||
//details
|
||||
detailsSb.append("<table border='0' cellpadding='4' width='280'>"); //NON-NLS
|
||||
//hit
|
||||
detailsSb.append("<tr>"); //NON-NLS
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.kwHitThLbl"));
|
||||
detailsSb.append("<td>").append(EscapeUtil.escapeHtml(attr.getValueString())).append("</td>"); //NON-NLS
|
||||
detailsSb.append("<td>").append(EscapeUtil.escapeHtml(keyword)).append("</td>"); //NON-NLS
|
||||
detailsSb.append("</tr>"); //NON-NLS
|
||||
}
|
||||
|
||||
//preview
|
||||
attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID());
|
||||
attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW));
|
||||
if (attr != null) {
|
||||
detailsSb.append("<tr>"); //NON-NLS
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.previewThLbl"));
|
||||
@ -247,16 +261,17 @@ class QueryResults {
|
||||
detailsSb.append("</tr>"); //NON-NLS
|
||||
|
||||
//list
|
||||
attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||
attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
|
||||
if (attr != null) {
|
||||
detailsSb.append("<tr>"); //NON-NLS
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.listThLbl"));
|
||||
detailsSb.append("<td>").append(attr.getValueString()).append("</td>"); //NON-NLS
|
||||
detailsSb.append("</tr>"); //NON-NLS
|
||||
}
|
||||
|
||||
//regex
|
||||
if (!keywordSearchQuery.isLiteral()) {
|
||||
attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID());
|
||||
attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP));
|
||||
if (attr != null) {
|
||||
detailsSb.append("<tr>"); //NON-NLS
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.regExThLbl"));
|
||||
@ -264,9 +279,9 @@ class QueryResults {
|
||||
detailsSb.append("</tr>"); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
detailsSb.append("</table>"); //NON-NLS
|
||||
|
||||
IngestServices.getInstance().postMessage(IngestMessage.createDataMessage(MODULE_NAME, subjectSb.toString(), detailsSb.toString(), uniqueKey, written.getArtifact()));
|
||||
IngestServices.getInstance().postMessage(IngestMessage.createDataMessage(MODULE_NAME, subjectSb.toString(), detailsSb.toString(), uniqueKey, artifact));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,15 +19,11 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -52,6 +48,7 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
@ -84,8 +81,6 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
|
||||
private final int MIN_EMAIL_ADDR_LENGTH = 8;
|
||||
|
||||
private final ListMultimap<Keyword, KeywordHit> hitsMultiMap = ArrayListMultimap.create();
|
||||
|
||||
// Lucene regular expressions do not support the following Java predefined
|
||||
// and POSIX character classes. There are other valid Java character classes
|
||||
// that are not supported by Lucene but we do not check for all of them.
|
||||
@ -188,8 +183,9 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
solrQuery.setSort(SortClause.asc(Server.Schema.ID.toString()));
|
||||
|
||||
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
|
||||
SolrDocumentList resultList ;
|
||||
SolrDocumentList resultList;
|
||||
boolean allResultsProcessed = false;
|
||||
QueryResults results = new QueryResults(this);
|
||||
|
||||
while (!allResultsProcessed) {
|
||||
try {
|
||||
@ -201,7 +197,13 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
try {
|
||||
List<KeywordHit> keywordHits = createKeywordHits(resultDoc);
|
||||
for (KeywordHit hit : keywordHits) {
|
||||
hitsMultiMap.put(new Keyword(hit.getHit(), true, true, originalKeyword.getListName(), originalKeyword.getOriginalTerm()), hit);
|
||||
Keyword keywordInstance = new Keyword(hit.getHit(), true, true, originalKeyword.getListName(), originalKeyword.getOriginalTerm());
|
||||
List<KeywordHit> hitsForKeyword = results.getResults(keywordInstance);
|
||||
if (hitsForKeyword == null) {
|
||||
hitsForKeyword = new ArrayList<>();
|
||||
results.addResult(keywordInstance, hitsForKeyword);
|
||||
}
|
||||
hitsForKeyword.add(hit);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error creating keyword hits", ex); //NON-NLS
|
||||
@ -218,10 +220,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(Server.class, "Server.query.exception.msg", keywordString), ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
QueryResults results = new QueryResults(this);
|
||||
for (Keyword k : hitsMultiMap.keySet()) {
|
||||
results.addResult(k, hitsMultiMap.get(k));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -284,8 +283,8 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
/*
|
||||
* If searching for credit card account numbers, do a Luhn check
|
||||
* on the term and discard it if it does not pass.
|
||||
* If searching for credit card account numbers, do a Luhn
|
||||
* check on the term and discard it if it does not pass.
|
||||
*/
|
||||
if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
|
||||
Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit);
|
||||
@ -316,10 +315,14 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
} catch (TskCoreException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable error) {
|
||||
/* NOTE: Matcher.find() is known to throw StackOverflowError in rare cases (see JIRA-2700).
|
||||
StackOverflowError is an error, not an exception, and therefore needs to be caught
|
||||
as a Throwable. When this occurs we should re-throw the error as TskCoreException so that it is
|
||||
logged by the calling method and move on to the next Solr document. */
|
||||
/*
|
||||
* NOTE: Matcher.find() is known to throw StackOverflowError in rare
|
||||
* cases (see JIRA-2700). StackOverflowError is an error, not an
|
||||
* exception, and therefore needs to be caught as a Throwable. When
|
||||
* this occurs we should re-throw the error as TskCoreException so
|
||||
* that it is logged by the calling method and move on to the next
|
||||
* Solr document.
|
||||
*/
|
||||
throw new TskCoreException("Failed to create keyword hits for Solr document id " + docId + " due to " + error.getMessage());
|
||||
}
|
||||
return hits;
|
||||
@ -370,50 +373,15 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
return escapedQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a unique, comma separated list of document ids that match the given
|
||||
* hit for the same object.
|
||||
*
|
||||
* @param keyword The keyword object that resulted in one or more hits.
|
||||
* @param hit The specific hit for which we want to identify all other
|
||||
* chunks that match the keyword
|
||||
*
|
||||
* @return A comma separated list of unique document ids.
|
||||
*/
|
||||
private String getDocumentIds(Keyword keyword, KeywordHit hit) {
|
||||
Set<String> documentIds = new HashSet<>();
|
||||
|
||||
for (KeywordHit h : hitsMultiMap.get(keyword)) {
|
||||
// Add the document id only if it is for the same object as the
|
||||
// given hit and we haven't already seen it.
|
||||
if (h.getSolrObjectId() == hit.getSolrObjectId() && !documentIds.contains(h.getSolrDocumentId())) {
|
||||
documentIds.add(h.getSolrDocumentId());
|
||||
}
|
||||
}
|
||||
|
||||
return StringUtils.join(documentIds, ",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the keyword hits for a given search term into artifacts.
|
||||
*
|
||||
* @param foundKeyword The keyword that was found by the regex search.
|
||||
* @param hit The keyword hit.
|
||||
* @param snippet The document snippet that contains the hit
|
||||
* @param listName The name of the keyword list that contained the
|
||||
* keyword for which the hit was found.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return An object that wraps an artifact and a mapping by id of its
|
||||
* attributes.
|
||||
*/
|
||||
// TODO: Are we actually making meaningful use of the KeywordCachedArtifact
|
||||
// class?
|
||||
@Override
|
||||
public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
public BlackboardArtifact writeSingleFileHitsToBlackBoard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName();
|
||||
|
||||
if (content == null) {
|
||||
LOGGER.log(Level.WARNING, "Error adding artifact for keyword hit to blackboard"); //NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create either a "plain vanilla" keyword hit artifact with keyword and
|
||||
* regex attributes, or a credit card account artifact with attributes
|
||||
@ -426,8 +394,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm()));
|
||||
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString()));
|
||||
try {
|
||||
newArtifact = hit.getContent().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
|
||||
newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS
|
||||
return null;
|
||||
@ -452,7 +419,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
if (hit.isArtifactHit()) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifact().getArtifactID())); //NON-NLS
|
||||
} else {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContent().getId())); //NON-NLS
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -488,8 +455,8 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* document id to support showing just the chunk that contained the
|
||||
* hit.
|
||||
*/
|
||||
if (hit.getContent() instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) hit.getContent();
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) content;
|
||||
if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS
|
||||
|| file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) {
|
||||
attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId()));
|
||||
@ -500,7 +467,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* Create an account artifact.
|
||||
*/
|
||||
try {
|
||||
newArtifact = hit.getContent().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS
|
||||
return null;
|
||||
@ -521,9 +488,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
|
||||
try {
|
||||
newArtifact.addAttributes(attributes);
|
||||
KeywordCachedArtifact writeResult = new KeywordCachedArtifact(newArtifact);
|
||||
writeResult.add(attributes);
|
||||
return writeResult;
|
||||
return newArtifact;
|
||||
} catch (TskCoreException e) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding bb attributes for terms search artifact", e); //NON-NLS
|
||||
return null;
|
||||
@ -570,6 +535,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
||||
* @param groupName The group name of the regular expression that was
|
||||
* used to parse the attribute data.
|
||||
* @param matcher A matcher for the snippet.
|
||||
|
||||
*/
|
||||
static private void addAttributeIfNotAlreadyCaptured(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, BlackboardAttribute.ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) {
|
||||
BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType);
|
||||
|
@ -19,7 +19,6 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -46,7 +45,6 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.StopWatch;
|
||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
|
||||
/**
|
||||
* Singleton keyword search manager: Launches search threads for each job and
|
||||
@ -482,8 +480,6 @@ public final class SearchRunner {
|
||||
if (!newResults.getKeywords().isEmpty()) {
|
||||
|
||||
// Write results to BB
|
||||
//new artifacts created, to report to listeners
|
||||
Collection<BlackboardArtifact> newArtifacts = new ArrayList<>();
|
||||
|
||||
//scale progress bar more more granular, per result sub-progress, within per keyword
|
||||
int totalUnits = newResults.getKeywords().size();
|
||||
@ -496,7 +492,7 @@ public final class SearchRunner {
|
||||
subProgresses[keywordsSearched].progress(keywordList.getName() + ": " + queryDisplayStr, unitProgress);
|
||||
|
||||
// Create blackboard artifacts
|
||||
newArtifacts = newResults.writeAllHitsToBlackBoard(null, subProgresses[keywordsSearched], this, keywordList.getIngestMessages());
|
||||
newResults.writeAllHitsToBlackBoard(null, subProgresses[keywordsSearched], this, keywordList.getIngestMessages());
|
||||
|
||||
} //if has results
|
||||
|
||||
|
@ -824,7 +824,7 @@ public class Server {
|
||||
|
||||
return new Core(coreName, theCase.getCaseType(), index);
|
||||
|
||||
} catch (SolrServerException | SolrException | IOException ex) {
|
||||
} catch (Exception ex) {
|
||||
throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg"), ex);
|
||||
}
|
||||
}
|
||||
@ -1232,6 +1232,8 @@ public class Server {
|
||||
// core in it, and is only good for core-specific operations
|
||||
private final HttpSolrServer solrCore;
|
||||
|
||||
private final int QUERY_TIMEOUT_MILLISECONDS = 86400000; // 24 Hours = 86,400,000 Milliseconds
|
||||
|
||||
private Core(String name, CaseType caseType, Index index) {
|
||||
this.name = name;
|
||||
this.caseType = caseType;
|
||||
@ -1240,7 +1242,8 @@ public class Server {
|
||||
this.solrCore = new HttpSolrServer(currentSolrServer.getBaseURL() + "/" + name); //NON-NLS
|
||||
|
||||
//TODO test these settings
|
||||
//solrCore.setSoTimeout(1000 * 60); // socket read timeout, make large enough so can index larger files
|
||||
// socket read timeout, make large enough so can index larger files
|
||||
solrCore.setSoTimeout(QUERY_TIMEOUT_MILLISECONDS);
|
||||
//solrCore.setConnectionTimeout(1000);
|
||||
solrCore.setDefaultMaxConnectionsPerHost(2);
|
||||
solrCore.setMaxTotalConnections(5);
|
||||
|
@ -42,6 +42,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
@ -318,24 +319,9 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the keyword hits for a given search term into artifacts.
|
||||
*
|
||||
* @param foundKeyword The keyword that was found by the search.
|
||||
* @param hit The keyword hit.
|
||||
* @param snippet The document snippet that contains the hit
|
||||
* @param listName The name of the keyword list that contained the keyword
|
||||
* for which the hit was found.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return An object that wraps an artifact and a mapping by id of its
|
||||
* attributes.
|
||||
*/
|
||||
// TODO: Are we actually making meaningful use of the KeywordCachedArtifact
|
||||
// class?
|
||||
|
||||
@Override
|
||||
public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
public BlackboardArtifact writeSingleFileHitsToBlackBoard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) {
|
||||
/*
|
||||
* Create either a "plain vanilla" keyword hit artifact with keyword and
|
||||
* regex attributes, or a credit card account artifact with attributes
|
||||
@ -349,7 +335,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, originalKeyword.getSearchTerm()));
|
||||
|
||||
try {
|
||||
newArtifact = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS
|
||||
@ -375,7 +361,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
if (hit.isArtifactHit()) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", searchTerm, hit.getSnippet(), hit.getArtifact().getArtifactID())); //NON-NLS
|
||||
} else {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", searchTerm, hit.getSnippet(), hit.getContent().getId())); //NON-NLS
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", searchTerm, hit.getSnippet(), hit.getContentID())); //NON-NLS
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -411,8 +397,8 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
* document id to support showing just the chunk that contained the
|
||||
* hit.
|
||||
*/
|
||||
if (hit.getContent() instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) hit.getContent();
|
||||
if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile)content;
|
||||
if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS
|
||||
|| file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) {
|
||||
attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId()));
|
||||
@ -423,7 +409,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
* Create an account artifact.
|
||||
*/
|
||||
try {
|
||||
newArtifact = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_ACCOUNT);
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS
|
||||
return null;
|
||||
@ -445,9 +431,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
||||
|
||||
try {
|
||||
newArtifact.addAttributes(attributes);
|
||||
KeywordCachedArtifact writeResult = new KeywordCachedArtifact(newArtifact);
|
||||
writeResult.add(attributes);
|
||||
return writeResult;
|
||||
return newArtifact;
|
||||
} catch (TskCoreException e) {
|
||||
LOGGER.log(Level.SEVERE, "Error adding bb attributes for terms search artifact", e); //NON-NLS
|
||||
return null;
|
||||
|
@ -170,7 +170,7 @@
|
||||
<!-- Update configuration file to include jre -->
|
||||
<property name="inst.property.file" value="${inst-path}/etc/${app.name}.conf" />
|
||||
<!-- Sets max heap size to be ${jvm.max.mem} which is set in the run-ai-(32/64) target -->
|
||||
<var name="jvm.args" value=""--branding ${app.name} -J-Xms24m -J-Xmx${jvm.max.mem}m -J-XX:MaxPermSize=128M -J-Xverify:none "" />
|
||||
<var name="jvm.args" value=""--branding ${app.name} -J-Xms24m -J-Xmx${jvm.max.mem}m -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication "" />
|
||||
<propertyfile file="${inst.property.file}">
|
||||
<!-- Note: can be higher on 64 bit systems, should be in sync with project.properties -->
|
||||
<entry key="default_options" value="@JVM_OPTIONS" />
|
||||
|
@ -92,7 +92,7 @@
|
||||
|
||||
<property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" />
|
||||
<!-- for Japanese localized version add option: -Duser.language=ja -->
|
||||
<property name="jvm.options" value=""--branding ${app.name} -J-Xms24m -J-XX:MaxPermSize=128M -J-Xverify:none -J-Xdock:name=${app.title}"" />
|
||||
<property name="jvm.options" value=""--branding ${app.name} -J-Xms24m -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication -J-Xdock:name=${app.title}"" />
|
||||
<propertyfile file="${app.property.file}">
|
||||
<!-- Note: can be higher on 64 bit systems, should be in sync with project.properties -->
|
||||
<entry key="default_options" value="@JVM_OPTIONS" />
|
||||
|
@ -4,7 +4,7 @@ app.title=Autopsy
|
||||
### lowercase version of above
|
||||
app.name=${branding.token}
|
||||
### if left unset, version will default to today's date
|
||||
app.version=4.4.1
|
||||
app.version=4.4.2
|
||||
### build.type must be one of: DEVELOPMENT, RELEASE
|
||||
#build.type=RELEASE
|
||||
build.type=DEVELOPMENT
|
||||
@ -16,7 +16,7 @@ update_versions=false
|
||||
#custom JVM options
|
||||
#Note: can be higher on 64 bit systems, should be in sync with build.xml
|
||||
# for Japanese version add: -J-Duser.language=ja
|
||||
run.args.extra=-J-Xms24m -J-XX:MaxPermSize=128M -J-Xverify:none
|
||||
run.args.extra=-J-Xms24m -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication
|
||||
auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2
|
||||
auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
|
||||
auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false
|
||||
|
Loading…
x
Reference in New Issue
Block a user