1 /*
   2  * Copyright (c) 2002-2012, the original author or authors.
   3  *
   4  * This software is distributable under the BSD license. See the terms of the
   5  * BSD license in the documentation provided with this software.
   6  *
   7  * http://www.opensource.org/licenses/bsd-license.php
   8  */
   9 package jdk.internal.jline.console.history;
  10 
  11 import java.io.BufferedOutputStream;
  12 import java.io.BufferedReader;
  13 import java.io.File;
  14 import java.io.FileOutputStream;
  15 import java.io.FileReader;
  16 import java.io.Flushable;
  17 import java.io.IOException;
  18 import java.io.InputStream;
  19 import java.io.InputStreamReader;
  20 import java.io.PrintStream;
  21 import java.io.Reader;
  22 
  23 import jdk.internal.jline.internal.Log;
  24 import static jdk.internal.jline.internal.Preconditions.checkNotNull;
  25 
  26 /**
  27  * {@link History} using a file for persistent backing.
  28  * <p/>
  29  * Implementers should install shutdown hook to call {@link FileHistory#flush}
  30  * to save history to disk.
  31  *
  32  * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
  33  * @since 2.0
  34  */
  35 public class FileHistory
  36     extends MemoryHistory
  37     implements PersistentHistory, Flushable
  38 {
  39     private final File file;
  40 
  41     public FileHistory(final File file) throws IOException {
  42         this.file = checkNotNull(file);
  43         load(file);
  44     }
  45 
  46     public File getFile() {
  47         return file;
  48     }
  49 
  50     public void load(final File file) throws IOException {
  51         checkNotNull(file);
  52         if (file.exists()) {
  53             Log.trace("Loading history from: ", file);
  54             load(new FileReader(file));
  55         }
  56     }
  57 
  58     public void load(final InputStream input) throws IOException {
  59         checkNotNull(input);
  60         load(new InputStreamReader(input));
  61     }
  62 
  63     public void load(final Reader reader) throws IOException {
  64         checkNotNull(reader);
  65         BufferedReader input = new BufferedReader(reader);
  66 
  67         String item;
  68         while ((item = input.readLine()) != null) {
  69             internalAdd(item);
  70         }
  71     }
  72 
  73     public void flush() throws IOException {
  74         Log.trace("Flushing history");
  75 
  76         if (!file.exists()) {
  77             File dir = file.getParentFile();
  78             if (!dir.exists() && !dir.mkdirs()) {
  79                 Log.warn("Failed to create directory: ", dir);
  80             }
  81             if (!file.createNewFile()) {
  82                 Log.warn("Failed to create file: ", file);
  83             }
  84         }
  85 
  86         PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
  87         try {
  88             for (Entry entry : this) {
  89                 out.println(entry.value());
  90             }
  91         }
  92         finally {
  93             out.close();
  94         }
  95     }
  96 
  97     public void purge() throws IOException {
  98         Log.trace("Purging history");
  99 
 100         clear();
 101 
 102         if (!file.delete()) {
 103             Log.warn("Failed to delete history file: ", file);
 104         }
 105     }
 106 }