Autopsy  4.13.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractEdge.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2019 Basis Technology Corp.
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.recentactivity;
20 
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Scanner;
35 import java.util.logging.Level;
36 import org.openide.modules.InstalledFileLocator;
37 import org.openide.util.NbBundle.Messages;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.BlackboardArtifact;
51 import org.sleuthkit.datamodel.Content;
52 import org.sleuthkit.datamodel.TskCoreException;
53 
57 final class ExtractEdge extends Extract {
58 
59  private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
60  private final Path moduleTempResultPath;
61  private Content dataSource;
62  private IngestJobContext context;
63  private HashMap<String, ArrayList<String>> containersTable;
64 
65  private static final String EDGE = "Edge"; //NON-NLS
66 
67  private static final String EDGE_KEYWORD_VISIT = "Visited:"; //NON-NLS
68  private static final String IGNORE_COMMA_IN_QUOTES_REGEX = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"; //NON-NLS
69 
70  private static final String EDGE_TABLE_TYPE_DOWNLOAD = "iedownload"; //NON-NLS
71  private static final String EDGE_TABLE_TYPE_HISTORY = "History"; //NON-NLS
72  private static final String EDGE_TABLE_TYPE_COOKIE = "cookie"; //NON-NLS
73 
74  private static final String EDGE_HEAD_URL = "url"; //NON-NLS
75  private static final String EDGE_HEAD_ACCESSTIME = "accessedtime"; //NON-NLS
76  private static final String EDGE_HEAD_NAME = "name"; //NON-NLS
77  private static final String EDGE_HEAD_CONTAINER_ID = "containerid"; //NON-NLS
78  private static final String EDGE_HEAD_RESPONSEHEAD = "responseheaders"; //NON-NLS
79  private static final String EDGE_HEAD_TITLE = "title"; //NON-NLS
80  private static final String EDGE_HEAD_RDOMAIN = "rdomain"; //NON-NLS
81  private static final String EDGE_HEAD_VALUE = "value"; //NON-NLS
82  private static final String EDGE_HEAD_LASTMOD = "lastmodified"; //NON-NLS
83 
84  private static final String EDGE_WEBCACHE_PREFIX = "WebCacheV01"; //NON-NLS
85  private static final String EDGE_CONTAINER_FILE_PREFIX = "Container_"; //NON-NLS
86  private static final String EDGE_CONTAINER_FILE_EXT = ".csv"; //NON-NLS
87  private static final String EDGE_WEBCACHE_EXT = ".dat"; //NON-NLS
88 
89  private static final String ESE_TOOL_NAME = "ESEDatabaseView.exe"; //NON-NLS
90  private static final String EDGE_WEBCACHE_NAME = "WebCacheV01.dat"; //NON-NLS
91  private static final String EDGE_SPARTAN_NAME = "Spartan.edb"; //NON-NLS
92  private static final String EDGE_CONTAINTERS_FILE_NAME = "Containers.csv"; //NON-NLS
93  private static final String EDGE_FAVORITE_FILE_NAME = "Favorites.csv"; //NON-NLS
94  private static final String EDGE_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
95  private static final String EDGE_ERROR_FILE_NAME = "File.txt"; //NON-NLS
96  private static final String EDGE_WEBCACHE_FOLDER_NAME = "WebCache"; //NON-NLS
97  private static final String EDGE_SPARTAN_FOLDER_NAME = "MicrosoftEdge"; //NON-NLS
98 
99  private static final String ESE_TOOL_FOLDER = "ESEDatabaseView"; //NON-NLS
100  private static final String EDGE_RESULT_FOLDER_NAME = "results"; //NON-NLS
101 
102  private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a"); //NON-NLS
103 
104  @Messages({
105  "ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer",
106  "ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Edge WebCacheV01 file",
107  "ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file",
108  "ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file",
109  "ExtractEdge_Module_Name=Microsoft Edge",
110  "ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history",
111  "Progress_Message_Edge_History=Microsoft Edge History",
112  "Progress_Message_Edge_Bookmarks=Microsoft Edge Bookmarks",
113  "Progress_Message_Edge_Cookies=Microsoft Edge Cookies",
114  })
115 
119  ExtractEdge() throws NoCurrentCaseException {
120  moduleTempResultPath = Paths.get(RAImageIngestModule.getRATempPath(Case.getCurrentCaseThrows(), EDGE), EDGE_RESULT_FOLDER_NAME);
121  }
122 
123  @Override
124  protected String getName() {
125  return Bundle.ExtractEdge_Module_Name();
126  }
127 
128  @Override
129  void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
130  this.dataSource = dataSource;
131  this.context = context;
132  this.setFoundData(false);
133 
134  List<AbstractFile> webCacheFiles = null;
135  List<AbstractFile> spartanFiles = null;
136 
137  try {
138  webCacheFiles = fetchWebCacheDBFiles();
139  } catch (TskCoreException ex) {
140  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_errGettingWebCacheFiles());
141  LOG.log(Level.SEVERE, "Error fetching 'WebCacheV01.dat' files for Microsoft Edge", ex); //NON-NLS
142  }
143 
144  try {
145  spartanFiles = fetchSpartanDBFiles(); // For later use with bookmarks
146  } catch (TskCoreException ex) {
147  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
148  LOG.log(Level.SEVERE, "Error fetching 'spartan.edb' files for Microsoft Edge", ex); //NON-NLS
149  }
150 
151  // No edge files found
152  if (webCacheFiles == null && spartanFiles == null) {
153  return;
154  }
155 
156  this.setFoundData(true);
157 
158  if (!PlatformUtil.isWindowsOS()) {
159  LOG.log(Level.WARNING, "Microsoft Edge files found, unable to parse on Non-Windows system"); //NON-NLS
160  return;
161  }
162 
163  final String esedumper = getPathForESEDumper();
164  if (esedumper == null) {
165  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_unableFindESEViewer());
166  LOG.log(Level.SEVERE, "Error finding ESEDatabaseViewer program"); //NON-NLS
167  return; //If we cannot find the ESEDatabaseView we cannot proceed
168  }
169 
170  try {
171  this.processWebCacheDbFile(esedumper, webCacheFiles, progressBar);
172  } catch (IOException | TskCoreException ex) {
173  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_webcacheFail());
174  LOG.log(Level.SEVERE, "Error returned from processWebCacheDbFile", ex); // NON-NLS
175  }
176 
177  progressBar.progress(Bundle.Progress_Message_Edge_Bookmarks());
178  try {
179  this.processSpartanDbFile(esedumper, spartanFiles);
180  } catch (IOException | TskCoreException ex) {
181  this.addErrorMessage(Bundle.ExtractEdge_process_errMsg_spartanFail());
182  LOG.log(Level.SEVERE, "Error returned from processSpartanDbFile", ex); // NON-NLS
183  }
184  }
185 
195  void processWebCacheDbFile(String eseDumperPath, List<AbstractFile> webCacheFiles, DataSourceIngestModuleProgress progressBar) throws IOException, TskCoreException {
196 
197  for (AbstractFile webCacheFile : webCacheFiles) {
198 
199  if (context.dataSourceIngestIsCancelled()) {
200  return;
201  }
202 
203  clearContainerTable();
204 
205  //Run the dumper
206  String tempWebCacheFileName = EDGE_WEBCACHE_PREFIX
207  + Integer.toString((int) webCacheFile.getId()) + EDGE_WEBCACHE_EXT; //NON-NLS
208  File tempWebCacheFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempWebCacheFileName);
209 
210  try {
211  ContentUtils.writeToFile(webCacheFile, tempWebCacheFile,
212  context::dataSourceIngestIsCancelled);
213  } catch (IOException ex) {
214  throw new IOException("Error writingToFile: " + webCacheFile, ex); //NON-NLS
215  }
216 
217  File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) webCacheFile.getId()));
218  resultsDir.mkdirs();
219  try {
220  executeDumper(eseDumperPath, tempWebCacheFile.getAbsolutePath(),
221  resultsDir.getAbsolutePath());
222 
223  if (context.dataSourceIngestIsCancelled()) {
224  return;
225  }
226 
227  progressBar.progress(Bundle.Progress_Message_Edge_History());
228 
229  this.getHistory(webCacheFile, resultsDir);
230 
231  if (context.dataSourceIngestIsCancelled()) {
232  return;
233  }
234 
235  progressBar.progress(Bundle.Progress_Message_Edge_Cookies());
236 
237  this.getCookies(webCacheFile, resultsDir);
238 
239  } finally {
240  tempWebCacheFile.delete();
241  FileUtil.deleteFileDir(resultsDir);
242  }
243  }
244  }
245 
255  void processSpartanDbFile(String eseDumperPath, List<AbstractFile> spartanFiles) throws IOException, TskCoreException {
256 
257  for (AbstractFile spartanFile : spartanFiles) {
258 
259  if (context.dataSourceIngestIsCancelled()) {
260  return;
261  }
262 
263  //Run the dumper
264  String tempSpartanFileName = EDGE_WEBCACHE_PREFIX
265  + Integer.toString((int) spartanFile.getId()) + EDGE_WEBCACHE_EXT;
266  File tempSpartanFile = new File(RAImageIngestModule.getRATempPath(currentCase, EDGE), tempSpartanFileName);
267 
268  try {
269  ContentUtils.writeToFile(spartanFile, tempSpartanFile,
270  context::dataSourceIngestIsCancelled);
271  } catch (IOException ex) {
272  throw new IOException("Error writingToFile: " + spartanFile, ex); //NON-NLS
273  }
274 
275  File resultsDir = new File(moduleTempResultPath.toAbsolutePath() + Integer.toString((int) spartanFile.getId()));
276  resultsDir.mkdirs();
277  try {
278  executeDumper(eseDumperPath, tempSpartanFile.getAbsolutePath(),
279  resultsDir.getAbsolutePath());
280 
281  if (context.dataSourceIngestIsCancelled()) {
282  return;
283  }
284 
285  this.getBookmarks(spartanFile, resultsDir);
286 
287  } finally {
288  tempSpartanFile.delete();
289  FileUtil.deleteFileDir(resultsDir);
290  }
291  }
292  }
293 
303  private void getHistory(AbstractFile origFile, File resultDir) throws TskCoreException, FileNotFoundException {
304  ArrayList<File> historyFiles = getHistoryFiles(resultDir);
305 
306  if (historyFiles == null) {
307  return;
308  }
309 
310  for (File file : historyFiles) {
311  if (context.dataSourceIngestIsCancelled()) {
312  return;
313  }
314 
315  Scanner fileScanner;
316  try {
317  fileScanner = new Scanner(new FileInputStream(file.toString()));
318  } catch (FileNotFoundException ex) {
319  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
320  continue; // If we couldn't open this file, continue to the next file
321  }
322 
323  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
324 
325  try {
326  List<String> headers = null;
327  while (fileScanner.hasNext()) {
328  if (context.dataSourceIngestIsCancelled()) {
329  return;
330  }
331 
332  String line = fileScanner.nextLine();
333  if (headers == null) {
334  headers = Arrays.asList(line.toLowerCase().split(","));
335  continue;
336  }
337 
338  if (line.contains(EDGE_KEYWORD_VISIT)) {
339  BlackboardArtifact ba = getHistoryArtifact(origFile, headers, line);
340  if (ba != null) {
341  bbartifacts.add(ba);
342  }
343  }
344  }
345  } finally {
346  fileScanner.close();
347  }
348 
349  if (!bbartifacts.isEmpty()) {
350  postArtifacts(bbartifacts);
351  }
352  }
353  }
354 
363  private void getBookmarks(AbstractFile origFile, File resultDir) throws TskCoreException {
364  Scanner fileScanner;
365  File favoriteFile = new File(resultDir, EDGE_FAVORITE_FILE_NAME);
366 
367  try {
368  fileScanner = new Scanner(new FileInputStream(favoriteFile));
369  } catch (FileNotFoundException ex) {
370  // This is a non-fatal error, if the favorites file is not found
371  // there might have not been any favorites\bookmarks
372  return;
373  }
374 
375  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
376 
377  try {
378  List<String> headers = null;
379  while (fileScanner.hasNext()) {
380  String line = fileScanner.nextLine();
381  if (headers == null) {
382  headers = Arrays.asList(line.toLowerCase().split(","));
383  continue;
384  }
385 
386  BlackboardArtifact ba = getBookmarkArtifact(origFile, headers, line);
387  if (ba != null) {
388  bbartifacts.add(ba);
389  }
390  }
391  } finally {
392  fileScanner.close();
393  }
394 
395  if (!bbartifacts.isEmpty()) {
396  postArtifacts(bbartifacts);
397  }
398  }
399 
407  private void getCookies(AbstractFile origFile, File resultDir) throws TskCoreException {
408  File containerFiles[] = resultDir.listFiles((dir, name) -> name.toLowerCase().contains(EDGE_TABLE_TYPE_COOKIE));
409 
410  if (containerFiles == null) {
411  return;
412  }
413 
414  for (File file : containerFiles) {
415  if (context.dataSourceIngestIsCancelled()) {
416  return;
417  }
418 
419  Scanner fileScanner;
420  try {
421  fileScanner = new Scanner(new FileInputStream(file.toString()));
422  } catch (FileNotFoundException ex) {
423  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
424  continue; // If we couldn't open this file, continue to the next file
425  }
426 
427  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
428 
429  try {
430  List<String> headers = null;
431  while (fileScanner.hasNext()) {
432  if (context.dataSourceIngestIsCancelled()) {
433  return;
434  }
435 
436  String line = fileScanner.nextLine();
437  if (headers == null) {
438  headers = Arrays.asList(line.toLowerCase().split(","));
439  continue;
440  }
441 
442  BlackboardArtifact ba = getCookieArtifact(origFile, headers, line);
443  if (ba != null) {
444  bbartifacts.add(ba);
445  }
446  }
447  } finally {
448  fileScanner.close();
449  }
450 
451  if (!bbartifacts.isEmpty()) {
452  postArtifacts(bbartifacts);
453  }
454  }
455  }
456 
467  private void getDownloads(AbstractFile origFile, File resultDir) throws TskCoreException, FileNotFoundException {
468  ArrayList<File> downloadFiles = getDownloadFiles(resultDir);
469 
470  if (downloadFiles == null) {
471  return;
472  }
473 
474  for (File file : downloadFiles) {
475  if (context.dataSourceIngestIsCancelled()) {
476  return;
477  }
478 
479  Scanner fileScanner;
480  try {
481  fileScanner = new Scanner(new FileInputStream(file.toString()));
482  } catch (FileNotFoundException ex) {
483  LOG.log(Level.WARNING, "Unable to find the ESEDatabaseView file at " + file.getPath(), ex); //NON-NLS
484  continue; // If we couldn't open this file, continue to the next file
485  }
486  Collection<BlackboardArtifact> bbartifacts = new ArrayList<>();
487 
488  try {
489  List<String> headers = null;
490  while (fileScanner.hasNext()) {
491  if (context.dataSourceIngestIsCancelled()) {
492  return;
493  }
494 
495  String line = fileScanner.nextLine();
496  if (headers == null) {
497  headers = Arrays.asList(line.toLowerCase().split(","));
498  continue;
499  }
500 
501  if (line.contains(EDGE_TABLE_TYPE_DOWNLOAD)) {
502 
503  BlackboardArtifact ba = getDownloadArtifact(origFile, headers, line);
504  if (ba != null) {
505  bbartifacts.add(ba);
506  }
507  }
508  }
509  } finally {
510  fileScanner.close();
511  }
512 
513  postArtifacts(bbartifacts);
514  }
515  }
516 
522  private String getPathForESEDumper() {
523  Path path = Paths.get(ESE_TOOL_FOLDER, ESE_TOOL_NAME);
524  File eseToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
525  ExtractEdge.class.getPackage().getName(), false);
526  if (eseToolFile != null) {
527  return eseToolFile.getAbsolutePath();
528  }
529 
530  return null;
531  }
532 
539  private List<AbstractFile> fetchWebCacheDBFiles() throws TskCoreException {
541  = currentCase.getServices().getFileManager();
542  return fileManager.findFiles(dataSource, EDGE_WEBCACHE_NAME, EDGE_WEBCACHE_FOLDER_NAME);
543  }
544 
551  private List<AbstractFile> fetchSpartanDBFiles() throws TskCoreException {
553  = currentCase.getServices().getFileManager();
554  return fileManager.findFiles(dataSource, EDGE_SPARTAN_NAME, EDGE_SPARTAN_FOLDER_NAME);
555  }
556 
568  private void executeDumper(String dumperPath, String inputFilePath,
569  String outputDir) throws IOException {
570 
571  final Path outputFilePath = Paths.get(outputDir, EDGE_OUTPUT_FILE_NAME);
572  final Path errFilePath = Paths.get(outputDir, EDGE_ERROR_FILE_NAME);
573  LOG.log(Level.INFO, "Writing ESEDatabaseViewer results to: {0}", outputDir); //NON-NLS
574 
575  List<String> commandLine = new ArrayList<>();
576  commandLine.add(dumperPath);
577  commandLine.add("/table"); //NON-NLS
578  commandLine.add(inputFilePath);
579  commandLine.add("*"); //NON-NLS
580  commandLine.add("/scomma"); //NON-NLS
581  commandLine.add(outputDir + "\\" + "*.csv"); //NON-NLS
582 
583  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
584  processBuilder.redirectOutput(outputFilePath.toFile());
585  processBuilder.redirectError(errFilePath.toFile());
586 
587  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
588  }
589 
600  private BlackboardArtifact getHistoryArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
601  String[] rowSplit = line.split(",");
602 
603  int index = headers.indexOf(EDGE_HEAD_URL);
604  String urlUserStr = rowSplit[index];
605 
606  String[] str = urlUserStr.split("@");
607  String user = (str[0].replace(EDGE_KEYWORD_VISIT, "")).trim();
608  String url = str[1];
609 
610  index = headers.indexOf(EDGE_HEAD_ACCESSTIME);
611  String accessTime = rowSplit[index].trim();
612  Long ftime = null;
613  try {
614  Long epochtime = DATE_FORMATTER.parse(accessTime).getTime();
615  ftime = epochtime / 1000;
616  } catch (ParseException ex) {
617  LOG.log(Level.WARNING, "The Accessed Time format in history file seems invalid " + accessTime, ex); //NON-NLS
618  }
619 
620  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY);
621 
622  bbart.addAttributes(createHistoryAttribute(url, ftime,
623  null, null,
624  this.getName(),
625  NetworkUtils.extractDomain(url), user));
626 
627  return bbart;
628  }
629 
639  private BlackboardArtifact getCookieArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
640  String[] lineSplit = line.split(","); // NON-NLS
641 
642  String accessTime = lineSplit[headers.indexOf(EDGE_HEAD_LASTMOD)].trim();
643  Long ftime = null;
644  try {
645  Long epochtime = DATE_FORMATTER.parse(accessTime).getTime();
646  ftime = epochtime / 1000;
647  } catch (ParseException ex) {
648  LOG.log(Level.WARNING, "The Accessed Time format in history file seems invalid " + accessTime, ex); //NON-NLS
649  }
650 
651  String domain = lineSplit[headers.indexOf(EDGE_HEAD_RDOMAIN)].trim();
652  String name = hexToChar(lineSplit[headers.indexOf(EDGE_HEAD_NAME)].trim());
653  String value = hexToChar(lineSplit[headers.indexOf(EDGE_HEAD_VALUE)].trim());
654  String url = flipDomain(domain);
655 
656  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE);
657  bbart.addAttributes(createCookieAttributes(url, ftime, name, value, this.getName(), NetworkUtils.extractDomain(url)));
658  return bbart;
659  }
660 
674  private BlackboardArtifact getDownloadArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
675  BlackboardArtifact bbart = null;
676 
677  String[] lineSplit = line.split(","); // NON-NLS
678  String rheader = lineSplit[headers.indexOf(EDGE_HEAD_RESPONSEHEAD)];
679 
680  return bbart;
681  }
682 
695  private BlackboardArtifact getBookmarkArtifact(AbstractFile origFile, List<String> headers, String line) throws TskCoreException {
696  // split on all commas as long as they are not inbetween quotes
697  String[] lineSplit = line.split(IGNORE_COMMA_IN_QUOTES_REGEX, -1);
698 
699  String url = lineSplit[headers.indexOf(EDGE_HEAD_URL)];
700  String title = lineSplit[headers.indexOf(EDGE_HEAD_TITLE)].replace("\"", ""); // NON-NLS
701 
702  if (url.isEmpty()) {
703  return null;
704  }
705 
706  BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
707  bbart.addAttributes(createBookmarkAttributes(url, title, null,
708  this.getName(), NetworkUtils.extractDomain(url)));
709  return bbart;
710  }
711 
718  private String hexToChar(String hexString) {
719  String[] hexValues = hexString.split(" "); // NON-NLS
720  StringBuilder output = new StringBuilder();
721 
722  for (String str : hexValues) {
723  try {
724  int value = Integer.parseInt(str, 16);
725  if (value > 31) { // Ignore non-print characters
726  output.append((char) value);
727  }
728  } catch (NumberFormatException ex) {
729  return null;
730  }
731  }
732 
733  return output.toString();
734  }
735 
747  private String flipDomain(String domain) {
748  if (domain == null || domain.isEmpty()) {
749  return null;
750  }
751 
752  String[] tokens = domain.split("\\."); // NON-NLS
753 
754  if (tokens.length < 2 || tokens.length > 3) {
755  return domain; // don't know what to do, just send it back as is
756  }
757 
758  StringBuilder buf = new StringBuilder();
759  if (tokens.length > 2) {
760  buf.append(tokens[2]);
761  buf.append(".");
762  }
763  buf.append(tokens[1]);
764  buf.append(".");
765  buf.append(tokens[0]);
766 
767  return buf.toString();
768  }
769 
777  private ArrayList<File> getDownloadFiles(File resultDir) throws FileNotFoundException {
778  return getContainerFiles(resultDir, EDGE_TABLE_TYPE_DOWNLOAD);
779  }
780 
788  private ArrayList<File> getHistoryFiles(File resultDir) throws FileNotFoundException {
789  return getContainerFiles(resultDir, EDGE_TABLE_TYPE_HISTORY);
790  }
791 
800  private ArrayList<File> getContainerFiles(File resultDir, String type) throws FileNotFoundException {
801  HashMap<String, ArrayList<String>> idTable = getContainerIDTable(resultDir);
802 
803  ArrayList<String> idList = idTable.get(type);
804  if (idList == null) {
805  return null;
806  }
807 
808  ArrayList<File> fileList = new ArrayList<>();
809  for (String str : idList) {
810  String fileName = EDGE_CONTAINER_FILE_PREFIX + str + EDGE_CONTAINER_FILE_EXT;
811  fileList.add(new File(resultDir, fileName));
812  }
813 
814  return fileList;
815  }
816 
827  private HashMap<String, ArrayList<String>> getContainerIDTable(File resultDir) throws FileNotFoundException {
828 
829  if (containersTable == null) {
830  File containerFile = new File(resultDir, EDGE_CONTAINTERS_FILE_NAME);
831 
832  try (Scanner fileScanner = new Scanner(new FileInputStream(containerFile))) {
833  List<String> headers = null;
834  containersTable = new HashMap<>();
835  int nameIdx = 0;
836  int idIdx = 0;
837  while (fileScanner.hasNext()) {
838  String line = fileScanner.nextLine();
839  if (headers == null) {
840  headers = Arrays.asList(line.toLowerCase().split(","));
841  nameIdx = headers.indexOf(EDGE_HEAD_NAME);
842  idIdx = headers.indexOf(EDGE_HEAD_CONTAINER_ID);
843  } else {
844  String[] row = line.split(","); // NON-NLS
845  String name = row[nameIdx];
846  String id = row[idIdx];
847 
848  ArrayList<String> idList = containersTable.get(name);
849  if (idList == null) {
850  idList = new ArrayList<>();
851  containersTable.put(name, idList);
852  }
853 
854  idList.add(id);
855  }
856  }
857  }
858  }
859 
860  return containersTable;
861  }
862 
866  private void clearContainerTable(){
867  containersTable = null;
868  }
869 }
synchronized List< AbstractFile > findFiles(String fileName)

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