001 /** 002 * jline - Java console input library 003 * Copyright (c) 2002-2006, 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 * An {@link InputStream} implementation that wraps a {@link ConsoleReader}. 044 * It is useful for setting up the {@link System#in} for a generic 045 * console. 046 * 047 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> 048 */ 049 public class ConsoleReaderInputStream 050 extends SequenceInputStream 051 { 052 private static InputStream systemIn = System.in; 053 054 055 public static void setIn () 056 throws IOException 057 { 058 setIn (new ConsoleReader ()); 059 } 060 061 062 public static void setIn (final ConsoleReader reader) 063 { 064 System.setIn (new ConsoleReaderInputStream (reader)); 065 } 066 067 068 /** 069 * Restore the original {@link System#in} input stream. 070 */ 071 public static void restoreIn () 072 { 073 System.setIn (systemIn); 074 } 075 076 077 public ConsoleReaderInputStream (final ConsoleReader reader) 078 { 079 super (new ConsoleEnumeration (reader)); 080 } 081 082 083 private static class ConsoleEnumeration 084 implements Enumeration 085 { 086 private final ConsoleReader reader; 087 private ConsoleLineInputStream next = null; 088 private ConsoleLineInputStream prev = null; 089 090 091 public ConsoleEnumeration (final ConsoleReader reader) 092 { 093 this.reader = reader; 094 } 095 096 097 public Object nextElement () 098 { 099 if (next != null) 100 { 101 InputStream n = next; 102 prev = next; 103 next = null; 104 return n; 105 } 106 107 return new ConsoleLineInputStream (reader); 108 } 109 110 111 public boolean hasMoreElements () 112 { 113 // the last line was null 114 if (prev != null && prev.wasNull == true) 115 return false; 116 117 if (next == null) 118 next = (ConsoleLineInputStream)nextElement (); 119 120 return next != null; 121 } 122 } 123 124 125 private static class ConsoleLineInputStream 126 extends InputStream 127 { 128 private final ConsoleReader reader; 129 private String line = null; 130 private int index = 0; 131 private boolean eol = false; 132 protected boolean wasNull = false; 133 134 public ConsoleLineInputStream (final ConsoleReader reader) 135 { 136 this.reader = reader; 137 } 138 139 140 public int read () 141 throws IOException 142 { 143 if (eol) 144 return -1; 145 146 if (line == null) 147 line = reader.readLine (); 148 149 if (line == null) 150 { 151 wasNull = true; 152 return -1; 153 } 154 155 if (index >= line.length ()) 156 { 157 eol = true; 158 return '\n'; // lines are ended with a newline 159 } 160 161 return line.charAt (index++); 162 } 163 } 164 } 165