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 (File historyFile)
051                    throws IOException
052            {
053                    setHistoryFile (historyFile);
054            }
055    
056    
057            public void setHistoryFile (File historyFile)
058                    throws IOException
059            {
060                    if (historyFile.isFile ())
061                            load (new FileInputStream (historyFile));
062                    setOutput (new PrintWriter (new FileWriter (historyFile, false), true));
063                    flushBuffer ();
064            }
065    
066    
067            /** 
068             *  Load the history buffer from the specified InputStream.
069             */
070            public void load (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 (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 (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 (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 (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