1 /* |
|
2 * Copyright (c) 2002-2016, 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 /** |
|
42 * Load a history file into memory, truncating to default max size. |
|
43 */ |
|
44 public FileHistory(final File file) throws IOException { |
|
45 this(file, true); |
|
46 } |
|
47 |
|
48 /** |
|
49 * Create a FileHistory, but only initialize if doInit is true. This allows |
|
50 * setting maxSize or other settings; call load() before using if doInit is |
|
51 * false. |
|
52 */ |
|
53 public FileHistory(final File file, final boolean doInit) throws IOException { |
|
54 this.file = checkNotNull(file).getAbsoluteFile(); |
|
55 if (doInit) { |
|
56 load(); |
|
57 } |
|
58 } |
|
59 |
|
60 /** |
|
61 * Load history from file, e.g. if using delayed init. |
|
62 */ |
|
63 public void load() throws IOException { |
|
64 load(file); |
|
65 } |
|
66 |
|
67 public File getFile() { |
|
68 return file; |
|
69 } |
|
70 |
|
71 public void load(final File file) throws IOException { |
|
72 checkNotNull(file); |
|
73 if (file.exists()) { |
|
74 Log.trace("Loading history from: ", file); |
|
75 FileReader reader = null; |
|
76 try{ |
|
77 reader = new FileReader(file); |
|
78 load(reader); |
|
79 } finally{ |
|
80 if(reader != null){ |
|
81 reader.close(); |
|
82 } |
|
83 } |
|
84 } |
|
85 } |
|
86 |
|
87 public void load(final InputStream input) throws IOException { |
|
88 checkNotNull(input); |
|
89 load(new InputStreamReader(input)); |
|
90 } |
|
91 |
|
92 public void load(final Reader reader) throws IOException { |
|
93 checkNotNull(reader); |
|
94 BufferedReader input = new BufferedReader(reader); |
|
95 |
|
96 String item; |
|
97 while ((item = input.readLine()) != null) { |
|
98 internalAdd(item); |
|
99 } |
|
100 } |
|
101 |
|
102 public void flush() throws IOException { |
|
103 Log.trace("Flushing history"); |
|
104 |
|
105 if (!file.exists()) { |
|
106 File dir = file.getParentFile(); |
|
107 if (!dir.exists() && !dir.mkdirs()) { |
|
108 Log.warn("Failed to create directory: ", dir); |
|
109 } |
|
110 if (!file.createNewFile()) { |
|
111 Log.warn("Failed to create file: ", file); |
|
112 } |
|
113 } |
|
114 |
|
115 PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(file))); |
|
116 try { |
|
117 for (Entry entry : this) { |
|
118 out.println(entry.value()); |
|
119 } |
|
120 } |
|
121 finally { |
|
122 out.close(); |
|
123 } |
|
124 } |
|
125 |
|
126 public void purge() throws IOException { |
|
127 Log.trace("Purging history"); |
|
128 |
|
129 clear(); |
|
130 |
|
131 if (!file.delete()) { |
|
132 Log.warn("Failed to delete history file: ", file); |
|
133 } |
|
134 } |
|
135 } |
|