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 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 jline.internal.Log;
  24 
  25 import static jline.internal.Preconditions.checkNotNull;
  26 
  27 /**
  28  * {@link History} using a file for persistent backing.
  29  * <p/>
  30  * Implementers should install shutdown hook to call {@link FileHistory#flush}
  31  * to save history to disk.
  32  *
  33  * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
  34  * @since 2.0
  35  */
  36 public class FileHistory
  37     extends MemoryHistory
  38     implements PersistentHistory, Flushable
  39 {
  40     private final File file;
  41 
  42     public FileHistory(final File file) throws IOException {
  43         this.file = checkNotNull(file);
  44         load(file);
  45     }
  46 
  47     public File getFile() {
  48         return file;
  49     }
  50 
  51     public void load(final File file) throws IOException {
  52         checkNotNull(file);
  53         if (file.exists()) {
  54             Log.trace("Loading history from: ", file);
  55             load(new FileReader(file));
  56         }
  57     }
  58 
  59     public void load(final InputStream input) throws IOException {
  60         checkNotNull(input);
  61         load(new InputStreamReader(input));
  62     }
  63 
  64     public void load(final Reader reader) throws IOException {
  65         checkNotNull(reader);
  66         BufferedReader input = new BufferedReader(reader);
  67 
  68         String item;
  69         while ((item = input.readLine()) != null) {
  70             internalAdd(item);
  71         }
  72     }
  73 
  74     public void flush() throws IOException {
  75         Log.trace("Flushing history");
  76 
  77         if (!file.exists()) {
  78             File dir = file.getParentFile();
  79             if (!dir.exists() && !dir.mkdirs()) {
  80                 Log.warn("Failed to create directory: ", dir);
  81             }
  82             if (!file.createNewFile()) {
  83                 Log.warn("Failed to create file: ", file);
  84             }
  85         }
  86 
  87         PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
  88         try {
  89             for (Entry entry : this) {
  90                 out.println(entry.value());
  91             }
  92         }
  93         finally {
  94             out.close();
  95         }
  96     }
  97 
  98     public void purge() throws IOException {
  99         Log.trace("Purging history");
 100 
 101         clear();
 102 
 103         if (!file.delete()) {
 104             Log.warn("Failed to delete history file: ", file);
 105         }
 106     }
 107 }