Skip to content

Commit

Permalink
Merge pull request #332 from VineetReynolds/FORGE-1012
Browse files Browse the repository at this point in the history
FORGE-1012, FORGE-942, FORGE-554 (Multiple bug fixes for Shell)
  • Loading branch information
gastaldi committed Jul 17, 2013
2 parents c4eb146 + 6cf263d commit 7f80a75
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ else if (path.startsWith("~"))
// for windows, support drive letter prefixes here.
else if (isWindows && path.matches("^[a-zA-Z]{1,1}:(/|\\\\).*"))
{
int idx = path.indexOf(slashChar) + 1;
int idx = path.lastIndexOf(slashChar) + 1;
r = new DirectoryResource(factory, new File(path.substring(0, idx)).getAbsoluteFile());
cursor = idx;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public boolean keyPress(final int key)
}
else
{
shell.print("exit");
shell.println("exit");
shutdown.fire(new Shutdown(Status.NORMAL));
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.fusesource.jansi.internal.WindowsSupport;
import org.jboss.forge.shell.util.OSUtils;

/**
Expand All @@ -28,7 +29,7 @@ public class ConsoleInputSession
* awaiting termination during an internal restart of Forge, and another reader thread would have just started but
* would be awaiting the lock on System.in.
*/
private static final ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(1000);
private static final ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(1000);

private volatile boolean connected;

Expand All @@ -39,23 +40,17 @@ public ConsoleInputSession(InputStream consoleStream)

this.externalInputStream = new InputStream()
{
private String b;
private int c;
private Integer b;

@Override
public int read() throws IOException
{
try
{
if (b == null || c == b.length())
{
b = blockingQueue.poll(365, TimeUnit.DAYS);
c = 0;
}

b = blockingQueue.poll(365, TimeUnit.DAYS);
if (b != null)
{
return b.charAt(c++);
return b;
}
}
catch (InterruptedException e)
Expand All @@ -71,47 +66,25 @@ public int read() throws IOException

private void startReader()
{
Thread readerThread = new Thread()
Thread readerThread = null;
if (OSUtils.isWindows())
{
@Override
public void run()
{
while (connected)
{
try
{
byte[] bBuf = new byte[20];
int read = consoleStream.read(bBuf);

if (read > 0)
{
blockingQueue.put(new String(bBuf, 0, read));
}

Thread.sleep(10);
}
catch (IOException e)
{
if (connected)
{
connected = false;
throw new RuntimeException("broken pipe");
}
}
catch (InterruptedException e)
{
//
}
}
}
};

readerThread = new WindowsReaderThread();
}
else
{
readerThread = new GenericReaderThread();
}
readerThread.setDaemon(true);
readerThread.start();
}

public void interruptPipe()
{
blockingQueue.offer(OSUtils.getLineSeparator());
for(byte b : OSUtils.getLineSeparator().getBytes())
{
blockingQueue.offer((int) b);
}
}

public void stop()
Expand All @@ -124,4 +97,67 @@ public InputStream getExternalInputStream()
return externalInputStream;
}

/**
* The generic reader thread implementation for OSes other than Windows. Relies on reading from System,in with the
* terminal having being set to raw mode through stty.
*/
private final class GenericReaderThread extends Thread
{
@Override
public void run()
{
while (connected)
{
try
{
int read = consoleStream.read();
blockingQueue.put(read);
Thread.sleep(10);
}
catch (IOException e)
{
if (connected)
{
connected = false;
throw new RuntimeException("broken pipe");
}
}
catch (InterruptedException e)
{
// Stop reading
break;
}
}
}
}

/**
* The reader thread for Windows. Delegates to Jansi to obtain the keystrokes since System.in does not provide
* keystrokes for arrow keys in a clean way.
*
* See FORGE-942: the keystrokes for special events are available via System.in only when some special sequence of
* events is triggered, and not in all cases.
*/
private final class WindowsReaderThread extends Thread
{
@Override
public void run()
{
while (connected)
{
try
{
int read = WindowsSupport.readByte();
blockingQueue.put(read);
Thread.sleep(10);
}
catch (InterruptedException e)
{
// Stop reading
break;
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ else if (valueMap.get(option) == null)
for (Resource<?> r : new PathspecParser(resourceFactory, shell.getCurrentResource(), val + "*")
.resolve())
{
// Add result to the results list, and append a '/' if the
// Add result to the results list, and append a file separator ('/' or '\\') if the
// resource has children.
String name = ("~".equals(val) ? "~/" : "") + r.getName()
+ (r.isFlagSet(ResourceFlag.Node) ? "/" : "");
String name = ("~".equals(val) ? "~" + File.separator : "") + r.getName()
+ (r.isFlagSet(ResourceFlag.Node) ? File.separator : "");
results.add(name);
}

Expand Down

0 comments on commit 7f80a75

Please sign in to comment.