View Javadoc

1   /*
2    * Copyright (c) 2002-2012, the original author or authors.
3    *
4    * This software is distributable under the BSD license. See the terms of the
5    * BSD license in the documentation provided with this software.
6    *
7    * http://www.opensource.org/licenses/bsd-license.php
8    */
9   package jline.console.internal;
10   
11  import jline.console.ConsoleReader;
12   
13  import java.io.IOException;
14  import java.io.InputStream;
15  import java.io.SequenceInputStream;
16  import java.util.Enumeration;
17  
18  // FIXME: Clean up API and move to jline.console.runner package
19  
20  /**
21   * An {@link InputStream} implementation that wraps a {@link ConsoleReader}.
22   * It is useful for setting up the {@link System#in} for a generic console.
23   *
24   * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
25   * @since 2.7
26   */
27  class ConsoleReaderInputStream
28      extends SequenceInputStream
29  {
30      private static InputStream systemIn = System.in;
31   
32      public static void setIn() throws IOException {
33          setIn(new ConsoleReader());
34      }
35   
36      public static void setIn(final ConsoleReader reader) {
37          System.setIn(new ConsoleReaderInputStream(reader));
38      }
39   
40      /**
41       * Restore the original {@link System#in} input stream.
42       */
43      public static void restoreIn() {
44          System.setIn(systemIn);
45      }
46   
47      public ConsoleReaderInputStream(final ConsoleReader reader) {
48          super(new ConsoleEnumeration(reader));
49      }
50   
51      private static class ConsoleEnumeration
52          implements Enumeration
53      {
54          private final ConsoleReader reader;
55          private ConsoleLineInputStream next = null;
56          private ConsoleLineInputStream prev = null;
57   
58          public ConsoleEnumeration(final ConsoleReader reader) {
59              this.reader = reader;
60          }
61   
62          public Object nextElement() {
63              if (next != null) {
64                  InputStream n = next;
65                  prev = next;
66                  next = null;
67   
68                  return n;
69              }
70   
71              return new ConsoleLineInputStream(reader);
72          }
73   
74          public boolean hasMoreElements() {
75              // the last line was null
76              if ((prev != null) && (prev.wasNull == true)) {
77                  return false;
78              }
79   
80              if (next == null) {
81                  next = (ConsoleLineInputStream) nextElement();
82              }
83   
84              return next != null;
85          }
86      }
87   
88      private static class ConsoleLineInputStream
89          extends InputStream
90      {
91          private final ConsoleReader reader;
92          private String line = null;
93          private int index = 0;
94          private boolean eol = false;
95          protected boolean wasNull = false;
96   
97          public ConsoleLineInputStream(final ConsoleReader reader) {
98              this.reader = reader;
99          }
100  
101         public int read() throws IOException {
102             if (eol) {
103                 return -1;
104             }
105  
106             if (line == null) {
107                 line = reader.readLine();
108             }
109  
110             if (line == null) {
111                 wasNull = true;
112                 return -1;
113             }
114  
115             if (index >= line.length()) {
116                 eol = true;
117                 return '\n'; // lines are ended with a newline
118             }
119  
120             return line.charAt(index++);
121         }
122     }
123 }