From 97574463ed7cd604e3406b29f262d53fd79d7536 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 25 Oct 2021 14:38:07 -0400 Subject: [PATCH] 7673 Allow helpers to call correct Blackboard.postArtifacts() API --- .../xry/XRYCallsFileParser.java | 9 +- .../xry/XRYContactsFileParser.java | 7 +- .../xry/XRYMessagesFileParser.java | 4 +- .../autopsy/ingest/IngestManager.java | 30 ++- .../ALeappAnalyzerIngestModule.java | 4 +- .../ILeappAnalyzerIngestModule.java | 4 +- .../leappanalyzers/LeappFileProcessor.java | 213 +++++++++--------- 7 files changed, 140 insertions(+), 131 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYCallsFileParser.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYCallsFileParser.java index 58a418e66d..610ef84265 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYCallsFileParser.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYCallsFileParser.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019-2020 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.List; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Blackboard.BlackboardException; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -301,7 +300,7 @@ final class XRYCallsFileParser extends AbstractSingleEntityParser { for (String phone : calleeList) { try { currentCase.getCommunicationsManager().createAccountFileInstance( - Account.Type.PHONE, phone, PARSER_NAME, parent); + Account.Type.PHONE, phone, PARSER_NAME, parent, null); } catch (InvalidAccountIDException ex) { logger.log(Level.WARNING, String.format("Invalid account identifier %s", phone), ex); } @@ -314,13 +313,13 @@ final class XRYCallsFileParser extends AbstractSingleEntityParser { if (!otherAttributes.isEmpty()) { BlackboardArtifact artifact = parent.newDataArtifact(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG), otherAttributes); - currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME); + currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME, null); } } else { // Otherwise we can safely use the helper. CommunicationArtifactsHelper helper = new CommunicationArtifactsHelper( - currentCase, PARSER_NAME, parent, Account.Type.PHONE); + currentCase, PARSER_NAME, parent, Account.Type.PHONE, null); helper.addCalllog(direction, callerId, calleeList, startTime, endTime, callType, otherAttributes); diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYContactsFileParser.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYContactsFileParser.java index f721479d07..a961abfe21 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYContactsFileParser.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYContactsFileParser.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019-2020 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,6 @@ import java.util.List; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; import static org.sleuthkit.autopsy.datasourceprocessors.xry.AbstractSingleEntityParser.PARSER_NAME; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -136,7 +135,7 @@ final class XRYContactsFileParser extends AbstractSingleEntityParser { // complain about illegal arguments. if (phoneNumber != null || homePhoneNumber != null || mobilePhoneNumber != null || hasAnEmail) { CommunicationArtifactsHelper helper = new CommunicationArtifactsHelper( - currentCase, PARSER_NAME, parent, Account.Type.DEVICE); + currentCase, PARSER_NAME, parent, Account.Type.DEVICE, null); helper.addContact(contactName, phoneNumber, homePhoneNumber, mobilePhoneNumber, emailAddr, additionalAttributes); @@ -145,7 +144,7 @@ final class XRYContactsFileParser extends AbstractSingleEntityParser { if (!additionalAttributes.isEmpty()) { BlackboardArtifact artifact = parent.newDataArtifact(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT), additionalAttributes); - currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME); + currentCase.getBlackboard().postArtifact(artifact, PARSER_NAME, null); } } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYMessagesFileParser.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYMessagesFileParser.java index 6fb7413c8e..9c24a1703b 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYMessagesFileParser.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYMessagesFileParser.java @@ -318,7 +318,7 @@ final class XRYMessagesFileParser implements XRYFileParser { } else { try { currentCase.getCommunicationsManager().createAccountFileInstance( - Account.Type.PHONE, pair.getValue(), PARSER_NAME, parent); + Account.Type.PHONE, pair.getValue(), PARSER_NAME, parent, null); } catch (InvalidAccountIDException ex) { logger.log(Level.WARNING, String.format("Invalid account identifier %s", pair.getValue()), ex); } @@ -437,7 +437,7 @@ final class XRYMessagesFileParser implements XRYFileParser { } CommunicationArtifactsHelper helper = new CommunicationArtifactsHelper( - currentCase, PARSER_NAME, parent, Account.Type.PHONE); + currentCase, PARSER_NAME, parent, Account.Type.PHONE, null); helper.addMessage(messageType, direction, senderId, recipientIdsList, dateTime, readStatus, subject, text, threadId, otherAttributes); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java index 7dc12492d9..f5542a5784 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -34,6 +34,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; @@ -308,32 +309,37 @@ public class IngestManager implements IngestProgressSnapshotProvider { } if (!newDataArtifacts.isEmpty()) { IngestJob ingestJob = null; - Long ingestJobId = tskEvent.getIngestJobId(); - if (ingestJobId != null) { + Optional ingestJobId = tskEvent.getIngestJobId(); + if (ingestJobId.isPresent()) { synchronized (ingestJobsById) { - ingestJob = ingestJobsById.get(ingestJobId); + ingestJob = ingestJobsById.get(ingestJobId.get()); } } else { /* - * Cases where the ingest job ID returned by the event will be - * null: + * There are two cases where the ingest job ID returned by the + * event is expected be null: * * 1. The artifacts are being posted by a data source proccessor - * (DSP) that runs before the ingest job is created, i.e., a DSP - * that does not support streaming ingest. In this use case, the - * event is handled synchronously before the ingest job is + * (DSP) module that runs before the ingest job is created, + * i.e., a DSP that does not support streaming ingest and has no + * noton of an ingest job ID. In this use case, the event is + * handled synchronously (the DSP calls + * Blackboard.postArtifacts(), which puts the event on the event + * bus to which this method subscribes) before the ingest job is * created, so the code below will not find an ingest job to * which to add the artifacts. However, the artifacts will be * analyzed when the ingest job executor, working in batch mode, * schedules ingest tasks for all of the data artifacts in the * case database. * - * 2. The artifacts were posted by a third party ingest module - * that either has not been updated to use the current - * Blackboard.postartifacts() API, or is using it incorrectly. + * 2. The artifacts were posted by an ingest module that either + * has not been updated to use the current + * Blackboard.postArtifacts() API, or is using it incorrectly. * In this use case, the code below should be able to find the * ingest job to which to add the artifacts via their data - * source. However, there is a slight risk here that the wrong + * source. + * + * In both use cases, there is a slight risk that the wrong * ingest job will be selected if multiple ingests of the same * data source are in progress. */ diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java index 3409098d95..06f367d691 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -101,7 +101,7 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { } try { - aLeappFileProcessor = new LeappFileProcessor(XMLFILE, ALeappAnalyzerModuleFactory.getModuleName()); + aLeappFileProcessor = new LeappFileProcessor(XMLFILE, ALeappAnalyzerModuleFactory.getModuleName(), context); } catch (IOException | IngestModuleException | NoCurrentCaseException ex) { throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java index 339be316a9..cf89294aff 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -101,7 +101,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { } try { - iLeappFileProcessor = new LeappFileProcessor(XMLFILE, ILeappAnalyzerModuleFactory.getModuleName()); + iLeappFileProcessor = new LeappFileProcessor(XMLFILE, ILeappAnalyzerModuleFactory.getModuleName(), context); } catch (IOException | IngestModuleException | NoCurrentCaseException ex) { throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java index 9f19f18996..4796272418 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -61,6 +61,7 @@ import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.autopsy.coreutils.NetworkUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult; import org.sleuthkit.datamodel.AbstractFile; @@ -108,10 +109,10 @@ public final class LeappFileProcessor { * Main constructor. * * @param attributeType The BlackboardAttribute type or null if not - * used. used. - * @param columnName The name of the column in the tsv file. - * @param required Whether or not this attribute is required to be - * present. + * used. used. + * @param columnName The name of the column in the tsv file. + * @param required Whether or not this attribute is required to be + * present. */ TsvColumn(BlackboardAttribute.Type attributeType, String columnName, boolean required) { this.attributeType = attributeType; @@ -144,6 +145,7 @@ public final class LeappFileProcessor { private static final Logger logger = Logger.getLogger(LeappFileProcessor.class.getName()); private final String xmlFile; //NON-NLS private final String moduleName; + private final IngestJobContext context; private final Map tsvFiles; private final Map tsvFileArtifacts; @@ -194,13 +196,14 @@ public final class LeappFileProcessor { Blackboard blkBoard; - public LeappFileProcessor(String xmlFile, String moduleName) throws IOException, IngestModuleException, NoCurrentCaseException { + public LeappFileProcessor(String xmlFile, String moduleName, IngestJobContext context) throws IOException, IngestModuleException, NoCurrentCaseException { this.tsvFiles = new HashMap<>(); this.tsvFileArtifacts = new HashMap<>(); this.tsvFileArtifactComments = new HashMap<>(); this.tsvFileAttributes = new HashMap<>(); this.xmlFile = xmlFile; this.moduleName = moduleName; + this.context = context; blkBoard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard(); @@ -249,7 +252,7 @@ public final class LeappFileProcessor { * we know we want to process and return the list to process those files. */ private List findTsvFiles(Path LeappOutputDir) throws IngestModuleException { - List allTsvFiles = new ArrayList<>(); + List allTsvFiles; List foundTsvFiles = new ArrayList<>(); try (Stream walk = Files.walk(LeappOutputDir)) { @@ -275,7 +278,7 @@ public final class LeappFileProcessor { * Process the Leapp files that were found that match the xml mapping file * * @param LeappFilesToProcess List of files to process - * @param LeappImageFile Abstract file to create artifact for + * @param LeappImageFile Abstract file to create artifact for * * @throws FileNotFoundException * @throws IOException @@ -308,7 +311,7 @@ public final class LeappFileProcessor { * Process the Leapp files that were found that match the xml mapping file * * @param LeappFilesToProcess List of files to process - * @param dataSource The data source. + * @param dataSource The data source. * * @throws FileNotFoundException * @throws IOException @@ -318,7 +321,7 @@ public final class LeappFileProcessor { for (String LeappFileName : LeappFilesToProcess) { String fileName = FilenameUtils.getName(LeappFileName); - File LeappFile = new File(LeappFileName); + File LeappFile = new File(LeappFileName); if (tsvFileAttributes.containsKey(fileName)) { List attrList = tsvFileAttributes.get(fileName); BlackboardArtifact.Type artifactType = tsvFileArtifacts.get(fileName); @@ -345,7 +348,7 @@ public final class LeappFileProcessor { String trackpointSegmentName = null; GeoTrackPoints pointList = new GeoTrackPoints(); AbstractFile geoAbstractFile = null; - + if (LeappFile == null || !LeappFile.exists() || fileName == null) { logger.log(Level.WARNING, String.format("Leap file: %s is null or does not exist", LeappFile == null ? LeappFile.toString() : "")); return; @@ -405,11 +408,11 @@ public final class LeappFileProcessor { } } } - + try { - if (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName.toLowerCase(), "norelationship").toLowerCase() == "trackpoint") { - (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, "", geoAbstractFile)).addTrack(trackpointSegmentName, pointList, new ArrayList<>()); - + if (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName.toLowerCase(), "norelationship").toLowerCase().equals("trackpoint")) { + (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, "", geoAbstractFile)).addTrack(trackpointSegmentName, pointList, new ArrayList<>()); + } } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_message_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS @@ -418,10 +421,9 @@ public final class LeappFileProcessor { } @NbBundle.Messages({ - "LeappFileProcessor.cannot.create.waypoint.relationship=Cannot create TSK_WAYPOINT artifact.", - }) + "LeappFileProcessor.cannot.create.waypoint.relationship=Cannot create TSK_WAYPOINT artifact.",}) - private void createRoute (Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { + private void createRoute(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { Double startLatitude = Double.valueOf(0); Double startLongitude = Double.valueOf(0); @@ -435,7 +437,7 @@ public final class LeappFileProcessor { String sourceFile = null; AbstractFile absFile = null; String comment = ""; - + try { for (BlackboardAttribute bba : bbattributes) { switch (bba.getAttributeType().getTypeName()) { @@ -478,18 +480,16 @@ public final class LeappFileProcessor { GeoWaypoints waypointList = new GeoWaypoints(); waypointList.addPoint(new Waypoint(startLatitude, startLongitude, zeroValue, "")); waypointList.addPoint(new Waypoint(endLatitude, endLongitude, zeroValue, locationName)); - (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, comment, absFile)).addRoute(destinationName, dateTime, waypointList, new ArrayList<>()); - + (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, comment, absFile)).addRoute(destinationName, dateTime, waypointList, new ArrayList<>()); + } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_waypoint_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS } - - + } - + @NbBundle.Messages({ - "LeappFileProcessor.cannot.create.trackpoint.relationship=Cannot create TSK_TRACK_POINT artifact.", - }) + "LeappFileProcessor.cannot.create.trackpoint.relationship=Cannot create TSK_TRACK_POINT artifact.",}) private AbstractFile createTrackpoint(Collection bbattributes, Content dataSource, String fileName, String trackpointSegmentName, GeoTrackPoints pointList) throws IngestModuleException { @@ -503,7 +503,7 @@ public final class LeappFileProcessor { String sourceFile = null; String comment = null; AbstractFile absFile = null; - + try { for (BlackboardAttribute bba : bbattributes) { switch (bba.getAttributeType().getTypeName()) { @@ -539,28 +539,26 @@ public final class LeappFileProcessor { absFile = (AbstractFile) dataSource; } if ((trackpointSegmentName == null) || (trackpointSegmentName == segmentName)) { - trackpointSegmentName = segmentName; - pointList.addPoint(new TrackPoint(latitude, longitude, altitude, segmentName, zeroValue, zeroValue, zeroValue, dateTime)); + trackpointSegmentName = segmentName; + pointList.addPoint(new TrackPoint(latitude, longitude, altitude, segmentName, zeroValue, zeroValue, zeroValue, dateTime)); } else { - (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, comment, absFile)).addTrack(segmentName, pointList, new ArrayList<>()); - trackpointSegmentName = segmentName; - pointList = new GeoTrackPoints(); - pointList.addPoint(new TrackPoint(latitude, longitude, altitude, segmentName, zeroValue, zeroValue, zeroValue, dateTime)); - + (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, comment, absFile)).addTrack(segmentName, pointList, new ArrayList<>()); + trackpointSegmentName = segmentName; + pointList = new GeoTrackPoints(); + pointList.addPoint(new TrackPoint(latitude, longitude, altitude, segmentName, zeroValue, zeroValue, zeroValue, dateTime)); + } } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_trackpoint_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS } - - return absFile; - + + return absFile; + } - @NbBundle.Messages({ - "LeappFileProcessor.cannot.create.message.relationship=Cannot create TSK_MESSAGE Relationship.", - }) - + "LeappFileProcessor.cannot.create.message.relationship=Cannot create TSK_MESSAGE Relationship.",}) + private void createMessageRelationship(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { String messageType = null; @@ -614,7 +612,7 @@ public final class LeappFileProcessor { sourceFile = bba.getValueString(); break; case "TSK_READ_STATUS": - if (bba.getValueInt() == 1 ) { + if (bba.getValueInt() == 1) { messageStatus = MessageReadStatus.READ; } else { messageStatus = MessageReadStatus.UNREAD; @@ -638,19 +636,19 @@ public final class LeappFileProcessor { AbstractFile absFile = findAbstractFile(dataSource, sourceFile); if (absFile == null) { absFile = (AbstractFile) dataSource; - } + } CommunicationArtifactsHelper accountArtifact; - Account.Type accountType = getAccountType(fileName); + Account.Type accountType = getAccountType(fileName); if (alternateId == null) { accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType); + moduleName, absFile, accountType); } else { accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType, accountType, alternateId); + moduleName, absFile, accountType, accountType, alternateId); } BlackboardArtifact messageArtifact = accountArtifact.addMessage(messageType, communicationDirection, senderId, - receipentId, dateTime, messageStatus, subject, - messageText, threadId, otherAttributes); + receipentId, dateTime, messageStatus, subject, + messageText, threadId, otherAttributes); if (!fileAttachments.isEmpty()) { messageAttachments = new MessageAttachments(fileAttachments, new ArrayList<>()); accountArtifact.addAttachments(messageArtifact, messageAttachments); @@ -662,8 +660,7 @@ public final class LeappFileProcessor { } @NbBundle.Messages({ - "LeappFileProcessor.cannot.create.contact.relationship=Cannot create TSK_CONTACT Relationship.", - }) + "LeappFileProcessor.cannot.create.contact.relationship=Cannot create TSK_CONTACT Relationship.",}) private void createContactRelationship(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { String alternateId = null; @@ -715,14 +712,14 @@ public final class LeappFileProcessor { } Account.Type accountType = getAccountType(fileName); if (accountType != null) { - + CommunicationArtifactsHelper accountArtifact; if (alternateId == null) { accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType); + moduleName, absFile, accountType); } else { accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType, accountType, alternateId); + moduleName, absFile, accountType, accountType, alternateId); } BlackboardArtifact messageArtifact = accountArtifact.addContact(contactName, phoneNumber, homePhoneNumber, mobilePhoneNumber, emailAddr, otherAttributes); } @@ -732,14 +729,13 @@ public final class LeappFileProcessor { } @NbBundle.Messages({ - "LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.", - }) + "LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.",}) private void createCalllogRelationship(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { String callerId = null; String alternateId = null; - List calleeId = Arrays.asList(); + List calleeId = Arrays.asList(); CommunicationDirection communicationDirection = CommunicationDirection.UNKNOWN; Long startDateTime = Long.valueOf(0); Long endDateTime = Long.valueOf(0); @@ -751,14 +747,14 @@ public final class LeappFileProcessor { for (BlackboardAttribute bba : bbattributes) { switch (bba.getAttributeType().getTypeName()) { case "TSK_TEXT_FILE": - sourceFile = bba.getValueString(); - break; + sourceFile = bba.getValueString(); + break; case "TSK_DATETIME_START": - startDateTime = bba.getValueLong(); - break; + startDateTime = bba.getValueLong(); + break; case "TSK_DATETIME_END": - startDateTime = bba.getValueLong(); - break; + startDateTime = bba.getValueLong(); + break; case "TSK_DIRECTION": if (bba.getValueString().toLowerCase().equals("outgoing")) { communicationDirection = CommunicationDirection.OUTGOING; @@ -773,8 +769,8 @@ public final class LeappFileProcessor { break; case "TSK_PHONE_NUMBER_TO": if (!bba.getValueString().isEmpty()) { - String [] calleeTempList = bba.getValueString().split(",", 0); - calleeId = Arrays.asList(calleeTempList); + String[] calleeTempList = bba.getValueString().split(",", 0); + calleeId = Arrays.asList(calleeTempList); } break; case "TSK_ID": @@ -786,12 +782,12 @@ public final class LeappFileProcessor { break; } } - + if (calleeId.isEmpty() && communicationDirection == CommunicationDirection.OUTGOING) { - String [] calleeTempList = callerId.split(",", 0); - calleeId = Arrays.asList(calleeTempList); - callerId = null; - } + String[] calleeTempList = callerId.split(",", 0); + calleeId = Arrays.asList(calleeTempList); + callerId = null; + } AbstractFile absFile = findAbstractFile(dataSource, sourceFile); if (absFile == null) { absFile = (AbstractFile) dataSource; @@ -800,10 +796,10 @@ public final class LeappFileProcessor { CommunicationArtifactsHelper accountArtifact; if (accountType != null) { accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType); + moduleName, absFile, accountType); } else { accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType, accountType, alternateId); + moduleName, absFile, accountType, accountType, alternateId); } BlackboardArtifact callLogArtifact = accountArtifact.addCalllog(communicationDirection, callerId, calleeId, startDateTime, endDateTime, mediaType, otherAttributes); } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { @@ -811,7 +807,7 @@ public final class LeappFileProcessor { } } - + private Account.Type getAccountType(String AccountTypeName) { switch (AccountTypeName.toLowerCase()) { case "zapya.tsv": @@ -849,7 +845,7 @@ public final class LeappFileProcessor { case "whatsapp - contacts.tsv": return Account.Type.WHATSAPP; case "tangomessages messages.tsv": - return Account.Type.TANGO; + return Account.Type.TANGO; case "shareit file transfer.tsv": return Account.Type.SHAREIT; case "line - calllogs.tsv": @@ -880,20 +876,22 @@ public final class LeappFileProcessor { return Account.Type.PHONE; } } - + /** * Process the line read and create the necessary attributes for it. * - * @param lineValues List of column values. + * @param lineValues List of column values. * @param columnIndexes Mapping of column headers (trimmed; to lower case) - * to column index. All header columns and only all header columns should be - * present. - * @param attrList The list of attributes as specified for the schema of - * this file. - * @param fileName The name of the file being processed. - * @param lineNum The line number in the file. + * to column index. All header columns and only all + * header columns should be present. + * @param attrList The list of attributes as specified for the schema + * of this file. + * @param fileName The name of the file being processed. + * @param lineNum The line number in the file. + * * @return The collection of blackboard attributes for the artifact created - * from this line. + * from this line. + * * @throws IngestModuleException */ private Collection processReadLine(List lineValues, Map columnIndexes, @@ -949,9 +947,10 @@ public final class LeappFileProcessor { * Check type of attribute and possibly format string based on it. * * @param colAttr Column Attribute information - * @param value string to be formatted + * @param value string to be formatted + * * @return formatted string based on attribute type if no attribute type - * found then return original string + * found then return original string */ private String formatValueBasedOnAttrType(TsvColumn colAttr, String value) { if (colAttr.getAttributeType().getTypeName().equals("TSK_DOMAIN")) { @@ -971,9 +970,10 @@ public final class LeappFileProcessor { * value. * * @param attrType The attribute type. - * @param value The string value to be converted to the appropriate data - * type for the attribute type. + * @param value The string value to be converted to the appropriate data + * type for the attribute type. * @param fileName The file name that the value comes from. + * * @return The generated blackboard attribute. */ private BlackboardAttribute getAttribute(BlackboardAttribute.Type attrType, String value, String fileName) { @@ -1022,7 +1022,9 @@ public final class LeappFileProcessor { * Handles converting a string value to a blackboard attribute. * * @param orig The original string value. + * * @return The generated blackboard attribute. + * * @throws ParseException * @throws NumberFormatException */ @@ -1033,13 +1035,15 @@ public final class LeappFileProcessor { * Runs parsing function on string value to convert to right data type and * generates a blackboard attribute for that converted data type. * - * @param value The string value. - * @param attrType The blackboard attribute type. - * @param fileName The name of the file from which the value comes. - * @param blankIsNull If string is blank return null attribute. - * @param zeroIsNull If string is some version of 0, return null attribute. + * @param value The string value. + * @param attrType The blackboard attribute type. + * @param fileName The name of the file from which the value comes. + * @param blankIsNull If string is blank return null attribute. + * @param zeroIsNull If string is some version of 0, return null + * attribute. * @param valueConverter The means of converting the string value to an - * appropriate blackboard attribute. + * appropriate blackboard attribute. + * * @return The generated blackboard attribute or null if not determined. */ private BlackboardAttribute parseAttrValue(String value, BlackboardAttribute.Type attrType, String fileName, boolean blankIsNull, boolean zeroIsNull, ParseExceptionFunction valueConverter) { @@ -1157,7 +1161,7 @@ public final class LeappFileProcessor { for (int k = 0; k < attributeNlist.getLength(); k++) { NamedNodeMap nnm = attributeNlist.item(k).getAttributes(); String attributeName = nnm.getNamedItem("attributename").getNodeValue(); - + if (!attributeName.toLowerCase().matches("null")) { String columnName = nnm.getNamedItem("columnName").getNodeValue(); String required = nnm.getNamedItem("required").getNodeValue(); @@ -1209,11 +1213,12 @@ public final class LeappFileProcessor { /** * Generic method for creating a blackboard artifact with attributes * - * @param artType The artifact type. - * @param dataSource is the Content object that needs to have the artifact - * added for it + * @param artType The artifact type. + * @param dataSource is the Content object that needs to have the artifact + * added for it * @param bbattributes is the collection of blackboard attributes that need - * to be added to the artifact after the artifact has been created + * to be added to the artifact after the artifact has + * been created * * @return The newly-created artifact, or null on error */ @@ -1238,7 +1243,7 @@ public final class LeappFileProcessor { * Method to post a list of BlackboardArtifacts to the blackboard. * * @param artifacts A list of artifacts. IF list is empty or null, the - * function will return. + * function will return. */ void postArtifacts(Collection artifacts) { if (artifacts == null || artifacts.isEmpty()) { @@ -1246,7 +1251,7 @@ public final class LeappFileProcessor { } try { - Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifacts(artifacts, moduleName); + Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifacts(artifacts, moduleName, context.getJobId()); } catch (Blackboard.BlackboardException ex) { logger.log(Level.SEVERE, Bundle.LeappFileProcessor_postartifacts_error(), ex); //NON-NLS } @@ -1259,7 +1264,7 @@ public final class LeappFileProcessor { */ private void configExtractor() throws IOException { PlatformUtil.extractResourceToUserConfigDir(LeappFileProcessor.class, - xmlFile, true); + xmlFile, true); } private static final Set ALLOWED_EXTENSIONS = new HashSet<>(Arrays.asList("zip", "tar", "tgz")); @@ -1316,14 +1321,14 @@ public final class LeappFileProcessor { } } - + private AbstractFile findAbstractFile(Content dataSource, String fileNamePath) { if (fileNamePath == null) { return null; } - + List files; - + String fileName = FilenameUtils.getName(fileNamePath); String filePath = FilenameUtils.normalize(FilenameUtils.getPath(fileNamePath), true); @@ -1347,4 +1352,4 @@ public final class LeappFileProcessor { return null; } - } +}