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()