root factory work

This commit is contained in:
Greg DiCristofaro 2022-02-23 15:27:26 -05:00
parent 44e31cdc56
commit 9c9c8265d3
3 changed files with 147 additions and 53 deletions

View File

@ -30,6 +30,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.mainui.datamodel.TreeResultsDTO.TreeDisplayCount;
import org.sleuthkit.autopsy.mainui.datamodel.TreeResultsDTO.TreeItemDTO;
import org.sleuthkit.autopsy.mainui.datamodel.events.DAOEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.HostPersonEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.TreeEvent;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.Person;
@ -106,31 +107,26 @@ public class HostPersonDAO extends AbstractDAO {
person.getName(),
TreeDisplayCount.NOT_SHOWN);
}
private static final Set<String> caseEvents = Stream.of(
Case.Events.PERSONS_ADDED,
Case.Events.PERSONS_DELETED,
Case.Events.PERSONS_UPDATED,
Case.Events.HOSTS_ADDED,
Case.Events.HOSTS_ADDED_TO_PERSON,
Case.Events.HOSTS_DELETED,
Case.Events.HOSTS_REMOVED_FROM_PERSON,
Case.Events.HOSTS_UPDATED
)
.map(caseEvent -> caseEvent.toString())
.collect(Collectors.toSet());
@Override
Set<? extends DAOEvent> processEvent(PropertyChangeEvent evt) {
// GVDTODO
String eventName = evt.getPropertyName();
if (Case.Events.PERSONS_ADDED.toString().equals(eventName)) {
} else if (Case.Events.PERSONS_DELETED.toString().equals(eventName)) {
} else if (Case.Events.PERSONS_UPDATED.toString().equals(eventName)) {
} else if (Case.Events.HOSTS_ADDED.toString().equals(eventName)) {
} else if (Case.Events.HOSTS_ADDED_TO_PERSON.toString().equals(eventName)) {
} else if (Case.Events.HOSTS_DELETED.toString().equals(eventName)) {
} else if (Case.Events.HOSTS_REMOVED_FROM_PERSON.toString().equals(eventName)) {
} else if (Case.Events.HOSTS_UPDATED.toString().equals(eventName)) {
}
// if (CaseEvent.DATA_ADDED.toString().equals(eventName)
// && (evt.getOldValue() instanceof ModuleDataEvent)) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return caseEvents.contains(evt.getPropertyName())
? Collections.singleton(new HostPersonEvent())
: Collections.emptySet();
}
@Override

View File

@ -0,0 +1,30 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 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.mainui.datamodel.events;
/**
* An event that hosts or persons were changed.
*/
public class HostPersonEvent implements DAOEvent {
@Override
public Type getType() {
return Type.TREE;
}
}

View File

