Wednesday, February 4, 2009

JLine UI for Apache Felix

Apache Felix by default provides a very simple text shell UI. Unfortunately, it is not very convenient to use. For example, it doesn't support command history. JLineTUI is a replacement, which make uses of the wondeful JLine library to provide helpful features like command history etc.

Source Code: JLineTUIActivator.java

package us.timetrack.felix.shell;

import org.apache.felix.shell.ShellService;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;

public class JLineTUIActivator implements BundleActivator {
private BundleContext _ctx = null;
private ServiceTracker _tracker = null;
private Thread _thread = null;
private ShellTUIRunnable _runnable = null;

@Override
public void start(BundleContext ctx) throws Exception {
this._ctx = ctx;
_tracker = new ServiceTracker(_ctx, ShellService.class.getName(), null);
_tracker.open();
_runnable = new ShellTUIRunnable(_tracker);
_thread = new Thread(_runnable);
_thread.start();
}

@Override
public void stop(BundleContext ctx) throws Exception {
if(_runnable!=null) _runnable.stop();
_thread.join();
_tracker.close();
}
}


Source Code: ShellTUIRunnable.java

package us.timetrack.felix.shell;

import java.io.IOException;
import java.io.PrintStream;

import jline.ConsoleReader;

import org.apache.felix.shell.ShellService;
import org.osgi.util.tracker.ServiceTracker;

class ShellTUIRunnable implements Runnable {
private static final String PROMPT="$";
private ServiceTracker _tracker = null;
private volatile boolean _stop = false;
private PrintStream _out = null;

ShellTUIRunnable(ServiceTracker tracker){
this._tracker = tracker;
this._out = System.out;
}

void stop(){
_stop = true;
}

@Override
public void run() {
ConsoleReader reader = openConsoleReader();
if( reader==null ) return;
while(!_stop){
dispatchCommand(readCommandLine(reader));
}
}

private void dispatchCommand(String command) {
if(command==null) return;
command = command.trim();
if(command.isEmpty()) return;
ShellService service = (ShellService)_tracker.getService();
try {
service.executeCommand(command, _out, System.err);
} catch (Exception e) {
System.err.println("Shell JLine UI: "+e.getMessage());
}
}

private String readCommandLine(ConsoleReader reader) {
String command = null;
try{
command = reader.readLine(PROMPT);
}catch(IOException exception){
stop();
System.err.println("cannot accept command" + exception.getMessage());
}
return command;
}

private ConsoleReader openConsoleReader() {
ConsoleReader reader = null;
try{
reader = new ConsoleReader();
reader.setBellEnabled(false);
}catch(IOException exception){
System.err.println("cannot open the console to read: " + exception.getMessage());
}
return reader;
}
}

No comments:

Blog Archive