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.awt.Insets;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
32 import java.util.logging.Level;
33 import javax.swing.JScrollPane;
34 import javax.swing.border.EmptyBorder;
35 import org.apache.commons.lang3.ObjectUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.openide.util.NbBundle;
38 import org.openide.util.lookup.ServiceProvider;
54 @ServiceProvider(service = ArtifactContentViewer.class)
58 private static final long serialVersionUID = 1L;
60 private static final Set<Integer> HANDLED_ATTRIBUTE_TYPES =
new HashSet<Integer>(Arrays.asList(
61 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID(),
62 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO.getTypeID(),
63 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM.getTypeID(),
64 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID.getTypeID(),
65 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION.getTypeID(),
66 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
67 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID(),
68 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()
71 private GridBagLayout m_gridBagLayout =
new GridBagLayout();
72 private GridBagConstraints m_constraints =
new GridBagConstraints();
74 private PersonaAccountFetcher currentAccountFetcher = null;
89 @SuppressWarnings(
"unchecked")
91 private
void initComponents() {
93 setLayout(
new java.awt.GridBagLayout());
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);
106 List<AccountPersonaSearcherData> personaSearchDataList =
new ArrayList<>();
108 if (callLogViewData != null) {
109 personaSearchDataList.addAll(updateView(callLogViewData));
112 if (!personaSearchDataList.isEmpty()) {
113 currentAccountFetcher =
new PersonaAccountFetcher(artifact, personaSearchDataList,
this);
114 currentAccountFetcher.execute();
116 currentAccountFetcher = null;
135 if (artifact == null) {
139 BlackboardAttribute directionAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION));
140 BlackboardAttribute toAccountAttr = null;
141 BlackboardAttribute fromAccountAttr = null;
142 BlackboardAttribute localAccountAttr = null;
144 CallLogViewData callLogViewData = null;
146 String direction = null;
147 String fromAccountIdentifier = null;
148 String toAccountIdentifier = null;
149 List<String> otherParties = null;
150 List<String> toContactNames = null;
151 List<String> fromContactNames = null;
153 Content dataSource = artifact.getDataSource();
154 String deviceId = ((DataSource) dataSource).getDeviceId();
156 if (directionAttr != null) {
157 direction = directionAttr.getValueString();
158 if (direction.equalsIgnoreCase(
"Incoming")) {
159 fromAccountAttr = ObjectUtils.firstNonNull(
160 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)),
161 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
162 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID))
165 toAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO));
166 localAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO));
167 }
else if (direction.equalsIgnoreCase(
"Outgoing")) {
168 toAccountAttr = ObjectUtils.firstNonNull(
169 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)),
170 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
171 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID))
174 fromAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM));
175 localAccountAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM));
180 if (fromAccountAttr == null) {
181 fromAccountAttr = ObjectUtils.firstNonNull(
182 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)),
183 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)),
184 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
185 artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID))
191 if (fromAccountAttr != null) {
192 String fromAccountAttrValue = fromAccountAttr.getValueString();
193 if (fromAccountAttrValue.equalsIgnoreCase(deviceId) ==
false) {
194 fromAccountIdentifier = fromAccountAttrValue;
199 if (toAccountAttr != null) {
201 String[] numbers = toAccountAttr.getValueString().split(
",");
202 String toAccountAttrValue = StringUtils.trim(numbers[0]);
203 if (toAccountAttrValue.equalsIgnoreCase(deviceId) ==
false) {
204 toAccountIdentifier = toAccountAttrValue;
210 if (numbers.length > 1) {
211 otherParties =
new ArrayList<>();
212 for (
int i = 1; i < numbers.length; i++) {
213 otherParties.add(StringUtils.trim(numbers[i]));
219 if (null != fromAccountAttr || null != toAccountAttr) {
220 callLogViewData =
new CallLogViewData(fromAccountIdentifier, toAccountIdentifier);
221 callLogViewData.setDirection(direction);
223 callLogViewData.setOtherParties(otherParties);
225 extractTimeAndDuration(artifact, callLogViewData);
227 callLogViewData.setDataSourceName(dataSource.getName());
230 if (localAccountAttr != null) {
231 String attrValue = localAccountAttr.getValueString();
233 if (attrValue.equalsIgnoreCase(deviceId) ==
false && attrValue.contains(
",") ==
false) {
234 callLogViewData.setLocalAccountId(attrValue);
238 callLogViewData.setOtherAttributes(extractOtherAttributes(artifact));
240 callLogViewData.setFromContactNameList(fromContactNames);
241 callLogViewData.setToContactNameList(toContactNames);
244 return callLogViewData;
257 private void extractTimeAndDuration(BlackboardArtifact artifact, CallLogViewData callLogViewData)
throws TskCoreException {
259 BlackboardAttribute startTimeAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START));
260 if (startTimeAttr == null) {
261 startTimeAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
263 if (startTimeAttr != null) {
264 long startTime = startTimeAttr.getValueLong();
265 callLogViewData.setDateTimeStr(startTimeAttr.getDisplayString());
267 BlackboardAttribute endTimeAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END));
268 if (endTimeAttr != null) {
269 long endTime = endTimeAttr.getValueLong();
270 if (endTime > 0 && (endTime - startTime) > 0) {
271 callLogViewData.setDuration(String.format(
"%d seconds", (endTime - startTime)));
288 List<BlackboardAttribute> attributes = artifact.getAttributes();
289 Map<String, String> otherAttributes =
new HashMap<>();
291 for (BlackboardAttribute attr : attributes) {
292 if (HANDLED_ATTRIBUTE_TYPES.contains(attr.getAttributeType().getTypeID()) ==
false) {
293 otherAttributes.put(attr.getAttributeType().getDisplayName(), attr.getDisplayString());
297 return otherAttributes;
308 "CallLogArtifactViewer_heading_parties=Parties",
309 "CallLogArtifactViewer_value_unknown=Unknown",
310 "CallLogArtifactViewer_label_from=From",
311 "CallLogArtifactViewer_label_to=To"
313 private List<AccountPersonaSearcherData>
updateView(CallLogViewData callLogViewData) {
315 CommunicationArtifactViewerHelper.addHeader(
this, m_gridBagLayout, this.m_constraints, 0, Bundle.CallLogArtifactViewer_heading_parties());
317 List<AccountPersonaSearcherData> dataList =
new ArrayList<>();
319 if (callLogViewData.getFromAccount() != null) {
320 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_from());
323 String accountDisplayString = getAccountDisplayString(callLogViewData.getFromAccount(), callLogViewData);
324 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, accountDisplayString);
326 List<String> contactNames = callLogViewData.getFromContactNameList();
327 for (String name : contactNames) {
328 CommunicationArtifactViewerHelper.addContactRow(
this, m_gridBagLayout, m_constraints, name);
332 dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(
this, m_gridBagLayout,
this.m_constraints, callLogViewData.getFromAccount()));
336 if (callLogViewData.getToAccount() != null) {
337 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_to());
338 String accountDisplayString = getAccountDisplayString(callLogViewData.getToAccount(), callLogViewData);
339 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, accountDisplayString);
341 List<String> contactNames = callLogViewData.getToContactNameList();
342 for (String name : contactNames) {
343 CommunicationArtifactViewerHelper.addContactRow(
this, m_gridBagLayout, m_constraints, name);
346 dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(
this, m_gridBagLayout,
this.m_constraints, callLogViewData.getToAccount()));
351 for (String otherParty : callLogViewData.getOtherParties()) {
352 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_to());
353 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, otherParty);
355 dataList.addAll(CommunicationArtifactViewerHelper.addPersonaRow(
this, m_gridBagLayout,
this.m_constraints, otherParty));
358 updateMetadataView(callLogViewData);
360 updateOtherAttributesView(callLogViewData);
362 updateSourceView(callLogViewData);
365 showCRDisabledMessage();
368 CommunicationArtifactViewerHelper.addPageEndGlue(
this, m_gridBagLayout, this.m_constraints);
370 this.setLayout(m_gridBagLayout);
381 "CallLogArtifactViewer_heading_metadata=Metadata",
382 "CallLogArtifactViewer_label_direction=Direction",
383 "CallLogArtifactViewer_label_date=Date",
384 "CallLogArtifactViewer_label_duration=Duration"
390 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_direction());
391 if (callLogViewData.getDirection() != null) {
392 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDirection());
394 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_value_unknown());
397 if (callLogViewData.getDateTimeStr() != null) {
398 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_date());
399 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDateTimeStr());
402 if (callLogViewData.getDuration() != null) {
403 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_duration());
404 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDuration());
415 "CallLogArtifactViewer_heading_Source=Source",
416 "CallLogArtifactViewer_label_datasource=Data Source",})
419 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource());
420 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
429 "CallLogArtifactViewer_heading_others=Other Attributes"
433 if (callLogViewData.getOtherAttributes().isEmpty()) {
438 for (Map.Entry<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
439 CommunicationArtifactViewerHelper.addKey(
this, m_gridBagLayout, this.m_constraints, entry.getKey());
440 CommunicationArtifactViewerHelper.addValue(
this, m_gridBagLayout, this.m_constraints, entry.getValue());
445 "CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
449 CommunicationArtifactViewerHelper.addMessageRow(
this, m_gridBagLayout, messageInsets, 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;
509 m_constraints.fill = GridBagConstraints.NONE;
boolean isSupported(BlackboardArtifact artifact)
CallLogViewData getCallLogViewData(BlackboardArtifact artifact)
static Integer getLineSpacing()
void extractTimeAndDuration(BlackboardArtifact artifact, CallLogViewData callLogViewData)
static Insets getPanelInsets()
static Integer getSectionIndent()
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)
static Integer getSectionSpacing()
synchronized static Logger getLogger(String name)
static boolean isEnabled()