Nice. Simpler than what I was doing. I was going down a slightly different route. I was going down the route of creating a whole new sub DefaultShell. I think both routes can co-exist. Let me merge in your changes and I should have my stuff in shortly.
Regards, Hiram On Dec 6, 2007 7:42 PM, <[EMAIL PROTECTED]> wrote: > Author: gnodet > Date: Thu Dec 6 16:42:27 2007 > New Revision: 601933 > > URL: http://svn.apache.org/viewvc?rev=601933&view=rev > Log: > Implements subshells and use a dynamic layout > > Added: > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/ExitCommand.java > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/HelpCommand.java > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/test/java/org/ > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/test/java/org/apache/ > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/test/java/org/apache/geronimo/ > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/test/java/org/apache/geronimo/gshell/ > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/test/java/org/apache/geronimo/gshell/spring/ > Removed: > > servicemix/branches/servicemix-4.0/runtime/minimum/src/main/release/etc/layout.xml > Modified: > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/SpringCommandRegistry.java > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/support/OsgiCommandSupport.java > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml > > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml > > Added: > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/ExitCommand.java > URL: > http://svn.apache.org/viewvc/servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/ExitCommand.java?rev=601933&view=auto > ============================================================================== > --- > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/ExitCommand.java > (added) > +++ > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/ExitCommand.java > Thu Dec 6 16:42:27 2007 > @@ -0,0 +1,44 @@ > +package org.apache.geronimo.gshell.spring; > + > +import org.apache.geronimo.gshell.ExitNotification; > +import org.apache.geronimo.gshell.clp.Argument; > +import org.apache.geronimo.gshell.command.Variables; > +import org.apache.geronimo.gshell.command.annotation.CommandComponent; > +import org.apache.geronimo.gshell.layout.LayoutManager; > +import org.apache.geronimo.gshell.support.OsgiCommandSupport; > + > +/** > + * Exit the current shell. > + * > + * @version $Rev: 593392 $ $Date: 2007-11-09 03:14:15 +0100 (Fri, 09 Nov > 2007) $ > + */ > [EMAIL PROTECTED](id="gshell-builtins:exit", description="Exit the > (sub)shell") > +public class ExitCommand > + extends OsgiCommandSupport > +{ > + @Argument(description="System exit code") > + private int exitCode = 0; > + > + protected Object doExecute() throws Exception { > + if (context.getVariables().get(LayoutManager.CURRENT_NODE) != null) > + { > + log.info("Exiting subshell"); > + Variables v = context.getVariables(); > + while (v != null && v.get(LayoutManager.CURRENT_NODE) != null) { > + v.unset(LayoutManager.CURRENT_NODE); > + v = v.parent(); > + } > + return SUCCESS; > + } > + else > + { > + log.info("Exiting w/code: {}", exitCode); > + > + // > + // DO NOT Call System.exit() !!! > + // > + > + throw new ExitNotification(exitCode); > + } > + } > +} > > Added: > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/HelpCommand.java > URL: > http://svn.apache.org/viewvc/servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/HelpCommand.java?rev=601933&view=auto > ============================================================================== > --- > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/HelpCommand.java > (added) > +++ > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/HelpCommand.java > Thu Dec 6 16:42:27 2007 > @@ -0,0 +1,175 @@ > +package org.apache.geronimo.gshell.spring; > + > +import java.util.List; > + > +import org.apache.geronimo.gshell.ansi.Code; > +import org.apache.geronimo.gshell.ansi.Renderer; > +import org.apache.geronimo.gshell.branding.Branding; > +import org.apache.geronimo.gshell.clp.Argument; > +import org.apache.geronimo.gshell.command.Command; > +import org.apache.geronimo.gshell.command.annotation.CommandComponent; > +import org.apache.geronimo.gshell.command.annotation.Requirement; > +import org.apache.geronimo.gshell.layout.LayoutManager; > +import org.apache.geronimo.gshell.layout.model.AliasNode; > +import org.apache.geronimo.gshell.layout.model.CommandNode; > +import org.apache.geronimo.gshell.layout.model.GroupNode; > +import org.apache.geronimo.gshell.layout.model.Node; > +import org.apache.geronimo.gshell.registry.CommandRegistry; > +import org.apache.geronimo.gshell.registry.NotRegisteredException; > +import org.apache.geronimo.gshell.support.OsgiCommandSupport; > +import org.codehaus.plexus.util.StringUtils; > + > +/** > + * Display help > + * > + * @version $Rev: 596570 $ $Date: 2007-11-20 09:47:27 +0100 (Tue, 20 Nov > 2007) $ > + */ > [EMAIL PROTECTED](id="gshell-builtins:help", description="Show command help") > +public class HelpCommand > + extends OsgiCommandSupport > +{ > + @Requirement > + private CommandRegistry commandRegistry; > + > + @Requirement > + private LayoutManager layoutManager; > + > + @Requirement > + private Branding branding; > + > + @Argument(required = false, multiValued = true) > + private List<String> path; > + > + private Renderer renderer = new Renderer(); > + > + public HelpCommand(CommandRegistry commandRegistry, LayoutManager > layoutManager, Branding branding) { > + this.commandRegistry = commandRegistry; > + this.layoutManager = layoutManager; > + this.branding = branding; > + } > + > + protected OsgiCommandSupport createCommand() throws Exception { > + return new HelpCommand(commandRegistry, layoutManager, branding); > + } > + > + protected Object doExecute() throws Exception { > + io.out.println(); > + > + GroupNode gn = layoutManager.getLayout(); > + if (context.getVariables().get(LayoutManager.CURRENT_NODE) != null) { > + gn = (GroupNode) > context.getVariables().get(LayoutManager.CURRENT_NODE); > + } > + CommandNode cn = null; > + if (path != null) { > + for (String p : path) { > + if (cn != null) { > + io.err.println("Unexpected path '" + p + "'"); > + return FAILURE; > + } > + Node n = gn.find(p); > + if (n == null) { > + io.err.println("Path '" + p + "' not found!"); > + return FAILURE; > + } else if (n instanceof GroupNode) { > + gn = (GroupNode) n; > + } else if (n instanceof CommandNode) { > + cn = (CommandNode) n; > + } else { > + throw new IllegalStateException("Unsupported node type " > + n.getParent().getName()); > + } > + } > + } > + > + if (cn == null) { > + // TODO: take into account the sub shell > + if (path == null || path.isEmpty()) { > + io.out.print(branding.getAbout()); > + io.out.println(); > + io.out.println("Available commands:"); > + } else { > + io.out.println("Available commands in " + path); > + } > + displayGroupCommands(gn); > + } > + else { > + displayCommandHelp(cn.getId()); > + } > + > + return SUCCESS; > + } > + > + private void displayGroupCommands(final GroupNode group) throws > Exception { > + int maxNameLen = 20; // FIXME: Figure this out dynamically > + > + // First display command/aliases nodes > + for (Node child : group.nodes()) { > + if (child instanceof CommandNode) { > + try { > + CommandNode node = (CommandNode) child; > + String name = StringUtils.rightPad(node.getName(), > maxNameLen); > + > + Command command = commandRegistry.lookup(node.getId()); > + String desc = command.getDescription(); > + > + io.out.print(" "); > + io.out.print(renderer.render(Renderer.encode(name, > Code.BOLD))); > + > + if (desc != null) { > + io.out.print(" "); > + io.out.println(desc); > + } > + else { > + io.out.println(); > + } > + } catch (NotRegisteredException e) { > + // Ignore those exceptions (command will not be > displayed) > + } > + } > + else if (child instanceof AliasNode) { > + AliasNode node = (AliasNode) child; > + String name = StringUtils.rightPad(node.getName(), > maxNameLen); > + > + io.out.print(" "); > + io.out.print(renderer.render(Renderer.encode(name, > Code.BOLD))); > + io.out.print(" "); > + > + io.out.print("Alias to: "); > + > io.out.println(renderer.render(Renderer.encode(node.getCommand(), > Code.BOLD))); > + } > + } > + > + io.out.println(); > + > + // Then groups > + for (Node child : group.nodes()) { > + if (child instanceof GroupNode) { > + GroupNode node = (GroupNode) child; > + > + io.out.print(" "); > + > io.out.println(renderer.render(Renderer.encode(node.getPath(), Code.BOLD))); > + > + io.out.println(); > + //displayGroupCommands(node); > + //io.out.println(); > + } > + } > + } > + > + private void displayCommandHelp(final String path) throws Exception { > + assert path != null; > + > + Command cmd = commandRegistry.lookup(path); > + > + if (cmd == null) { > + io.out.println("Command " + Renderer.encode(path, Code.BOLD) + " > not found."); > + io.out.println("Try " + Renderer.encode("help", Code.BOLD) + " > for a list of available commands."); > + } > + else { > + io.out.println("Command " + Renderer.encode(path, Code.BOLD)); > + io.out.println(" " + cmd.getDescription()); > + } > + > + io.out.println(); > + } > +} > + > > Modified: > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/SpringCommandRegistry.java > URL: > http://svn.apache.org/viewvc/servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/SpringCommandRegistry.java?rev=601933&r1=601932&r2=601933&view=diff > ============================================================================== > --- > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/SpringCommandRegistry.java > (original) > +++ > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/spring/SpringCommandRegistry.java > Thu Dec 6 16:42:27 2007 > @@ -19,9 +19,18 @@ > import java.util.Map; > > import org.apache.geronimo.gshell.command.Command; > +import org.apache.geronimo.gshell.command.CommandContext; > +import org.apache.geronimo.gshell.common.Arguments; > +import org.apache.geronimo.gshell.layout.LayoutManager; > +import org.apache.geronimo.gshell.layout.NotFoundException; > +import org.apache.geronimo.gshell.layout.model.CommandNode; > +import org.apache.geronimo.gshell.layout.model.GroupNode; > +import org.apache.geronimo.gshell.layout.model.Layout; > +import org.apache.geronimo.gshell.layout.model.Node; > import org.apache.geronimo.gshell.registry.DefaultCommandRegistry; > -import org.apache.geronimo.gshell.registry.NotRegisteredException; > import org.apache.geronimo.gshell.registry.DuplicateRegistrationException; > +import org.apache.geronimo.gshell.registry.NotRegisteredException; > +import org.apache.geronimo.gshell.shell.Environment; > > /** > * Created by IntelliJ IDEA. > @@ -30,13 +39,124 @@ > * Time: 3:47:24 PM > * To change this template use File | Settings | File Templates. > */ > -public class SpringCommandRegistry extends DefaultCommandRegistry { > +public class SpringCommandRegistry extends DefaultCommandRegistry implements > LayoutManager { > + > + public static final String SEPARATOR = ":"; > + > + private Environment env; > + > + private Map groupAliases; > + private Layout layout = new Layout(); > + > + public SpringCommandRegistry(Environment env) { > + this.env = env; > + } > + > + public Map getGroupAliases() { > + return groupAliases; > + } > + > + public void setGroupAliases(Map groupAliases) { > + this.groupAliases = groupAliases; > + } > > public void register(final Command command, Map<String, ?> properties) > throws DuplicateRegistrationException { > + String id = command.getId(); > + String[] s = id.split(SEPARATOR); > + GroupNode gn = layout; > + for (int i = 0; i < s.length - 1; i++) { > + if (groupAliases != null && groupAliases.containsKey(s[i])) { > + s[i] = (String) groupAliases.get(s[i]); > + if (s[i].length() == 0) { > + continue; > + } > + } > + Node n = gn.find(s[i]); > + if (n == null) { > + GroupNode g = new GroupNode(s[i]); > + gn.add(g); > + register(new GroupCommand(s[i], g)); > + gn = g; > + } else if (n instanceof GroupNode) { > + gn = (GroupNode) n; > + } else { > + throw new IllegalStateException("A command conflicts has > been detected when registering " + id); > + } > + } > + CommandNode cn = new CommandNode(s[s.length - 1], id); > + gn.add(cn); > register(command); > } > > public void unregister(final Command command, Map<String, ?> properties) > throws NotRegisteredException { > unregister(command); > + } > + > + public Layout getLayout() { > + return layout; > + } > + > + public Node findNode(String s) throws NotFoundException { > + Node start = (Node) env.getVariables().get(CURRENT_NODE); > + if (start != null) { > + Node n = findNode(start, s); > + if (n != null) { > + return n; > + } > + } > + return findNode(layout, s); > + } > + > + public Node findNode(Node node, String s) throws NotFoundException { > + if (node instanceof GroupNode) { > + Node n = ((GroupNode) node).find(s); > + if (n instanceof GroupNode) { > + return new CommandNode(n.getName(), n.getName()); > + } > + return n; > + } else { > + throw new NotFoundException(s); > + } > + } > + > + public class GroupCommand implements Command { > + > + private String id; > + private GroupNode gn; > + > + public GroupCommand(String id, GroupNode gn) { > + this.id = id; > + this.gn = gn; > + } > + > + @Deprecated > + public String getId() { > + return id; > + } > + > + @Deprecated > + public String getDescription() { > + return "Group command"; > + } > + > + public Object execute(CommandContext commandContext, Object... > objects) throws Exception { > + if (objects.length > 0) { > + String cmdId = String.valueOf(objects[0]); > + Node n = gn.find(cmdId); > + CommandContext ctx = commandContext; > + Command cmd; > + if (n instanceof CommandNode) { > + cmd = lookup(((CommandNode) n).getId()); > + } else if (n instanceof GroupNode) { > + cmd = new GroupCommand(cmdId, (GroupNode) n); > + } else { > + throw new IllegalStateException("Unrecognized node type: > " + n.getClass().getName()); > + } > + return cmd.execute(ctx, Arguments.shift(objects)); > + } else { > + env.getVariables().set(CURRENT_NODE, gn); > + return SUCCESS; > + } > + } > } > } > > Modified: > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/support/OsgiCommandSupport.java > URL: > http://svn.apache.org/viewvc/servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/support/OsgiCommandSupport.java?rev=601933&r1=601932&r2=601933&view=diff > ============================================================================== > --- > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/support/OsgiCommandSupport.java > (original) > +++ > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/support/OsgiCommandSupport.java > Thu Dec 6 16:42:27 2007 > @@ -49,7 +49,7 @@ > > protected Variables variables; > > - @Option(name="-h", aliases={"--help"}, description="Display this help > message") > + @Option(name="-h", aliases={"--help"}, description="Display this help > message", requireOverride = true) > private boolean displayHelp; > > public String getId() { > > Modified: > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml > URL: > http://svn.apache.org/viewvc/servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml?rev=601933&r1=601932&r2=601933&view=diff > ============================================================================== > --- > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml > (original) > +++ > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml > Thu Dec 6 16:42:27 2007 > @@ -30,11 +30,11 @@ > > <bean id="echo" > class="org.apache.geronimo.gshell.commands.builtins.EchoCommand" /> > > - <bean id="exit" > class="org.apache.geronimo.gshell.commands.builtins.ExitCommand" /> > + <bean id="exit" class="org.apache.geronimo.gshell.spring.ExitCommand" /> > > - <bean id="help" > class="org.apache.geronimo.gshell.commands.builtins.HelpCommand"> > + <bean id="help" class="org.apache.geronimo.gshell.spring.HelpCommand"> > + <constructor-arg ref="commandRegistry" /> > <constructor-arg ref="commandRegistry" /> > - <constructor-arg ref="layoutManager" /> > <constructor-arg ref="branding" /> > </bean> > > > Modified: > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml > URL: > http://svn.apache.org/viewvc/servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml?rev=601933&r1=601932&r2=601933&view=diff > ============================================================================== > --- > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml > (original) > +++ > servicemix/branches/servicemix-4.0/runtime/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml > Thu Dec 6 16:42:27 2007 > @@ -46,7 +46,7 @@ > <property name="commandLineBuilder" ref="commandLineBuilder" /> > <property name="commandRegistry" ref="commandRegistry" /> > <property name="env" ref="environment" /> > - <property name="layoutManager" ref="layoutManager" /> > + <property name="layoutManager" ref="commandRegistry" /> > </bean> > > <bean id="interactiveShell" > class="org.apache.geronimo.gshell.DefaultShell"> > @@ -62,16 +62,14 @@ > <constructor-arg ref="branding" /> > </bean> > > - <bean id="layoutManager" > class="org.apache.geronimo.gshell.layout.DefaultLayoutManager" > init-method="initialize"> > - <constructor-arg ref="layoutLoader" index="0" > type="org.apache.geronimo.gshell.layout.loader.LayoutLoader" /> > - <constructor-arg ref="environment" index="1" /> > - </bean> > - > - <bean id="layoutLoader" > class="org.apache.geronimo.gshell.layout.loader.XMLLayoutLoader" > init-method="initialize"> > - <constructor-arg ref="shellInfo" /> > + <bean id="commandRegistry" > class="org.apache.geronimo.gshell.spring.SpringCommandRegistry"> > + <constructor-arg ref="environment" /> > + <property name="groupAliases"> > + <map> > + <entry key="gshell-builtins" value="" /> > + </map> > + </property> > </bean> > - > - <bean id="commandRegistry" > class="org.apache.geronimo.gshell.spring.SpringCommandRegistry" /> > > <bean id="commandLineBuilder" > class="org.apache.geronimo.gshell.spring.SpringCommandLineBuilder"> > <property name="environment" ref="environment" /> > > > -- Regards, Hiram Blog: http://hiramchirino.com Open Source SOA http://open.iona.com
