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 }