/* * Copyright 2009 NCHOVY * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.script; import java.io.File; import java.util.HashSet; import java.util.Properties; import java.util.Set; import org.krakenapps.ansicode.AnsiEscapeCode; import org.krakenapps.ansicode.LocalEchoControl; import org.krakenapps.api.AccountManager; import org.krakenapps.api.FunctionKeyEvent; import org.krakenapps.api.Script; import org.krakenapps.api.ScriptContext; import org.krakenapps.api.ScriptInputStream; import org.krakenapps.api.ScriptOutputStream; import org.krakenapps.api.ScriptSession; import org.krakenapps.api.WindowSizeEventListener; import org.krakenapps.console.ConsoleAutoComplete; import org.krakenapps.console.ConsoleController; import org.krakenapps.console.ConsoleHistoryManager; import org.krakenapps.console.QuitHandler; import org.krakenapps.main.Kraken; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; public class ScriptContextImpl implements ScriptContext { private int width = 80; private int height = 24; private BundleContext bc; private Script currentScript; private ScriptInputStream inputStream; private ScriptOutputStream outputStream; private Properties properties; private boolean doEcho = true; private ScriptSession session; private ConsoleController controller; private ConsoleHistoryManager history; private QuitHandler quit; private Set<WindowSizeEventListener> callbacks = new HashSet<WindowSizeEventListener>(); public ScriptContextImpl(BundleContext bc) { this(bc, null); } public ScriptContextImpl(BundleContext bc, QuitHandler quit) { this.bc = bc; this.properties = new Properties(); this.controller = new ConsoleController(this, new ConsoleAutoComplete(Kraken.getContext())); this.history = new ConsoleHistoryManager(controller); this.controller.setArrowKeyHandler(history); this.session = new ScriptSessionImpl(history); this.session.setProperty("dir", new File(System.getProperty("user.dir"))); this.quit = quit; } @Override public AccountManager getAccountManager() { ServiceReference ref = bc.getServiceReference(AccountManager.class.getName()); AccountManager accountManager = (AccountManager) bc.getService(ref); return accountManager; } @Override public int getWidth() { return width; } @Override public int getHeight() { return height; } @Override public void setWindowSize(int width, int height) { this.width = width; this.height = height; for (WindowSizeEventListener callback : callbacks) { Thread t = new Thread(new SizeEventCallback(callback, width, height), "WindowSizeEventCallback"); t.start(); } } public ConsoleController getController() { return controller; } public ConsoleHistoryManager getHistoryManager() { return history; } @Override public ScriptSession getSession() { return session; } @Override public Properties getEnvironmentVariables() { return properties; } @Override public Script getCurrentScript() { return currentScript; } @Override public void setCurrentScript(Script currentScript) { this.currentScript = currentScript; } @Override public ScriptInputStream getInputStream() { return inputStream; } @Override public ScriptOutputStream getOutputStream() { return outputStream; } @Override public void printPrompt() { getOutputStream().print(getSession().getPrompt()); } @Override public void print(String value) { if (value == null) return; if (outputStream != null) outputStream.print(value); } @Override public void print(Object value) { print(value.toString()); } @Override public void println() { println(""); } @Override public void println(String value) { if (value == null) return; print(value); print("\r\n"); } @Override public void println(Object value) { println(value.toString()); } @Override public void printf(String format, Object... args) { if (outputStream != null) outputStream.printf(format, args); } @Override public void print(AnsiEscapeCode ansiCode) { if (outputStream != null) outputStream.print(ansiCode); } @Override public char read() throws InterruptedException { return inputStream.read(); } @Override public String readLine() throws InterruptedException { return inputStream.readLine(); } @Override public String readPassword() throws InterruptedException { turnEchoOff(); try { return readLine(); } finally { turnEchoOn(); println(""); } } @Override public void setEnvironmentVariables(Properties newProperties) { this.properties = newProperties; } @Override public void setInputStream(ScriptInputStream newInputStream) { this.inputStream = newInputStream; } @Override public void setOutputStream(ScriptOutputStream newOutputStream) { this.outputStream = newOutputStream; } @Override public void turnEchoOn() { doEcho = true; } @Override public void turnEchoOff() { doEcho = false; } @Override public boolean isEchoOn() { return doEcho; } public void turnLocalEchoOn() { print(new LocalEchoControl(LocalEchoControl.Option.Set)); } public void turnLocalEchoOff() { print(new LocalEchoControl(LocalEchoControl.Option.Reset)); } @Override public void transferInput(char character) { inputStream.supplyInput(character); } @Override public void transferInput(FunctionKeyEvent keyEvent) { inputStream.supplyFunctionKey(keyEvent); } @Override public void addWindowSizeEventListener(WindowSizeEventListener callback) { if (callback == null) throw new IllegalArgumentException("callback must be not null"); callbacks.add(callback); } @Override public void removeWindowSizeEventListener(WindowSizeEventListener callback) { if (callback == null) throw new IllegalArgumentException("callback must be not null"); callbacks.remove(callback); } private static class SizeEventCallback implements Runnable { private int width; private int height; private WindowSizeEventListener callback; public SizeEventCallback(WindowSizeEventListener callback, int width, int height) { this.width = width; this.height = height; this.callback = callback; } @Override public void run() { callback.sizeChanged(width, height); } } @Override public void quit() { if (quit != null) { quit.onQuit(); quit = null; } else throw new RuntimeException("quit"); } }