    001    /**
    002     *      jline - Java console input library
    003     *      Copyright (c) 2002, 2003, 2004, 2005, Marc Prud'hommeaux <mwp1@cornell.edu>
    004     *      All rights reserved.
    005     *
    006     *      Redistribution and use in source and binary forms, with or
    007     *      without modification, are permitted provided that the following
    008     *      conditions are met:
    009     *
    010     *      Redistributions of source code must retain the above copyright
    011     *      notice, this list of conditions and the following disclaimer.
    012     *
    013     *      Redistributions in binary form must reproduce the above copyright
    014     *      notice, this list of conditions and the following disclaimer
    015     *      in the documentation and/or other materials provided with
    016     *      the distribution.
    017     *
    018     *      Neither the name of JLine nor the names of its contributors
    019     *      may be used to endorse or promote products derived from this
    020     *      software without specific prior written permission.
    021     *
    022     *      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    023     *      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
    024     *      BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
    025     *      AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    026     *      EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    027     *      FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
    028     *      OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    029     *      PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    030     *      DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    031     *      AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    032     *      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    033     *      IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    034     *      OF THE POSSIBILITY OF SUCH DAMAGE.
    035     */
    036    package jline;
    037
    038    import java.io.*;
    039    import java.util.*;
    040
    041
    042    /**
    043     *  A command history buffer.
    044     *
    045     *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
    046     */
    047    public class History
    048    {
    049            private List                    history                 = new ArrayList ();
    050            private PrintWriter             output                  = null;
    051            private int                             maxSize                 = 500;
    052            private int                             currentIndex    = 0;
    053
    054
    055            /**
    056             *  Construstor: initialize a blank history.
    057             */
    058            public History ()
    059            {
    060            }
    061
    062
    063            /**
    064             *  Construstor: initialize History object the the specified
    065             *  {@link File} for storage.
    066             */
    067            public History (final File historyFile)
    068                    throws IOException
    069            {
    070                    setHistoryFile (historyFile);
    071            }
    072
    073
    074            public void setHistoryFile (final File historyFile)
    075                    throws IOException
    076            {
    077                    if (historyFile.isFile ())
    078                            load (new FileInputStream (historyFile));
    079                    setOutput (new PrintWriter (new FileWriter (historyFile), true));
    080                    flushBuffer ();
    081            }
    082
    083
    084            /**
    085             *  Load the history buffer from the specified InputStream.
    086             */
    087            public void load (final InputStream in)
    088                    throws IOException
    089            {
    090                    load (new InputStreamReader (in));
    091            }
    092
    093
    094            /**
    095             *  Load the history buffer from the specified Reader.
    096             */
    097            public void load (final Reader reader)
    098                    throws IOException
    099            {
    100                    BufferedReader breader = new BufferedReader (reader);
    101                    List lines = new ArrayList ();
    102                    String line;
    103                    while ((line = breader.readLine ()) != null)
    104                    {
    105                            lines.add (line);
    106                    }
    107
    108                    for (Iterator i = lines.iterator (); i.hasNext (); )
    109                            addToHistory ((String)i.next ());
    110            }
    111
    112
    113            public int size ()
    114            {
    115                    return history.size ();
    116            }
    117
    118
    119            /**
    120             *  Clear the history buffer
    121             */
    122            public void clear ()
    123            {
    124                    history.clear ();
    125                    currentIndex = 0;
    126            }
    127
    128
    129            /**
    130             *  Add the specified buffer to the end of the history. The pointer is
    131             *  set to the end of the history buffer.
    132             */
    133            public void addToHistory (final String buffer)
    134            {
    135                    // don't append duplicates to the end of the buffer
    136                    if (history.size () != 0 && buffer.equals (
    137                            history.get (history.size () - 1)))
    138                            return;
    139
    140                    history.add (buffer);
    141                    while (history.size () > getMaxSize ())
    142                            history.remove (0);
    143
    144                    currentIndex = history.size ();
    145
    146                    if (getOutput () != null)
    147                    {
    148                            getOutput ().println (buffer);
    149                            getOutput ().flush ();
    150                    }
    151            }
    152
    153
    154            /**
    155             *  Flush the entire history buffer to the output PrintWriter.
    156             */
    157            public void flushBuffer ()
    158                    throws IOException
    159            {
    160                    if (getOutput () != null)
    161                    {
    162                            for (Iterator i = history.iterator (); i.hasNext ();
    163                                    getOutput ().println ((String)i.next ()));
    164
    165                            getOutput ().flush ();
    166                    }
    167            }
    168
    169
    170            /**
    171             *  Move to the end of the history buffer.
    172             */
    173            public void moveToEnd ()
    174            {
    175                    currentIndex = history.size ();
    176            }
    177
    178
    179            /**
    180             *  Set the maximum size that the history buffer will store.
    181             */
    182            public void setMaxSize (final int maxSize)
    183            {
    184                    this.maxSize = maxSize;
    185            }
    186
    187
    188            /**
    189             *  Get the maximum size that the history buffer will store.
    190             */
    191            public int getMaxSize ()
    192            {
    193                    return this.maxSize;
    194            }
    195
    196
    197            /**
    198             *  The output to which all history elements will be written (or null
    199             *  of history is not saved to a buffer).
    200             */
    201            public void setOutput (final PrintWriter output)
    202            {
    203                    this.output = output;
    204            }
    205
    206
    207            /**
    208             *  Returns the PrintWriter that is used to store history elements.
    209             */
    210            public PrintWriter getOutput ()
    211            {
    212                    return this.output;
    213            }
    214
    215
    216            /**
    217             *  Returns the current history index.
    218             */
    219            public int getCurrentIndex ()
    220            {
    221                    return this.currentIndex;
    222            }
    223
    224
    225            /**
    226             *  Return the content of the current buffer.
    227             */
    228            public String current ()
    229            {
    230                    if (currentIndex >= history.size ())
    231                            return "";
    232
    233                    return (String)history.get (currentIndex);
    234            }
    235
    236
    237            /**
    238             *  Move the pointer to the previous element in the buffer.
    239             *
    240             *  @return  true if we successfully went to the previous element
    241             */
    242            public boolean previous ()
    243            {
    244                    if (currentIndex <= 0)
    245                            return false;
    246
    247                    currentIndex--;
    248                    return true;
    249            }
    250
    251
    252            /**
    253             *  Move the pointer to the next element in the buffer.
    254             *
    255             *  @return  true if we successfully went to the next element
    256             */
    257            public boolean next ()
    258            {
    259                    if (currentIndex >= history.size ())
    260                            return false;
    261
    262                    currentIndex++;
    263                    return true;
    264            }
    265
    266
    267            /**
    268             *  Returns an immutable list of the history buffer.
    269             */
    270            public List getHistoryList ()
    271            {
    272                    return Collections.unmodifiableList (history);
    273            }
    274
    275
    276            /**
    277             *  Returns the standard {@link AbstractCollection#toString} representation
    278             *  of the history list.
    279             */
    280            public String toString ()
    281            {
    282                    return history.toString ();
    283            }
    284    }
    285