Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
LeappFileProcessor.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 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.modules.leappanalyzers;
20 
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.io.UncheckedIOException;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.text.ParseException;
30 import java.text.SimpleDateFormat;
31 import java.util.List;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.Date;
37 import java.util.HashMap;
38 import static java.util.Locale.US;
39 import java.util.Map;
40 import java.util.logging.Level;
41 import java.util.stream.Collectors;
42 import java.util.stream.IntStream;
43 import java.util.stream.Stream;
44 import javax.xml.parsers.DocumentBuilder;
45 import javax.xml.parsers.DocumentBuilderFactory;
46 import javax.xml.parsers.ParserConfigurationException;
47 import org.apache.commons.collections4.MapUtils;
48 import org.apache.commons.io.FilenameUtils;
49 import org.openide.util.NbBundle;
56 import org.sleuthkit.datamodel.AbstractFile;
57 import org.sleuthkit.datamodel.Blackboard;
58 import org.sleuthkit.datamodel.BlackboardArtifact;
59 import org.sleuthkit.datamodel.BlackboardAttribute;
60 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
61 import org.sleuthkit.datamodel.Content;
62 import org.sleuthkit.datamodel.TskCoreException;
63 import org.sleuthkit.datamodel.TskException;
64 import org.w3c.dom.Document;
65 import org.w3c.dom.NamedNodeMap;
66 import org.w3c.dom.NodeList;
67 import org.xml.sax.SAXException;
68 
72 public final class LeappFileProcessor {
73 
77  private static class TsvColumn {
78 
79  private final String attributeName;
80  private final String columnName;
81  private final boolean required;
82 
92  TsvColumn(String attributeName, String columnName, boolean required) {
93  this.attributeName = attributeName;
94  this.columnName = columnName;
95  this.required = required;
96  }
97 
101  String getAttributeName() {
102  return attributeName;
103  }
104 
108  String getColumnName() {
109  return columnName;
110  }
111 
115  boolean isRequired() {
116  return required;
117  }
118  }
119 
120  private static final Logger logger = Logger.getLogger(LeappFileProcessor.class.getName());
121  private static final String MODULE_NAME = ILeappAnalyzerModuleFactory.getModuleName();
122 
123  private final String xmlFile; //NON-NLS
124 
125  private final Map<String, String> tsvFiles;
126  private final Map<String, String> tsvFileArtifacts;
127  private final Map<String, String> tsvFileArtifactComments;
128  private final Map<String, List<TsvColumn>> tsvFileAttributes;
129 
130  Blackboard blkBoard;
131 
132  public LeappFileProcessor(String xmlFile) throws IOException, IngestModuleException, NoCurrentCaseException {
133  this.tsvFiles = new HashMap<>();
134  this.tsvFileArtifacts = new HashMap<>();
135  this.tsvFileArtifactComments = new HashMap<>();
136  this.tsvFileAttributes = new HashMap<>();
137  this.xmlFile = xmlFile;
138 
139  blkBoard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
140 
141  configExtractor();
142  loadConfigFile();
143 
144  }
145 
146  @NbBundle.Messages({
147  "LeappFileProcessor.error.running.Leapp=Error running Leapp, see log file.",
148  "LeappFileProcessor.error.creating.output.dir=Error creating Leapp module output directory.",
149  "LeappFileProcessor.starting.Leapp=Starting Leapp",
150  "LeappFileProcessor.running.Leapp=Running Leapp",
151  "LeappFileProcessor.has.run=Leapp",
152  "LeappFileProcessor.Leapp.cancelled=Leapp run was canceled",
153  "LeappFileProcessor.completed=Leapp Processing Completed",
154  "LeappFileProcessor.error.reading.Leapp.directory=Error reading Leapp Output Directory"})
155  public ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile) {
156  try {
157  List<String> LeappTsvOutputFiles = findTsvFiles(moduleOutputPath);
158  processLeappFiles(LeappTsvOutputFiles, LeappFile);
159  } catch (IOException | IngestModuleException ex) {
160  logger.log(Level.SEVERE, String.format("Error trying to process Leapp output files in directory %s. ", moduleOutputPath.toString()), ex); //NON-NLS
161  return ProcessResult.ERROR;
162  }
163 
164  return ProcessResult.OK;
165  }
166 
167  public ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath) {
168 
169  try {
170  List<String> LeappTsvOutputFiles = findTsvFiles(moduleOutputPath);
171  processLeappFiles(LeappTsvOutputFiles, dataSource);
172  } catch (IngestModuleException ex) {
173  logger.log(Level.SEVERE, String.format("Error trying to process Leapp output files in directory %s. ", moduleOutputPath.toString()), ex); //NON-NLS
174  return ProcessResult.ERROR;
175  }
176 
177  return ProcessResult.OK;
178  }
179 
184  private List<String> findTsvFiles(Path LeappOutputDir) throws IngestModuleException {
185  List<String> allTsvFiles = new ArrayList<>();
186  List<String> foundTsvFiles = new ArrayList<>();
187 
188  try (Stream<Path> walk = Files.walk(LeappOutputDir)) {
189 
190  allTsvFiles = walk.map(x -> x.toString())
191  .filter(f -> f.toLowerCase().endsWith(".tsv")).collect(Collectors.toList());
192 
193  for (String tsvFile : allTsvFiles) {
194  if (tsvFiles.containsKey(FilenameUtils.getName(tsvFile.toLowerCase()))) {
195  foundTsvFiles.add(tsvFile);
196  }
197  }
198 
199  } catch (IOException | UncheckedIOException e) {
200  throw new IngestModuleException(Bundle.LeappFileProcessor_error_reading_Leapp_directory() + LeappOutputDir.toString(), e);
201  }
202 
203  return foundTsvFiles;
204 
205  }
206 
216  private void processLeappFiles(List<String> LeappFilesToProcess, AbstractFile LeappImageFile) throws FileNotFoundException, IOException, IngestModuleException {
217  List<BlackboardArtifact> bbartifacts = new ArrayList<>();
218 
219  for (String LeappFileName : LeappFilesToProcess) {
220  String fileName = FilenameUtils.getName(LeappFileName);
221  File LeappFile = new File(LeappFileName);
222  if (tsvFileAttributes.containsKey(fileName)) {
223  List<TsvColumn> attrList = tsvFileAttributes.get(fileName);
224  try {
225  BlackboardArtifact.Type artifactType = Case.getCurrentCase().getSleuthkitCase().getArtifactType(tsvFileArtifacts.get(fileName));
226 
227  processFile(LeappFile, attrList, fileName, artifactType, bbartifacts, LeappImageFile);
228 
229  } catch (TskCoreException ex) {
230  throw new IngestModuleException(String.format("Error getting Blackboard Artifact Type for %s", tsvFileArtifacts.get(fileName)), ex);
231  }
232  }
233 
234  }
235 
236  if (!bbartifacts.isEmpty()) {
237  postArtifacts(bbartifacts);
238  }
239 
240  }
241 
251  private void processLeappFiles(List<String> LeappFilesToProcess, Content dataSource) throws IngestModuleException {
252  List<BlackboardArtifact> bbartifacts = new ArrayList<>();
253 
254  for (String LeappFileName : LeappFilesToProcess) {
255  String fileName = FilenameUtils.getName(LeappFileName);
256  File LeappFile = new File(LeappFileName);
257  if (tsvFileAttributes.containsKey(fileName)) {
258  List<TsvColumn> attrList = tsvFileAttributes.get(fileName);
259  BlackboardArtifact.Type artifactType = null;
260  try {
261  artifactType = Case.getCurrentCase().getSleuthkitCase().getArtifactType(tsvFileArtifacts.get(fileName));
262  } catch (TskCoreException ex) {
263  logger.log(Level.SEVERE, String.format("Error getting Blackboard Artifact Type for %s", tsvFileArtifacts.get(fileName)), ex);
264  }
265 
266  if (artifactType == null) {
267  continue;
268  }
269 
270  try {
271  processFile(LeappFile, attrList, fileName, artifactType, bbartifacts, dataSource);
272  } catch (TskCoreException | IOException ex) {
273  logger.log(Level.SEVERE, String.format("Error processing file at %s", LeappFile.toString()), ex);
274  }
275  }
276 
277  }
278 
279  if (!bbartifacts.isEmpty()) {
280  postArtifacts(bbartifacts);
281  }
282 
283  }
284 
285  private void processFile(File LeappFile, List<TsvColumn> attrList, String fileName, BlackboardArtifact.Type artifactType,
286  List<BlackboardArtifact> bbartifacts, Content dataSource) throws FileNotFoundException, IOException, IngestModuleException,
287  TskCoreException {
288 
289  if (LeappFile == null || !LeappFile.exists() || fileName == null) {
290  logger.log(Level.WARNING, String.format("Leap file: %s is null or does not exist", LeappFile == null ? LeappFile.toString() : "<null>"));
291  return;
292  } else if (attrList == null || artifactType == null || dataSource == null) {
293  logger.log(Level.WARNING, String.format("attribute list, artifact type or dataSource not provided for %s", LeappFile == null ? LeappFile.toString() : "<null>"));
294  return;
295  }
296 
297  try (BufferedReader reader = new BufferedReader(new FileReader(LeappFile))) {
298  String header = reader.readLine();
299  // Check first line, if it is null then no heading so nothing to match to, close and go to next file.
300  if (header != null) {
301  Map<Integer, String> columnNumberToProcess = findColumnsToProcess(fileName, header, attrList);
302  String line = reader.readLine();
303  while (line != null) {
304  Collection<BlackboardAttribute> bbattributes = processReadLine(line, columnNumberToProcess, fileName);
305 
306  if (!bbattributes.isEmpty() && !blkBoard.artifactExists(dataSource, BlackboardArtifact.ARTIFACT_TYPE.fromID(artifactType.getTypeID()), bbattributes)) {
307  BlackboardArtifact bbartifact = createArtifactWithAttributes(artifactType.getTypeID(), dataSource, bbattributes);
308  if (bbartifact != null) {
309  bbartifacts.add(bbartifact);
310  }
311  }
312 
313  line = reader.readLine();
314  }
315  }
316  }
317 
318  }
319 
329  private Collection<BlackboardAttribute> processReadLine(String line, Map<Integer, String> columnNumberToProcess, String fileName) throws IngestModuleException {
330  if (MapUtils.isEmpty(columnNumberToProcess)) {
331  return Collections.emptyList();
332  } else if (line == null) {
333  logger.log(Level.WARNING, "Line is null. Returning empty list for attributes.");
334  return Collections.emptyList();
335  }
336 
337  String[] columnValues;
338 
339  // Check to see if the 2 values are equal, they may not be equal if there is no corresponding data in the line.
340  // or if the size of the line to split is not equal to the column numbers we are looking to process. This
341  // can happen when the last value of the tsv line has no data in it.
342  // If this happens then adding an empty value(s) for each columnValue where data does not exist
343  Integer maxColumnNumber = Collections.max(columnNumberToProcess.keySet());
344  if ((maxColumnNumber > line.split("\\t").length) || (columnNumberToProcess.size() > line.split("\\t").length)) {
345  columnValues = Arrays.copyOf(line.split("\\t"), maxColumnNumber + 1);
346  } else {
347  columnValues = line.split("\\t");
348  }
349 
350  Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
351 
352  for (Map.Entry<Integer, String> columnToProcess : columnNumberToProcess.entrySet()) {
353  Integer columnNumber = columnToProcess.getKey();
354  String attributeName = columnToProcess.getValue();
355 
356  if (columnValues[columnNumber] != null) {
357  try {
358  BlackboardAttribute.Type attributeType = Case.getCurrentCase().getSleuthkitCase().getAttributeType(attributeName.toUpperCase());
359  if (attributeType == null) {
360  continue;
361  }
362  String attrType = attributeType.getValueType().getLabel().toUpperCase();
363  checkAttributeType(bbattributes, attrType, columnValues, columnNumber, attributeType, fileName);
364  } catch (TskCoreException ex) {
365  throw new IngestModuleException(String.format("Error getting Attribute type for Attribute Name %s", attributeName), ex); //NON-NLS
366  }
367  }
368  }
369 
370  if (tsvFileArtifactComments.containsKey(fileName)) {
371  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, tsvFileArtifactComments.get(fileName)));
372  }
373 
374  return bbattributes;
375 
376  }
377 
378  private void checkAttributeType(Collection<BlackboardAttribute> bbattributes, String attrType, String[] columnValues, int columnNumber, BlackboardAttribute.Type attributeType,
379  String fileName) {
380 
381  if (columnValues == null || columnNumber < 0 || columnNumber > columnValues.length || columnValues[columnNumber] == null) {
382  logger.log(Level.WARNING, String.format("Unable to determine column value at index %d in columnValues: %s",
383  columnNumber,
384  columnValues == null ? "<null>" : "[" + String.join(", ", columnValues) + "]"));
385  return;
386  }
387 
388  String columnValue = columnValues[columnNumber];
389 
390  if (attrType.matches("STRING")) {
391  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, columnValue));
392  } else if (attrType.matches("INTEGER")) {
393  try {
394  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, Integer.valueOf(columnValue)));
395  } catch (NumberFormatException ex) {
396  logger.log(Level.WARNING, String.format("Unable to format %s as an integer.", columnValue), ex);
397  }
398  } else if (attrType.matches("LONG")) {
399  try {
400  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, Long.valueOf(columnValue)));
401  } catch (NumberFormatException ex) {
402  logger.log(Level.WARNING, String.format("Unable to format %s as an long.", columnValue), ex);
403  }
404  } else if (attrType.matches("DOUBLE")) {
405  try {
406  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, Double.valueOf(columnValue)));
407  } catch (NumberFormatException ex) {
408  logger.log(Level.WARNING, String.format("Unable to format %s as an double.", columnValue), ex);
409  }
410  } else if (attrType.matches("BYTE")) {
411  try {
412  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, Byte.valueOf(columnValue)));
413  } catch (NumberFormatException ex) {
414  logger.log(Level.WARNING, String.format("Unable to format %s as an byte.", columnValue), ex);
415  }
416  } else if (attrType.matches("DATETIME")) {
417  // format of data should be the same in all the data and the format is 2020-03-28 01:00:17
418  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-d HH:mm:ss", US);
419  Long dateLong = Long.valueOf(0);
420  try {
421  Date newDate = dateFormat.parse(columnValue);
422  dateLong = newDate.getTime() / 1000;
423  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, dateLong));
424  } catch (ParseException ex) {
425  // catching error and displaying date that could not be parsed
426  // we set the timestamp to 0 and continue on processing
427  logger.log(Level.WARNING, String.format("Failed to parse date/time %s for attribute type %s in file %s.", columnValue, attributeType.getDisplayName(), fileName)); //NON-NLS
428  }
429  } else if (attrType.matches("JSON")) {
430 
431  bbattributes.add(new BlackboardAttribute(attributeType, MODULE_NAME, columnValue));
432  } else {
433  // Log this and continue on with processing
434  logger.log(Level.WARNING, String.format("Attribute Type %s not defined.", attrType)); //NON-NLS
435  }
436 
437  }
438 
451  private Map<Integer, String> findColumnsToProcess(String fileName, String line, List<TsvColumn> attrList) {
452  String[] columnNames = line.split("\\t");
453  HashMap<Integer, String> columnsToProcess = new HashMap<>();
454 
455  Integer columnPosition = 0;
456  for (String columnName : columnNames) {
457  // for some reason the first column of the line has unprintable characters so removing them
458  String cleanColumnName = columnName.trim().replaceAll("[^\\n\\r\\t\\p{Print}]", "");
459  for (TsvColumn tsvColumn : attrList) {
460  if (cleanColumnName.equalsIgnoreCase(tsvColumn.getColumnName())) {
461  columnsToProcess.put(columnPosition, tsvColumn.getAttributeName());
462  break;
463  }
464  }
465  columnPosition++;
466  }
467 
468  if (columnsToProcess.size() != attrList.size()) {
469  String missingColumns = IntStream.range(0, attrList.size())
470  .filter((idx) -> !columnsToProcess.containsKey(attrList.get(idx).getAttributeName()))
471  .mapToObj((idx) -> String.format("'%s'", attrList.get(idx).getColumnName() == null ? "<null>" : attrList.get(idx).getColumnName()))
472  .collect(Collectors.joining(", "));
473 
474  logger.log(Level.WARNING, String.format("Columns size expected not found in file %s based on xml from %s. Column Keys Missing = [%s]; Header Line = '%s'.",
475  this.xmlFile == null ? "<null>" : this.xmlFile,
476  fileName,
477  missingColumns,
478  line));
479  }
480 
481  return columnsToProcess;
482  }
483 
484  @NbBundle.Messages({
485  "LeappFileProcessor.cannot.load.artifact.xml=Cannor load xml artifact file.",
486  "LeappFileProcessor.cannotBuildXmlParser=Cannot buld an XML parser.",
487  "LeappFileProcessor_cannotParseXml=Cannot Parse XML file.",
488  "LeappFileProcessor.postartifacts_error=Error posting Blackboard Artifact",
489  "LeappFileProcessor.error.creating.new.artifacts=Error creating new artifacts."
490  })
491 
495  private void loadConfigFile() throws IngestModuleException {
496  Document xmlinput;
497  try {
498  String path = PlatformUtil.getUserConfigDirectory() + File.separator + xmlFile;
499  File f = new File(path);
500  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
501  DocumentBuilder db = dbf.newDocumentBuilder();
502  xmlinput = db.parse(f);
503 
504  } catch (IOException e) {
505  throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_load_artifact_xml() + e.getLocalizedMessage(), e); //NON-NLS
506  } catch (ParserConfigurationException pce) {
507  throw new IngestModuleException(Bundle.LeappFileProcessor_cannotBuildXmlParser() + pce.getLocalizedMessage(), pce); //NON-NLS
508  } catch (SAXException sxe) {
509  throw new IngestModuleException(Bundle.LeappFileProcessor_cannotParseXml() + sxe.getLocalizedMessage(), sxe); //NON-NLS
510  }
511 
512  getFileNode(xmlinput);
513  getArtifactNode(xmlinput);
514  getAttributeNodes(xmlinput);
515 
516  }
517 
518  private void getFileNode(Document xmlinput) {
519 
520  NodeList nlist = xmlinput.getElementsByTagName("FileName"); //NON-NLS
521 
522  for (int i = 0; i < nlist.getLength(); i++) {
523  NamedNodeMap nnm = nlist.item(i).getAttributes();
524  tsvFiles.put(nnm.getNamedItem("filename").getNodeValue().toLowerCase(), nnm.getNamedItem("description").getNodeValue());
525 
526  }
527 
528  }
529 
530  private void getArtifactNode(Document xmlinput) {
531 
532  NodeList artifactNlist = xmlinput.getElementsByTagName("ArtifactName"); //NON-NLS
533  for (int k = 0; k < artifactNlist.getLength(); k++) {
534  NamedNodeMap nnm = artifactNlist.item(k).getAttributes();
535  String artifactName = nnm.getNamedItem("artifactname").getNodeValue();
536  String comment = nnm.getNamedItem("comment").getNodeValue();
537  String parentName = artifactNlist.item(k).getParentNode().getAttributes().getNamedItem("filename").getNodeValue();
538 
539  BlackboardArtifact.Type foundArtifactType = null;
540  try {
541  foundArtifactType = Case.getCurrentCase().getSleuthkitCase().getArtifactType(artifactName);
542  } catch (TskCoreException ex) {
543  logger.log(Level.SEVERE, String.format("There was an issue that arose while trying to fetch artifact type for %s.", artifactName), ex);
544  }
545 
546  if (foundArtifactType == null) {
547  logger.log(Level.SEVERE, String.format("No known artifact mapping found for [artifact: %s, %s]",
548  artifactName, getXmlFileIdentifier(parentName)));
549  }
550 
551  tsvFileArtifacts.put(parentName, artifactName);
552 
553  if (!comment.toLowerCase().matches("null")) {
554  tsvFileArtifactComments.put(parentName, comment);
555  }
556  }
557 
558  }
559 
560  private String getXmlFileIdentifier(String fileName) {
561  return String.format("file: %s, filename: %s",
562  this.xmlFile == null ? "<null>" : this.xmlFile,
563  fileName == null ? "<null>" : fileName);
564  }
565 
566  private String getXmlAttrIdentifier(String fileName, String attributeName) {
567  return String.format("attribute: %s %s",
568  attributeName == null ? "<null>" : attributeName,
569  getXmlFileIdentifier(fileName));
570  }
571 
572  private void getAttributeNodes(Document xmlinput) {
573 
574  NodeList attributeNlist = xmlinput.getElementsByTagName("AttributeName"); //NON-NLS
575  for (int k = 0; k < attributeNlist.getLength(); k++) {
576  NamedNodeMap nnm = attributeNlist.item(k).getAttributes();
577  String attributeName = nnm.getNamedItem("attributename").getNodeValue();
578 
579  if (!attributeName.toLowerCase().matches("null")) {
580  String columnName = nnm.getNamedItem("columnName").getNodeValue();
581  String required = nnm.getNamedItem("required").getNodeValue();
582  String parentName = attributeNlist.item(k).getParentNode().getParentNode().getAttributes().getNamedItem("filename").getNodeValue();
583 
584  BlackboardAttribute.Type foundAttrType = null;
585  try {
586  foundAttrType = Case.getCurrentCase().getSleuthkitCase().getAttributeType(attributeName.toUpperCase());
587  } catch (TskCoreException ex) {
588  logger.log(Level.SEVERE, String.format("There was an issue that arose while trying to fetch attribute type for %s.", attributeName), ex);
589  }
590 
591  if (foundAttrType == null) {
592  logger.log(Level.SEVERE, String.format("No known attribute mapping found for [%s]", getXmlAttrIdentifier(parentName, attributeName)));
593  }
594 
595  if (required != null && required.compareToIgnoreCase("yes") != 0 && required.compareToIgnoreCase("no") != 0) {
596  logger.log(Level.SEVERE, String.format("Required value %s did not match 'yes' or 'no' for [%s]",
597  required, getXmlAttrIdentifier(parentName, attributeName)));
598  }
599 
600  if (columnName == null) {
601  logger.log(Level.SEVERE, String.format("No column name provided for [%s]", getXmlAttrIdentifier(parentName, attributeName)));
602  } else if (columnName.trim().length() != columnName.length()) {
603  logger.log(Level.SEVERE, String.format("Column name '%s' starts or ends with whitespace for [%s]", columnName, getXmlAttrIdentifier(parentName, attributeName)));
604  } else if (columnName.matches("[^ \\S]")) {
605  logger.log(Level.SEVERE, String.format("Column name '%s' contains invalid characters [%s]", columnName, getXmlAttrIdentifier(parentName, attributeName)));
606  }
607 
608  TsvColumn thisCol = new TsvColumn(
609  attributeName.toLowerCase(),
610  columnName.toLowerCase(),
611  "yes".compareToIgnoreCase(required) == 0);
612 
613  if (tsvFileAttributes.containsKey(parentName)) {
614  List<TsvColumn> attrList = tsvFileAttributes.get(parentName);
615  attrList.add(thisCol);
616  tsvFileAttributes.replace(parentName, attrList);
617  } else {
618  List<TsvColumn> attrList = new ArrayList<>();
619  attrList.add(thisCol);
620  tsvFileAttributes.put(parentName, attrList);
621  }
622  }
623 
624  }
625  }
626 
639  private BlackboardArtifact createArtifactWithAttributes(int type, AbstractFile abstractFile, Collection<BlackboardAttribute> bbattributes) {
640  try {
641  BlackboardArtifact bbart = abstractFile.newArtifact(type);
642  bbart.addAttributes(bbattributes);
643  return bbart;
644  } catch (TskException ex) {
645  logger.log(Level.WARNING, Bundle.LeappFileProcessor_error_creating_new_artifacts(), ex); //NON-NLS
646  }
647  return null;
648  }
649 
662  private BlackboardArtifact createArtifactWithAttributes(int type, Content dataSource, Collection<BlackboardAttribute> bbattributes) {
663  try {
664  BlackboardArtifact bbart = dataSource.newArtifact(type);
665  bbart.addAttributes(bbattributes);
666  return bbart;
667  } catch (TskException ex) {
668  logger.log(Level.WARNING, Bundle.LeappFileProcessor_error_creating_new_artifacts(), ex); //NON-NLS
669  }
670  return null;
671  }
672 
679  void postArtifacts(Collection<BlackboardArtifact> artifacts) {
680  if (artifacts == null || artifacts.isEmpty()) {
681  return;
682  }
683 
684  try {
685  Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifacts(artifacts, MODULE_NAME);
686  } catch (Blackboard.BlackboardException ex) {
687  logger.log(Level.SEVERE, Bundle.LeappFileProcessor_postartifacts_error(), ex); //NON-NLS
688  }
689  }
690 
696  private void configExtractor() throws IOException {
698  xmlFile, true);
699  }
700 
701 }
BlackboardArtifact createArtifactWithAttributes(int type, Content dataSource, Collection< BlackboardAttribute > bbattributes)
void checkAttributeType(Collection< BlackboardAttribute > bbattributes, String attrType, String[] columnValues, int columnNumber, BlackboardAttribute.Type attributeType, String fileName)
void processLeappFiles(List< String > LeappFilesToProcess, AbstractFile LeappImageFile)
BlackboardArtifact createArtifactWithAttributes(int type, AbstractFile abstractFile, Collection< BlackboardAttribute > bbattributes)
Collection< BlackboardAttribute > processReadLine(String line, Map< Integer, String > columnNumberToProcess, String fileName)
ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath)
ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile)
static< T > boolean extractResourceToUserConfigDir(final Class< T > resourceClass, final String resourceFileName, boolean overWrite)
void processFile(File LeappFile, List< TsvColumn > attrList, String fileName, BlackboardArtifact.Type artifactType, List< BlackboardArtifact > bbartifacts, Content dataSource)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
void processLeappFiles(List< String > LeappFilesToProcess, Content dataSource)
String getXmlAttrIdentifier(String fileName, String attributeName)
Map< Integer, String > findColumnsToProcess(String fileName, String line, List< TsvColumn > attrList)

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