mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
first draft
This commit is contained in:
parent
583400b73d
commit
6853f79bcc
@ -23,13 +23,18 @@ import java.beans.PropertyChangeListener;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.nodes.ChildFactory;
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
import org.sleuthkit.autopsy.casemodule.CasePreferences;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
@ -39,7 +44,6 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
|||||||
import org.sleuthkit.datamodel.SleuthkitVisitableItem;
|
import org.sleuthkit.datamodel.SleuthkitVisitableItem;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Child factory to create the top level children of the autopsy tree
|
* Child factory to create the top level children of the autopsy tree
|
||||||
*
|
*
|
||||||
@ -55,8 +59,8 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
|||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
String eventType = evt.getPropertyName();
|
String eventType = evt.getPropertyName();
|
||||||
if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString()) &&
|
if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())
|
||||||
Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
&& Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||||
refreshChildren();
|
refreshChildren();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,6 +78,78 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
|||||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), pcl);
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), pcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private DataSource getDs(List<DataSource> dataSources, int idx) {
|
||||||
|
return dataSources.get(idx % dataSources.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private OwnerHostTree getTree(SleuthkitCase tskCase) throws TskCoreException {
|
||||||
|
List<DataSource> dataSources = tskCase.getDataSources();
|
||||||
|
if (CollectionUtils.isEmpty(dataSources)) {
|
||||||
|
return new OwnerHostTree(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OwnerHostTree(
|
||||||
|
Arrays.asList(
|
||||||
|
new Owner("Owner1", Arrays.asList(
|
||||||
|
new Host("Host1.1", Arrays.asList(getDs(dataSources, 0), getDs(dataSources, 1))),
|
||||||
|
new Host("Host1.2", Collections.emptyList())),
|
||||||
|
Arrays.asList(getDs(dataSources,2))
|
||||||
|
),
|
||||||
|
new Owner("Owner1", Arrays.asList(
|
||||||
|
new Host("Host1.1", Arrays.asList(getDs(dataSources, 0), getDs(dataSources, 1))),
|
||||||
|
new Host("Host2.3", Collections.emptyList())),
|
||||||
|
Arrays.asList(getDs(dataSources,3))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Arrays.asList(
|
||||||
|
new Host("Host0.1", Arrays.asList(getDs(dataSources, 4))),
|
||||||
|
new Host("Host0.2", Arrays.asList(getDs(dataSources, 5)))
|
||||||
|
),
|
||||||
|
Arrays.asList(getDs(dataSources, 6), getDs(dataSources, 7))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Object> getNodes(OwnerHostTree tree) {
|
||||||
|
List<Owner> owners = (tree == null) ? null : tree.getOwners();
|
||||||
|
List<Host> hosts = (tree == null) ? null : tree.getHosts();
|
||||||
|
List<DataSource> dataSources = (tree == null) ? null : tree.getDataSources();
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(owners)) {
|
||||||
|
List<Object> toReturn = owners.stream()
|
||||||
|
.filter(o -> o != null)
|
||||||
|
.sorted((a, b) -> StringUtils.compareIgnoreCase(a.getName(), b.getName()))
|
||||||
|
.map(o -> new OwnerNode(o))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(hosts) || CollectionUtils.isNotEmpty(dataSources)) {
|
||||||
|
toReturn.add(OwnerNode.getUnknownOwner(hosts, dataSources));
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
} else if (CollectionUtils.isNotEmpty(hosts)) {
|
||||||
|
List<Object> toReturn = hosts.stream()
|
||||||
|
.filter(h -> h != null)
|
||||||
|
.sorted((a, b) -> StringUtils.compareIgnoreCase(a.getName(), b.getName()))
|
||||||
|
.map(h -> new HostNode(h))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(dataSources)) {
|
||||||
|
toReturn.add(HostNode.getUnknownHost(dataSources));
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
} else {
|
||||||
|
Stream<DataSource> dataSourceSafe = dataSources == null ? Stream.empty() : dataSources.stream();
|
||||||
|
return dataSourceSafe
|
||||||
|
.filter(d -> d != null)
|
||||||
|
.sorted((a, b) -> StringUtils.compareIgnoreCase(a.getName(), b.getName()))
|
||||||
|
.map(d -> new DataSourceGroupingNode(d))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates keys for the top level children.
|
* Creates keys for the top level children.
|
||||||
*
|
*
|
||||||
@ -82,28 +158,11 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean createKeys(List<Object> list) {
|
protected boolean createKeys(List<Object> list) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
|
||||||
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
|
||||||
List<DataSource> dataSources = tskCase.getDataSources();
|
list.addAll(getNodes(getTree(tskCase)));
|
||||||
|
|
||||||
Collections.sort(dataSources, new Comparator<DataSource>() {
|
|
||||||
@Override
|
|
||||||
public int compare(DataSource dataS1, DataSource dataS2) {
|
|
||||||
String dataS1Name = dataS1.getName().toLowerCase();
|
|
||||||
String dataS2Name = dataS2.getName().toLowerCase();
|
|
||||||
return dataS1Name.compareTo(dataS2Name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<DataSourceGrouping> keys = new ArrayList<>();
|
|
||||||
dataSources.forEach((datasource) -> {
|
|
||||||
keys.add(new DataSourceGrouping(datasource));
|
|
||||||
});
|
|
||||||
list.addAll(keys);
|
|
||||||
|
|
||||||
list.add(new Reports());
|
list.add(new Reports());
|
||||||
} else {
|
} else {
|
||||||
List<AutopsyVisitableItem> keys = new ArrayList<>(Arrays.asList(
|
List<AutopsyVisitableItem> keys = new ArrayList<>(Arrays.asList(
|
||||||
@ -115,7 +174,6 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
|||||||
|
|
||||||
list.addAll(keys);
|
list.addAll(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
logger.log(Level.SEVERE, "Error getting datas sources list from the database.", tskCoreException);
|
logger.log(Level.SEVERE, "Error getting datas sources list from the database.", tskCoreException);
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
@ -138,8 +196,7 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
|||||||
return ((SleuthkitVisitableItem) key).accept(new CreateSleuthkitNodeVisitor());
|
return ((SleuthkitVisitableItem) key).accept(new CreateSleuthkitNodeVisitor());
|
||||||
} else if (key instanceof AutopsyVisitableItem) {
|
} else if (key instanceof AutopsyVisitableItem) {
|
||||||
return ((AutopsyVisitableItem) key).accept(new RootContentChildren.CreateAutopsyNodeVisitor());
|
return ((AutopsyVisitableItem) key).accept(new RootContentChildren.CreateAutopsyNodeVisitor());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
logger.log(Level.SEVERE, "Unknown key type ", key.getClass().getName());
|
logger.log(Level.SEVERE, "Unknown key type ", key.getClass().getName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -150,5 +207,180 @@ public final class AutopsyTreeChildFactory extends ChildFactory.Detachable<Objec
|
|||||||
*/
|
*/
|
||||||
public void refreshChildren() {
|
public void refreshChildren() {
|
||||||
refresh(true);
|
refresh(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Owner {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final List<Host> hosts;
|
||||||
|
private final List<DataSource> dataSources;
|
||||||
|
|
||||||
|
public Owner(String name, List<Host> hosts, List<DataSource> dataSources) {
|
||||||
|
this.name = name;
|
||||||
|
this.hosts = hosts;
|
||||||
|
this.dataSources = dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Host> getHosts() {
|
||||||
|
return hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DataSource> getDataSources() {
|
||||||
|
return dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Host {
|
||||||
|
private final String name;
|
||||||
|
private final List<DataSource> dataSources;
|
||||||
|
|
||||||
|
public Host(String name, List<DataSource> dataSources) {
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.dataSources = (dataSources == null) ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<DataSource>(dataSources));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DataSource> getDataSources() {
|
||||||
|
return this.dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"HostNode_unknownHostNode_title=Unknown Host"
|
||||||
|
})
|
||||||
|
static class HostNode extends DisplayableItemNode {
|
||||||
|
|
||||||
|
public static HostNode getUnknownHost(List<DataSource> dataSources) {
|
||||||
|
return new HostNode(null, dataSources);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static RootContentChildren getChildren(List<DataSource> dataSources) {
|
||||||
|
Stream<DataSourceGroupingNode> dsNodes = (dataSources == null)
|
||||||
|
? Stream.empty()
|
||||||
|
: dataSources.stream()
|
||||||
|
.filter(ds -> ds != null)
|
||||||
|
.sorted((a, b) -> StringUtils.compareIgnoreCase(a.getName(), b.getName()))
|
||||||
|
.map(d -> new DataSourceGroupingNode(d));
|
||||||
|
|
||||||
|
return new RootContentChildren(dsNodes.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private HostNode(Host host, List<DataSource> dataSources) {
|
||||||
|
super(getChildren(dataSources), host == null ? null : Lookups.singleton(host));
|
||||||
|
String safeName = (host == null || host.getName() == null) ? Bundle.HostNode_getUnknownHostNode_title() : host.getName();
|
||||||
|
super.setName(safeName);
|
||||||
|
super.setDisplayName(safeName);
|
||||||
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/image.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
HostNode(Host host) {
|
||||||
|
this(host, host == null ? null : host.getDataSources());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLeafTypeNode() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
|
||||||
|
return visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemType() {
|
||||||
|
return getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class OwnerHostTree {
|
||||||
|
|
||||||
|
private final List<Owner> owners;
|
||||||
|
private final List<Host> hosts;
|
||||||
|
private final List<DataSource> dataSources;
|
||||||
|
|
||||||
|
public OwnerHostTree(List<Owner> owners, List<Host> hosts, List<DataSource> dataSources) {
|
||||||
|
this.owners = owners;
|
||||||
|
this.hosts = hosts;
|
||||||
|
this.dataSources = dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Owner> getOwners() {
|
||||||
|
return owners;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Host> getHosts() {
|
||||||
|
return hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DataSource> getDataSources() {
|
||||||
|
return dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"OwnerNode_unknownHostNode_title=Unknown Owner"
|
||||||
|
})
|
||||||
|
static class OwnerNode extends DisplayableItemNode {
|
||||||
|
|
||||||
|
public static OwnerNode getUnknownOwner(List<Host> hosts, List<DataSource> dataSources) {
|
||||||
|
return new OwnerNode(null, hosts, dataSources);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RootContentChildren getChildren(List<Host> hosts, List<DataSource> dataSources) {
|
||||||
|
List<HostNode> childNodes = (hosts == null)
|
||||||
|
? Collections.emptyList()
|
||||||
|
: hosts.stream()
|
||||||
|
.filter(h -> h != null)
|
||||||
|
.sorted((a, b) -> StringUtils.compareIgnoreCase(a.getName(), b.getName()))
|
||||||
|
.map(h -> new HostNode(h))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(hosts)) {
|
||||||
|
childNodes.add(HostNode.getUnknownHost(dataSources));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RootContentChildren(childNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnerNode(Owner owner) {
|
||||||
|
this(owner, (owner != null) ? owner.getHosts() : null, (owner != null) ? owner.getDataSources() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnerNode(Owner owner, List<Host> hosts, List<DataSource> dataSources) {
|
||||||
|
super(getChildren(hosts, dataSources), Lookups.singleton(owner));
|
||||||
|
String safeName = (owner == null || owner.getName() == null) ? Bundle.OwnerNode_unknownHostNode_title() : owner.getName();
|
||||||
|
super.setName(safeName);
|
||||||
|
super.setDisplayName(safeName);
|
||||||
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/image.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLeafTypeNode() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
|
||||||
|
return visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItemType() {
|
||||||
|
return getClass().getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -193,6 +193,10 @@ public interface DisplayableItemNodeVisitor<T> {
|
|||||||
*/
|
*/
|
||||||
T visit(AttachmentNode node);
|
T visit(AttachmentNode node);
|
||||||
|
|
||||||
|
T visit(AutopsyTreeChildFactory.OwnerNode aThis);
|
||||||
|
|
||||||
|
T visit(AutopsyTreeChildFactory.HostNode aThis);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor with an implementable default behavior for all types. Override
|
* Visitor with an implementable default behavior for all types. Override
|
||||||
* specific visit types to not use the default behavior.
|
* specific visit types to not use the default behavior.
|
||||||
@ -540,5 +544,14 @@ public interface DisplayableItemNodeVisitor<T> {
|
|||||||
return defaultVisit(node);
|
return defaultVisit(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T visit(AutopsyTreeChildFactory.HostNode node) {
|
||||||
|
return defaultVisit(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T visit(AutopsyTreeChildFactory.OwnerNode node) {
|
||||||
|
return defaultVisit(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user