From: <cr...@us...> - 2009-04-19 14:06:38
|
Revision: 5310 http://jnode.svn.sourceforge.net/jnode/?rev=5310&view=rev Author: crawley Date: 2009-04-19 14:06:34 +0000 (Sun, 19 Apr 2009) Log Message: ----------- Implement the shell properties, and tools to set and display them. Changed jnode.interpreter, jnode.invoker, jnode.debug and others into shell properties (were system properties). Modified Paths: -------------- trunk/distr/descriptors/net.wimpi.telnetd.xml trunk/shell/descriptors/org.jnode.shell.command.xml trunk/shell/descriptors/org.jnode.shell.xml trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/CommandShell.java trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/Shell.java trunk/shell/src/shell/org/jnode/shell/ShellManager.java trunk/shell/src/shell/org/jnode/shell/ShellUtils.java trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/command/EnvCommand.java trunk/shell/src/shell/org/jnode/shell/command/SetCommand.java trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java trunk/shell/src/shell/org/jnode/shell/syntax/PropertyNameArgument.java trunk/shell/src/test/org/jnode/test/shell/CompletionTest.java trunk/shell/src/test/org/jnode/test/shell/DefaultSyntaxCompletionTest.java Added Paths: ----------- trunk/shell/src/shell/org/jnode/shell/syntax/ShellPropertyNameArgument.java Modified: trunk/distr/descriptors/net.wimpi.telnetd.xml =================================================================== --- trunk/distr/descriptors/net.wimpi.telnetd.xml 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/distr/descriptors/net.wimpi.telnetd.xml 2009-04-19 14:06:34 UTC (rev 5310) @@ -28,19 +28,13 @@ <permission class="java.lang.RuntimePermission" name="modifyThreadGroup"/> <permission class="java.lang.RuntimePermission" name="exitVM"/> - <!-- do we need them all like in org.jnode.shell ? only "jnode.prompt" has been checked --> - <permission class="java.io.FilePermission" name="<<ALL FILES>>" actions="read,write"/> + <permission class="java.io.FilePermission" name="<<ALL FILES>>" actions="read,write"/> <permission class="java.lang.RuntimePermission" name="modifyThreadGroup"/> <permission class="java.lang.RuntimePermission" name="modifyThread"/> <permission class="java.lang.RuntimePermission" name="setIO"/> <permission class="java.net.SocketPermission" name="*" actions="resolve,listen,connect"/> <permission class="java.net.SocketPermission" name="*:0-" actions="connect,resolve,listen"/> <permission class="java.util.PropertyPermission" name="jnode.cmdline" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.debug" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.history" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.invoker" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.interpreter" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.prompt" actions="read,write"/> <permission class="java.util.PropertyPermission" name="*" actions="read,write"/> <permission class="java.util.PropertyPermission" name="user.dir" actions="read"/> </extension> Modified: trunk/shell/descriptors/org.jnode.shell.command.xml =================================================================== --- trunk/shell/descriptors/org.jnode.shell.command.xml 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/descriptors/org.jnode.shell.command.xml 2009-04-19 14:06:34 UTC (rev 5310) @@ -150,6 +150,8 @@ <empty description="Print the system properties"/> <option argLabel="env" shortName="e" longName="env" description="Print the system environment variables"/> + <option argLabel="shell" shortName="s" longName="shell" + description="Print the current shell properties"/> </syntax> <syntax alias="exit" description="Exit the current shell"/> <syntax alias="gc"> @@ -358,11 +360,21 @@ <argument argLabel="file"/> </syntax> <syntax alias="set"> - <sequence description="Set a system property or environment variable"> + <sequence description="Set a shell property"> + <option argLabel="shell" shortName="s" longName="shell"/> + <argument argLabel="skey"/> + <argument argLabel="value"/> + </sequence> + <sequence> + <argument description="Remove a shell property" argLabel="skey"/> + <option argLabel="shell" shortName="s" longName="shell"/> + </sequence> + <sequence description="Set a system property"> <argument argLabel="key"/> <argument argLabel="value"/> </sequence> <argument description="Remove a system property" argLabel="key"/> + </syntax> <syntax alias="sleep" description="Sleep for a given number of seconds"> <argument argLabel="seconds"/> @@ -378,7 +390,7 @@ <option argLabel="file" longName="load" shortName="l"/> <argument argLabel="alias"/> </sequence> - <sequence description="Set a system property"> + <sequence description="Remove the syntax for a given alias"> <option argLabel="remove" longName="remove" shortName="r"/> <argument argLabel="alias"/> </sequence> Modified: trunk/shell/descriptors/org.jnode.shell.xml =================================================================== --- trunk/shell/descriptors/org.jnode.shell.xml 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/descriptors/org.jnode.shell.xml 2009-04-19 14:06:34 UTC (rev 5310) @@ -42,11 +42,6 @@ <permission class="java.net.SocketPermission" name="*" actions="resolve,listen,connect"/> <permission class="java.net.SocketPermission" name="*:0-" actions="connect,resolve,listen"/> <permission class="java.util.PropertyPermission" name="jnode.cmdline" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.debug" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.history" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.invoker" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.interpreter" actions="read"/> - <permission class="java.util.PropertyPermission" name="jnode.prompt" actions="read,write"/> <permission class="java.util.PropertyPermission" name="*" actions="read,write"/> <permission class="java.util.PropertyPermission" name="user.dir" actions="read"/> <permission class="java.lang.reflect.ReflectPermission" name="suppressAccessChecks"/> Modified: trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -65,8 +65,6 @@ static final String EXECUTE_METHOD = "execute"; boolean blocking; - - boolean debugEnabled; Thread blockingThread; CommandThread threadProcess = null; @@ -266,11 +264,6 @@ @Override public boolean isDebugEnabled() { - return this.debugEnabled; + return commandShell.isDebugEnabled(); } - - @Override - public void setDebugEnabled(boolean debugEnabled) { - this.debugEnabled = debugEnabled; - } } Modified: trunk/shell/src/shell/org/jnode/shell/CommandShell.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -37,10 +37,12 @@ import java.security.PrivilegedAction; import java.text.DateFormat; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; +import java.util.TreeMap; import javax.naming.NameNotFoundException; @@ -93,7 +95,7 @@ public static final String CMDLINE_PROPERTY_NAME = "jnode.cmdline"; public static final String DEBUG_PROPERTY_NAME = "jnode.debug"; - public static final String DEBUG_DEFAULT = "false"; + public static final String DEBUG_DEFAULT = "true"; public static final String HISTORY_PROPERTY_NAME = "jnode.history"; public static final String HISTORY_DEFAULT = "true"; @@ -162,10 +164,10 @@ private String lastInputLine = ""; private SimpleCommandInvoker invoker; - private String invokerName; private CommandInterpreter interpreter; - private String interpreterName; + + private HashMap<String, String> propertyMap; private CompletionInfo completion; @@ -214,7 +216,7 @@ console.addConsoleListener(this); aliasMgr = ShellUtils.getAliasManager().createAliasManager(); syntaxMgr = ShellUtils.getSyntaxManager().createSyntaxManager(); - System.setProperty(PROMPT_PROPERTY_NAME, DEFAULT_PROMPT); + propertyMap = initShellProperties(); } catch (NameNotFoundException ex) { throw new ShellException("Cannot find required resource", ex); } catch (Exception ex) { @@ -235,7 +237,7 @@ new OutputStreamWriter(System.err)); aliasMgr = ShellUtils.getAliasManager().createAliasManager(); syntaxMgr = ShellUtils.getSyntaxManager().createSyntaxManager(); - System.setProperty(PROMPT_PROPERTY_NAME, DEFAULT_PROMPT); + propertyMap = initShellProperties(); } catch (NameNotFoundException ex) { throw new ShellException("Cannot find required resource", ex); } catch (Exception ex) { @@ -243,6 +245,16 @@ } } + private HashMap<String, String> initShellProperties() { + HashMap<String, String> map = new HashMap<String, String>(); + map.put(PROMPT_PROPERTY_NAME, DEFAULT_PROMPT); + map.put(DEBUG_PROPERTY_NAME, DEBUG_DEFAULT); + map.put(HISTORY_PROPERTY_NAME, HISTORY_DEFAULT); + map.put(INVOKER_PROPERTY_NAME, INITIAL_INVOKER); + map.put(INTERPRETER_PROPERTY_NAME, INITIAL_INTERPRETER); + return map; + } + private void setupStreams(Reader in, Writer out, Writer err) { this.cout = new CommandOutput(out); this.cerr = new CommandOutput(err); @@ -279,8 +291,11 @@ // Here, we are running in the CommandShell (main) Thread // so, we can register ourself as the current shell // (it will also be the current shell for all children Thread) - - configureShell(); + try { + configureShell(); + } catch (ShellException ex) { + throw new ShellFailureException("Shell setup failure", ex); + } // Run commands from the JNode command line first final String cmdLine = System.getProperty(CMDLINE_PROPERTY_NAME, ""); @@ -344,7 +359,6 @@ while (!isExited()) { String input = null; try { - refreshFromProperties(); clearEof(); outPW.print(prompt()); readingCommand = true; @@ -448,7 +462,7 @@ stackTrace(ex); } - public void configureShell() { + public void configureShell() throws ShellException { try { ShellUtils.getShellManager().registerShell(this); @@ -457,84 +471,98 @@ ShellUtils.registerCommandInvoker(ProcletCommandInvoker.FACTORY); ShellUtils.registerCommandInvoker(IsolateCommandInvoker.FACTORY); ShellUtils.registerCommandInterpreter(DefaultInterpreter.FACTORY); - ShellUtils - .registerCommandInterpreter(RedirectingInterpreter.FACTORY); - } catch (NameNotFoundException e1) { - e1.printStackTrace(); + ShellUtils.registerCommandInterpreter(RedirectingInterpreter.FACTORY); + } catch (NameNotFoundException ex) { + throw new ShellFailureException( + "Bailing out: fatal error during CommandShell configuration", ex); } - // Configure the shell based on System properties. - setupFromProperties(); + try { + setupFromProperties(); + } catch (ShellException ex) { + errPW.println("Problem shell configuration"); + errPW.println(ex.getMessage()); + stackTrace(ex); + errPW.println("Retrying shell configuration with fallback invoker/interpreter settings"); + propertyMap.put(INVOKER_PROPERTY_NAME, FALLBACK_INVOKER); + propertyMap.put(INTERPRETER_PROPERTY_NAME, FALLBACK_INTERPRETER); + try { + setupFromProperties(); + } catch (ShellException ex2) { + throw new ShellFailureException( + "Bailing out: fatal error during CommandShell configuration", ex2); + } + } // Now become interactive ownThread = Thread.currentThread(); } + + @Override + public String getProperty(String propName) { + return propertyMap.get(propName); + } - private void setupFromProperties() { - debugEnabled = Boolean.parseBoolean(System.getProperty( - DEBUG_PROPERTY_NAME, DEBUG_DEFAULT)); - historyEnabled = Boolean.parseBoolean(System.getProperty( - HISTORY_PROPERTY_NAME, HISTORY_DEFAULT)); - try { - setCommandInvoker(System.getProperty(INVOKER_PROPERTY_NAME, - INITIAL_INVOKER)); - } catch (Exception ex) { - errPW.println(ex.getMessage()); - stackTrace(ex); - // Use the fallback invoker - setCommandInvoker(FALLBACK_INVOKER); + @Override + public void removeProperty(String key) throws ShellException { + if (key.equals(INTERPRETER_PROPERTY_NAME) || key.equals(INVOKER_PROPERTY_NAME) || + key.equals(DEBUG_PROPERTY_NAME) || key.equals(PROMPT_PROPERTY_NAME) || + key.equals(HISTORY_PROPERTY_NAME)) { + throw new ShellException("Property '" + key + "' cannot be removed"); } - try { - setCommandInterpreter(System.getProperty(INTERPRETER_PROPERTY_NAME, - INITIAL_INTERPRETER)); - } catch (Exception ex) { - errPW.println(ex.getMessage()); - stackTrace(ex); - // Use the fallback interpreter - setCommandInterpreter(FALLBACK_INTERPRETER); - } - invoker.setDebugEnabled(debugEnabled); + propertyMap.remove(key); } - private void refreshFromProperties() { - debugEnabled = Boolean.parseBoolean(System.getProperty( - DEBUG_PROPERTY_NAME, DEBUG_DEFAULT)); - historyEnabled = Boolean.parseBoolean(System.getProperty( - HISTORY_PROPERTY_NAME, HISTORY_DEFAULT)); + @Override + public void setProperty(String propName, String value) throws ShellException { + String oldValue = propertyMap.get(propName); + propertyMap.put(propName, value); try { - setCommandInterpreter(System.getProperty(INTERPRETER_PROPERTY_NAME, "")); - } catch (Exception ex) { - errPW.println(ex.getMessage()); - stackTrace(ex); + setupFromProperties(); + } catch (ShellException ex) { + // Try to undo the change + propertyMap.put(propName, oldValue); + try { + setupFromProperties(); + } catch (ShellException ex2) { + // This may be our only chance to diagnose the original exception .... + errPW.println(ex.getMessage()); + stackTrace(ex); + throw new ShellFailureException("Failed to revert shell properties", ex2); + } + throw ex; } - try { - setCommandInvoker(System.getProperty(INVOKER_PROPERTY_NAME, "")); - } catch (Exception ex) { - errPW.println(ex.getMessage()); - stackTrace(ex); - } - invoker.setDebugEnabled(debugEnabled); } - public synchronized void setCommandInvoker(String name) throws IllegalArgumentException { - if (!name.equals(this.invokerName)) { - this.invoker = ShellUtils.createInvoker(name, this); - if (this.invokerName != null) { + @Override + public TreeMap<String, String> getProperties() { + return new TreeMap<String, String>(propertyMap); + } + + private void setupFromProperties() throws ShellException { + setCommandInvoker(propertyMap.get(INVOKER_PROPERTY_NAME)); + setCommandInterpreter(propertyMap.get(INTERPRETER_PROPERTY_NAME)); + debugEnabled = Boolean.parseBoolean(propertyMap.get(DEBUG_PROPERTY_NAME)); + historyEnabled = Boolean.parseBoolean(propertyMap.get(HISTORY_PROPERTY_NAME)); + } + + private synchronized void setCommandInvoker(String name) throws ShellException { + if (invoker == null || !name.equals(invoker.getName())) { + boolean alreadySet = invoker != null; + invoker = ShellUtils.createInvoker(name, this); + if (alreadySet) { outPW.println("Switched to " + name + " invoker"); } - this.invokerName = name; - System.setProperty(INVOKER_PROPERTY_NAME, name); } } - public synchronized void setCommandInterpreter(String name) throws IllegalArgumentException { - if (!name.equals(this.interpreterName)) { - this.interpreter = ShellUtils.createInterpreter(name); - if (this.interpreterName != null) { + private synchronized void setCommandInterpreter(String name) throws ShellException { + if (interpreter == null || !name.equals(interpreter.getName())) { + boolean alreadySet = interpreter != null; + interpreter = ShellUtils.createInterpreter(name); + if (alreadySet) { outPW.println("Switched to " + name + " interpreter"); } - this.interpreterName = name; - System.setProperty(INTERPRETER_PROPERTY_NAME, name); } } @@ -637,7 +665,8 @@ Thread.currentThread().getContextClassLoader(); return new CommandInfo(cl.loadClass(cmd), false); } catch (ClassNotFoundException ex2) { - throw new ShellException("Cannot find an alias or load a command class for '" + cmd + "'", ex); + throw new ShellException( + "Cannot find an alias or load a command class for '" + cmd + "'", ex); } } } @@ -687,8 +716,7 @@ * Gets the expanded prompt */ protected String prompt() { - String prompt = System - .getProperty(PROMPT_PROPERTY_NAME, DEFAULT_PROMPT); + String prompt = getProperty(PROMPT_PROPERTY_NAME); final StringBuffer result = new StringBuffer(); boolean commandMode = false; try { @@ -876,10 +904,6 @@ } } - public SimpleCommandInvoker getDefaultCommandInvoker() { - return ShellUtils.createInvoker("default", this); - } - public int runCommandFile(File file, String alias, String[] args) throws ShellException { // FIXME extend to allow arguments to be passed to the script. boolean enabled = setHistoryEnabled(false); Modified: trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -53,7 +53,6 @@ private final PrintWriter err; private final CommandShell shell; - private boolean debugEnabled; private static final Class<?>[] MAIN_ARG_TYPES = new Class[] {String[].class}; @@ -165,12 +164,6 @@ @Override public boolean isDebugEnabled() { - return this.debugEnabled; + return shell.isDebugEnabled(); } - - @Override - public void setDebugEnabled(boolean debugEnabled) { - this.debugEnabled = debugEnabled; - } - } Modified: trunk/shell/src/shell/org/jnode/shell/Shell.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/Shell.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/Shell.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -22,6 +22,7 @@ import java.io.File; import java.io.Writer; +import java.util.TreeMap; import org.jnode.driver.console.Console; import org.jnode.driver.console.InputCompleter; @@ -99,5 +100,47 @@ * @return the escaped word. */ public String escapeWord(String word); + + /** + * Set a shell property. Some properties have special meaning to a Shell + * and may cause its behavior to change. + * + * @param propName the name of the property + * @param value the property value + * @throws ShellException This may be thrown if the name / value pair is + * not acceptable. + */ + public void setProperty(String propName, String value) throws ShellException; + + /** + * Get the current value of a shell property. + * + * @param propName the property name. + * @return the property value or {@code null} + */ + public String getProperty(String propName); + + /** + * Remove a shell property. Special properties typically may not be removed, + * + * @param propName the name of the property + * @throws ShellException This may be thrown if the property cannot be removed. + */ + public void removeProperty(String key) throws ShellException; + + /** + * Get the shell properties for this shell instance. The result is a copy + * of the shell properties object; i.e. changes to the result Map object + * have no effect on the shell. + * <p> + * Note that shell properties are + * not the same as UNIX-style shell variables. An interpreter that supports + * shell variables may mirror some of them in the properties, but it is not + * required to. The recommended place for publishing (exported) shell variables + * is the "environment variables"; e.g. in {@link System#getenv()}. + * + * @return a copy of the shell properties. + */ + public TreeMap<String, String> getProperties(); } Modified: trunk/shell/src/shell/org/jnode/shell/ShellManager.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/ShellManager.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/ShellManager.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -57,9 +57,9 @@ public void unregisterInterpreterFactory(CommandInterpreter.Factory factory); public SimpleCommandInvoker createInvoker(String name, CommandShell shell) - throws IllegalArgumentException; + throws ShellException; public CommandInterpreter createInterpreter(String name) - throws IllegalArgumentException; + throws ShellException; } Modified: trunk/shell/src/shell/org/jnode/shell/ShellUtils.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/ShellUtils.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/ShellUtils.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -103,7 +103,7 @@ } public static SimpleCommandInvoker createInvoker(String name, CommandShell shell) - throws IllegalArgumentException { + throws ShellException { try { return getShellManager().createInvoker(name, shell); } catch (NameNotFoundException ex) { @@ -112,7 +112,7 @@ } public static CommandInterpreter createInterpreter(String name) - throws IllegalArgumentException, ShellFailureException { + throws ShellException { try { return getShellManager().createInterpreter(name); } catch (NameNotFoundException ex) { Modified: trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -75,6 +75,4 @@ String getName(); boolean isDebugEnabled(); - - void setDebugEnabled(boolean enabled); } Modified: trunk/shell/src/shell/org/jnode/shell/command/EnvCommand.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/command/EnvCommand.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/command/EnvCommand.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -30,6 +30,7 @@ import java.util.TreeMap; import org.jnode.shell.AbstractCommand; +import org.jnode.shell.ShellUtils; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FlagArgument; @@ -39,13 +40,17 @@ public class EnvCommand extends AbstractCommand { // FIXME ... this class and the corresponding alias are incorrectly named - private final FlagArgument envArg = new FlagArgument( - "env", Argument.OPTIONAL + Argument.SINGLE, - "If set, print the System 'env' variables rather that the System properties."); + private final FlagArgument envArg = new FlagArgument( + "env", Argument.OPTIONAL + Argument.SINGLE, + "If set, print the System 'env' variables rather that the System properties."); + private final FlagArgument shellArg = new FlagArgument( + "shell", Argument.OPTIONAL + Argument.SINGLE, + "If set, print the current shell properties rather that the System properties."); + public EnvCommand() { super("Print the System properties"); - registerArguments(envArg); + registerArguments(envArg, shellArg); } public static void main(String[] args) throws Exception { @@ -56,18 +61,20 @@ * Execute this command */ public void execute() throws Exception { - final TreeMap<Object, Object> sortedPs; - if (envArg.isSet()) { - Map<String, String> ps = - (Map<String, String>) AccessController.doPrivileged(new GetEnvAction()); - sortedPs = new TreeMap<Object, Object>(ps); + final TreeMap<?, ?> sortedPs; + if (envArg.isSet()) { + Map<String, String> ps = + (Map<String, String>) AccessController.doPrivileged(new GetEnvAction()); + sortedPs = new TreeMap<Object, Object>(ps); + } else if (shellArg.isSet()) { + sortedPs = ShellUtils.getCurrentShell().getProperties(); } else { Properties ps = AccessController.doPrivileged(new GetPropertiesAction()); sortedPs = new TreeMap<Object, Object>(ps); } final PrintWriter out = getOutput().getPrintWriter(); - for (Map.Entry<Object, Object> entry : sortedPs.entrySet()) { + for (Map.Entry<?, ?> entry : sortedPs.entrySet()) { final String key = entry.getKey().toString(); final String value = entry.getValue().toString(); out.println(key + '=' + value); Modified: trunk/shell/src/shell/org/jnode/shell/command/SetCommand.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/command/SetCommand.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/command/SetCommand.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -23,28 +23,41 @@ import java.io.PrintWriter; import org.jnode.shell.AbstractCommand; +import org.jnode.shell.ShellUtils; import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; import org.jnode.shell.syntax.PropertyNameArgument; +import org.jnode.shell.syntax.ShellPropertyNameArgument; import org.jnode.shell.syntax.StringArgument; /** - * Shell command to set property values. + * Shell command to set system or shell property values. * * @author Ewout Prangsma (ep...@us...) * @author Martin Husted Hartvig (ha...@jn...) * @author Levente S\u00e1ntha + * @author cr...@jn... */ public class SetCommand extends AbstractCommand { - private PropertyNameArgument keyArg = - new PropertyNameArgument("key", Argument.MANDATORY, "The name of the property to be set (or cleared)"); - private StringArgument valueArg = - new StringArgument("value", Argument.OPTIONAL, "The new property value"); + private PropertyNameArgument keyArg = new PropertyNameArgument( + "key", Argument.OPTIONAL, "The name of the property to be set (or cleared)"); + private ShellPropertyNameArgument skeyArg = new ShellPropertyNameArgument( + "skey", Argument.OPTIONAL, "The name of the shell property to be set (or cleared)"); + + private StringArgument valueArg = new StringArgument( + "value", Argument.OPTIONAL, "The new property value"); + + private final FlagArgument shellArg = new FlagArgument( + "shell", Argument.OPTIONAL + Argument.SINGLE, + "If set, print the current shell properties rather that the System properties."); + + public SetCommand() { super("Set or clear the value of a property"); - registerArguments(keyArg, valueArg); + registerArguments(keyArg, skeyArg, valueArg, shellArg); } public static void main(String[] args) throws Exception { @@ -53,14 +66,26 @@ public void execute() throws Exception { PrintWriter out = getOutput().getPrintWriter(); - String key = keyArg.getValue(); - if (!valueArg.isSet()) { - out.println("Removing " + key); - System.getProperties().remove(key); + if (shellArg.isSet()) { + String key = skeyArg.getValue(); + if (!valueArg.isSet()) { + out.println("Removing " + key); + ShellUtils.getCurrentShell().removeProperty(key); + } else { + String value = valueArg.getValue(); + out.println("Setting " + key + " to " + value); + ShellUtils.getCurrentShell().setProperty(key, value); + } } else { - String value = valueArg.getValue(); - out.println("Setting " + key + " to " + value); - System.getProperties().setProperty(key, value); + String key = keyArg.getValue(); + if (!valueArg.isSet()) { + out.println("Removing " + key); + System.getProperties().remove(key); + } else { + String value = valueArg.getValue(); + out.println("Setting " + key + " to " + value); + System.getProperties().setProperty(key, value); + } } } } Modified: trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -23,6 +23,7 @@ import java.util.HashMap; import org.jnode.shell.CommandInterpreter; +import org.jnode.shell.ShellException; import org.jnode.shell.SimpleCommandInvoker; import org.jnode.shell.CommandShell; import org.jnode.shell.Shell; @@ -62,18 +63,19 @@ this.currentShell.set(currentShell); } - public CommandInterpreter createInterpreter(String name) throws IllegalArgumentException { + public CommandInterpreter createInterpreter(String name) throws ShellException { CommandInterpreter.Factory factory = interpreterFactories.get(name); if (factory == null) { - throw new IllegalArgumentException("Unknown interpreter '" + name + "'"); + throw new ShellException("Unknown interpreter '" + name + "'"); } return factory.create(); } - public SimpleCommandInvoker createInvoker(String name, CommandShell shell) throws IllegalArgumentException { + public SimpleCommandInvoker createInvoker(String name, CommandShell shell) + throws ShellException { SimpleCommandInvoker.Factory factory = invokerFactories.get(name); if (factory == null) { - throw new IllegalArgumentException("Unknown invoker '" + name + "'"); + throw new ShellException("Unknown invoker '" + name + "'"); } return factory.create(shell); } Modified: trunk/shell/src/shell/org/jnode/shell/syntax/PropertyNameArgument.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/syntax/PropertyNameArgument.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/shell/org/jnode/shell/syntax/PropertyNameArgument.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -20,6 +20,11 @@ package org.jnode.shell.syntax; +import gnu.java.security.action.GetPropertiesAction; + +import java.security.AccessController; +import java.util.Properties; + import org.jnode.driver.console.CompletionInfo; import org.jnode.shell.CommandLine.Token; @@ -51,7 +56,8 @@ @Override public void doComplete(CompletionInfo completion, String partial, int flags) { - for (Object key : System.getProperties().keySet()) { + Properties ps = AccessController.doPrivileged(new GetPropertiesAction()); + for (Object key : ps.keySet()) { String name = (String) key; if (name.startsWith(partial)) { completion.addCompletion(name); Added: trunk/shell/src/shell/org/jnode/shell/syntax/ShellPropertyNameArgument.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/syntax/ShellPropertyNameArgument.java (rev 0) +++ trunk/shell/src/shell/org/jnode/shell/syntax/ShellPropertyNameArgument.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -0,0 +1,74 @@ +/* + * $Id$ + * + * Copyright (C) 2003-2009 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.shell.syntax; + +import javax.naming.NameNotFoundException; + +import org.jnode.driver.console.CompletionInfo; +import org.jnode.shell.ShellUtils; +import org.jnode.shell.CommandLine.Token; + + +/** + * This argument class accepts property names, with completion against the + * names in the current shell's property map. + * + * @author cr...@jn... + */ +public class ShellPropertyNameArgument extends Argument<String> { + + public ShellPropertyNameArgument(String label, int flags, String description) { + super(label, flags, new String[0], description); + } + + public ShellPropertyNameArgument(String label, int flags) { + this(label, flags, null); + } + + public ShellPropertyNameArgument(String label) { + this(label, 0); + } + + @Override + protected String doAccept(Token token, int flags) throws CommandSyntaxException { + return token.text; + } + + @Override + public void doComplete(CompletionInfo completion, String partial, int flags) { + try { + for (Object key : ShellUtils.getCurrentShell().getProperties().keySet()) { + String name = (String) key; + if (name.startsWith(partial)) { + completion.addCompletion(name); + } + } + } catch (NameNotFoundException ex) { + // uh oh ... no completion possible + } + } + + @Override + protected String argumentKind() { + return "property"; + } + +} Modified: trunk/shell/src/test/org/jnode/test/shell/CompletionTest.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/CompletionTest.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/test/org/jnode/test/shell/CompletionTest.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -133,7 +133,7 @@ public void testDefaultInterpreterNewSyntax() throws Exception { TestCommandShell cs = new TestCommandShell(); - cs.setCommandInterpreter("default"); + cs.setProperty(CommandShell.INTERPRETER_PROPERTY_NAME, "default"); final String[] propertyCompletions = getExpectedPropertyNameCompletions(); Modified: trunk/shell/src/test/org/jnode/test/shell/DefaultSyntaxCompletionTest.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/DefaultSyntaxCompletionTest.java 2009-04-18 18:19:06 UTC (rev 5309) +++ trunk/shell/src/test/org/jnode/test/shell/DefaultSyntaxCompletionTest.java 2009-04-19 14:06:34 UTC (rev 5310) @@ -115,7 +115,7 @@ public void testDefaultSyntax() throws Exception { TestCommandShell cs = new TestCommandShell(); - cs.setCommandInterpreter("default"); + cs.setProperty(CommandShell.INTERPRETER_PROPERTY_NAME, "default"); final String[] propertyCompletions = getExpectedPropertyNameCompletions(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |