Autopsy  4.18.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
PersonGroupingNode.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.Collections;
24 import java.util.EnumSet;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.logging.Level;
28 import java.util.stream.Collectors;
29 import javax.swing.Action;
30 import org.openide.nodes.ChildFactory;
31 import org.openide.nodes.Children;
32 import org.openide.nodes.Sheet;
33 import org.openide.util.NbBundle;
34 import org.openide.util.NbBundle.Messages;
35 import org.openide.util.WeakListeners;
36 import org.openide.util.lookup.Lookups;
43 import org.sleuthkit.datamodel.Host;
44 import org.sleuthkit.datamodel.Person;
45 import org.sleuthkit.datamodel.TskCoreException;
46 
51 @NbBundle.Messages(value = {"PersonNode_unknownPersonNode_title=Unknown Persons"})
53 
54  private static final String ICON_PATH = "org/sleuthkit/autopsy/images/person.png";
55 
60  public static String getUnknownPersonId() {
61  return Bundle.PersonNode_unknownPersonNode_title();
62  }
63 
67  private static class PersonChildren extends ChildFactory.Detachable<HostGrouping> {
68 
69  private static final Logger logger = Logger.getLogger(PersonChildren.class.getName());
70 
71  private static final Set<Case.Events> CHILD_EVENTS = EnumSet.of(
75 
76  private static final Set<String> CHILD_EVENTS_STR = CHILD_EVENTS.stream()
77  .map(ev -> ev.name())
78  .collect(Collectors.toSet());
79 
80  private final Person person;
81 
87  PersonChildren(Person person) {
88  this.person = person;
89  }
90 
94  private final PropertyChangeListener hostAddedDeletedPcl = new PropertyChangeListener() {
95  @Override
96  public void propertyChange(PropertyChangeEvent evt) {
97  String eventType = evt.getPropertyName();
98  if (eventType != null && CHILD_EVENTS_STR.contains(eventType)) {
99  refresh(true);
100  }
101  }
102  };
103 
104  @Override
105  protected void addNotify() {
106  Case.addEventTypeSubscriber(CHILD_EVENTS, hostAddedDeletedPcl);
107  }
108 
109  @Override
110  protected void removeNotify() {
111  Case.removeEventTypeSubscriber(CHILD_EVENTS, hostAddedDeletedPcl);
112  }
113 
114  @Override
116  return key == null ? null : new HostNode(key);
117  }
118 
119  @Override
120  protected boolean createKeys(List<HostGrouping> toPopulate) {
121  List<Host> hosts = Collections.emptyList();
122  try {
123  hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getPersonManager().getHostsForPerson(this.person);
124  } catch (NoCurrentCaseException | TskCoreException ex) {
125  String personName = person == null || person.getName() == null ? "<unknown>" : person.getName();
126  logger.log(Level.WARNING, String.format("Unable to get data sources for host: %s", personName), ex);
127  }
128 
129  toPopulate.addAll(hosts.stream()
130  .map(HostGrouping::new)
131  .sorted()
132  .collect(Collectors.toList()));
133 
134  return true;
135  }
136  }
137 
138  private final Person person;
139  private final Long personId;
140 
144  private final PropertyChangeListener personChangePcl = new PropertyChangeListener() {
145  @Override
146  public void propertyChange(PropertyChangeEvent evt) {
147  String eventType = evt.getPropertyName();
148  if (personId != null && eventType.equals(Case.Events.PERSONS_CHANGED.toString()) && evt instanceof PersonsChangedEvent) {
149  ((PersonsChangedEvent) evt).getNewValue().stream()
150  .filter(p -> p != null && p.getPersonId() == personId)
151  .findFirst()
152  .ifPresent((newPerson) -> {
153  setName(newPerson.getName());
154  setDisplayName(newPerson.getName());
155  });
156  }
157  }
158  };
159 
166  private static String getDisplayName(Person person) {
167  return (person == null || person.getName() == null)
168  ? getUnknownPersonId()
169  : person.getName();
170  }
171 
177  PersonGroupingNode(Person person) {
178  this(person, getDisplayName(person));
179  }
180 
187  private PersonGroupingNode(Person person, String displayName) {
188  super(Children.create(new PersonChildren(person), false),
189  person == null ? Lookups.fixed(displayName) : Lookups.fixed(person, displayName));
190  super.setName(displayName);
191  super.setDisplayName(displayName);
192  this.setIconBaseWithExtension(ICON_PATH);
193  this.person = person;
194  this.personId = person == null ? null : person.getPersonId();
196  WeakListeners.propertyChange(personChangePcl, this));
197  }
198 
199  @Override
200  public boolean isLeafTypeNode() {
201  return false;
202  }
203 
204  @Override
205  public String getItemType() {
206  return getClass().getName();
207  }
208 
209  @Override
210  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
211  return visitor.visit(this);
212  }
213 
214  @NbBundle.Messages({
215  "PersonGroupingNode_createSheet_nameProperty=Name",})
216  @Override
217  protected Sheet createSheet() {
218  Sheet sheet = Sheet.createDefault();
219  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
220  if (sheetSet == null) {
221  sheetSet = Sheet.createPropertiesSet();
222  sheet.put(sheetSet);
223  }
224 
225  sheetSet.put(new NodeProperty<>("Name", Bundle.PersonGroupingNode_createSheet_nameProperty(), "", getDisplayName())); //NON-NLS
226 
227  return sheet;
228  }
229 
230  @Override
231  @Messages({"PersonGroupingNode_actions_rename=Rename Person...",
232  "PersonGroupingNode_actions_delete=Delete Person"})
233  public Action[] getActions(boolean context) {
234  if (this.person == null) {
235  return new Action[0];
236  } else {
237  return new Action[]{
238  new EditPersonAction(this.person),
239  new DeletePersonAction(this.person),
240  null
241  };
242  }
243  }
244 }
PersonGroupingNode(Person person, String displayName)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:658
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:703

Copyright © 2012-2021 Basis Technology. Generated on: Wed Jun 2 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.