19 package org.sleuthkit.autopsy.contentviewers.artifactviewers;
21 import java.awt.Component;
22 import java.awt.GridBagConstraints;
23 import java.awt.GridBagLayout;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
31 import java.util.logging.Level;
32 import javax.swing.JScrollPane;
33 import org.apache.commons.lang3.ObjectUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.openide.util.NbBundle;
36 import org.openide.util.lookup.ServiceProvider;
51 @ServiceProvider(service = ArtifactContentViewer.class)
55 private static final long serialVersionUID = 1L;
57 private static final Set<Integer> HANDLED_ATTRIBUTE_TYPES =
new HashSet<Integer>(Arrays.asList(
58 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID(),
59 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO.getTypeID(),
60 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM.getTypeID(),
61 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID.getTypeID(),
62 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION.getTypeID(),
63 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
64 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(),
65 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()
68 private GridBagLayout m_gridBagLayout =
new GridBagLayout();
69 private GridBagConstraints m_constraints =
new GridBagConstraints();
71 private PersonaAccountFetcher currentAccountFetcher = null;
85 @SuppressWarnings(
"unchecked")
87 private
void initComponents() {
89 setLayout(
new java.awt.GridBagLayout());
96 if (artifact == null) {
100 CallLogViewData callLogViewData = null;
102 callLogViewData = getCallLogViewData(artifact);
103 }
catch (TskCoreException ex) {
104 logger.log(Level.SEVERE, String.format(
"Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
108 if (callLogViewData != null) {
109 List<AccountPersonaSearcherData> personaSearchDataList = updateView(callLogViewData);
110 if (!personaSearchDataList.isEmpty()) {
111 currentAccountFetcher =
new PersonaAccountFetcher(artifact, personaSearchDataList,
this);
112 currentAccountFetcher.execute();
114 currentAccountFetcher = null;
132 if (artifact == null) {
136 BlackboardAttribute directionAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION));
137 BlackboardAttribute toAccountAttr = null;
138 BlackboardAttribute fromAccountAttr = null;
139 BlackboardAttribute localAccountAttr = null;
141 CallLogViewData callLogViewData = null;
143 String direction = null;
144 String fromAccountIdentifier = null;
145 String toAccountIdentifier = null;
146 List<String> otherParties = null;
147 List<String> toContactNames = null;
148 List<String> fromContactNames = null;
150 Content dataSource = artifact.getDataSource();
151 String deviceId = ((DataSource) dataSource).getDeviceId();
153 if (directionAttr != null) {
154 direction = directionAttr.getValueString();
155 if (direction.equalsIgnoreCase(
"Incoming")) {
156 fromAccountAttr = ObjectUtils.firstNonNull(
157 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)),
158 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
159 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID))
162 toAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO));
163 localAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO));
164 }
else if (direction.equalsIgnoreCase(
"Outgoing")) {
165 toAccountAttr = ObjectUtils.firstNonNull(
166 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)),
167 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
168 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID))
171 fromAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM));
172 localAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM));
177 if (fromAccountAttr == null) {
178 fromAccountAttr = ObjectUtils.firstNonNull(
179 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)),
180 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)),
181 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
182 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID))
188 if (fromAccountAttr != null) {
189 String fromAccountAttrValue = fromAccountAttr.getValueString();
190 if (fromAccountAttrValue.equalsIgnoreCase(deviceId) ==
false) {
191 fromAccountIdentifier = fromAccountAttrValue;
196 if (toAccountAttr != null) {
198 String[] numbers = toAccountAttr.getValueString().split(
",");
199 String toAccountAttrValue = StringUtils.trim(numbers[0]);
200 if (toAccountAttrValue.equalsIgnoreCase(deviceId) ==
false) {
201 toAccountIdentifier = toAccountAttrValue;
207 if (numbers.length > 1) {
208 otherParties =
new ArrayList<>();
209 for (
int i = 1; i < numbers.length; i++) {
210 otherParties.add(StringUtils.trim(numbers[i]));
216 if (null != fromAccountAttr || null != toAccountAttr) {
217 callLogViewData =
new CallLogViewData(fromAccountIdentifier, toAccountIdentifier);
218 callLogViewData.setDirection(direction);
220 callLogViewData.setOtherParties(otherParties);
222 extractTimeAndDuration(artifact, callLogViewData);
224 callLogViewData.setDataSourceName(dataSource.getName());
227 if (localAccountAttr != null) {
228 String attrValue = localAccountAttr.getValueString();
230 if (attrValue.equalsIgnoreCase(deviceId) ==
false && attrValue.contains(
",") ==
false) {
231 callLogViewData.setLocalAccountId(attrValue);
235 callLogViewData.setOtherAttributes(extractOtherAttributes(artifact));
237 callLogViewData.setFromContactNameList(fromContactNames);
238 callLogViewData.setToContactNameList(toContactNames);
241 return callLogViewData;
254 private void extractTimeAndDuration(BlackboardArtifact artifact, CallLogViewData callLogViewData)
throws TskCoreException {
256 BlackboardAttribute startTimeAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START));
257 if (startTimeAttr == null) {
258 startTimeAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
260 if (startTimeAttr != null) {
261 long startTime = startTimeAttr.getValueLong();
262 callLogViewData.setDateTimeStr(startTimeAttr.getDisplayString());
264 BlackboardAttribute endTimeAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END));
265 if (endTimeAttr != null) {
266 long endTime = endTimeAttr.getValueLong();
267 if (endTime > 0 && (endTime - startTime) > 0) {
268 callLogViewData.setDuration(String.format(
"%d seconds", (endTime - startTime)));
285 List<BlackboardAttribute> attributes = artifact.getAttributes();
286 Map<String, String> otherAttributes =
new HashMap<>();
288 for (BlackboardAttribute attr : attributes) {
289 if (HANDLED_ATTRIBUTE_TYPES.contains(attr.getAttributeType().getTypeID()) ==
false) {
290 otherAttributes.put(attr.getAttributeType().getDisplayName(), attr.getDisplayString());
294 return otherAttributes;
305 "CallLogArtifactViewer_heading_parties=Parties",
306 "CallLogArtifactViewer_value_unknown=Unknown",
307 "CallLogArtifactViewer_label_from=From",
308 "CallLogArtifactViewer_label_to=To"
310 private List<AccountPersonaSearcherData>
updateView(CallLogViewData callLogViewData) {
312 CommunicationArtifactViewerHelper.addHeader(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_parties());
314 List<AccountPersonaSearcherData> dataList =
new ArrayList<>();
316 if (callLogViewData.getFromAccount() != null) {
317 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_from());
320 String accountDisplayString = getAccountDisplayString(callLogViewData.getFromAccount(), callLogViewData);
321 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, accountDisplayString);
323 List<String> contactNames = callLogViewData.getFromContactNameList();
324 for (String name : contactNames) {
325 CommunicationArtifactViewerHelper.addContactRow(
this, m_gridBagLayout, m_constraints, name);
329 dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(
this, m_gridBagLayout,
this.m_constraints, callLogViewData.getFromAccount()));
333 if (callLogViewData.getToAccount() != null) {
334 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_to());
335 String accountDisplayString = getAccountDisplayString(callLogViewData.getToAccount(), callLogViewData);
336 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, accountDisplayString);
338 List<String> contactNames = callLogViewData.getToContactNameList();
339 for (String name : contactNames) {
340 CommunicationArtifactViewerHelper.addContactRow(
this, m_gridBagLayout, m_constraints, name);
343 dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(
this, m_gridBagLayout,
this.m_constraints, callLogViewData.getToAccount()));
348 for (String otherParty : callLogViewData.getOtherParties()) {
349 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_to());
350 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, otherParty);
352 dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(
this, m_gridBagLayout,
this.m_constraints, otherParty));
355 updateMetadataView(callLogViewData);
357 updateOtherAttributesView(callLogViewData);
359 updateSourceView(callLogViewData);
362 showCRDisabledMessage();
365 CommunicationArtifactViewerHelper.addPageEndGlue(
this, m_gridBagLayout, this.m_constraints);
367 this.setLayout(m_gridBagLayout);
380 "CallLogArtifactViewer_heading_metadata=Metadata",
381 "CallLogArtifactViewer_label_direction=Direction",
382 "CallLogArtifactViewer_label_date=Date",
383 "CallLogArtifactViewer_label_duration=Duration"
387 CommunicationArtifactViewerHelper.addHeader(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_metadata());
389 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_direction());
390 if (callLogViewData.getDirection() != null) {
391 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDirection());
393 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_value_unknown());
396 if (callLogViewData.getDateTimeStr() != null) {
397 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_date());
398 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDateTimeStr());
401 if (callLogViewData.getDuration() != null) {
402 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_duration());
403 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDuration());
414 "CallLogArtifactViewer_heading_Source=Source",
415 "CallLogArtifactViewer_label_datasource=Data Source",})
417 CommunicationArtifactViewerHelper.addHeader(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_Source());
418 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource());
419 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
428 "CallLogArtifactViewer_heading_others=Other Attributes"
432 if (callLogViewData.getOtherAttributes().isEmpty()) {
435 CommunicationArtifactViewerHelper.addHeader(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_others());
437 for (Map.Entry<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
438 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, entry.getKey());
439 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, entry.getValue());
444 "CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
447 CommunicationArtifactViewerHelper.addBlankLine(
this, m_gridBagLayout, m_constraints);
448 m_constraints.gridy++;
449 CommunicationArtifactViewerHelper.addMessageRow(
this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
450 m_constraints.gridy++;
464 "CallLogArtifactViewer_suffix_local=(Local)",})
466 String accountDisplayValue = accountIdentifier;
467 if (callLogViewDataNew.getLocalAccountId() != null && callLogViewDataNew.getLocalAccountId().equalsIgnoreCase(accountIdentifier)) {
468 accountDisplayValue +=
" " + Bundle.CallLogArtifactViewer_suffix_local();
470 return accountDisplayValue;
475 return new JScrollPane(
this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
481 return (artifact != null)
482 && (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID());
491 if (currentAccountFetcher != null && !currentAccountFetcher.isDone()) {
492 currentAccountFetcher.cancel(
true);
493 currentAccountFetcher = null;
498 this.setLayout(null);
500 m_gridBagLayout =
new GridBagLayout();
501 m_constraints =
new GridBagConstraints();
503 m_constraints.anchor = GridBagConstraints.FIRST_LINE_START;
504 m_constraints.gridy = 0;
505 m_constraints.gridx = 0;
506 m_constraints.weighty = 0.0;
507 m_constraints.weightx = 0.0;
508 m_constraints.insets =
new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
509 m_constraints.fill = GridBagConstraints.NONE;
boolean isSupported(BlackboardArtifact artifact)
CallLogViewData getCallLogViewData(BlackboardArtifact artifact)
void extractTimeAndDuration(BlackboardArtifact artifact, CallLogViewData callLogViewData)
void updateMetadataView(CallLogViewData callLogViewData)
List< AccountPersonaSearcherData > updateView(CallLogViewData callLogViewData)
void updateSourceView(CallLogViewData callLogViewData)
String getAccountDisplayString(String accountIdentifier, CallLogViewData callLogViewDataNew)
void showCRDisabledMessage()
void updateOtherAttributesView(CallLogViewData callLogViewData)
Map< String, String > extractOtherAttributes(BlackboardArtifact artifact)
void setArtifact(BlackboardArtifact artifact)
synchronized static Logger getLogger(String name)
static boolean isEnabled()