001 /*
002 * Copyright (c) 2002-2006, Marc Prud'hommeaux. All rights reserved.
003 *
004 * This software is distributable under the BSD license. See the terms of the
005 * BSD license in the documentation provided with this software.
006 */
007 package jline;
008
009 import java.io.*;
010 import java.util.*;
011
012 /**
013 * A command history buffer.
014 *
015 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
016 */
017 public class History {
018 private List history = new ArrayList();
019 private PrintWriter output = null;
020 private int maxSize = 500;
021 private int currentIndex = 0;
022
023 /**
024 * Construstor: initialize a blank history.
025 */
026 public History() {
027 }
028
029 /**
030 * Construstor: initialize History object the the specified
031 * {@link File} for storage.
032 */
033 public History(final File historyFile) throws IOException {
034 setHistoryFile(historyFile);
035 }
036
037 public void setHistoryFile(final File historyFile)
038 throws IOException {
039 if (historyFile.isFile()) {
040 load(new FileInputStream(historyFile));
041 }
042
043 setOutput(new PrintWriter(new FileWriter(historyFile), true));
044 flushBuffer();
045 }
046
047 /**
048 * Load the history buffer from the specified InputStream.
049 */
050 public void load(final InputStream in) throws IOException {
051 load(new InputStreamReader(in));
052 }
053
054 /**
055 * Load the history buffer from the specified Reader.
056 */
057 public void load(final Reader reader) throws IOException {
058 BufferedReader breader = new BufferedReader(reader);
059 List lines = new ArrayList();
060 String line;
061
062 while ((line = breader.readLine()) != null) {
063 lines.add(line);
064 }
065
066 for (Iterator i = lines.iterator(); i.hasNext();) {
067 addToHistory((String) i.next());
068 }
069 }
070
071 public int size() {
072 return history.size();
073 }
074
075 /**
076 * Clear the history buffer
077 */
078 public void clear() {
079 history.clear();
080 currentIndex = 0;
081 }
082
083 /**
084 * Add the specified buffer to the end of the history. The pointer is
085 * set to the end of the history buffer.
086 */
087 public void addToHistory(final String buffer) {
088 // don't append duplicates to the end of the buffer
089 if ((history.size() != 0)
090 && buffer.equals(history.get(history.size() - 1))) {
091 return;
092 }
093
094 history.add(buffer);
095
096 while (history.size() > getMaxSize()) {
097 history.remove(0);
098 }
099
100 currentIndex = history.size();
101
102 if (getOutput() != null) {
103 getOutput().println(buffer);
104 getOutput().flush();
105 }
106 }
107
108 /**
109 * Flush the entire history buffer to the output PrintWriter.
110 */
111 public void flushBuffer() throws IOException {
112 if (getOutput() != null) {
113 for (Iterator i = history.iterator(); i.hasNext();
114 getOutput().println((String) i.next())) {
115 ;
116 }
117
118 getOutput().flush();
119 }
120 }
121
122 /**
123 * Move to the end of the history buffer.
124 */
125 public void moveToEnd() {
126 currentIndex = history.size();
127 }
128
129 /**
130 * Set the maximum size that the history buffer will store.
131 */
132 public void setMaxSize(final int maxSize) {
133 this.maxSize = maxSize;
134 }
135
136 /**
137 * Get the maximum size that the history buffer will store.
138 */
139 public int getMaxSize() {
140 return this.maxSize;
141 }
142
143 /**
144 * The output to which all history elements will be written (or null
145 * of history is not saved to a buffer).
146 */
147 public void setOutput(final PrintWriter output) {
148 this.output = output;
149 }
150
151 /**
152 * Returns the PrintWriter that is used to store history elements.
153 */
154 public PrintWriter getOutput() {
155 return this.output;
156 }
157
158 /**
159 * Returns the current history index.
160 */
161 public int getCurrentIndex() {
162 return this.currentIndex;
163 }
164
165 /**
166 * Return the content of the current buffer.
167 */
168 public String current() {
169 if (currentIndex >= history.size()) {
170 return "";
171 }
172
173 return (String) history.get(currentIndex);
174 }
175
176 /**
177 * Move the pointer to the previous element in the buffer.
178 *
179 * @return true if we successfully went to the previous element
180 */
181 public boolean previous() {
182 if (currentIndex <= 0) {
183 return false;
184 }
185
186 currentIndex--;
187
188 return true;
189 }
190
191 /**
192 * Move the pointer to the next element in the buffer.
193 *
194 * @return true if we successfully went to the next element
195 */
196 public boolean next() {
197 if (currentIndex >= history.size()) {
198 return false;
199 }
200
201 currentIndex++;
202
203 return true;
204 }
205
206 /**
207 * Returns an immutable list of the history buffer.
208 */
209 public List getHistoryList() {
210 return Collections.unmodifiableList(history);
211 }
212
213 /**
214 * Returns the standard {@link AbstractCollection#toString} representation
215 * of the history list.
216 */
217 public String toString() {
218 return history.toString();
219 }
220 }