Merge pull request #4597 from raman-bt/1183-mark-group-unseen

1183: Mark group as 'unseen' for all examiners
This commit is contained in:
Richard Cordovano 2019-03-22 13:29:30 -04:00 committed by GitHub
commit ee655997f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 23 deletions

View File

@ -88,7 +88,7 @@ public class NextUnseenGroup extends Action {
if (group.isPresent()) { if (group.isPresent()) {
// NOTE: We need to wait for current group to be marked as seen because the 'advance' // NOTE: We need to wait for current group to be marked as seen because the 'advance'
// method grabs the top of the unseen list // method grabs the top of the unseen list
groupManager.markGroupSeen(group.get(), true) groupManager.markGroupSeen(group.get())
.addListener(this::advanceToNextUnseenGroup, MoreExecutors.newDirectExecutorService()); .addListener(this::advanceToNextUnseenGroup, MoreExecutors.newDirectExecutorService());
return; return;
} }

View File

@ -1141,44 +1141,67 @@ public final class DrawableDB {
} }
/** /**
* Record in the DB that the group with the given key has the given seen * Record in the DB that the group with the given key is seen
* state for the given examiner id. * by given examiner id.
* *
* @param groupKey * @param groupKey key identifying the group.
* @param seen * @param examinerID examiner id.
* @param examinerID
* *
* @throws TskCoreException * @throws TskCoreException
*/ */
public void markGroupSeen(GroupKey<?> groupKey, boolean seen, long examinerID) throws TskCoreException { public void markGroupSeen(GroupKey<?> groupKey, long examinerID) throws TskCoreException {
/* /*
* Check the groupSeenCache to see if the seen status for this group was set recently. * Check the groupSeenCache to see if the seen status for this group was set recently.
* If recently set to the same value, there's no need to update it * If recently set to seen, there's no need to update it
*/ */
Boolean cachedValue = groupSeenCache.getIfPresent(groupKey); Boolean cachedValue = groupSeenCache.getIfPresent(groupKey);
if (cachedValue != null && cachedValue == seen) { if (cachedValue != null && cachedValue == true) {
return; return;
} }
// query to find the group id from attribute/value // query to find the group id from attribute/value
String innerQuery = String.format("( SELECT group_id FROM " + GROUPS_TABLENAME String innerQuery = String.format("( SELECT group_id FROM " + GROUPS_TABLENAME //NON-NLS
+ " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d )", + " WHERE attribute = \'%s\' AND value = \'%s\' and data_source_obj_id = %d )", //NON-NLS
SleuthkitCase.escapeSingleQuotes(groupKey.getAttribute().attrName.toString()), SleuthkitCase.escapeSingleQuotes(groupKey.getAttribute().attrName.toString()),
SleuthkitCase.escapeSingleQuotes(groupKey.getValueDisplayName()), SleuthkitCase.escapeSingleQuotes(groupKey.getValueDisplayName()),
groupKey.getAttribute() == DrawableAttribute.PATH ? groupKey.getDataSourceObjId() : 0); groupKey.getAttribute() == DrawableAttribute.PATH ? groupKey.getDataSourceObjId() : 0);
String insertSQL = String.format(" (group_id, examiner_id, seen) VALUES (%s, %d, %d)", innerQuery, examinerID, seen ? 1 : 0); String insertSQL = String.format(" (group_id, examiner_id, seen) VALUES (%s, %d, %d)", innerQuery, examinerID, 1); //NON-NLS
if (DbType.POSTGRESQL == tskCase.getDatabaseType()) { if (DbType.POSTGRESQL == tskCase.getDatabaseType()) {
insertSQL += String.format(" ON CONFLICT (group_id, examiner_id) DO UPDATE SET seen = %d", seen ? 1 : 0); insertSQL += String.format(" ON CONFLICT (group_id, examiner_id) DO UPDATE SET seen = %d", 1); //NON-NLS
} }
tskCase.getCaseDbAccessManager().insertOrUpdate(GROUPS_SEEN_TABLENAME, insertSQL); tskCase.getCaseDbAccessManager().insertOrUpdate(GROUPS_SEEN_TABLENAME, insertSQL);
groupSeenCache.put(groupKey, seen); groupSeenCache.put(groupKey, true);
} }
/**
* Record in the DB that given group is unseen.
* The group is marked unseen for ALL examiners that have seen the group.
*
* @param groupKey key identifying the group.
*
* @throws TskCoreException
*/
public void markGroupUnseen(GroupKey<?> groupKey) throws TskCoreException {
/*
* Check the groupSeenCache to see if the seen status for this group was set recently.
* If recently set to unseen, there's no need to update it
*/
Boolean cachedValue = groupSeenCache.getIfPresent(groupKey);
if (cachedValue != null && cachedValue == false) {
return;
}
String updateSQL = String.format(" SET seen = 0 WHERE group_id in ( " + getGroupIdQuery(groupKey) + ")" ); //NON-NLS
tskCase.getCaseDbAccessManager().update(GROUPS_SEEN_TABLENAME, updateSQL);
groupSeenCache.put(groupKey, false);
}
/** /**
* Sets the isAnalysed flag in the groups table for the given group to true. * Sets the isAnalysed flag in the groups table for the given group to true.
* *

View File

@ -264,24 +264,23 @@ public class GroupManager {
} }
/** /**
* 'Save' the given group as seen in the drawable db. * Marks the given group as 'seen' by the current examiner, in drawable db.
* *
* @param group The DrawableGroup to mark as seen. * @param group The DrawableGroup to mark as seen.
* @param seen The seen state to set for the given group.
* *
* @return A ListenableFuture that encapsulates saving the seen state to the * @return A ListenableFuture that encapsulates saving the seen state to the
* DB. * DB.
* *
* *
*/ */
public ListenableFuture<?> markGroupSeen(DrawableGroup group, boolean seen) { public ListenableFuture<?> markGroupSeen(DrawableGroup group) {
return exec.submit(() -> { return exec.submit(() -> {
try { try {
Examiner examiner = controller.getSleuthKitCase().getCurrentExaminer(); Examiner examiner = controller.getSleuthKitCase().getCurrentExaminer();
getDrawableDB().markGroupSeen(group.getGroupKey(), seen, examiner.getId()); getDrawableDB().markGroupSeen(group.getGroupKey(), examiner.getId());
// only update and reshuffle if its new results // only update and reshuffle if its new results
if (group.isSeen() != seen) { if (group.isSeen() != true) {
group.setSeen(seen); group.setSeen(true);
updateUnSeenGroups(group); updateUnSeenGroups(group);
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
@ -290,6 +289,30 @@ public class GroupManager {
}); });
} }
/**
* Marks the given group as unseen in the drawable db.
*
* @param group The DrawableGroup.
*
* @return A ListenableFuture that encapsulates saving the seen state to the
* DB.
*/
public ListenableFuture<?> markGroupUnseen(DrawableGroup group) {
return exec.submit(() -> {
try {
getDrawableDB().markGroupUnseen(group.getGroupKey());
// only update and reshuffle if its new results
if (group.isSeen() != false) {
group.setSeen(false);
updateUnSeenGroups(group);
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error setting group: %s to unseen.", group.getGroupKey().getValue().toString()), ex); //NON-NLS
}
});
}
/** /**
* Update unseenGroups list accordingly based on the current status of * Update unseenGroups list accordingly based on the current status of
* 'group'. Removes it if it is seen or adds it if it is unseen. * 'group'. Removes it if it is seen or adds it if it is unseen.
@ -325,7 +348,7 @@ public class GroupManager {
// If we're grouping by category, we don't want to remove empty groups. // If we're grouping by category, we don't want to remove empty groups.
if (group.getFileIDs().isEmpty()) { if (group.getFileIDs().isEmpty()) {
markGroupSeen(group, true); markGroupSeen(group);
if (groupKey.getAttribute() != DrawableAttribute.CATEGORY) { if (groupKey.getAttribute() != DrawableAttribute.CATEGORY) {
if (analyzedGroups.contains(group)) { if (analyzedGroups.contains(group)) {
analyzedGroups.remove(group); analyzedGroups.remove(group);
@ -570,7 +593,7 @@ public class GroupManager {
// reset the seen status for the group (if it is currently considered analyzed) // reset the seen status for the group (if it is currently considered analyzed)
if (group != null) { if (group != null) {
markGroupSeen(group, false); markGroupUnseen(group);
} }
} }