001    /**
002     *      jline - Java console input library
003     *      Copyright (c) 2002,2003 Marc Prud'hommeaux mwp1@cornell.edu
004     *      
005     *      This library is free software; you can redistribute it and/or
006     *      modify it under the terms of the GNU Lesser General Public
007     *      License as published by the Free Software Foundation; either
008     *      version 2.1 of the License, or (at your option) any later version.
009     *      
010     *      This library is distributed in the hope that it will be useful,
011     *      but WITHOUT ANY WARRANTY; without even the implied warranty of
012     *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     *      Lesser General Public License for more details.
014     *      
015     *      You should have received a copy of the GNU Lesser General Public
016     *      License along with this library; if not, write to the Free Software
017     *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018     */
019    package jline;
020    
021    import java.io.*;
022    import java.util.*;
023    
024    
025    /**
026     *  A command history buffer.
027     *
028     *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
029     */
030    public class History
031    {
032            private List                    history                 = new ArrayList ();
033            private PrintWriter             output                  = null;
034            private int                             maxSize                 = 500;
035            private int                             currentIndex    = 0;
036    
037    
038            /**
039             *  Construstor: initialize a blank history.
040             */
041            public History ()
042            {
043            }
044    
045    
046            /**
047             *  Construstor: initialize History object the the specified
048             *  {@link File} for storage.
049             */
050            public History (final File historyFile)
051                    throws IOException
052            {
053                    setHistoryFile (historyFile);
054            }
055    
056    
057            public void setHistoryFile (final File historyFile)
058                    throws IOException
059            {
060                    if (historyFile.isFile ())
061                            load (new FileInputStream (historyFile));
062                    setOutput (new PrintWriter (new FileWriter (historyFile), true));
063                    flushBuffer ();
064            }
065    
066    
067            /**
068             *  Load the history buffer from the specified InputStream.
069             */
070            public void load (final InputStream in)
071                    throws IOException
072            {
073                    load (new InputStreamReader (in));
074            }
075    
076    
077            /**
078             *  Load the history buffer from the specified Reader.
079             */
080            public void load (final Reader reader)
081                    throws IOException
082            {
083                    BufferedReader breader = new BufferedReader (reader);
084                    List lines = new ArrayList ();
085                    String line;
086                    while ((line = breader.readLine ()) != null)
087                    {
088                            lines.add (line);
089                    }
090    
091                    for (Iterator i = lines.iterator (); i.hasNext (); )
092                            addToHistory ((String)i.next ());
093            }
094    
095    
096            public int size ()
097            {
098                    return history.size ();
099            }
100    
101    
102            /**
103             *  Clear the history buffer
104             */
105            public void clear ()
106            {
107                    history.clear ();
108                    currentIndex = 0;
109            }
110    
111    
112            /**
113             *  Add the specified buffer to the end of the history. The pointer is
114             *  set to the end of the history buffer.
115             */
116            public void addToHistory (final String buffer)
117            {
118                    // don't append duplicates to the end of the buffer
119                    if (history.size () != 0 && buffer.equals (
120                            history.get (history.size () - 1)))
121                            return;
122    
123                    history.add (buffer);
124                    while (history.size () > getMaxSize ())
125                            history.remove (0);
126    
127                    currentIndex = history.size ();
128    
129                    if (getOutput () != null)
130                    {
131                            getOutput ().println (buffer);
132                            getOutput ().flush ();
133                    }
134            }
135    
136    
137            /**
138             *  Flush the entire history buffer to the output PrintWriter.
139             */
140            public void flushBuffer ()
141                    throws IOException
142            {
143                    if (getOutput () != null)
144                    {
145                            for (Iterator i = history.iterator (); i.hasNext ();
146                                    getOutput ().println ((String)i.next ()));
147    
148                            getOutput ().flush ();
149                    }
150            }
151    
152    
153            /**
154             *  Move to the end of the history buffer.
155             */
156            public void moveToEnd ()
157            {
158                    currentIndex = history.size ();
159            }
160    
161    
162            /**
163             *  Set the maximum size that the history buffer will store.
164             */
165            public void setMaxSize (final int maxSize)
166            {
167                    this.maxSize = maxSize;
168            }
169    
170    
171            /**
172             *  Get the maximum size that the history buffer will store.
173             */
174            public int getMaxSize ()
175            {
176                    return this.maxSize;
177            }
178    
179    
180            /**
181             *  The output to which all history elements will be written (or null
182             *  of history is not saved to a buffer).
183             */
184            public void setOutput (final PrintWriter output)
185            {
186                    this.output = output;
187            }
188    
189    
190            /**
191             *  Returns the PrintWriter that is used to store history elements.
192             */
193            public PrintWriter getOutput ()
194            {
195                    return this.output;
196            }
197    
198    
199            /**
200             *  Returns the current history index.
201             */
202            public int getCurrentIndex ()
203            {
204                    return this.currentIndex;
205            }
206    
207    
208            /**
209             *  Return the content of the current buffer.
210             */
211            public String current ()
212            {
213                    if (currentIndex >= history.size ())
214                            return "";
215    
216                    return (String)history.get (currentIndex);
217            }
218    
219    
220            /**
221             *  Move the pointer to the previous element in the buffer.
222             *
223             *  @return  true if we successfully went to the previous element
224             */
225            public boolean previous ()
226            {
227                    if (currentIndex <= 0)
228                            return false;
229    
230                    currentIndex--;
231                    return true;
232            }
233    
234    
235            /**
236             *  Move the pointer to the next element in the buffer.
237             *
238             *  @return  true if we successfully went to the next element
239             */
240            public boolean next ()
241            {
242                    if (currentIndex >= history.size ())
243                            return false;
244    
245                    currentIndex++;
246                    return true;
247            }
248    
249    
250            /**
251             *  Returns an immutable list of the history buffer.
252             */
253            public List getHistoryList ()
254            {
255                    return Collections.unmodifiableList (history);
256            }
257    
258    
259            /**
260             *  Returns the standard {@link AbstractCollection#toString} representation
261             *  of the history list.
262             */
263            public String toString ()
264            {
265                    return history.toString ();
266            }
267    }
268