@ -18,68 +18,108 @@
*/
package org.sleuthkit.autopsy.mainui.nodes;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages;
import org.openide.util.WeakListeners;
import org.sleuthkit.autopsy.casemodule.CasePreferences;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.mainui.datamodel.HostSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.MainDAO;
import org.sleuthkit.autopsy.mainui.datamodel.OsAccountsSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.PersonSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.ReportsSearchParams;
import org.sleuthkit.autopsy.mainui.datamodel.TreeResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.TreeResultsDTO.TreeItemDTO;
import org.sleuthkit.autopsy.mainui.datamodel.events.DAOAggregateEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.DAOEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.HostPersonEvent;
import org.sleuthkit.autopsy.mainui.datamodel.events.TreeEvent;
import org.sleuthkit.autopsy.mainui.nodes.TreeNode.StaticTreeNode;
import static org.sleuthkit.autopsy.mainui.nodes.TreeNode.getDefaultLookup;
import org.sleuthkit.datamodel.Person;
/**
*
* Root tree view factories.
*/
@Messages({"RootFactory_unknownPersons_displayName=Unknown Persons"})
public class RootFactory {
public Children getRootChildren() {
// GVDTODO integrate
if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) {
return Children.create(new HostPersonRootFactory(), true);
} else {
return new DefaultViewRootFactory();
}
}
private static String getLongString(Long l) {
return l == null ? "" : l.toString();
}
public static class HostPersonRootFactory extends TreeChildFactory<PersonSearchParams> {
/**
* Factory for populating child nodes in a tree based on TreeResultsDTO
*/
static class HostPersonRootFactory extends ChildFactory.Detachable<TreeItemDTO<?>> {
private static final Logger logger = Logger.getLogger(HostPersonRootFactory.class.getName());
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
if (evt.getNewValue() instanceof DAOAggregateEvent) {
for (DAOEvent daoEvt : ((DAOAggregateEvent) evt.getNewValue()).getEvents()) {
if (daoEvt instanceof HostPersonEvent) {
HostPersonRootFactory.this.refresh(false);
return;
}
}
}
};
private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, MainDAO.getInstance().getTreeEventsManager());
@Override
protected TreeNode<PersonSearchParams> createNewNode(TreeResultsDTO.TreeItemDTO<? extends PersonSearchParams> rowData) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
protected boolean createKeys(List<TreeItemDTO<?>> toPopulate) {
try {
TreeResultsDTO<? extends PersonSearchParams> persons = MainDAO.getInstance().getHostPersonDAO().getAllPersons();
if (persons.getItems().isEmpty() || (persons.getItems().size() == 1 && persons.getItems().get(0).getSearchParams().getPerson() == null)) {
toPopulate.addAll(MainDAO.getInstance().getHostPersonDAO().getAllHosts().getItems());
} else {
toPopulate.addAll(persons.getItems());
}
} catch (ExecutionException | IllegalArgumentException ex) {
logger.log(Level.WARNING, "Error acquiring top-level host/person data", ex);
}
return true;
}
@Override
protected TreeResultsDTO<? extends PersonSearchParams> getChildResults() throws IllegalArgumentException, ExecutionException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
protected Node createNodeForKey(TreeItemDTO<?> key) {
if (key.getSearchParams() instanceof HostSearchParams) {
return new HostNode((TreeItemDTO<? extends HostSearchParams>) key);
} else if (key.getSearchParams() instanceof PersonSearchParams) {
return new PersonNode((TreeItemDTO<? extends PersonSearchParams>) key);
} else {
return null;
}
}
@Override
protected TreeResultsDTO.TreeItemDTO<? extends PersonSearchParams> getOrCreateRelevantChild(TreeEvent treeEvt) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public int compare(TreeResultsDTO.TreeItemDTO<? extends PersonSearchParams> o1, TreeResultsDTO.TreeItemDTO<? extends PersonSearchParams> o2) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static class DefaultViewRootFactory extends Children.Array {
public DefaultViewRootFactory() {
super(Arrays.asList(
new AllDataSourcesNode(),
@ -92,15 +132,27 @@ public class RootFactory {
));
}
}
@Messages({"RootFactory_AllDataSourcesNode_displayName=Data Sources"})
public static class AllDataSourcesNode extends StaticTreeNode {
public AllDataSourcesNode() {
super("ALL_DATA_SOURCES",
Bundle.RootFactory_AllDataSourcesNode_displayName(),
"org/sleuthkit/autopsy/images/image.png",
new HostFactory(Optional.empty()));
}
}
}
public static class PersonNode extends TreeNode<PersonSearchParams> {
public PersonNode(TreeResultsDTO.TreeItemDTO<? extends PersonSearchParams> itemData) {
super(PersonSearchParams.getTypeId(),
"org/sleuthkit/autopsy/images/person.png",
itemData,
Children.create(new HostFactory(Optional.of(itemData.getSearchParams().getPerson())), true),
getDefaultLookup(itemData));
}
}
public static class HostFactory extends TreeChildFactory<HostSearchParams> {
@ -113,7 +165,7 @@ public class RootFactory {
@Override
protected TreeNode<HostSearchParams> createNewNode(TreeResultsDTO.TreeItemDTO<? extends HostSearchParams> rowData) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return new HostNode(rowData);
}
@Override
@ -125,24 +177,40 @@ public class RootFactory {
}
}
@Override
protected void handleDAOAggregateEvent(DAOAggregateEvent aggEvt) {
for (DAOEvent evt : aggEvt.getEvents()) {
if (evt instanceof HostPersonEvent) {
super.update();
return;
}
}
}
@Override
protected TreeResultsDTO.TreeItemDTO<? extends HostSearchParams> getOrCreateRelevantChild(TreeEvent treeEvt) {
// GVDTODO
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return null;
}
@Override
public int compare(TreeResultsDTO.TreeItemDTO<? extends HostSearchParams> o1, TreeResultsDTO.TreeItemDTO<? extends HostSearchParams> o2) {
return Comparator.comparing((TreeResultsDTO.TreeItemDTO<? extends HostSearchParams> h) -> h.getSearchParams().getHost().getName()).compare(o1, o2);
}
}
public static class HostNode extends TreeNode<HostSearchParams> {
public HostNode(TreeResultsDTO.TreeItemDTO<? extends HostSearchParams> itemData) {
super(HostSearchParams.getTypeId(),
"org/sleuthkit/autopsy/images/host.png",
itemData,
Children.create(new FileSystemFactory(itemData.getSearchParams().getHost()), true),
getDefaultLookup(itemData));
}
}
public static class DataSourceGroupedNode extends StaticTreeNode {
public DataSourceGroupedNode(long dataSourceObjId, String dsName, boolean isImage) {
super("DATA_SOURCE_GROUPED_" + dataSourceObjId,
dsName,
@ -199,7 +267,7 @@ public class RootFactory {
new DataArtifactTypeFactory(dataSourceObjId));
}
}
@Messages({"RootFactory_AnalysisResultsRootNode_displayName=Analysis Results"})
public static class AnalysisResultsRootNode extends StaticTreeNode {
@ -220,7 +288,7 @@ public class RootFactory {
super("DATA_SOURCE_BY_TYPE_" + getLongString(dataSourceObjId),
Bundle.RootFactory_OsAccountsRootNode_displayName(),
"org/sleuthkit/autopsy/images/os-account.png");
this.dataSourceObjId = dataSourceObjId;
}
@ -228,12 +296,12 @@ public class RootFactory {
public void respondSelection(DataResultTopComponent dataResultPanel) {
dataResultPanel.displayOsAccounts(new OsAccountsSearchParams(dataSourceObjId));
}
}
@Messages({"RootFactory_TagsRootNode_displayName=Tags"})
public static class TagsRootNode extends StaticTreeNode {
public TagsRootNode(Long dataSourceObjId) {
super("DATA_SOURCE_BY_TYPE_" + getLongString(dataSourceObjId),
Bundle.RootFactory_TagsRootNode_displayName(),