1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/pom.xml Sun May 15 17:46:06 2011 +0400
1.3 @@ -0,0 +1,165 @@
1.4 +<?xml version="1.0" encoding="utf-8"?>
1.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1.6 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
1.7 +
1.8 + <modelVersion>4.0.0</modelVersion>
1.9 +
1.10 + <groupId>org.vaadin.addons</groupId>
1.11 + <artifactId>console</artifactId>
1.12 + <version>1.1.7-SNAPSHOT</version>
1.13 + <packaging>jar</packaging>
1.14 + <name>Vaadin Console add-on</name>
1.15 + <parent>
1.16 + <groupId>ru.bazon.think-easy-money</groupId>
1.17 + <artifactId>think-easy-money-all</artifactId>
1.18 + <version>1.0-SNAPSHOT</version>
1.19 + </parent>
1.20 +
1.21 + <build>
1.22 + <plugins>
1.23 + <plugin>
1.24 + <groupId>org.apache.maven.plugins</groupId>
1.25 + <artifactId>maven-compiler-plugin</artifactId>
1.26 + <configuration>
1.27 + <source>1.6</source>
1.28 + <target>1.6</target>
1.29 + </configuration>
1.30 + </plugin>
1.31 +
1.32 + <plugin>
1.33 + <groupId>org.apache.maven.plugins</groupId>
1.34 + <artifactId>maven-jar-plugin</artifactId>
1.35 + <version>2.3.1</version>
1.36 + <configuration>
1.37 + <archive>
1.38 + <index>true</index>
1.39 + <manifest>
1.40 + <addClasspath>true</addClasspath>
1.41 + <!--
1.42 + Implementation-Title and Implementation-Version come from the
1.43 + POM by default
1.44 + -->
1.45 + <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
1.46 + </manifest>
1.47 + <manifestEntries>
1.48 + <!-- Package format version - do not change -->
1.49 + <Vaadin-Package-Version>1</Vaadin-Package-Version>
1.50 +
1.51 + <!-- Add-on specific fields to update -->
1.52 + <Vaadin-License-Title>Apache License 2.0</Vaadin-License-Title>
1.53 +
1.54 + <!--
1.55 + Implementation-Title and Implementation-Version come from the
1.56 + POM by default
1.57 + -->
1.58 + <Implementation-Vendor>Vaadin Ltd</Implementation-Vendor>
1.59 + <Implementation-Title>${pom.name}</Implementation-Title>
1.60 + <Implementation-Version>${pom.version}</Implementation-Version>
1.61 +
1.62 + <!-- Comma-separated list of widgetsets in the package -->
1.63 + <Vaadin-Widgetsets>org.vaadin.console.ConsoleWidgetset</Vaadin-Widgetsets>
1.64 + </manifestEntries>
1.65 + </archive>
1.66 + </configuration>
1.67 + </plugin>
1.68 +
1.69 + <!-- Compiles your custom GWT components with the GWT compiler -->
1.70 + <!--
1.71 + A hosted mode browser for client-side widget debugging can be run
1.72 + with the goal gwt:run after uncommenting the correct line below. A
1.73 + remote debugger can then be connected to port 8998. Note that e.g. a
1.74 + Jetty server should be running with the server side parts - use the
1.75 + goal jetty:run .
1.76 + -->
1.77 + <plugin>
1.78 + <groupId>org.codehaus.mojo</groupId>
1.79 + <artifactId>gwt-maven-plugin</artifactId>
1.80 + <version>2.2.0</version>
1.81 + <configuration>
1.82 + <!-- if you don't specify any modules, the plugin will find them -->
1.83 + <webappDirectory>${project.build.directory}/${project.build.finalName}/VAADIN/widgetsets</webappDirectory>
1.84 + <!-- On Mac running Snow Leopard, add "-d32" -->
1.85 + <!--
1.86 + This causes error messages (but build works) in phase "package":
1.87 + two processes would use the same debug port
1.88 + -->
1.89 + <!--
1.90 + extraJvmArgs>-Xmx512M -Xss1024k -Xdebug
1.91 + -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8998</extraJvmArgs
1.92 + -->
1.93 + <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
1.94 + <runTarget>xsite</runTarget>
1.95 + <hostedWebapp>${project.build.directory}/${project.build.finalName}</hostedWebapp>
1.96 + <noServer>true</noServer>
1.97 + <port>8080</port>
1.98 + <soyc>false</soyc>
1.99 + </configuration>
1.100 + <executions>
1.101 + <execution>
1.102 + <goals>
1.103 + <goal>resources</goal>
1.104 + <goal>compile</goal>
1.105 + </goals>
1.106 + </execution>
1.107 + </executions>
1.108 + </plugin>
1.109 + </plugins>
1.110 +
1.111 + <!--
1.112 + This is needed for the sources required by the GWT compiler to be
1.113 + included in the produced JARs
1.114 + -->
1.115 + <resources>
1.116 + <resource>
1.117 + <directory>src/main/java</directory>
1.118 + </resource>
1.119 + <resource>
1.120 + <directory>src/main/resources</directory>
1.121 + </resource>
1.122 + </resources>
1.123 + </build>
1.124 +
1.125 + <profiles>
1.126 + <profile>
1.127 + <id>updateWidgetset</id>
1.128 + <build>
1.129 + <plugins>
1.130 + <plugin>
1.131 + <groupId>com.vaadin</groupId>
1.132 + <artifactId>vaadin-maven-plugin</artifactId>
1.133 + <version>1.0.2</version>
1.134 + <executions>
1.135 + <execution>
1.136 + <configuration>
1.137 + </configuration>
1.138 + <goals>
1.139 + <goal>update-widgetset</goal>
1.140 + </goals>
1.141 + </execution>
1.142 + </executions>
1.143 + </plugin>
1.144 + </plugins>
1.145 + </build>
1.146 + </profile>
1.147 + </profiles>
1.148 +
1.149 + <dependencies>
1.150 + <dependency>
1.151 + <groupId>com.vaadin</groupId>
1.152 + <artifactId>vaadin</artifactId>
1.153 + <version>6.6.0</version>
1.154 + </dependency>
1.155 + <dependency>
1.156 + <groupId>org.vaadin.addons</groupId>
1.157 + <artifactId>widget-rpc</artifactId>
1.158 + <version>1.1.3</version>
1.159 + </dependency>
1.160 + <dependency>
1.161 + <groupId>com.google.gwt</groupId>
1.162 + <artifactId>gwt-user</artifactId>
1.163 + <version>2.2.0</version>
1.164 + <scope>provided</scope>
1.165 + </dependency>
1.166 + </dependencies>
1.167 +
1.168 +</project>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/main/java/org/vaadin/console/Console.java Sun May 15 17:46:06 2011 +0400
2.3 @@ -0,0 +1,730 @@
2.4 +package org.vaadin.console;
2.5 +
2.6 +import java.io.ByteArrayOutputStream;
2.7 +import java.io.IOException;
2.8 +import java.io.OutputStream;
2.9 +import java.io.PrintStream;
2.10 +import java.io.Serializable;
2.11 +import java.util.ArrayList;
2.12 +import java.util.Collections;
2.13 +import java.util.HashMap;
2.14 +import java.util.HashSet;
2.15 +import java.util.List;
2.16 +import java.util.Map;
2.17 +import java.util.Set;
2.18 +
2.19 +import org.vaadin.rpc.ServerSideHandler;
2.20 +import org.vaadin.rpc.ServerSideProxy;
2.21 +import org.vaadin.rpc.client.Method;
2.22 +
2.23 +import com.vaadin.terminal.PaintException;
2.24 +import com.vaadin.terminal.PaintTarget;
2.25 +import com.vaadin.ui.AbstractComponent;
2.26 +import com.vaadin.ui.Component;
2.27 +
2.28 +/**
2.29 + * Server side component for the VTextConsole widget.
2.30 + *
2.31 + * @author Sami Ekblad / Vaadin
2.32 + *
2.33 + */
2.34 +@com.vaadin.ui.ClientWidget(org.vaadin.console.client.ui.VTextConsole.class)
2.35 +public class Console extends AbstractComponent implements Component.Focusable {
2.36 +
2.37 + private static final long serialVersionUID = 590258219352859644L;
2.38 + private Handler handler;
2.39 + private final HashMap<String, Command> commands = new HashMap<String, Command>();
2.40 + private final Config config = new Config();
2.41 +
2.42 + private static final String DEFAULT_PS = "}> ";
2.43 + private static final String DEFAULT_GREETING = "Console ready.";
2.44 + private static final int DEFAULT_BUFFER = 0;
2.45 + private static final int DEFAULT_COLS = -1;
2.46 + private static final int DEFAULT_ROWS = -1;
2.47 + private static final boolean DEFAULT_WRAP = true;
2.48 + private static final int MAX_COLS = 500;
2.49 + private static final int MAX_ROWS = 200;
2.50 +
2.51 + public boolean isWrap() {
2.52 + return config.wrap;
2.53 + }
2.54 +
2.55 + public void setWrap(final boolean wrap) {
2.56 + config.wrap = wrap;
2.57 + client.call("setWrap", wrap);
2.58 + }
2.59 +
2.60 + private final ServerSideProxy client = new ServerSideProxy(
2.61 + new ClientCallback());
2.62 +
2.63 + /**
2.64 + * Inner class to handle client calls.
2.65 + *
2.66 + */
2.67 + public class ClientCallback implements ServerSideHandler {
2.68 +
2.69 + private static final long serialVersionUID = 3992611573500588703L;
2.70 +
2.71 + public void requestRepaint() {
2.72 + Console.this.requestRepaint();
2.73 + }
2.74 +
2.75 + public Object[] initRequestFromClient() {
2.76 + return new Object[] { config.cols, config.rows,
2.77 + config.maxBufferSize, config.wrap, config.greeting,
2.78 + config.ps };
2.79 + }
2.80 +
2.81 + public void callFromClient(String method, Object[] params) {
2.82 + // TODO Auto-generated method stub
2.83 +
2.84 + }
2.85 +
2.86 + }
2.87 +
2.88 + /**
2.89 + * The tab order number of this field.
2.90 + */
2.91 + private int tabIndex = 0;
2.92 + @SuppressWarnings("unused")
2.93 + private Integer fontw;
2.94 + @SuppressWarnings("unused")
2.95 + private Integer fonth;
2.96 + private PrintStream printStream;
2.97 + private String lastSuggestInput;
2.98 + private List<CommandProvider> commandProviders;
2.99 +
2.100 + /**
2.101 + * An inner class for holding the configuration data.
2.102 + */
2.103 + public static class Config implements Serializable {
2.104 +
2.105 + private static final long serialVersionUID = -812601232248504108L;
2.106 +
2.107 + int maxBufferSize = DEFAULT_BUFFER;
2.108 + int cols = DEFAULT_COLS;
2.109 + int rows = DEFAULT_ROWS;
2.110 + boolean wrap = DEFAULT_WRAP;
2.111 + String ps = DEFAULT_PS;
2.112 + String greeting = DEFAULT_GREETING;
2.113 +
2.114 + }
2.115 +
2.116 + /**
2.117 + * Console Handler interface.
2.118 + *
2.119 + * Handler provides a hook to handle various console related events and
2.120 + * override the default processing.
2.121 + *
2.122 + */
2.123 + public interface Handler extends Serializable {
2.124 +
2.125 + /**
2.126 + * Called when user uses TAB to complete the command entered into the
2.127 + * Console input.
2.128 + *
2.129 + * @param console
2.130 + * @param lastInput
2.131 + * @return
2.132 + */
2.133 + Set<String> getSuggestions(Console console, String lastInput);
2.134 +
2.135 + /**
2.136 + * Called when user has entered input to the Console and presses enter
2.137 + * to execute it.
2.138 + *
2.139 + * @param console
2.140 + * @param lastInput
2.141 + */
2.142 + void inputReceived(Console console, String lastInput);
2.143 +
2.144 + /**
2.145 + * Handle an exception during a Command execution.
2.146 + *
2.147 + * @param console
2.148 + * @param e
2.149 + * @param cmd
2.150 + * @param argv
2.151 + */
2.152 + void handleException(Console console, Exception e, Command cmd,
2.153 + String[] argv);
2.154 +
2.155 + /**
2.156 + * Handle situation where a command could not be found.
2.157 + *
2.158 + * @param console
2.159 + * @param argv
2.160 + */
2.161 + void commandNotFound(Console console, String[] argv);
2.162 +
2.163 + }
2.164 +
2.165 + /**
2.166 + * Commands that can be executed against the Component instance. They
2.167 + * provide convenient string to method mapping. Basically, a Command is a
2.168 + * method that that can be executed in Component. It can have parameters or
2.169 + * not.
2.170 + *
2.171 + */
2.172 + public interface Command extends Serializable {
2.173 +
2.174 + /**
2.175 + * Execute a Command with arguments.
2.176 + *
2.177 + * @param console
2.178 + * @param argv
2.179 + * @return
2.180 + * @throws Exception
2.181 + */
2.182 + public Object execute(Console console, String[] argv) throws Exception;
2.183 +
2.184 + /**
2.185 + * Get usage information about this command.
2.186 + *
2.187 + * @param console
2.188 + * @param argv
2.189 + * @return
2.190 + */
2.191 + public String getUsage(Console console, String[] argv);
2.192 + }
2.193 +
2.194 + /**
2.195 + * Interface for providing Commands to the console. One can register a
2.196 + * command providers to console instead of individual commands to provide a
2.197 + * lot of commands.
2.198 + *
2.199 + */
2.200 + public interface CommandProvider extends Serializable {
2.201 +
2.202 + /**
2.203 + * List all available command from this provider.
2.204 + *
2.205 + * @param console
2.206 + * @return
2.207 + */
2.208 + Set<String> getAvailableCommands(Console console);
2.209 +
2.210 + /**
2.211 + * Get Command instance based on command name.
2.212 + *
2.213 + * @param console
2.214 + * @param commandName
2.215 + * @return
2.216 + */
2.217 + Command getCommand(Console console, String commandName);
2.218 +
2.219 + }
2.220 +
2.221 + public void addCommandProvider(final CommandProvider commandProvider) {
2.222 + if (commandProviders == null) {
2.223 + commandProviders = new ArrayList<CommandProvider>();
2.224 + }
2.225 + commandProviders.add(commandProvider);
2.226 + }
2.227 +
2.228 + public void removeCommandProvider(final CommandProvider commandProvider) {
2.229 + if (commandProviders == null) {
2.230 + return;
2.231 + }
2.232 + commandProviders.remove(commandProvider);
2.233 + }
2.234 +
2.235 + public void removeAllCommandProviders() {
2.236 + if (commandProviders == null) {
2.237 + return;
2.238 + }
2.239 + commandProviders.clear();
2.240 + }
2.241 +
2.242 + public Console(final Console.Handler handler) {
2.243 + this();
2.244 + setHandler(handler);
2.245 + }
2.246 +
2.247 + public Console() {
2.248 + setImmediate(true);
2.249 + setHandler(new DefaultConsoleHandler());
2.250 + registerCallbacks();
2.251 + }
2.252 +
2.253 + private void registerCallbacks() {
2.254 + client.register("suggest", new Method() {
2.255 +
2.256 + public void invoke(String methodName, Object[] params) {
2.257 + handleSuggest((String) params[0]);
2.258 + }
2.259 + });
2.260 + client.register("input", new Method() {
2.261 +
2.262 + public void invoke(String methodName, Object[] params) {
2.263 + handleInput((String) params[0]);
2.264 + }
2.265 + });
2.266 +
2.267 + }
2.268 +
2.269 + @Override
2.270 + public void paintContent(final PaintTarget target) throws PaintException {
2.271 + super.paintContent(target);
2.272 + client.paintContent(target);
2.273 + }
2.274 +
2.275 + @Override
2.276 + public void changeVariables(final Object source,
2.277 + final Map<String, Object> variables) {
2.278 + super.changeVariables(source, variables);
2.279 + client.changeVariables(source, variables);
2.280 + if (variables.containsKey("width")) {
2.281 + setWidth((String) variables.get("width"));
2.282 + }
2.283 + if (variables.containsKey("height")) {
2.284 + setHeight((String) variables.get("height"));
2.285 + }
2.286 + if (variables.containsKey("fontw")) {
2.287 + fontw = (Integer) variables.get("fontw");
2.288 + }
2.289 + if (variables.containsKey("fonth")) {
2.290 + fonth = (Integer) variables.get("fonth");
2.291 + }
2.292 + if (variables.containsKey("cols")) {
2.293 + config.cols = (Integer) variables.get("cols");
2.294 + }
2.295 + if (variables.containsKey("rows")) {
2.296 + config.rows = (Integer) variables.get("rows");
2.297 + }
2.298 + }
2.299 +
2.300 + /**
2.301 + * Overridden to filter client-side calculation/changes and avoid loops.
2.302 + *
2.303 + */
2.304 + @Override
2.305 + public void setWidth(float width, int unit) {
2.306 + if (width != getWidth() || unit != getWidthUnits()) {
2.307 + super.setWidth(width, unit);
2.308 + }
2.309 + }
2.310 +
2.311 + /**
2.312 + * Overridden to filter client-side calculation/changes and avoid loops.
2.313 + *
2.314 + */
2.315 + @Override
2.316 + public void setHeight(float height, int unit) {
2.317 + if (height != getHeight() || unit != getHeightUnits()) {
2.318 + super.setHeight(height, unit);
2.319 + }
2.320 + }
2.321 +
2.322 + protected void handleSuggest(final String input) {
2.323 +
2.324 + final boolean cancelIfNotASingleMatch = (input != null && !input
2.325 + .equals(lastSuggestInput));
2.326 + lastSuggestInput = input;
2.327 +
2.328 + final Set<String> matches = handler.getSuggestions(this, input);
2.329 +
2.330 + if (matches == null || matches.size() == 0) {
2.331 + bell();
2.332 + return;
2.333 + }
2.334 +
2.335 + // Output the original
2.336 + final String prefix = parseCommandPrefix(input);
2.337 + String output = input.substring(0, input.lastIndexOf(prefix));
2.338 + if (matches.size() == 1) {
2.339 + // Output the only match
2.340 + output += matches.iterator().next() + " "; // append the single
2.341 + // match
2.342 + } else {
2.343 +
2.344 + // We output until the common prefix
2.345 + StringBuilder commonPrefix = new StringBuilder(prefix);
2.346 + final int maxLen = matches.iterator().next().length();
2.347 + for (int i = prefix.length(); i < maxLen; i++) {
2.348 + char c = 0;
2.349 + boolean charMatch = true;
2.350 + for (final String m : matches) {
2.351 + if (c == 0) {
2.352 + c = m.charAt(i);
2.353 + } else if (i < m.length()) {
2.354 + charMatch &= m.charAt(i) == c;
2.355 + if (!charMatch) {
2.356 + break;
2.357 + }
2.358 + } else {
2.359 + charMatch = false;
2.360 + break;
2.361 + }
2.362 + }
2.363 + if (charMatch) {
2.364 + commonPrefix.append(c);
2.365 + }
2.366 + }
2.367 + output += commonPrefix.toString();
2.368 + if (prefix.equals(commonPrefix.toString())
2.369 + && !cancelIfNotASingleMatch) {
2.370 + final StringBuffer suggestions = new StringBuffer("\n");
2.371 + for (final String m : matches) {
2.372 + suggestions.append(" " + m);
2.373 + }
2.374 + print(suggestions.toString());
2.375 + } else {
2.376 + bell();
2.377 + lastSuggestInput = output; // next suggest will not beep
2.378 + }
2.379 + }
2.380 + prompt(output);
2.381 + focus();
2.382 +
2.383 + }
2.384 +
2.385 + public void bell() {
2.386 + client.call("bell");
2.387 + }
2.388 +
2.389 + protected void handleInput(final String input) {
2.390 +
2.391 + // Ask registered handler
2.392 + handler.inputReceived(this, input);
2.393 +
2.394 + }
2.395 +
2.396 + protected void parseAndExecuteCommand(final String input) {
2.397 + final String[] argv = parseInput(input);
2.398 + if (argv != null && argv.length > 0) {
2.399 + final Command c = getCommand(argv[0]);
2.400 + if (c != null) {
2.401 + final String result = executeCommand(c, argv);
2.402 + if (result != null) {
2.403 + print(result);
2.404 + }
2.405 + } else {
2.406 + handler.commandNotFound(this, argv);
2.407 + }
2.408 + }
2.409 + }
2.410 +
2.411 + protected String executeCommand(final Command cmd, final String[] argv) {
2.412 + try {
2.413 + final Object r = cmd.execute(this, argv);
2.414 + return r != null ? "" + r : null;
2.415 + } catch (final Exception e) {
2.416 + handler.handleException(this, e, cmd, argv);
2.417 + }
2.418 + return null;
2.419 + }
2.420 +
2.421 + protected String parseCommandPrefix(final String input) {
2.422 + if (input == null) {
2.423 + return null;
2.424 + }
2.425 + if (!input.endsWith(" ")) {
2.426 + final String[] argv = parseInput(input);
2.427 + if (argv != null && argv.length > 0) {
2.428 + return argv[argv.length - 1];
2.429 + }
2.430 + }
2.431 + return "";
2.432 + }
2.433 +
2.434 + protected static String[] parseInput(final String input) {
2.435 + if (input != null && !"".equals(input.trim())) {
2.436 + final String[] temp = input.split(" ");
2.437 + if (temp != null && temp.length > 0) {
2.438 + final List<String> parsed = new ArrayList<String>(temp.length);
2.439 + String current = null;
2.440 + for (final String element : temp) {
2.441 + final int quotCount = count(element, '\"');
2.442 + if (quotCount > 0 && quotCount % 2 != 0) {
2.443 + // uneven number of quotes star or end combining params
2.444 + if (current != null) {
2.445 + parsed.add(current + " "
2.446 + + element.replaceAll("\"", "")); // end
2.447 + current = null;
2.448 + } else {
2.449 + current = element.replaceAll("\"", ""); // start
2.450 + }
2.451 + } else if (current != null) {
2.452 + current += " " + element.replaceAll("\"", "");
2.453 + } else {
2.454 + parsed.add(element.replaceAll("\"", ""));
2.455 + }
2.456 + }
2.457 +
2.458 + // TODO: actually this is not quite right: We have an open quote
2.459 + // somewhere. Exception maybe?
2.460 + if (current != null) {
2.461 + parsed.add(current.replaceAll("\"", ""));
2.462 + }
2.463 + return parsed.toArray(new String[] {});
2.464 + }
2.465 + }
2.466 + return new String[] {};
2.467 + }
2.468 +
2.469 + protected static int count(final String sourceString, final char lookFor) {
2.470 + if (sourceString == null) {
2.471 + return -1;
2.472 + }
2.473 + int count = 0;
2.474 + for (int i = 0; i < sourceString.length(); i++) {
2.475 + final char c = sourceString.charAt(i);
2.476 + if (c == lookFor) {
2.477 + count++;
2.478 + }
2.479 + }
2.480 + return count;
2.481 + }
2.482 +
2.483 + public void print(final String output) {
2.484 + client.call("print", output);
2.485 + }
2.486 +
2.487 + public String getGreeting() {
2.488 + return config.greeting;
2.489 + }
2.490 +
2.491 + public String getPs() {
2.492 + return config.ps;
2.493 + }
2.494 +
2.495 + public int getMaxBufferSize() {
2.496 + return config.maxBufferSize;
2.497 + }
2.498 +
2.499 + public int getRows() {
2.500 + return config.rows;
2.501 + }
2.502 +
2.503 + public void setGreeting(final String greeting) {
2.504 + config.greeting = greeting;
2.505 + client.call("setGreeting", greeting);
2.506 + }
2.507 +
2.508 + public void setPs(final String ps) {
2.509 + config.ps = ps == null ? DEFAULT_PS : ps;
2.510 + client.call("setPs", config.ps);
2.511 + }
2.512 +
2.513 + public void setMaxBufferSize(final int lines) {
2.514 + config.maxBufferSize = lines > 0 ? lines : 0;
2.515 + client.call("setMaxBufferSize", config.maxBufferSize);
2.516 + }
2.517 +
2.518 + public void setRows(final int rows) {
2.519 + config.rows = rows;
2.520 + if (config.rows < 1) {
2.521 + config.rows = 1;
2.522 + }
2.523 + if (config.rows > MAX_ROWS) {
2.524 + config.rows = MAX_ROWS;
2.525 + }
2.526 + client.call("setRows", rows);
2.527 + }
2.528 +
2.529 + public int getCols() {
2.530 + return config.cols;
2.531 + }
2.532 +
2.533 + public void setCols(final int cols) {
2.534 + config.cols = cols;
2.535 + if (config.cols < 1) {
2.536 + config.cols = 1;
2.537 + }
2.538 + if (config.cols > MAX_COLS) {
2.539 + config.cols = MAX_COLS;
2.540 + }
2.541 + client.call("setCols", config.cols);
2.542 + }
2.543 +
2.544 + public void prompt() {
2.545 + client.call("prompt");
2.546 + }
2.547 +
2.548 + public void prompt(final String initialInput) {
2.549 + client.call("prompt", initialInput);
2.550 + }
2.551 +
2.552 + public void println(final String string) {
2.553 + client.call("println", string);
2.554 + }
2.555 +
2.556 + public void newLine() {
2.557 + client.call("newLine");
2.558 + }
2.559 +
2.560 + public void reset() {
2.561 + client.call("reset");
2.562 + }
2.563 +
2.564 + public void clear() {
2.565 + formFeed();
2.566 + }
2.567 +
2.568 + public void formFeed() {
2.569 + client.call("ff");
2.570 + }
2.571 +
2.572 + public void carriageReturn() {
2.573 + client.call("cr");
2.574 + }
2.575 +
2.576 + public void lineFeed() {
2.577 + client.call("lf");
2.578 + }
2.579 +
2.580 + public void clearCommandHistory() {
2.581 + client.call("clearHistory");
2.582 + }
2.583 +
2.584 + public void clearBuffer() {
2.585 + client.call("clearBuffer");
2.586 + }
2.587 +
2.588 + public void scrollToEnd() {
2.589 + client.call("scrollToEnd");
2.590 + }
2.591 +
2.592 + /**
2.593 + * Gets the Tabulator index of this Focusable component.
2.594 + *
2.595 + * @see com.vaadin.ui.Component.Focusable#getTabIndex()
2.596 + */
2.597 + public int getTabIndex() {
2.598 + return tabIndex;
2.599 + }
2.600 +
2.601 + /**
2.602 + * Sets the Tabulator index of this Focusable component.
2.603 + *
2.604 + * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
2.605 + */
2.606 + public void setTabIndex(final int tabIndex) {
2.607 + this.tabIndex = tabIndex;
2.608 + }
2.609 +
2.610 + /**
2.611 + * {@inheritDoc}
2.612 + */
2.613 + @Override
2.614 + public void focus() {
2.615 + super.focus();
2.616 + }
2.617 +
2.618 + /* PrintStream implementation for console output. */
2.619 +
2.620 + public PrintStream getPrintStream() {
2.621 + if (printStream == null) {
2.622 + printStream = new PrintStream(new OutputStream() {
2.623 +
2.624 + ByteArrayOutputStream buffer = new ByteArrayOutputStream();
2.625 +
2.626 + @Override
2.627 + public void write(final int b) throws IOException {
2.628 + buffer.write(b);
2.629 + // Line buffering
2.630 + if (13 == b) {
2.631 + flush();
2.632 + }
2.633 + }
2.634 +
2.635 + @Override
2.636 + public void flush() throws IOException {
2.637 + super.flush();
2.638 + buffer.flush();
2.639 + Console.this.print(buffer.toString());
2.640 + buffer.reset();
2.641 + }
2.642 + }, true);
2.643 + }
2.644 + return printStream;
2.645 + }
2.646 +
2.647 + /* Generic command handling */
2.648 +
2.649 + /**
2.650 + * Add a Command to this Console.
2.651 + *
2.652 + * This will override the any commands of the same name available via
2.653 + * {@link CommandProvider}.
2.654 + */
2.655 + public void addCommand(final String name, final Command cmd) {
2.656 + commands.put(name, cmd);
2.657 + }
2.658 +
2.659 + /**
2.660 + * Remove a command from this console.
2.661 + *
2.662 + * This does not remove Command available from {@link CommandProvider}.
2.663 + *
2.664 + * @param cmdName
2.665 + */
2.666 + public void removeCommand(final String cmdName) {
2.667 + commands.remove(cmdName);
2.668 + }
2.669 +
2.670 + /**
2.671 + * Get a Command by its name.
2.672 + *
2.673 + * @param cmdName
2.674 + * @return
2.675 + */
2.676 + public Command getCommand(final String cmdName) {
2.677 +
2.678 + // Try directly registered command first
2.679 + Command cmd = commands.get(cmdName);
2.680 + if (cmd != null) {
2.681 + return cmd;
2.682 + }
2.683 +
2.684 + // Ask from the providers
2.685 + if (commandProviders != null) {
2.686 + for (final CommandProvider cp : commandProviders) {
2.687 + cmd = cp.getCommand(this, cmdName);
2.688 + if (cmd != null) {
2.689 + return cmd;
2.690 + }
2.691 + }
2.692 + }
2.693 +
2.694 + // Not found
2.695 + return null;
2.696 + }
2.697 +
2.698 + /**
2.699 + * Get the current Console Handler.
2.700 + *
2.701 + * @return
2.702 + */
2.703 + public Handler getHandler() {
2.704 + return handler;
2.705 + }
2.706 +
2.707 + /**
2.708 + * Set the handler for this console.
2.709 + *
2.710 + * @see Handler
2.711 + * @param handler
2.712 + */
2.713 + public void setHandler(final Handler handler) {
2.714 + this.handler = handler != null ? handler : new DefaultConsoleHandler();
2.715 + }
2.716 +
2.717 + /**
2.718 + * Get map of available commands in this Console.
2.719 + *
2.720 + * @return
2.721 + */
2.722 + public Set<String> getCommands() {
2.723 + final Set<String> res = new HashSet<String>();
2.724 + if (commandProviders != null) {
2.725 + for (final CommandProvider cp : commandProviders) {
2.726 + res.addAll(cp.getAvailableCommands(this));
2.727 + }
2.728 + }
2.729 + res.addAll(commands.keySet());
2.730 + return Collections.unmodifiableSet(res);
2.731 + }
2.732 +
2.733 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/main/java/org/vaadin/console/ConsoleWidgetset.gwt.xml Sun May 15 17:46:06 2011 +0400
3.3 @@ -0,0 +1,26 @@
3.4 +<?xml version="1.0" encoding="UTF-8"?>
3.5 +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
3.6 +<module>
3.7 + <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
3.8 +
3.9 +
3.10 + <!--
3.11 + Uncomment the following to compile the widgetset for one browser only.
3.12 + This can reduce the GWT compilation time significantly when debugging.
3.13 + The line should be commented out before deployment to production
3.14 + environments.
3.15 +
3.16 + Multiple browsers can be specified for GWT 1.7 as a comma separated
3.17 + list. The supported user agents at the moment of writing were:
3.18 + ie6,ie8,gecko,gecko1_8,safari,opera
3.19 +
3.20 + The value gecko1_8 is used for Firefox 3 and later and safari is used for
3.21 + webkit based browsers including Google Chrome.
3.22 + -->
3.23 + <stylesheet src="console/styles.css"/>
3.24 + <!--
3.25 + <set-property name="user.agent" value="safari"/>
3.26 + -->
3.27 +
3.28 + <inherits name="org.vaadin.rpc.WidgetRPC" />
3.29 +</module>
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/main/java/org/vaadin/console/DefaultConsoleHandler.java Sun May 15 17:46:06 2011 +0400
4.3 @@ -0,0 +1,48 @@
4.4 +package org.vaadin.console;
4.5 +
4.6 +import java.util.HashSet;
4.7 +import java.util.Set;
4.8 +
4.9 +import org.vaadin.console.Console.Command;
4.10 +import org.vaadin.console.Console.Handler;
4.11 +
4.12 +/**
4.13 + * Default handler for console.
4.14 + *
4.15 + */
4.16 +public class DefaultConsoleHandler implements Handler {
4.17 +
4.18 + private static final long serialVersionUID = 1L;
4.19 +
4.20 + public void handleException(final Console console, final Exception e,
4.21 + final Command cmd, final String[] argv) {
4.22 + e.printStackTrace();
4.23 + console.println(e.getClass().getSimpleName() + ": " + e.getMessage());
4.24 + }
4.25 +
4.26 + public Set<String> getSuggestions(final Console console, final String input) {
4.27 +
4.28 + final String prefix = console.parseCommandPrefix(input);
4.29 + if (prefix != null) {
4.30 + final Set<String> matches = new HashSet<String>();
4.31 + final Set<String> cmds = console.getCommands();
4.32 + for (final String cmd : cmds) {
4.33 + if (cmd.startsWith(prefix)) {
4.34 + matches.add(cmd);
4.35 + }
4.36 + }
4.37 + return matches;
4.38 + }
4.39 + return null;
4.40 + }
4.41 +
4.42 + public void inputReceived(final Console console, final String lastInput) {
4.43 + console.parseAndExecuteCommand(lastInput);
4.44 + console.prompt();
4.45 + }
4.46 +
4.47 + public void commandNotFound(final Console console, final String[] argv) {
4.48 + console.print("ERROR: " + argv[0] + ": command not found.");
4.49 + }
4.50 +
4.51 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/main/java/org/vaadin/console/ObjectInspector.java Sun May 15 17:46:06 2011 +0400
5.3 @@ -0,0 +1,420 @@
5.4 +package org.vaadin.console;
5.5 +
5.6 +import java.beans.BeanInfo;
5.7 +import java.beans.Introspector;
5.8 +import java.beans.PropertyDescriptor;
5.9 +import java.io.Serializable;
5.10 +import java.lang.reflect.Field;
5.11 +import java.lang.reflect.InvocationTargetException;
5.12 +import java.lang.reflect.Method;
5.13 +import java.util.ArrayList;
5.14 +import java.util.Arrays;
5.15 +import java.util.Collections;
5.16 +import java.util.HashMap;
5.17 +import java.util.HashSet;
5.18 +import java.util.LinkedHashMap;
5.19 +import java.util.LinkedHashSet;
5.20 +import java.util.List;
5.21 +import java.util.Map;
5.22 +import java.util.Set;
5.23 +
5.24 +import org.vaadin.console.Console.Command;
5.25 +
5.26 +import com.vaadin.ui.Component;
5.27 +
5.28 +/**
5.29 + * Java object inspector.
5.30 + *
5.31 + * With object inspector you can simply wire methods from a class as commands to
5.32 + * the Console.
5.33 + *
5.34 + * @author Sami Ekblad
5.35 + *
5.36 + */
5.37 +public class ObjectInspector implements Serializable, Console.CommandProvider {
5.38 + private static final long serialVersionUID = -5001688079827306472L;
5.39 + private static final List<String> OBJECT_BLACKLIST = Arrays
5.40 + .asList(new String[] { "equals", "class", "hashCode", "notify",
5.41 + "notifyAll", "toString", "wait" });
5.42 + private static final List<String> VAADIN_BLACKLIST = Arrays
5.43 + .asList(new String[] { "addListener", "attach", "application",
5.44 + "changeVariables", "childRequestedRepaint",
5.45 + "componentError", "detach", "handleError", "paint",
5.46 + "paintContent", "removeListener", "requestRepaint",
5.47 + "requestRepaintRequests", "style", "tag" });
5.48 +
5.49 + private Object theObject;
5.50 + private final Map<String, Caller> commands = new HashMap<String, Caller>();
5.51 + private Set<String> ignoredCommands = new HashSet<String>();
5.52 +
5.53 + public ObjectInspector(final Object obj) {
5.54 +
5.55 + // Default ignores
5.56 + ignoredCommands.addAll(OBJECT_BLACKLIST);
5.57 + if (obj instanceof Component) {
5.58 + ignoredCommands.addAll(VAADIN_BLACKLIST);
5.59 + }
5.60 +
5.61 + // Create bean information
5.62 + setObject(obj);
5.63 +
5.64 + }
5.65 +
5.66 + private void setObject(final Object c) {
5.67 + theObject = c;
5.68 + listBeanPropertyCommands();
5.69 + listMethodCommands();
5.70 + }
5.71 +
5.72 + public Set<String> getAvailableCommands() {
5.73 + final List<String> l = new ArrayList<String>();
5.74 + l.addAll(commands.keySet());
5.75 + Collections.sort(l);
5.76 + return new LinkedHashSet<String>(l);
5.77 + }
5.78 +
5.79 +
5.80 +
5.81 + private void listMethodCommands() {
5.82 +
5.83 + final Method[] methods = theObject.getClass().getMethods();
5.84 + for (final Method method : methods) {
5.85 + final Method m = method;
5.86 + if (!isBeanGetter(m) && !isBeanSetter(m)) {
5.87 +
5.88 + String un = m.getName();
5.89 + if (isIgnored(un)
5.90 + || !isParamTypesOkForConsole(m.getParameterTypes())) {
5.91 + continue;
5.92 + }
5.93 +
5.94 + // Make unique. Try param names first.
5.95 + if (commands.containsKey(un)) {
5.96 + un += paramsToShortString(m.getParameterTypes());
5.97 + }
5.98 +
5.99 + // Fallback to appending number
5.100 + int j = 1;
5.101 + while (commands.containsKey(un)) {
5.102 + un = m.getName() + (j++);
5.103 + }
5.104 +
5.105 + final Caller cmd = m.getParameterTypes().length == 0 ? new Caller(theObject,
5.106 + m.getName(), null, m.getParameterTypes()) : new Caller(theObject,
5.107 + null, m.getName(), m.getParameterTypes());
5.108 + commands.put(un, cmd);
5.109 + }
5.110 + }
5.111 + }
5.112 +
5.113 + private String paramsToShortString(final Class<?>[] parameterTypes) {
5.114 + StringBuilder s = new StringBuilder();
5.115 + if (parameterTypes != null) {
5.116 + for (final Class<?> c : parameterTypes) {
5.117 + s.append(c.getSimpleName().substring(0, 3));
5.118 + }
5.119 + }
5.120 + return s.toString();
5.121 + }
5.122 +
5.123 + private boolean isBeanSetter(final Method m) {
5.124 + if (m.getName().startsWith("set")) {
5.125 + Method setMethod = null;
5.126 + try {
5.127 + final String n = "g" + m.getName().substring(1);
5.128 + setMethod = m.getDeclaringClass().getMethod(n);
5.129 + } catch (final SecurityException e) {
5.130 + } catch (final NoSuchMethodException e) {
5.131 + }
5.132 + if (setMethod == null) {
5.133 + try {
5.134 + final String n = "is" + m.getName().substring(3);
5.135 + setMethod = m.getDeclaringClass().getMethod(n);
5.136 + } catch (final SecurityException e) {
5.137 + } catch (final NoSuchMethodException e) {
5.138 + }
5.139 + }
5.140 + return setMethod != null;
5.141 + }
5.142 + return false;
5.143 + }
5.144 +
5.145 + private boolean isBeanGetter(final Method m) {
5.146 + final String n = m.getName();
5.147 + return (n.startsWith("is") && n.length() > 2)
5.148 + || (n.startsWith("get") && n.length() > 2);
5.149 + }
5.150 +
5.151 + /**
5.152 + * <p>
5.153 + * Perform introspection on a Java Bean class to find its properties.
5.154 + * </p>
5.155 + *
5.156 + * <p>
5.157 + * Note : This version only supports introspectable bean properties and
5.158 + * their getter and setter methods. Stand-alone <code>is</code> and
5.159 + * <code>are</code> methods are not supported.
5.160 + * </p>
5.161 + *
5.162 + * @param beanClass
5.163 + * the Java Bean class to get properties for.
5.164 + * @return an ordered map from property names to property descriptors
5.165 + */
5.166 + static LinkedHashMap<String, PropertyDescriptor> getPropertyDescriptors(
5.167 + final Class<?> beanClass) {
5.168 + final LinkedHashMap<String, PropertyDescriptor> pdMap = new LinkedHashMap<String, PropertyDescriptor>();
5.169 +
5.170 + // Try to introspect, if it fails, we just have an empty Item
5.171 + try {
5.172 + final BeanInfo info = Introspector.getBeanInfo(beanClass);
5.173 + final PropertyDescriptor[] pds = info.getPropertyDescriptors();
5.174 +
5.175 + // Add all the bean properties as MethodProperties to this Item
5.176 + for (final PropertyDescriptor pd : pds) {
5.177 + final Method getMethod = pd.getReadMethod();
5.178 + if ((getMethod != null)
5.179 + && getMethod.getDeclaringClass() != Object.class) {
5.180 + pdMap.put(pd.getName(), pd);
5.181 + }
5.182 + }
5.183 + } catch (final java.beans.IntrospectionException ignored) {
5.184 + }
5.185 +
5.186 + return pdMap;
5.187 + }
5.188 +
5.189 + /**
5.190 + * List commands for the theObject.
5.191 + *
5.192 + * @return
5.193 + */
5.194 + private void listBeanPropertyCommands() {
5.195 +
5.196 + final LinkedHashMap<String, PropertyDescriptor> beanProperties = getPropertyDescriptors(theObject
5.197 + .getClass());
5.198 + // bean properties
5.199 + for (final PropertyDescriptor p : beanProperties.values()) {
5.200 +
5.201 + // Make unique
5.202 + final String name = p.getName();
5.203 + if (isIgnored(name)) {
5.204 + continue;
5.205 + }
5.206 +
5.207 + commands.put(name,
5.208 + new Caller(theObject,p.getReadMethod().getName(),
5.209 + p.getWriteMethod() != null ? p.getWriteMethod()
5.210 + .getName() : null,
5.211 + p.getWriteMethod() != null ? p.getWriteMethod()
5.212 + .getParameterTypes() : null));
5.213 +
5.214 + // beanCommands.put(un, p);
5.215 + }
5.216 + }
5.217 +
5.218 + public static boolean isParamTypesOkForConsole(final Class<?>[] cls) {
5.219 + if (cls == null) {
5.220 + return true;
5.221 + }
5.222 + for (int i = 0; i < cls.length; i++) {
5.223 + if (!isParamTypeOkForConsole(cls[i])) {
5.224 + return false;
5.225 + }
5.226 + }
5.227 + return true;
5.228 + }
5.229 +
5.230 + public static boolean isParamTypeOkForConsole(final Class<?> cls) {
5.231 + return cls.isEnum() || cls == Boolean.class || cls == boolean.class
5.232 + || cls == long.class || cls == Long.class || cls == int.class
5.233 + || cls == Integer.class || cls == byte.class
5.234 + || cls == Byte.class || cls == float.class
5.235 + || cls == Float.class || cls == double.class
5.236 + || cls == Double.class || cls == String.class;
5.237 + }
5.238 +
5.239 + public boolean isIgnored(final String commandName) {
5.240 + return getIgnoredCommands().contains(commandName);
5.241 + }
5.242 +
5.243 + protected static Object[] argvToParams(final String[] argv,
5.244 + final Class<?>[] pt) {
5.245 + if (pt.length != argv.length - 1) {
5.246 + throw new IllegalArgumentException("Invalid number of parameters");
5.247 + }
5.248 + final Object[] args = new Object[argv.length - 1];
5.249 + for (int j = 1; j < argv.length; j++) {
5.250 + if (pt[j - 1] == String.class) {
5.251 + args[j - 1] = argv[j];
5.252 + } else if (pt[j - 1] == Byte.class || pt[j - 1] == byte.class) {
5.253 + args[j - 1] = Byte.parseByte(argv[j]);
5.254 + } else if (pt[j - 1] == Character.class || pt[j - 1] == char.class) {
5.255 + args[j - 1] = argv[j].charAt(0);
5.256 + } else if (pt[j - 1] == Long.class || pt[j - 1] == long.class) {
5.257 + args[j - 1] = Long.parseLong(argv[j]);
5.258 + } else if (pt[j - 1] == Integer.class || pt[j - 1] == int.class) {
5.259 + args[j - 1] = Integer.parseInt(argv[j]);
5.260 + } else if (pt[j - 1] == Boolean.class || pt[j - 1] == boolean.class) {
5.261 + args[j - 1] = Boolean.parseBoolean(argv[j]);
5.262 + } else if (pt[j - 1] == Float.class || pt[j - 1] == float.class) {
5.263 + args[j - 1] = Float.parseFloat(argv[j]);
5.264 + } else if (pt[j - 1] == Double.class || pt[j - 1] == double.class) {
5.265 + args[j - 1] = Float.parseFloat(argv[j]);
5.266 + } else if (pt[j - 1].isEnum()) {
5.267 + Field e;
5.268 + try {
5.269 + e = pt[j - 1].getDeclaredField(argv[j].toUpperCase());
5.270 + args[j - 1] = e.get(null);
5.271 + } catch (final Exception e1) {
5.272 + throw new IllegalArgumentException("Enum not found: "
5.273 + + argv[j].toUpperCase(), e1);
5.274 + }
5.275 + }
5.276 + }
5.277 + return args;
5.278 + }
5.279 +
5.280 + public Class<?>[] getCommandParams(final String method) {
5.281 + if (commands.containsKey(method)) {
5.282 + final Caller m = commands.get(method);
5.283 + return m.getParameterTypes() != null ? m.getParameterTypes()
5.284 + : new Class<?>[] {};
5.285 + }
5.286 + return new Class<?>[] {};
5.287 + }
5.288 +
5.289 + public void setIgnoredCommands(final Set<String> ignoredCommands) {
5.290 + this.ignoredCommands = ignoredCommands;
5.291 + }
5.292 +
5.293 + public Set<String> getIgnoredCommands() {
5.294 + return ignoredCommands;
5.295 + }
5.296 +
5.297 + /**
5.298 + * Method wrapper that serializes nicely.
5.299 + *
5.300 + */
5.301 + private static class Caller implements Console.Command, Serializable {
5.302 +
5.303 + private static final long serialVersionUID = -810707579200844512L;
5.304 +
5.305 + private final Object theObject;
5.306 + private final String readMethod;
5.307 + private final String writeMethod;
5.308 + private final Class<?>[] paramTypes;
5.309 +
5.310 + transient private Method rm;
5.311 + transient private Method wm;
5.312 +
5.313 + private Caller(final Object obj, final String read, final String write,
5.314 + final Class<?>[] params) {
5.315 + theObject = obj;
5.316 + readMethod = read;
5.317 + writeMethod = write;
5.318 + paramTypes = params;
5.319 + }
5.320 +
5.321 + private boolean isWritable() {
5.322 + return writeMethod != null && paramTypes != null
5.323 + && paramTypes.length > 0;
5.324 + }
5.325 +
5.326 + public boolean isReadable() {
5.327 + return readMethod != null;
5.328 + }
5.329 +
5.330 + public Object write(final Object[] params) throws SecurityException,
5.331 + NoSuchMethodException, IllegalArgumentException,
5.332 + IllegalAccessException, InvocationTargetException {
5.333 + if (wm == null) {
5.334 + wm = theObject.getClass().getMethod(writeMethod, paramTypes);
5.335 + }
5.336 + return wm.invoke(theObject, params);
5.337 + }
5.338 +
5.339 + public Object read() throws SecurityException, NoSuchMethodException,
5.340 + IllegalArgumentException, IllegalAccessException,
5.341 + InvocationTargetException {
5.342 + if (rm == null) {
5.343 + rm = theObject.getClass().getMethod(readMethod,
5.344 + new Class<?>[] {});
5.345 + }
5.346 + return rm.invoke(theObject);
5.347 + }
5.348 +
5.349 + public Object write(final String[] argv) throws SecurityException,
5.350 + NoSuchMethodException, IllegalArgumentException,
5.351 + IllegalAccessException, InvocationTargetException {
5.352 + return write(parseWriteParams(argv));
5.353 + }
5.354 +
5.355 + private Class<?>[] getParameterTypes() {
5.356 + return paramTypes;
5.357 + }
5.358 +
5.359 + private Object[] parseWriteParams(final String[] argv)
5.360 + throws SecurityException, NoSuchMethodException {
5.361 + if (wm == null) {
5.362 + wm = theObject.getClass().getMethod(writeMethod, paramTypes);
5.363 + }
5.364 + return argvToParams(argv, wm.getParameterTypes());
5.365 + }
5.366 +
5.367 + public Object execute(final Console console, final String[] argv)
5.368 + throws Exception {
5.369 +// public Object execute(final String[] argv) throws Exception {
5.370 +
5.371 + if (argv == null || argv.length < 1) {
5.372 + throw new IllegalArgumentException("Missing command");
5.373 + }
5.374 +
5.375 + if (argv.length > 1
5.376 + && !isParamTypesOkForConsole(getParameterTypes())) {
5.377 + throw new IllegalArgumentException("Unsupported parameter types");
5.378 + }
5.379 +
5.380 + if (argv.length == 1 && isReadable()) {
5.381 + // Read
5.382 + return read();
5.383 + } else if (isWritable()) {
5.384 + // Write
5.385 + if (isReadable()) {
5.386 + write(argv);
5.387 + return read(); // Return the read method instead
5.388 + } else {
5.389 + return write(argv); // return whatever is returned
5.390 + }
5.391 +
5.392 + }
5.393 +
5.394 + return null;
5.395 + }
5.396 + public String getUsage(final Console console, final String[] argv) {
5.397 + return null;
5.398 + }
5.399 + }
5.400 +
5.401 + public String getCommandUsage(final String[] argv) {
5.402 + return argv[0] + " " + paramsToString(getCommandParams(argv[0]));
5.403 + }
5.404 +
5.405 + private static String paramsToString(final Class<?>[] paramTypes) {
5.406 + StringBuilder res = new StringBuilder();
5.407 + if (paramTypes != null) {
5.408 + for (final Class<?> paramType : paramTypes) {
5.409 + res.append("<" + paramType.getSimpleName() + "> ");
5.410 + }
5.411 + }
5.412 + return res.toString();
5.413 + }
5.414 +
5.415 + public Set<String> getAvailableCommands(final Console console) {
5.416 + return getAvailableCommands();
5.417 + }
5.418 +
5.419 + public Command getCommand(final Console console, final String commandName) {
5.420 + return commands.get(commandName);
5.421 + }
5.422 +
5.423 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/main/java/org/vaadin/console/client/ui/TextConsole.java Sun May 15 17:46:06 2011 +0400
6.3 @@ -0,0 +1,781 @@
6.4 +package org.vaadin.console.client.ui;
6.5 +
6.6 +import java.util.ArrayList;
6.7 +import java.util.List;
6.8 +
6.9 +import com.google.gwt.dom.client.DivElement;
6.10 +import com.google.gwt.dom.client.Document;
6.11 +import com.google.gwt.dom.client.Element;
6.12 +import com.google.gwt.dom.client.InputElement;
6.13 +import com.google.gwt.dom.client.Node;
6.14 +import com.google.gwt.dom.client.Style.Display;
6.15 +import com.google.gwt.dom.client.Style.Unit;
6.16 +import com.google.gwt.dom.client.TableCellElement;
6.17 +import com.google.gwt.dom.client.TableElement;
6.18 +import com.google.gwt.dom.client.TableRowElement;
6.19 +import com.google.gwt.dom.client.TableSectionElement;
6.20 +import com.google.gwt.event.dom.client.ClickEvent;
6.21 +import com.google.gwt.event.dom.client.ClickHandler;
6.22 +import com.google.gwt.event.dom.client.KeyCodes;
6.23 +import com.google.gwt.event.dom.client.KeyDownEvent;
6.24 +import com.google.gwt.event.dom.client.KeyDownHandler;
6.25 +import com.google.gwt.event.shared.HandlerRegistration;
6.26 +import com.google.gwt.user.client.Timer;
6.27 +import com.google.gwt.user.client.ui.FocusWidget;
6.28 +import com.vaadin.terminal.gwt.client.Util;
6.29 +
6.30 +/**
6.31 + * GWT Console Widget.
6.32 + *
6.33 + * @author Sami Ekblad / Vaadin
6.34 + *
6.35 + */
6.36 +public class TextConsole extends FocusWidget {
6.37 +
6.38 + /* Control characters in http://en.wikipedia.org/wiki/Control_character */
6.39 +
6.40 + public static final char CTRL_BELL = 'G';
6.41 + public static final char CTRL_BACKSPACE = 'H';
6.42 + public static final char CTRL_TAB = 'I';
6.43 + public static final char CTRL_LINE_FEED = 'J';
6.44 + public static final char CTRL_FORM_FEED = 'L';
6.45 + public static final char CTRL_CARRIAGE_RETURN = 'M';
6.46 + public static final char CTRL_ESCAPE = '[';
6.47 + public static final char CTRL_DELETE = '?';
6.48 +
6.49 + private static final char[] CTRL = { CTRL_BELL, CTRL_BACKSPACE, CTRL_TAB,
6.50 + CTRL_LINE_FEED, CTRL_FORM_FEED, CTRL_CARRIAGE_RETURN, CTRL_ESCAPE,
6.51 + CTRL_DELETE };
6.52 +
6.53 + public static char getControlKey(final int kc) {
6.54 + for (final char c : CTRL) {
6.55 + if (kc == c) {
6.56 + return c;
6.57 + }
6.58 + }
6.59 + return 0;
6.60 + }
6.61 +
6.62 + private static final String DEFAULT_TABS = " ";
6.63 + private static final int BIG_NUMBER = 100000;
6.64 + private final DivElement term;
6.65 + private TextConsoleConfig config;
6.66 + private TextConsoleHandler handler;
6.67 + private final Element buffer;
6.68 + private final TableElement prompt;
6.69 + private final Element ps;
6.70 + private final InputElement input;
6.71 + private List<String> cmdHistory = new ArrayList<String>();
6.72 + private int cmdHistoryIndex = -1;
6.73 + private final HandlerRegistration clickHandler;
6.74 + private final HandlerRegistration keyHandler;
6.75 + private HandlerRegistration focusHandler;
6.76 + private int fontW = -1;
6.77 + private int fontH = -1;
6.78 + private int scrollbarW = -1;
6.79 + private int rows;
6.80 + private int cols;
6.81 + private String tabs = DEFAULT_TABS;
6.82 + private boolean focused;
6.83 + private int promptRows;
6.84 + private int padding;
6.85 + private final DivElement promptWrap;
6.86 + private Timer timer;
6.87 + private int maxBufferSize;
6.88 + private String cleanPs;
6.89 + private int paddingW;
6.90 +
6.91 + public TextConsole() {
6.92 +
6.93 + // Main element
6.94 + term = Document.get().createDivElement();
6.95 + term.addClassName("term");
6.96 + setElement(term);
6.97 + setTabIndex(0);
6.98 +
6.99 + // Buffer
6.100 + buffer = Document.get().createElement("pre");
6.101 + buffer.addClassName("b");
6.102 + term.appendChild(buffer);
6.103 +
6.104 + // Prompt elements
6.105 + promptWrap = Document.get().createDivElement();
6.106 + promptWrap.addClassName("pw");
6.107 + term.appendChild(promptWrap);
6.108 +
6.109 + prompt = Document.get().createTableElement();
6.110 + promptWrap.appendChild(prompt);
6.111 + prompt.setAttribute("cellpadding", "0");
6.112 + prompt.setAttribute("cellspacing", "0");
6.113 + prompt.setAttribute("border", "0");
6.114 + prompt.addClassName("p");
6.115 +
6.116 + final TableSectionElement tbody = Document.get().createTBodyElement();
6.117 + prompt.appendChild(tbody);
6.118 +
6.119 + final TableRowElement tr = Document.get().createTRElement();
6.120 + tbody.appendChild(tr);
6.121 +
6.122 + final TableCellElement psTd = Document.get().createTDElement();
6.123 + psTd.addClassName("psw");
6.124 + tr.appendChild(psTd);
6.125 +
6.126 + ps = Document.get().createElement("nobr");
6.127 + ps.addClassName("ps");
6.128 + psTd.appendChild(ps);
6.129 +
6.130 + final TableCellElement inputTd = Document.get().createTDElement();
6.131 + inputTd.addClassName("iw");
6.132 + tr.appendChild(inputTd);
6.133 +
6.134 + input = (InputElement) Document.get().createElement("input");
6.135 + inputTd.appendChild(input);
6.136 + input.addClassName("i");
6.137 + input.setTabIndex(-1);
6.138 + input.setAttribute("spellcheck", "false");
6.139 +
6.140 + config = TextConsoleConfig.newInstance();
6.141 +
6.142 + setPromtActive(false);
6.143 +
6.144 + clickHandler = addDomHandler(new ClickHandler() {
6.145 +
6.146 + public void onClick(final ClickEvent event) {
6.147 + setFocus(true);
6.148 + }
6.149 + }, ClickEvent.getType());
6.150 +
6.151 + keyHandler = addDomHandler(new KeyDownHandler() {
6.152 +
6.153 + public void onKeyDown(final KeyDownEvent event) {
6.154 +
6.155 + // (re-)show the prompt
6.156 + setPromtActive(true);
6.157 +
6.158 + if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
6.159 + event.preventDefault();
6.160 + carriageReturn();
6.161 + } else if (event.getNativeKeyCode() == KeyCodes.KEY_UP
6.162 + || event.getNativeKeyCode() == KeyCodes.KEY_DOWN) {
6.163 + event.preventDefault();
6.164 + handleCommandHistoryBrowse(event.getNativeKeyCode());
6.165 + } else if (event.getNativeKeyCode() == KeyCodes.KEY_TAB) {
6.166 + event.preventDefault();
6.167 + suggest();
6.168 + } else if (event.getNativeKeyCode() == KeyCodes.KEY_BACKSPACE
6.169 + && getInputLenght() == 0) {
6.170 + bell();
6.171 + } else if (event.getNativeEvent().getCtrlKey()) {
6.172 + final char ctrlChar = getControlKey(event.getNativeKeyCode());
6.173 + if (ctrlChar > 0) {
6.174 + event.preventDefault();
6.175 + handleControlChar(ctrlChar);
6.176 + }
6.177 + }
6.178 +
6.179 + }
6.180 + }, KeyDownEvent.getType());
6.181 +
6.182 + updateFontDimensions();
6.183 + }
6.184 +
6.185 + protected int getInputLenght() {
6.186 + final String v = input.getValue();
6.187 + if (v != null) {
6.188 + return v.length();
6.189 + }
6.190 + return -1;
6.191 + }
6.192 +
6.193 + protected void handleControlChar(final char c) {
6.194 + switch (c) {
6.195 + case TextConsole.CTRL_BACKSPACE:
6.196 + backspace();
6.197 + break;
6.198 + case TextConsole.CTRL_BELL:
6.199 + bell();
6.200 + break;
6.201 + case TextConsole.CTRL_CARRIAGE_RETURN:
6.202 + carriageReturn();
6.203 + break;
6.204 + case TextConsole.CTRL_DELETE:
6.205 + bell(); // TODO: not supported yet
6.206 + break;
6.207 + case TextConsole.CTRL_ESCAPE:
6.208 + bell(); // TODO: not supported yet
6.209 + break;
6.210 + case TextConsole.CTRL_FORM_FEED:
6.211 + formFeed();
6.212 + break;
6.213 + case TextConsole.CTRL_LINE_FEED:
6.214 + lineFeed();
6.215 + break;
6.216 + case TextConsole.CTRL_TAB:
6.217 + tab();
6.218 + break;
6.219 +
6.220 + default:
6.221 + bell();
6.222 + break;
6.223 + }
6.224 + }
6.225 +
6.226 + protected void suggest() {
6.227 + // No suggest by default. Implement by subclassing.
6.228 + }
6.229 +
6.230 + protected void handleCommandHistoryBrowse(final int i) {
6.231 + cmdHistoryIndex = i == KeyCodes.KEY_UP ? cmdHistoryIndex - 1
6.232 + : cmdHistoryIndex + 1;
6.233 + if (cmdHistoryIndex >= 0 && cmdHistoryIndex < cmdHistory.size()) {
6.234 + prompt(cmdHistory.get(cmdHistoryIndex));
6.235 + } else {
6.236 + prompt();
6.237 + }
6.238 + }
6.239 +
6.240 + public String getInput() {
6.241 + return input.getValue();
6.242 + }
6.243 +
6.244 + protected void setInput(final String inputText) {
6.245 + if (inputText != null) {
6.246 + input.setValue(inputText);
6.247 + } else {
6.248 + input.setValue("");
6.249 + }
6.250 + if (isFocused()) {
6.251 + focusPrompt();
6.252 + }
6.253 + }
6.254 +
6.255 + public void lineFeed() {
6.256 + carriageReturn();
6.257 + }
6.258 +
6.259 + protected void tab() {
6.260 + prompt(getInput() + "\t");
6.261 + }
6.262 +
6.263 + protected void backspace() {
6.264 + bell();
6.265 + }
6.266 +
6.267 + protected void carriageReturn() {
6.268 + setPromtActive(false);
6.269 + // Append newline first if not there yet
6.270 + if (!bufferIsEmpty() && !bufferEndsWithNewLine()) {
6.271 + newLine();
6.272 + reducePrompt(-1);
6.273 + }
6.274 + print(getCurrentPromptContent());
6.275 + newLine();
6.276 + if (promptRows > 1) {
6.277 + reducePrompt(-1);
6.278 + }
6.279 + String lineBuffer = getInput();
6.280 + lineBuffer = lineBuffer.trim();
6.281 + if (!"".equals(lineBuffer)) {
6.282 + cmdHistory.add(lineBuffer);
6.283 + cmdHistoryIndex = cmdHistory.size();
6.284 + }
6.285 + if (handler != null) {
6.286 + handler.terminalInput(this, lineBuffer);
6.287 + }
6.288 + }
6.289 +
6.290 + private boolean bufferIsEmpty() {
6.291 + return !buffer.hasChildNodes();
6.292 + }
6.293 +
6.294 + private void setPromtActive(final boolean active) {
6.295 + if (active && !isPromptActive()) {
6.296 + prompt.getStyle().setDisplay(Display.BLOCK);
6.297 + } else if (!active && isPromptActive()) {
6.298 + prompt.getStyle().setDisplay(Display.NONE);
6.299 + }
6.300 + }
6.301 +
6.302 + private boolean isPromptActive() {
6.303 + return !Display.NONE.getCssName()
6.304 + .equals(prompt.getStyle().getDisplay());
6.305 + }
6.306 +
6.307 + private boolean isFocused() {
6.308 + return focused;
6.309 + }
6.310 +
6.311 + public void setConfig(final TextConsoleConfig cfg) {
6.312 + config = cfg;
6.313 +
6.314 + updateFontDimensions();
6.315 +
6.316 + scrollbarW = getScrollbarWidth();
6.317 + final String padStr = term.getStyle().getPadding();
6.318 + if (padStr != null && padStr.endsWith("px")) {
6.319 + padding = Integer
6.320 + .parseInt(padStr.substring(0, padStr.length() - 2));
6.321 + } else {
6.322 + // _log("using default padding: 1x2");
6.323 + padding = 1;
6.324 + paddingW = 2;
6.325 + }
6.326 +
6.327 + // _log("setConfig: font=" + fontW + "x" + fontH + ";scrollbar="
6.328 + // + scrollbarW + ";cols=" + config.getCols() + ";rows="
6.329 + // + config.getRows() + ";size=" + getWidth() + "x" + getHeight());
6.330 +
6.331 + setPs(config.getPs());
6.332 + setCols(config.getCols());
6.333 + setRows(config.getRows());
6.334 + setMaxBufferSize(config.getMaxBufferSize());
6.335 + }
6.336 +
6.337 + private void updateFontDimensions() {
6.338 +
6.339 + // Test element for font size
6.340 + DivElement test = Document.get().createDivElement();
6.341 + test.setAttribute("style",
6.342 + "position: absolute;");
6.343 + test.setInnerHTML("X");
6.344 + term.appendChild(test);
6.345 +
6.346 + fontW = test.getClientWidth();
6.347 + fontH = test.getClientHeight();
6.348 + if (fontW <= 0 || fontW > 100) {
6.349 + fontW = test.getOffsetWidth();
6.350 + }
6.351 + if (fontH <= 0|| fontH > 100) {
6.352 + fontH = test.getOffsetHeight();
6.353 + }
6.354 + if (fontW <= 0 || fontW > 100) {
6.355 + fontW = 1;
6.356 + }
6.357 + if (fontH <= 0|| fontH > 100) {
6.358 + fontH = 1;
6.359 + }
6.360 + term.removeChild(test);
6.361 + }
6.362 +
6.363 + // Debug instrumentation. TODO: Remove.
6.364 +// protected void _log(final String string) {
6.365 +// ApplicationConnection.getConsole().log(string);
6.366 +// }
6.367 +
6.368 + public TextConsoleConfig getConfig() {
6.369 + return config;
6.370 + }
6.371 +
6.372 + private boolean bufferEndsWithNewLine() {
6.373 + final Node last = buffer != null ? buffer.getLastChild() : null;
6.374 + // _log("last node: " + (last != null ? last.getNodeName() : "<null>"));
6.375 + return last != null && "br".equals(last.getNodeName().toLowerCase());
6.376 + }
6.377 +
6.378 + private Node createTextNode(final String text) {
6.379 + return Document.get().createTextNode(text);
6.380 + }
6.381 +
6.382 + private Node createBr() {
6.383 + return Document.get().createBRElement();
6.384 + }
6.385 +
6.386 + public void focusPrompt() {
6.387 + focusPrompt(-1);
6.388 + }
6.389 +
6.390 + public void focusPrompt(final int cursorPos) {
6.391 + input.focus();
6.392 +
6.393 + // Focus to end
6.394 + final String s = getInput();
6.395 + if (s != null && s.length() > 0) {
6.396 + setSelectionRange(input, s.length(), s.length());
6.397 + }
6.398 + }
6.399 +
6.400 + private native void setSelectionRange(Element input, int selectionStart,
6.401 + int selectionEnd)/*-{
6.402 + if (input.setSelectionRange) {
6.403 + input.focus();
6.404 + input.setSelectionRange(selectionStart, selectionEnd);
6.405 + }
6.406 + else if (input.createTextRange) {
6.407 + var range = input.createTextRange();
6.408 + range.collapse(true);
6.409 + range.moveEnd('character', selectionEnd);
6.410 + range.moveStart('character', selectionStart);
6.411 + range.select();
6.412 + }
6.413 + }-*/;
6.414 +
6.415 + private native int getScrollbarWidth()/*-{
6.416 +
6.417 + var i = $doc.createElement('p');
6.418 + i.style.width = '100%';
6.419 + i.style.height = '200px';
6.420 + var o = $doc.createElement('div');
6.421 + o.style.position = 'absolute';
6.422 + o.style.top = '0px';
6.423 + o.style.left = '0px';
6.424 + o.style.visibility = 'hidden';
6.425 + o.style.width = '200px';
6.426 + o.style.height = '150px';
6.427 + o.style.overflow = 'hidden';
6.428 + o.appendChild(i);
6.429 + $doc.body.appendChild(o);
6.430 + var w1 = i.offsetWidth;
6.431 + var h1 = i.offsetHeight;
6.432 + o.style.overflow = 'scroll';
6.433 + var w2 = i.offsetWidth;
6.434 + var h2 = i.offsetHeight;
6.435 + if (w1 == w2) w2 = o.clientWidth;
6.436 + if (h1 == h2) h2 = o.clientWidth;
6.437 + $doc.body.removeChild(o);
6.438 + return w1-w2;
6.439 + }-*/;
6.440 +
6.441 + public void newLine() {
6.442 + // _log("newline");
6.443 + buffer.appendChild(createBr());
6.444 + checkBufferLimit();
6.445 + reducePrompt(1);
6.446 + }
6.447 +
6.448 + protected void setPs(final String string) {
6.449 + cleanPs = Util.escapeHTML(string);
6.450 + cleanPs = cleanPs.replaceAll(" ", " ");
6.451 + }
6.452 +
6.453 + public void prompt(final String inputText) {
6.454 + setPromtActive(true);
6.455 + scrollToEnd();
6.456 + ps.setInnerHTML(cleanPs);
6.457 + setInput(inputText);
6.458 + }
6.459 +
6.460 + public void scrollToEnd() {
6.461 + term.setScrollTop(BIG_NUMBER);
6.462 + }
6.463 +
6.464 + public void prompt() {
6.465 + prompt(null);
6.466 + }
6.467 +
6.468 + public void print(String string) {
6.469 + if (isPromptActive()) {
6.470 + setPromtActive(false);
6.471 + if (!bufferIsEmpty() && !bufferEndsWithNewLine()) {
6.472 + newLine();
6.473 + reducePrompt(-1);
6.474 + }
6.475 + string = getCurrentPromptContent() + string;
6.476 + }
6.477 + final boolean doWrap = config.isWrap();
6.478 + // _log("print original: '" + string + "' (" + doWrap + ")");
6.479 + String str = string.replaceAll("\t", tabs);
6.480 +
6.481 + // Continue to the last text node if available
6.482 + final Node last = getLastTextNode();
6.483 + int linesAdded = 0;
6.484 + if (last != null) {
6.485 + // _log("print append to old node: '" + last.getNodeValue() + "'");
6.486 + str = last.getNodeValue() + str;
6.487 + buffer.removeChild(last);
6.488 + linesAdded--;
6.489 + }
6.490 +
6.491 + // Split by the newlines anyway
6.492 + int s = 0, e = str.indexOf('\n');
6.493 + while (e >= s) {
6.494 + final String line = str.substring(s, e);
6.495 + linesAdded += appendLine(buffer, line, doWrap ? cols : -1);
6.496 + buffer.appendChild(createBr());
6.497 + s = e + 1;
6.498 + e = str.indexOf('\n', s);
6.499 + }
6.500 +
6.501 + // Print the remaining string
6.502 + if (s < str.length()) {
6.503 + linesAdded += appendLine(buffer, str.substring(s), doWrap ? cols
6.504 + : -1);
6.505 + }
6.506 +
6.507 + reducePrompt(linesAdded);
6.508 + }
6.509 +
6.510 + private String getCurrentPromptContent() {
6.511 + return prompt.getInnerText() + getInput();
6.512 + }
6.513 +
6.514 + private void reducePrompt(final int rows) {
6.515 + int newRows = promptRows - rows;
6.516 + if (newRows < 1) {
6.517 + newRows = 1;
6.518 + }
6.519 + // _log("prompt reduced from " + promptRows + " to " + newRows);
6.520 + setPromptHeight(newRows);
6.521 + }
6.522 +
6.523 + private void setPromptHeight(final int rows) {
6.524 + final int min = 1;
6.525 + final int max = getRows();
6.526 + promptRows = rows < min ? min : (rows > max ? max : rows);
6.527 + final int newHeight = fontH * rows;
6.528 + // _log("Prompt height=" + newHeight);
6.529 + promptWrap.getStyle().setHeight(newHeight, Unit.PX);
6.530 + }
6.531 +
6.532 + /**
6.533 + * Split long text based on length.
6.534 + *
6.535 + * @param parent
6.536 + * @param doWrap
6.537 + * @param str
6.538 + * @return
6.539 + */
6.540 + private int appendLine(final Node parent, String str, final int maxLine) {
6.541 + int linesAdded = 0;
6.542 + final boolean doWrap = maxLine > 0;
6.543 + if (!doWrap) {
6.544 + parent.appendChild(createTextNode(str));
6.545 + // _log("append: '" + str + "'");
6.546 + linesAdded++;
6.547 + } else {
6.548 + while (str.length() > maxLine) {
6.549 + final String piece = str.substring(0, maxLine);
6.550 + parent.appendChild(createTextNode(piece));
6.551 + parent.appendChild(createBr());
6.552 + linesAdded++;
6.553 + // _log("append: '" + piece + "'");
6.554 + str = str.substring(maxLine);
6.555 + }
6.556 + parent.appendChild(createTextNode(str));
6.557 + // _log("append rest: '" + str + "'");
6.558 + linesAdded++;
6.559 + }
6.560 +
6.561 + // make sore we don't exceed the maximum buffer size
6.562 + checkBufferLimit();
6.563 +
6.564 + return linesAdded;
6.565 + }
6.566 +
6.567 + private void checkBufferLimit() {
6.568 +
6.569 + // Buffer means only offscreen lines
6.570 + final int maxb = maxBufferSize + (rows - promptRows);
6.571 + while (getBufferSize() > maxb && buffer.hasChildNodes()) {
6.572 + buffer.removeChild(buffer.getFirstChild());
6.573 + }
6.574 +
6.575 + }
6.576 +
6.577 + private Node getLastTextNode() {
6.578 + if (buffer == null) {
6.579 + return null;
6.580 + }
6.581 + final Node l = buffer.getLastChild();
6.582 + if (l != null && l.getNodeType() == Node.TEXT_NODE) {
6.583 + return l;
6.584 + }
6.585 + return null;
6.586 + }
6.587 +
6.588 + public void println(final String string) {
6.589 + print(string + "\n");
6.590 + }
6.591 +
6.592 + @Override
6.593 + public void setHeight(final String height) {
6.594 + final int oldh = term.getClientHeight();
6.595 + super.setHeight(height);
6.596 + final int newh = term.getClientHeight();
6.597 + // _log("set height=" + height + " clientHeight="+oldh+" to "+newh);
6.598 + if (newh != oldh) {
6.599 + calculateRowsFromHeight();
6.600 + }
6.601 + }
6.602 +
6.603 + protected void calculateRowsFromHeight() {
6.604 + final int h = term.getClientHeight() - (2 * padding);
6.605 + rows = h / fontH;
6.606 + config.setRows(rows);
6.607 +
6.608 + // _log("calculateRowsFromHeight: font=" + fontW + "x" + fontH
6.609 + // + ";scrollbar=" + scrollbarW + ";cols=" + cols + ";rows="
6.610 + // + rows + ";size=" + getWidth() + "x" + getHeight());
6.611 +
6.612 + }
6.613 +
6.614 + protected void calculateHeightFromRows() {
6.615 + super.setHeight((rows * fontH) + "px");
6.616 +
6.617 + // _log("calculateHeightFromRows: font=" + fontW + "x" + fontH
6.618 + // + ";scrollbar=" + scrollbarW + ";cols=" + cols + ";rows="
6.619 + // + rows + ";size=" + getWidth() + "x" + getHeight());
6.620 +
6.621 + }
6.622 +
6.623 + protected void calculateColsFromWidth() {
6.624 + final int w = term.getClientWidth();
6.625 + cols = (w - 2 * paddingW) / fontW;
6.626 + config.setCols(cols);
6.627 + buffer.getStyle().setWidth((cols * fontW), Unit.PX);
6.628 + prompt.getStyle().setWidth((cols * fontW), Unit.PX);
6.629 + // _log("calculateColsFromWidth: font=" + fontW + "x" + fontH
6.630 + // + ";scrollbar=" + scrollbarW + ";cols=" + cols + ";rows="
6.631 + // + rows + ";size=" + getWidth() + "x" + getHeight());
6.632 +
6.633 + }
6.634 +
6.635 + protected void calculateWidthFromCols() {
6.636 + final int w = cols * fontW;
6.637 + super.setWidth((w + scrollbarW) + "px");
6.638 + buffer.getStyle().setWidth(w, Unit.PX);
6.639 + prompt.getStyle().setWidth(w, Unit.PX);
6.640 +
6.641 + // _log("calculateWidthFromCols: font=" + fontW + "x" + fontH
6.642 + // + ";scrollbar=" + scrollbarW + ";cols=" + cols + ";rows="
6.643 + // + rows + ";size=" + getWidth() + "x" + getHeight());
6.644 + }
6.645 +
6.646 + @Override
6.647 + public void setWidth(final String width) {
6.648 + final int oldw = term.getClientWidth();
6.649 + super.setWidth(width);
6.650 + final int neww = term.getClientWidth();
6.651 + // _log("set width=" + width + " clientWidth="+oldw+" to "+neww);
6.652 + if (neww != oldw) {
6.653 + calculateColsFromWidth();
6.654 + }
6.655 + }
6.656 +
6.657 + @Override
6.658 + public void setFocus(final boolean focused) {
6.659 + this.focused = focused;
6.660 + super.setFocus(focused);
6.661 + if (focused) {
6.662 + focusPrompt();
6.663 + }
6.664 + }
6.665 +
6.666 + public void setHandler(final TextConsoleHandler handler) {
6.667 + this.handler = handler;
6.668 +
6.669 + }
6.670 +
6.671 + public void setRows(final int rows) {
6.672 + if (rows > 0) {
6.673 + this.rows = rows;
6.674 + calculateHeightFromRows();
6.675 + } else {
6.676 + calculateRowsFromHeight();
6.677 + }
6.678 + }
6.679 +
6.680 + public int getRows() {
6.681 + return rows;
6.682 + }
6.683 +
6.684 + public void setCols(final int cols) {
6.685 + if (cols > 0) {
6.686 + this.cols = cols;
6.687 + calculateWidthFromCols();
6.688 + } else {
6.689 + calculateColsFromWidth();
6.690 + }
6.691 + }
6.692 +
6.693 + public int getCols() {
6.694 + return cols;
6.695 + }
6.696 +
6.697 + public void reset() {
6.698 + setPromtActive(false);
6.699 + clearBuffer();
6.700 + setPromptHeight(getRows());
6.701 + print(config.getGreeting());
6.702 + prompt();
6.703 + }
6.704 +
6.705 + public int getBufferSize() {
6.706 + return (buffer.getClientHeight() / fontH);
6.707 + }
6.708 +
6.709 + public int getMaxBufferSize() {
6.710 + return maxBufferSize;
6.711 + }
6.712 +
6.713 + public void setMaxBufferSize(final int maxBuffer) {
6.714 + maxBufferSize = maxBuffer > 0 ? maxBuffer : 0;
6.715 + checkBufferLimit();
6.716 + }
6.717 +
6.718 + public void clearBuffer() {
6.719 + // Remove all children.
6.720 + while (buffer.hasChildNodes()) {
6.721 + buffer.removeChild(buffer.getFirstChild());
6.722 + }
6.723 + }
6.724 +
6.725 + public void formFeed() {
6.726 + for (int i = 0; i < promptRows; i++) {
6.727 + newLine();
6.728 + }
6.729 + setPromptHeight(getRows());
6.730 + scrollToEnd();
6.731 +
6.732 + checkBufferLimit();
6.733 + }
6.734 +
6.735 + protected void clearCommandHistory() {
6.736 + cmdHistory = new ArrayList<String>();
6.737 + cmdHistoryIndex = -1;
6.738 + }
6.739 +
6.740 + public String getHeight() {
6.741 + return (term.getClientHeight() - 2 * padding) + "px";
6.742 + }
6.743 +
6.744 + public String getWidth() {
6.745 + return (term.getClientWidth() + scrollbarW - 2 * paddingW) + "px";
6.746 + }
6.747 +
6.748 + protected void bell() {
6.749 + // Clear previous
6.750 + if (timer != null) {
6.751 + timer.cancel();
6.752 + timer = null;
6.753 + term.removeClassName("term-rev");
6.754 + input.removeClassName("term-rev");
6.755 + }
6.756 + // Add styles and start the timer
6.757 + input.addClassName("term-rev");
6.758 + term.addClassName("term-rev");
6.759 + timer = new Timer() {
6.760 +
6.761 + @Override
6.762 + public void run() {
6.763 + term.removeClassName("term-rev");
6.764 + input.removeClassName("term-rev");
6.765 + }
6.766 + };
6.767 + timer.schedule(150);
6.768 + }
6.769 +
6.770 + @Override
6.771 + protected void onUnload() {
6.772 + super.onUnload();
6.773 +
6.774 + if (clickHandler != null) {
6.775 + clickHandler.removeHandler();
6.776 + }
6.777 + if (focusHandler != null) {
6.778 + focusHandler.removeHandler();
6.779 + }
6.780 + if (keyHandler != null) {
6.781 + keyHandler.removeHandler();
6.782 + }
6.783 + }
6.784 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/main/java/org/vaadin/console/client/ui/TextConsoleConfig.java Sun May 15 17:46:06 2011 +0400
7.3 @@ -0,0 +1,62 @@
7.4 +package org.vaadin.console.client.ui;
7.5 +
7.6 +import com.google.gwt.core.client.JavaScriptObject;
7.7 +
7.8 +public class TextConsoleConfig extends JavaScriptObject {
7.9 +
7.10 + public static TextConsoleConfig newInstance() {
7.11 + return JavaScriptObject.createObject().cast();
7.12 + }
7.13 +
7.14 + protected TextConsoleConfig() {
7.15 + }
7.16 +
7.17 + public final native int getCols() /*-{
7.18 + return this.cols;
7.19 + }-*/;
7.20 +
7.21 + public final native void setCols(int cols) /*-{
7.22 + this.cols = cols;
7.23 + }-*/;
7.24 +
7.25 + public final native int getRows() /*-{
7.26 + return this.rows;
7.27 + }-*/;
7.28 +
7.29 + public final native void setRows(int rows) /*-{
7.30 + this.rows = rows;
7.31 + }-*/;
7.32 +
7.33 + public final native void setGreeting(String greeting) /*-{
7.34 + this.greeting = greeting;
7.35 + }-*/;
7.36 +
7.37 + public final native String getGreeting() /*-{
7.38 + return this.greeting;
7.39 + }-*/;
7.40 +
7.41 + public final native void setWrap(boolean w) /*-{
7.42 + this.wrap = w;
7.43 + }-*/;
7.44 +
7.45 + public final native boolean isWrap() /*-{
7.46 + return this.wrap;
7.47 + }-*/;
7.48 +
7.49 + public final native void setPs(String ps) /*-{
7.50 + this.ps = ps;
7.51 + }-*/;
7.52 +
7.53 + public final native String getPs() /*-{
7.54 + return this.ps;
7.55 + }-*/;
7.56 +
7.57 + public final native int getMaxBufferSize() /*-{
7.58 + return this.bufferRows;
7.59 + }-*/;
7.60 +
7.61 + public final native void setMaxBufferSize(int rows) /*-{
7.62 + this.bufferRows = rows;
7.63 + }-*/;
7.64 +
7.65 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/src/main/java/org/vaadin/console/client/ui/TextConsoleHandler.java Sun May 15 17:46:06 2011 +0400
8.3 @@ -0,0 +1,7 @@
8.4 +package org.vaadin.console.client.ui;
8.5 +
8.6 +public interface TextConsoleHandler {
8.7 +
8.8 + public void terminalInput(TextConsole term, String input);
8.9 +
8.10 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/main/java/org/vaadin/console/client/ui/VTextConsole.java Sun May 15 17:46:06 2011 +0400
9.3 @@ -0,0 +1,252 @@
9.4 +package org.vaadin.console.client.ui;
9.5 +
9.6 +import org.vaadin.rpc.client.ClientSideHandler;
9.7 +import org.vaadin.rpc.client.ClientSideProxy;
9.8 +import org.vaadin.rpc.client.ClientSideProxy.Transcation;
9.9 +import org.vaadin.rpc.client.Method;
9.10 +
9.11 +import com.vaadin.terminal.gwt.client.ApplicationConnection;
9.12 +import com.vaadin.terminal.gwt.client.Paintable;
9.13 +import com.vaadin.terminal.gwt.client.UIDL;
9.14 +import com.vaadin.terminal.gwt.client.Util;
9.15 +
9.16 +/**
9.17 + * Vaadin client-side integration to Console GWT Widget.
9.18 + *
9.19 + * @author Sami Ekblad / Vaadin
9.20 + *
9.21 + */
9.22 +public class VTextConsole extends TextConsole implements Paintable,
9.23 + TextConsoleHandler, ClientSideHandler {
9.24 +
9.25 + private static final String CSS_CLASS_NAME = "v-console";
9.26 +
9.27 + private final ClientSideProxy comm = new ClientSideProxy("VTextConsole",
9.28 + this);
9.29 +
9.30 + /**
9.31 + * The constructor should first call super() to initialize the component and
9.32 + * then handle any initialization relevant to Vaadin.
9.33 + */
9.34 + public VTextConsole() {
9.35 + super();
9.36 + getElement().addClassName(CSS_CLASS_NAME);
9.37 + setHandler(this);
9.38 +
9.39 + // Register all server-driven functions
9.40 + registerServerCallbacks();
9.41 + }
9.42 +
9.43 + private void registerServerCallbacks() {
9.44 + comm.register("setGreeting", new Method() {
9.45 + public void invoke(final String methodName, final Object[] data) {
9.46 + getConfig().setGreeting((String) data[0]);
9.47 + }
9.48 + });
9.49 + comm.register("setPs", new Method() {
9.50 + public void invoke(final String methodName, final Object[] data) {
9.51 + setPs((String) data[0]);
9.52 + }
9.53 + });
9.54 + comm.register("setWrap", new Method() {
9.55 + public void invoke(final String methodName, final Object[] data) {
9.56 + getConfig().setWrap((Boolean) data[0]);
9.57 + }
9.58 + });
9.59 + comm.register("setRows", new Method() {
9.60 + public void invoke(final String methodName, final Object[] data) {
9.61 + getConfig().setRows((Integer) data[0]);
9.62 + setRows((Integer) data[0]);
9.63 + }
9.64 + });
9.65 + comm.register("setCols", new Method() {
9.66 + public void invoke(final String methodName, final Object[] data) {
9.67 + getConfig().setCols((Integer) data[0]);
9.68 + setCols((Integer) data[0]);
9.69 + }
9.70 + });
9.71 + comm.register("print", new Method() {
9.72 + public void invoke(final String methodName, final Object[] data) {
9.73 + print((String) data[0]);
9.74 + }
9.75 + });
9.76 + comm.register("println", new Method() {
9.77 + public void invoke(final String methodName, final Object[] data) {
9.78 + println((String) data[0]);
9.79 + }
9.80 + });
9.81 + comm.register("println", new Method() {
9.82 + public void invoke(final String methodName, final Object[] data) {
9.83 + println((String) data[0]);
9.84 + }
9.85 + });
9.86 + comm.register("prompt", new Method() {
9.87 + public void invoke(final String methodName, final Object[] data) {
9.88 + prompt((String) (data.length > 0 ? data[0] : null));
9.89 + }
9.90 + });
9.91 + comm.register("ff", new Method() {
9.92 + public void invoke(final String methodName, final Object[] data) {
9.93 + formFeed();
9.94 + }
9.95 + });
9.96 + comm.register("cr", new Method() {
9.97 + public void invoke(final String methodName, final Object[] data) {
9.98 + carriageReturn();
9.99 + }
9.100 + });
9.101 + comm.register("lf", new Method() {
9.102 + public void invoke(final String methodName, final Object[] data) {
9.103 + carriageReturn();
9.104 + }
9.105 + });
9.106 + comm.register("clearBuffer", new Method() {
9.107 + public void invoke(final String methodName, final Object[] data) {
9.108 + clearBuffer();
9.109 + }
9.110 + });
9.111 + comm.register("reset", new Method() {
9.112 + public void invoke(final String methodName, final Object[] data) {
9.113 + reset();
9.114 + }
9.115 + });
9.116 + comm.register("newLine", new Method() {
9.117 + public void invoke(final String methodName, final Object[] data) {
9.118 + newLine();
9.119 + }
9.120 + });
9.121 + comm.register("scrollToEnd", new Method() {
9.122 + public void invoke(final String methodName, final Object[] data) {
9.123 + scrollToEnd();
9.124 + }
9.125 + });
9.126 + comm.register("bell", new Method() {
9.127 + public void invoke(final String methodName, final Object[] data) {
9.128 + bell();
9.129 + }
9.130 + });
9.131 + comm.register("setMaxBufferSize", new Method() {
9.132 + public void invoke(final String methodName, final Object[] data) {
9.133 + getConfig().setMaxBufferSize((Integer) data[0]);
9.134 + setMaxBufferSize((Integer) data[0]);
9.135 + }
9.136 + });
9.137 + comm.register("clearHistory", new Method() {
9.138 + public void invoke(final String methodName, final Object[] data) {
9.139 + clearCommandHistory();
9.140 + }
9.141 + });
9.142 + }
9.143 +
9.144 + /**
9.145 + * Called whenever an update is received from the server
9.146 + */
9.147 + public void updateFromUIDL(final UIDL serverData,
9.148 + final ApplicationConnection appConn) {
9.149 + comm.update(this,serverData, appConn);
9.150 +
9.151 + }
9.152 +
9.153 + private void sendSizeToServer() {
9.154 + if (comm.isClientInitialized()) {
9.155 + final Transcation tx = comm.startTx();
9.156 + tx.send("height", getHeight());
9.157 + tx.send("width", getWidth());
9.158 + tx.commit();
9.159 + }
9.160 +
9.161 + }
9.162 +
9.163 + public void terminalInput(final TextConsole term, final String input) {
9.164 + if (comm.isClientInitialized()) {
9.165 + comm.call("input", input);
9.166 + }
9.167 + }
9.168 +
9.169 + @Override
9.170 + protected void calculateColsFromWidth() {
9.171 + final int oldCols = getCols();
9.172 + super.calculateColsFromWidth();
9.173 +
9.174 + if (comm.isClientInitialized() && getCols() != oldCols) {
9.175 + final Transcation tx = comm.startTx();
9.176 + tx.send("cols", getCols());
9.177 + tx.commit();
9.178 + }
9.179 + }
9.180 +
9.181 + @Override
9.182 + protected void calculateRowsFromHeight() {
9.183 + final int oldRows = getRows();
9.184 + super.calculateRowsFromHeight();
9.185 +
9.186 + if (comm.isClientInitialized() && getRows() != oldRows) {
9.187 + final Transcation tx = comm.startTx();
9.188 + tx.send("rows", getRows());
9.189 + tx.commit();
9.190 +
9.191 + }
9.192 +
9.193 + }
9.194 +
9.195 + @Override
9.196 + protected void calculateHeightFromRows() {
9.197 + super.calculateHeightFromRows();
9.198 + notifyPaintableSizeChange();
9.199 + sendSizeToServer();
9.200 + }
9.201 +
9.202 + @Override
9.203 + protected void calculateWidthFromCols() {
9.204 + super.calculateWidthFromCols();
9.205 + notifyPaintableSizeChange();
9.206 + sendSizeToServer();
9.207 + }
9.208 +
9.209 + private void notifyPaintableSizeChange() {
9.210 + Util.notifyParentOfSizeChange(this, false);
9.211 + }
9.212 +
9.213 + @Override
9.214 + protected void suggest() {
9.215 + if (comm.isClientInitialized()) {
9.216 + comm.call("suggest", getInput());
9.217 + }
9.218 + }
9.219 +
9.220 + @Override
9.221 + public void setConfig(final TextConsoleConfig cfg) {
9.222 + // Wrap everything to a single tx
9.223 + final Transcation tx = comm.startTx();
9.224 + super.setConfig(cfg);
9.225 + tx.commit();
9.226 + }
9.227 +
9.228 + /**
9.229 + * Initialize the Console synchronously.
9.230 + *
9.231 + */
9.232 + public boolean initWidget(Object[] params) {
9.233 +
9.234 + // Console configuration
9.235 + final TextConsoleConfig cfg = getConfig();
9.236 + int i = 0;
9.237 + cfg.setCols((Integer) params[i++]);
9.238 + cfg.setRows((Integer) params[i++]);
9.239 + cfg.setMaxBufferSize((Integer) params[i++]);
9.240 + cfg.setWrap((Boolean) params[i++]);
9.241 + cfg.setGreeting((String) params[i++]);
9.242 + cfg.setPs((String) params[i++]);
9.243 + comm.d("init: '" + cfg.getGreeting() + "';" + cfg.getCols() + "x"
9.244 + + cfg.getRows() + "");
9.245 + setConfig(cfg);
9.246 +
9.247 + reset();
9.248 + return false; // Not an async initialization
9.249 + }
9.250 +
9.251 + public void handleCallFromServer(String method, Object[] params) {
9.252 + comm.d("Unknown method called: " + method);
9.253 + }
9.254 +
9.255 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/src/main/java/org/vaadin/console/public/console/styles.css Sun May 15 17:46:06 2011 +0400
10.3 @@ -0,0 +1,70 @@
10.4 +.term {
10.5 + background-color: #000;
10.6 + color: #f0f0f0;
10.7 + /* color: #33d011; */
10.8 + padding: 1px;
10.9 + padding-left: 2px;
10.10 + padding-right: 2px;
10.11 + font-family: monospace;;
10.12 + font-size: 10pt;
10.13 + overflow: scroll;
10.14 + overflow-x: hidden;
10.15 +}
10.16 +
10.17 +.term-rev, .term input.term-rev {
10.18 + background-color: #f0f0f0;
10.19 + color: #000;
10.20 +}
10.21 +
10.22 +.term .b {
10.23 + margin: 0;
10.24 + padding: 0;
10.25 +}
10.26 +
10.27 +.term .pw {
10.28 + margin: 0;
10.29 + padding: 0;
10.30 +}
10.31 +
10.32 +.term .pw .p {
10.33 + border-collapse: collapse;
10.34 + margin: 0;
10.35 + padding: 0;
10.36 + height: 1em;
10.37 +}
10.38 +
10.39 +.term .pw .psw {
10.40 + margin: 0;
10.41 + padding: 0;
10.42 + width: auto;
10.43 +}
10.44 +
10.45 +.term .pw .iw {
10.46 + margin: 0;
10.47 + padding: 0;
10.48 + width: 100%;
10.49 +}
10.50 +
10.51 +.term .i {
10.52 + border: none;
10.53 + outline: none;
10.54 + border-width: 0;
10.55 + width: 100%;
10.56 + height: 1em;
10.57 + margin: 0;
10.58 + padding: 0;
10.59 + font-family: monospace;;
10.60 + font-size: 10pt;
10.61 + word-wrap:break-word;
10.62 + background-color: #000;
10.63 + color: #f0f0f0;
10.64 +}
10.65 +
10.66 +
10.67 +/** Coloring sample
10.68 +.term, .term .i {
10.69 + background-color: #F5F5F5 !important;
10.70 + color: #222222 !important;
10.71 +}
10.72 +
10.73 + **/
10.74 \ No newline at end of file
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/src/main/java/org/vaadin/console/sample/ConsoleSampleApplication.java Sun May 15 17:46:06 2011 +0400
11.3 @@ -0,0 +1,193 @@
11.4 +package org.vaadin.console.sample;
11.5 +
11.6 +import java.io.IOException;
11.7 +import java.io.InputStream;
11.8 +import java.io.InputStreamReader;
11.9 +import java.util.ArrayList;
11.10 +import java.util.Arrays;
11.11 +
11.12 +import org.vaadin.console.Console;
11.13 +import org.vaadin.console.Console.Command;
11.14 +import org.vaadin.console.ObjectInspector;
11.15 +
11.16 +import com.vaadin.Application;
11.17 +import com.vaadin.ui.Button;
11.18 +import com.vaadin.ui.Button.ClickEvent;
11.19 +import com.vaadin.ui.HorizontalLayout;
11.20 +import com.vaadin.ui.Label;
11.21 +import com.vaadin.ui.Panel;
11.22 +import com.vaadin.ui.TextField;
11.23 +import com.vaadin.ui.Window;
11.24 +
11.25 +public class ConsoleSampleApplication extends Application {
11.26 + private static final long serialVersionUID = 4009702916419936660L;
11.27 + protected static final String HELP = "Sample Vaadin shell. Following command are available:\n";
11.28 + private ObjectInspector inspector;
11.29 +
11.30 + @Override
11.31 + public void init() {
11.32 + Window mainWindow = new Window("Vaadin Console Demo");
11.33 + setMainWindow(mainWindow);
11.34 +
11.35 + Panel intro = new Panel("Vaadin Console Demo");
11.36 + intro
11.37 + .addComponent(new Label(
11.38 + "This console implements a test environment for itself.<br> All methods in console class are exposed as commands in the console itself.",
11.39 + Label.CONTENT_RAW));
11.40 + intro
11.41 + .addComponent(new Label(
11.42 + "Type 'help' to list all available commands and 'help <command>' to get parameter help.'"));
11.43 +
11.44 + // # 1
11.45 +
11.46 + // Create a console
11.47 + final Console console = new Console();
11.48 + mainWindow.addComponent(console);
11.49 +
11.50 + // Size and greeting
11.51 + console.setPs("}> ");
11.52 + console.setCols(80);
11.53 + console.setRows(24);
11.54 + console.setMaxBufferSize(24);
11.55 + console.setGreeting("Welcome to Vaadin console demo.");
11.56 + console.reset();
11.57 + console.focus();
11.58 +
11.59 + // Publish the methods in the Console class itself for testing purposes.
11.60 + console.addCommandProvider(inspector = new ObjectInspector(console));
11.61 +
11.62 + // Add help command
11.63 + Command helpCommand = new Console.Command() {
11.64 + private static final long serialVersionUID = 2838665604270727844L;
11.65 +
11.66 + public String getUsage(Console console, String[] argv) {
11.67 + return argv[0] + " <command>";
11.68 + }
11.69 +
11.70 + public Object execute(Console console, String[] argv)
11.71 + throws Exception {
11.72 + if (argv.length == 2) {
11.73 + Command hc = console.getCommand(argv[1]);
11.74 + ArrayList<String> cmdArgv = new ArrayList<String>(Arrays
11.75 + .asList(argv));
11.76 + cmdArgv.remove(0);
11.77 + return "Usage: "
11.78 + + hc.getUsage(console, cmdArgv
11.79 + .toArray(new String[] {}));
11.80 + }
11.81 + return listAvailableCommands();
11.82 + }
11.83 + };
11.84 +
11.85 + // Bind the same command with multiple names
11.86 + console.addCommand("help", helpCommand);
11.87 + console.addCommand("info", helpCommand);
11.88 + console.addCommand("man", helpCommand);
11.89 + // #
11.90 +
11.91 + // # 2
11.92 + Command systemCommand = new Command() {
11.93 + private static final long serialVersionUID = -5733237166568671987L;
11.94 +
11.95 + public Object execute(Console console, String[] argv)
11.96 + throws Exception {
11.97 + Process p = Runtime.getRuntime().exec(argv);
11.98 + InputStream in = p.getInputStream();
11.99 + StringBuilder o = new StringBuilder();
11.100 + InputStreamReader r = new InputStreamReader(in);
11.101 + int c = -1;
11.102 + try {
11.103 + while ((c = r.read()) != -1) {
11.104 + o.append((char) c);
11.105 + }
11.106 + } catch (IOException e) {
11.107 + o.append("[truncated]");
11.108 + } finally {
11.109 + if (r != null) {
11.110 + r.close();
11.111 + }
11.112 + }
11.113 + return o.toString();
11.114 + }
11.115 +
11.116 + public String getUsage(Console console, String[] argv) {
11.117 + // TODO Auto-generated method stub
11.118 + return null;
11.119 + }
11.120 + };
11.121 +
11.122 + // #
11.123 + console.addCommand("ls", systemCommand);
11.124 +
11.125 + // Add sample command
11.126 + DummyCmd dummy = new DummyCmd();
11.127 + console.addCommand("dir", dummy);
11.128 + console.addCommand("cd", dummy);
11.129 + console.addCommand("mkdir", dummy);
11.130 + console.addCommand("rm", dummy);
11.131 + console.addCommand("pwd", dummy);
11.132 + console.addCommand("more", dummy);
11.133 + console.addCommand("less", dummy);
11.134 + console.addCommand("exit", dummy);
11.135 +
11.136 + HorizontalLayout pl = new HorizontalLayout();
11.137 + pl.setSpacing(true);
11.138 + mainWindow.addComponent(pl);
11.139 + final TextField input = new TextField(null, "print this");
11.140 + pl.addComponent(input);
11.141 + pl.addComponent(new Button("print", new Button.ClickListener() {
11.142 + private static final long serialVersionUID = 1L;
11.143 +
11.144 + public void buttonClick(ClickEvent event) {
11.145 + console.print("" + input.getValue());
11.146 + }
11.147 + }));
11.148 +
11.149 + pl.addComponent(new Button("println", new Button.ClickListener() {
11.150 + private static final long serialVersionUID = 1L;
11.151 +
11.152 + public void buttonClick(ClickEvent event) {
11.153 + console.println("" + input.getValue());
11.154 + }
11.155 + }));
11.156 +
11.157 + }
11.158 +
11.159 + protected String readToString(InputStream in) {
11.160 + StringBuilder o = new StringBuilder();
11.161 + InputStreamReader r = new InputStreamReader(in);
11.162 + int c = -1;
11.163 + try {
11.164 + while ((c = r.read()) != -1) {
11.165 + o.append((char) c);
11.166 + }
11.167 + } catch (IOException e) {
11.168 + o.append("[truncated]");
11.169 + }
11.170 + return o.toString();
11.171 + }
11.172 +
11.173 + public static class DummyCmd implements Console.Command {
11.174 + private static final long serialVersionUID = -7725047596507450670L;
11.175 +
11.176 + public Object execute(Console console, String[] argv) throws Exception {
11.177 + return "Sorry, this is not a real shell and '" + argv[0]
11.178 + + "' is unsupported. Try 'help' instead.";
11.179 + }
11.180 +
11.181 + public String getUsage(Console console, String[] argv) {
11.182 + return "Sorry, this is not a real shell and '" + argv[0]
11.183 + + "' is unsupported. Try 'help' instead.";
11.184 + }
11.185 + }
11.186 +
11.187 + protected String listAvailableCommands() {
11.188 + StringBuilder res = new StringBuilder();
11.189 + for (String cmd : inspector.getAvailableCommands()) {
11.190 + res.append(" ");
11.191 + res.append(cmd);
11.192 + }
11.193 + return res.toString().trim();
11.194 + }
11.195 +
11.196 +}