You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jd...@apache.org on 2008/06/11 21:17:01 UTC

svn commit: r666796 [1/2] - in /geronimo/gshell/trunk: ./ gshell-assembly/src/main/underlay/etc/ gshell-core/ gshell-plugin/src/main/java/org/apache/geronimo/gshell/plugin/descriptor/ gshell-rapture/ gshell-rapture/src/ gshell-rapture/src/main/java/org...

Author: jdillon
Date: Wed Jun 11 12:17:00 2008
New Revision: 666796

URL: http://svn.apache.org/viewvc?rev=666796&view=rev
Log:
Renamed gshell-core to gshell-rapture, which is a module which just contains the glue to use GShell with Plexus

Added:
    geronimo/gshell/trunk/gshell-rapture/
      - copied from r666783, geronimo/gshell/trunk/gshell-core/
    geronimo/gshell/trunk/gshell-rapture/pom.xml
      - copied, changed from r666794, geronimo/gshell/trunk/gshell-core/pom.xml
    geronimo/gshell/trunk/gshell-rapture/src/
      - copied from r666794, geronimo/gshell/trunk/gshell-core/src/
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/FileHistory.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java   (with props)
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/VariableInterpolator.java   (with props)
Removed:
    geronimo/gshell/trunk/gshell-core/
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/CommandExecutionFailied.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/CommandLine.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/CommandLineBuilder.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultCommandContainer.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultCommandContainerLocator.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultCommandExecutor.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultCommandLineBuilder.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultHistory.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultLayoutManager.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultShell.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/DefaultShellInfo.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/ExecutingVisitor.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/FileHistory.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/LoggingVisitor.java
    geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/VariableInterpolator.java
Modified:
    geronimo/gshell/trunk/gshell-assembly/src/main/underlay/etc/application.xml
    geronimo/gshell/trunk/gshell-plugin/src/main/java/org/apache/geronimo/gshell/plugin/descriptor/CommandContainerDescriptor.java
    geronimo/gshell/trunk/pom.xml

Modified: geronimo/gshell/trunk/gshell-assembly/src/main/underlay/etc/application.xml
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-assembly/src/main/underlay/etc/application.xml?rev=666796&r1=666795&r2=666796&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-assembly/src/main/underlay/etc/application.xml (original)
+++ geronimo/gshell/trunk/gshell-assembly/src/main/underlay/etc/application.xml Wed Jun 11 12:17:00 2008
@@ -50,7 +50,7 @@
             <version>1.0-alpha-2-SNAPSHOT</version>
 
             <dependency>
-                <artifactId>gshell-core</artifactId>
+                <artifactId>gshell-rapture</artifactId>
             </dependency>
         </dependencyGroup>
 

Modified: geronimo/gshell/trunk/gshell-plugin/src/main/java/org/apache/geronimo/gshell/plugin/descriptor/CommandContainerDescriptor.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-plugin/src/main/java/org/apache/geronimo/gshell/plugin/descriptor/CommandContainerDescriptor.java?rev=666796&r1=666795&r2=666796&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-plugin/src/main/java/org/apache/geronimo/gshell/plugin/descriptor/CommandContainerDescriptor.java (original)
+++ geronimo/gshell/trunk/gshell-plugin/src/main/java/org/apache/geronimo/gshell/plugin/descriptor/CommandContainerDescriptor.java Wed Jun 11 12:17:00 2008
@@ -42,7 +42,7 @@
 
         setRole(CommandContainer.class);
         setRoleHint(model.getId());
-        setImplementation("org.apache.geronimo.gshell.container.DefaultCommandContainer"); // Avoid dependency on gshell-core
+        setImplementation("org.apache.geronimo.gshell.rapture.DefaultCommandContainer");
         setVersion(model.getVersion());
         setIsolatedRealm(false);
         setInstantiationStrategy("singleton");

Copied: geronimo/gshell/trunk/gshell-rapture/pom.xml (from r666794, geronimo/gshell/trunk/gshell-core/pom.xml)
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/pom.xml?p2=geronimo/gshell/trunk/gshell-rapture/pom.xml&p1=geronimo/gshell/trunk/gshell-core/pom.xml&r1=666794&r2=666796&rev=666796&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-core/pom.xml (original)
+++ geronimo/gshell/trunk/gshell-rapture/pom.xml Wed Jun 11 12:17:00 2008
@@ -30,11 +30,11 @@
         <version>1.0-alpha-2-SNAPSHOT</version>
     </parent>
 
-    <artifactId>gshell-core</artifactId>
-    <name>GShell Core</name>
+    <artifactId>gshell-rapture</artifactId>
+    <name>GShell Rapture</name>
 
     <description>
-        Provides the core of what is GShell ;-)
+        Provides the glue for using GShell with Plexus.
     </description>
 
     <dependencies>

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+/**
+ * Thrown when a command execution fails.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CommandExecutionFailied
+    extends Exception
+{
+    public CommandExecutionFailied(final Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandExecutionFailied.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+/**
+ * A abstraction of an executable command-line.
+ *
+ * <p>
+ * Could be a simple command or a complex command pipe-line.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface CommandLine
+{
+    /**
+     * Execute the command-line.
+     *
+     * @return  The final result of the command-line.
+     *
+     * @throws Exception    Failed to execute command-line.
+     */
+    Object execute() throws Exception;
+}

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLine.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.parser.ParseException;
+
+/**
+ * Builds {@link CommandLine} instances ready for executing.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface CommandLineBuilder
+{
+    CommandLine create(final String commandLine) throws ParseException;
+}

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/CommandLineBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.clp.CommandLineProcessor;
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.geronimo.gshell.clp.Printer;
+import org.apache.geronimo.gshell.clp.ProcessingException;
+import org.apache.geronimo.gshell.command.CommandContainer;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.command.CommandInfo;
+import org.apache.geronimo.gshell.command.Executable;
+import org.apache.geronimo.gshell.common.Arguments;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.plexus.GShellPlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Configuration;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ???
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=CommandContainer.class)
+public class DefaultCommandContainer
+    implements CommandContainer, Contextualizable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private GShellPlexusContainer container;
+
+    @Configuration("invalid") // Just to mark what this is used for, since we have to configure a default value
+    private String commandId;
+
+    // Contextualizable
+    
+    public void contextualize(final Context context) throws ContextException {
+        assert context != null;
+
+        container = (GShellPlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
+        assert container != null;
+        
+        log.debug("Container: {}", container);
+    }
+
+    // CommandContainer
+
+    public Executable getExecutable() {
+        assert container != null;
+
+        try {
+            return container.lookupComponent(Executable.class, commandId);
+        }
+        catch (ComponentLookupException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public Object execute(final CommandContext context, final Object... args) throws Exception {
+        assert context != null;
+        assert args != null;
+
+        log.trace("Executing; context={}, args={}", context, args);
+
+        Executable executable = getExecutable();
+
+        // TODO: Handle logging muck
+        
+        // TODO: Bind context, io and variables
+
+        // Process command line options/arguments, return if we have been asked to display --help
+        if (processArguments(context, executable, args)) {
+            return Executable.Result.SUCCESS;
+        }
+
+        Object result = executable.execute(context, args);
+
+        log.trace("Result: {}", result);
+
+        return result;
+    }
+
+    private boolean processArguments(final CommandContext context, final Executable executable, final Object... args) throws ProcessingException {
+        assert context != null;
+        assert args != null;
+
+        CommandLineProcessor clp = new CommandLineProcessor();
+        clp.addBean(executable);
+
+        // Attach some help context
+        HelpSupport help = new HelpSupport();
+        clp.addBean(help);
+
+        // Process the arguments
+        clp.process(Arguments.toStringArray(args));
+
+        // Display help if option detected
+        if (help.displayHelp) {
+            help.display(context, clp);
+            return true;
+        }
+
+        return false;
+    }
+
+    private static class HelpSupport
+    {
+        @Option(name="-h", aliases={"--help"}, description="Display this help message", requireOverride=true)
+        public boolean displayHelp;
+
+        protected void display(final CommandContext context, final CommandLineProcessor clp) {
+            assert context != null;
+            assert clp != null;
+
+            // Use the alias if we have one, else use the command name
+            CommandInfo info = context.getInfo();
+            String name = info.getAlias();
+            if (name == null) {
+                name = info.getName();
+            }
+
+            IO io = context.getIo();
+            Printer printer = new Printer(clp);
+            printer.printUsage(io.out, name);
+            io.out.println();
+        }
+    }
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.command.CommandContainer;
+import org.apache.geronimo.gshell.plexus.GShellPlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.PlexusConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default implementation of a {@link CommandContainer.Locator} component.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=CommandContainer.Locator.class)
+public class DefaultCommandContainerLocator
+    implements CommandContainer.Locator, Contextualizable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private GShellPlexusContainer container;
+
+    public void contextualize(final Context context) throws ContextException {
+        assert context != null;
+
+        container = (GShellPlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
+        assert container != null;
+
+        log.debug("Container: {}", container);
+    }
+
+    public CommandContainer locate(final String id) {
+        assert id != null;
+
+        log.debug("Locating container for ID: {}", id);
+
+        ComponentDescriptor descriptor = container.getComponentDescriptor(CommandContainer.class, id);
+        if (descriptor == null) {
+            // TODO: Throw typed exception
+            throw new RuntimeException("Command container not found for ID: " + id);
+        }
+
+        CommandContainer commandContainer;
+        try {
+            commandContainer = container.lookupComponent(CommandContainer.class, id);
+        }
+        catch (ComponentLookupException e) {
+            // TODO: Throw typed exception
+            throw new RuntimeException("Failed to access command container for ID: " + id, e);
+        }
+
+        return commandContainer;
+    }
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandContainerLocator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.application.DefaultVariables;
+import org.apache.geronimo.gshell.command.CommandContainer;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.command.CommandExecutor;
+import org.apache.geronimo.gshell.command.CommandInfo;
+import org.apache.geronimo.gshell.command.Variables;
+import org.apache.geronimo.gshell.common.Arguments;
+import org.apache.geronimo.gshell.common.Notification;
+import org.apache.geronimo.gshell.common.StopWatch;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.io.SystemOutputHijacker;
+import org.apache.geronimo.gshell.layout.LayoutManager;
+import org.apache.geronimo.gshell.layout.NotFoundException;
+import org.apache.geronimo.gshell.model.layout.AliasNode;
+import org.apache.geronimo.gshell.model.layout.CommandNode;
+import org.apache.geronimo.gshell.model.layout.Node;
+import org.apache.geronimo.gshell.shell.Environment;
+import org.apache.geronimo.gshell.ErrorNotification;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.util.IOUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * The default {@link CommandExecutor} component.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=CommandExecutor.class)
+public class DefaultCommandExecutor
+    implements CommandExecutor, Initializable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private ApplicationManager applicationManager;
+
+    @Requirement
+    private LayoutManager layoutManager;
+
+    @Requirement
+    private CommandContainer.Locator commandContainerLocator;
+
+    @Requirement
+    private CommandLineBuilder commandLineBuilder;
+
+    private Environment env;
+
+    public DefaultCommandExecutor() {}
+    
+    public DefaultCommandExecutor(final ApplicationManager applicationManager, final LayoutManager layoutManager, final CommandContainer.Locator commandContainerLocator, final CommandLineBuilder commandLineBuilder) {
+        assert applicationManager != null;
+        assert layoutManager != null;
+        assert commandContainerLocator != null;
+        assert commandLineBuilder != null;
+
+        this.applicationManager = applicationManager;
+        this.layoutManager = layoutManager;
+        this.commandContainerLocator = commandContainerLocator;
+        this.commandLineBuilder = commandLineBuilder;
+    }
+
+    public void initialize() throws InitializationException {
+        assert applicationManager != null;
+        
+        this.env = applicationManager.getContext().getEnvironment();
+    }
+
+    public Object execute(final String line) throws Exception {
+        assert line != null;
+
+        log.info("Executing (String): {}", line);
+
+        try {
+            CommandLine cl = commandLineBuilder.create(line);
+
+            return cl.execute();
+        }
+        catch (ErrorNotification n) {
+            // Decode the error notifiation
+            Throwable cause = n.getCause();
+
+            if (cause instanceof Exception) {
+                throw (Exception)cause;
+            }
+            else if (cause instanceof Error) {
+                throw (Error)cause;
+            }
+            else {
+                // Um, if we get this far, which we probably never will, then just re-toss the notifcation
+                throw n;
+            }
+        }
+    }
+
+    public Object execute(final Object... args) throws Exception {
+        assert args != null;
+        assert args.length > 1;
+
+        log.info("Executing (Object...): [{}]", Arguments.asString(args));
+
+        return execute(String.valueOf(args[0]), Arguments.shift(args), env.getIO());
+    }
+
+    public Object execute(final String path, final Object[] args) throws Exception {
+        assert path != null;
+        assert args != null;
+
+        log.info("Executing ({}): [{}]", path, Arguments.asString(args));
+
+        return execute(path, args, env.getIO());
+    }
+
+    public Object execute(final Object[][] commands) throws Exception {
+        assert commands != null;
+
+        // Prepare IOs
+        final IO[] ios = new IO[commands.length];
+        PipedOutputStream pos = null;
+
+        for (int i = 0; i < ios.length; i++) {
+            InputStream is = (i == 0) ? env.getIO().inputStream : new PipedInputStream(pos);
+            OutputStream os;
+
+            if (i == ios.length - 1) {
+                os = env.getIO().outputStream;
+            }
+            else {
+                os = pos = new PipedOutputStream();
+            }
+
+            ios[i] = new IO(is, new PrintStream(os), env.getIO().errorStream);
+        }
+
+        Thread[] threads = new Thread[commands.length];
+        final List<Throwable> errors = new CopyOnWriteArrayList<Throwable>();
+        final AtomicReference<Object> ref = new AtomicReference<Object>();
+
+        for (int i = 0; i < commands.length; i++) {
+            final int idx = i;
+
+            threads[i] = createThread(new Runnable() {
+                public void run() {
+                    try {
+                        Object o = execute(String.valueOf(commands[idx][0]), Arguments.shift(commands[idx]), ios[idx]);
+
+                        if (idx == commands.length - 1) {
+                            ref.set(o);
+                        }
+                    }
+                    catch (Throwable t) {
+                        errors.add(t);
+                    }
+                    finally {
+                        if (idx > 0) {
+                            IOUtil.close(ios[idx].inputStream);
+                        }
+                        if (idx < commands.length - 1) {
+                            IOUtil.close(ios[idx].outputStream);
+                        }
+                    }
+                }
+            });
+
+            threads[i].start();
+        }
+
+        for (int i = 0; i < commands.length; i++) {
+            threads[i].join();
+        }
+
+        if (!errors.isEmpty()) {
+            Throwable t = errors.get(0);
+
+            // Always preserve the type of notication throwables, reguardless of the trace
+            if (t instanceof Notification) {
+                throw (Notification)t;
+            }
+
+            // Otherwise wrap to preserve the trace
+            throw new CommandExecutionFailied(t);
+        }
+
+        return ref.get();
+    }
+
+    protected Thread createThread(Runnable run) {
+        return new Thread(run);
+    }
+
+    protected Object execute(final String path, final Object[] args, final IO io) throws Exception {
+        log.debug("Executing");
+
+        final String searchPath = (String) env.getVariables().get(LayoutManager.COMMAND_PATH);
+        log.debug("Search path: {}", searchPath);
+
+        final Node node = layoutManager.findNode(path, searchPath);
+        log.debug("Layout node: {}", node);
+
+        final String id = findCommandId(node);
+        log.debug("Command ID: {}", id);
+        
+        final CommandContainer container;
+        try {
+            container = commandContainerLocator.locate(id);
+        }
+        catch (Exception e) {
+            throw new NotFoundException(e.getMessage());
+        }
+
+        // Setup the command context and pass it to the command instance
+        CommandContext context = new CommandContext() {
+            // Command instances get their own namespace with defaults from the current
+            final Variables vars = new DefaultVariables(env.getVariables());
+
+            CommandInfo info;
+
+            public IO getIo() {
+                return io;
+            }
+
+            public Variables getVariables() {
+                return vars;
+            }
+
+            public CommandInfo getInfo() {
+                if (info == null) {
+                    info = new CommandInfo()
+                    {
+                        public String getId() {
+                            return id;
+                        }
+
+                        public String getName() {
+                            if (node instanceof AliasNode) {
+                                return ((AliasNode)node).getCommand();
+                            }
+
+                            return node.getName();
+                        }
+
+                        public String getAlias() {
+                            if (node instanceof AliasNode) {
+                                return node.getName();
+                            }
+
+                            return null;
+                        }
+
+                        public String getPath() {
+                            //
+                            // TODO:
+                            //
+                            
+                            return null;
+                        }
+                    };
+                }
+
+                return info;
+            }
+        };
+
+        // Setup command timings
+        StopWatch watch = new StopWatch(true);
+
+        // Hijack the system streams in the current thread's context
+        SystemOutputHijacker.register(io.outputStream, io.errorStream);
+
+        Object result;
+        try {
+            result = container.execute(context, args);
+
+            log.debug("Command completed with result: {}, after: {}", result, watch);
+        }
+        finally {
+            // Restore hijacked streams
+            SystemOutputHijacker.deregister();
+
+            // Make sure that the commands output has been flushed
+            try {
+                io.flush();
+            }
+            catch (Exception ignore) {}
+        }
+
+        return result;
+    }
+
+    protected String findCommandId(final Node node) throws NotFoundException {
+        assert node != null;
+
+        if (node instanceof AliasNode) {
+            AliasNode aliasNode = (AliasNode) node;
+            String targetPath = aliasNode.getCommand();
+            Node target = layoutManager.findNode(layoutManager.getLayout(), targetPath);
+
+            return findCommandId(target);
+        }
+        else if (node instanceof CommandNode) {
+            CommandNode commandNode = (CommandNode) node;
+
+            return commandNode.getId();
+        }
+
+        throw new NotFoundException("Unable to get command id for: " + node);
+    }
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandExecutor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.command.CommandExecutor;
+import org.apache.geronimo.gshell.rapture.LoggingVisitor;
+import org.apache.geronimo.gshell.ErrorNotification;
+import org.apache.geronimo.gshell.parser.ASTCommandLine;
+import org.apache.geronimo.gshell.parser.CommandLineParser;
+import org.apache.geronimo.gshell.parser.ParseException;
+import org.apache.geronimo.gshell.shell.Environment;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.IOUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+/**
+ * Builds {@link CommandLine} instances ready for executing.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=CommandLineBuilder.class)
+public class DefaultCommandLineBuilder
+    implements CommandLineBuilder
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private PlexusContainer container;
+
+    @Requirement
+    private ApplicationManager applicationManager;
+
+    private final CommandLineParser parser = new CommandLineParser();
+
+    public DefaultCommandLineBuilder() {}
+    
+    public DefaultCommandLineBuilder(final PlexusContainer container, final ApplicationManager applicationManager) {
+        assert container != null;
+        assert applicationManager != null;
+
+        this.container = container;
+        this.applicationManager = applicationManager;
+    }
+
+    private ASTCommandLine parse(final String input) throws ParseException {
+        assert input != null;
+
+        Reader reader = new StringReader(input);
+        ASTCommandLine cl;
+        try {
+            cl = parser.parse(reader);
+        }
+        finally {
+            IOUtil.close(reader);
+        }
+
+        // If debug is enabled, the log the parse tree
+        if (log.isDebugEnabled()) {
+            LoggingVisitor logger = new LoggingVisitor(log);
+            cl.jjtAccept(logger, null);
+        }
+
+        return cl;
+    }
+
+    public CommandLine create(final String commandLine) throws ParseException {
+        assert commandLine != null;
+
+        if (commandLine.trim().length() == 0) {
+            throw new IllegalArgumentException("Command line is empty");
+        }
+
+        try {
+            assert container != null;
+            CommandExecutor executor = (CommandExecutor) container.lookup(CommandExecutor.class);
+
+            assert applicationManager != null;
+            Environment env = applicationManager.getContext().getEnvironment();
+
+            final ExecutingVisitor visitor = new ExecutingVisitor(executor, env);
+            final ASTCommandLine root = parse(commandLine);
+
+            return new CommandLine() {
+                public Object execute() throws Exception {
+                    return root.jjtAccept(visitor, null);
+                }
+            };
+        }
+        catch (Exception e) {
+            throw new ErrorNotification(e);
+        }
+    }
+}

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultCommandLineBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import jline.History;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Default implementation of the {@link History} component.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=History.class,hint="default")
+public class DefaultHistory
+    extends FileHistory
+{
+    // Empty
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultHistory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.model.layout.GroupNode;
+import org.apache.geronimo.gshell.model.layout.Layout;
+import org.apache.geronimo.gshell.model.layout.Node;
+import org.apache.geronimo.gshell.layout.LayoutManager;
+import org.apache.geronimo.gshell.layout.NotFoundException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The default implementation of the {@link LayoutManager} component.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role= LayoutManager.class)
+public class DefaultLayoutManager
+    implements LayoutManager
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private ApplicationManager applicationManager;
+    
+    private Layout layout;
+
+    public DefaultLayoutManager() {}
+    
+    public DefaultLayoutManager(final ApplicationManager applicationManager) {
+        assert applicationManager != null;
+
+        this.applicationManager = applicationManager;
+    }
+
+    private Layout lookupLayout() {
+        assert applicationManager != null;
+
+        Layout layout = applicationManager.getContext().getApplication().getLayout();
+
+        if (layout == null) {
+            throw new IllegalStateException("Layout has not been configured for application");
+        }
+
+        return layout;
+    }
+
+    public Layout getLayout() {
+        if (layout == null) {
+            layout = lookupLayout();
+
+            log.debug("Using layout: {}", layout);
+        }
+        
+        return layout;
+    }
+
+    public Node findNode(final String path) throws NotFoundException {
+        return findNode(path, null);
+    }
+
+    public Node findNode(final String path, final String searchPath) throws NotFoundException {
+        assert path != null;
+
+        // Make sure we have initialized the layout
+        getLayout();
+
+        Node start;
+
+        if (path.startsWith(FILE_SEPARATOR)) {
+            start = layout;
+            return findNode(start, path);
+        }
+        else if (searchPath != null) {
+            String[] pathList = searchPath.split(SEARCH_PATH_SEPARATOR);
+            Node foundNode = null;
+            
+            for (String commandPath : pathList) {
+                try {
+                    Node pathNode = findNode(commandPath);
+                    foundNode = findNode(pathNode, path);
+                    
+                    if (foundNode != null) {
+                        break;
+                    }
+                }
+                catch (NotFoundException e) {
+                    // Ignore this for now.  We might still have paths to check
+                }
+            }
+            
+            if (foundNode == null) {
+                foundNode = findNode(layout, path);
+            }
+            
+            return foundNode;
+        }
+        else {
+            assert applicationManager != null;
+            
+            start = (Node) applicationManager.getContext().getEnvironment().getVariables().get(CURRENT_NODE);
+
+            if (start == null) {
+                start = layout;
+            }
+            
+            return findNode(start, path);
+        }
+    }
+
+    public Node findNode(final Node start, final String path) throws NotFoundException {
+        assert start != null;
+        assert path != null;
+
+        Node current = start;
+
+        String[] elements = path.split(FILE_SEPARATOR);
+        
+        for (String element : elements) {
+            if (current instanceof GroupNode) {
+                Node node = ((GroupNode)current).find(element);
+
+                if (node == null) {
+                    throw new NotFoundException(path);
+                }
+
+                current = node;
+            }
+            else {
+                throw new NotFoundException(path);
+            }
+        }
+
+        return current;
+    }
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultLayoutManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import jline.History;
+import org.apache.geronimo.gshell.ansi.Renderer;
+import org.apache.geronimo.gshell.application.ApplicationContext;
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.command.CommandExecutor;
+import org.apache.geronimo.gshell.console.Console;
+import org.apache.geronimo.gshell.console.Console.ErrorHandler;
+import org.apache.geronimo.gshell.console.Console.Prompter;
+import org.apache.geronimo.gshell.console.JLineConsole;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.model.application.Branding;
+import org.apache.geronimo.gshell.shell.Environment;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.geronimo.gshell.shell.ShellInfo;
+import org.apache.geronimo.gshell.ExitNotification;
+import org.apache.geronimo.gshell.ErrorNotification;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.util.IOUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * This is the primary implementation of {@link Shell}.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=Shell.class, hint="default")
+public class DefaultShell
+    implements Shell, Initializable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private ApplicationManager applicationManager;
+
+    @Requirement
+    private ShellInfo shellInfo;
+
+    @Requirement
+    private CommandExecutor executor;
+
+    @Requirement
+    private History history;
+
+    private Environment env;
+
+    private IO io;
+
+    private Branding branding;
+
+    private Prompter prompter;
+
+    private ErrorHandler errorHandler;
+
+    public DefaultShell() {}
+    
+    public DefaultShell(final ApplicationManager applicationManager, final ShellInfo shellInfo, final CommandExecutor executor, final History history) {
+        assert applicationManager != null;
+        assert shellInfo != null;
+        assert executor != null;
+        assert history != null;
+
+        this.applicationManager = applicationManager;
+        this.shellInfo = shellInfo;
+        this.executor = executor;
+        this.history = history;
+    }
+
+    public Environment getEnvironment() {
+        return env;
+    }
+
+    public ShellInfo getShellInfo() {
+        return shellInfo;
+    }
+
+    public boolean isInteractive() {
+        return true;
+    }
+
+    public void initialize() throws InitializationException {
+        assert applicationManager != null;
+        
+        // Dereference some bits from the applciation context
+        ApplicationContext context = applicationManager.getContext();
+        this.io = context.getIo();
+        this.env = context.getEnvironment();
+        this.branding = context.getApplication().getBranding();
+        
+        try {
+            loadProfileScripts();
+        }
+        catch (Exception e) {
+            throw new InitializationException(e.getMessage(), e);
+        }
+    }
+
+    //
+    // Command Execution (all delegates)
+    //
+    
+    public Object execute(final String line) throws Exception {
+        return executor.execute(line);
+    }
+
+    public Object execute(final Object... args) throws Exception {
+        return executor.execute((Object[])args);
+    }
+
+    public Object execute(final String path, final Object[] args) throws Exception {
+        return executor.execute(path, args);
+    }
+
+    public Object execute(Object[][] commands) throws Exception {
+        return executor.execute(commands);
+    }
+
+    //
+    // Interactive Shell
+    //
+
+    public void run(final Object... args) throws Exception {
+        assert args != null;
+
+        log.debug("Starting interactive console; args: {}", args);
+
+        assert branding != null;
+        loadUserScript(branding.getInteractiveScriptName());
+
+        // Setup 2 final refs to allow our executor to pass stuff back to us
+        final AtomicReference<ExitNotification> exitNotifHolder = new AtomicReference<ExitNotification>();
+        final AtomicReference<Object> lastResultHolder = new AtomicReference<Object>();
+
+        // Whip up a tiny console executor that will execute shell command-lines
+        Console.Executor executor = new Console.Executor() {
+            public Result execute(final String line) throws Exception {
+                assert line != null;
+                
+                try {
+                    Object result = DefaultShell.this.execute(line);
+                    
+                    lastResultHolder.set(result);
+                }
+                catch (ExitNotification n) {
+                    exitNotifHolder.set(n);
+                    
+                    return Result.STOP;
+                }
+
+                return Result.CONTINUE;
+            }
+        };
+
+        // Ya, bust out the sexy JLine console baby!
+        JLineConsole console = new JLineConsole(executor, io);
+
+        // Setup the prompt
+        console.setPrompter(getPrompter());
+
+        // Delegate errors for display and then continue
+        console.setErrorHandler(getErrorHandler());
+
+        // Hook up a nice history file (we gotta hold on to the history object at some point so the 'history' command can get to it) 
+        console.setHistory(history);
+
+        // Unless the user wants us to shut up, then display a nice welcome banner
+        if (!io.isQuiet()) {
+            String message = branding.getWelcomeMessage();
+            if (message != null) {
+                io.out.println(message);
+            }
+
+            //
+            // TODO: Render a nice line here if the branding has some property configured to enable it (move that bit out of branding's job)
+            //
+        }
+
+        // Check if there are args, and run them and then enter interactive
+        if (args.length != 0) {
+            execute(args);
+        }
+
+        // And then spin up the console and go for a jog
+        console.run();
+
+        // If any exit notification occured while running, then puke it up
+        ExitNotification n = exitNotifHolder.get();
+        if (n != null) {
+            throw n;
+        }
+    }
+
+    public Prompter getPrompter() {
+        if (prompter == null) {
+            prompter = createPrompter();
+        }
+        return prompter;
+    }
+    
+    public void setPrompter(final Prompter prompter) {
+        this.prompter = prompter;
+    }
+
+    /**
+     * Allow subclasses to override the default Prompter implementation used.
+     */
+    protected Prompter createPrompter() {
+        return new Prompter() {
+            Renderer renderer = new Renderer();
+            
+            public String prompt() {
+                assert shellInfo != null;
+
+                String userName = shellInfo.getUserName();
+                String hostName = shellInfo.getLocalHost().getHostName();
+
+                //
+                // HACK: There is no path... yet ;-)
+                //
+                String path = "/";
+
+                return renderer.render("@|bold " + userName + "|@" + hostName + ":@|bold " + path + "|> ");
+            }
+        };
+    }
+
+    public ErrorHandler getErrorHandler() {
+        if (errorHandler == null) {
+            errorHandler = createErrorHandler();
+        }
+        return errorHandler;
+    }
+
+    public void setErrorHandler(ErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    public ErrorHandler createErrorHandler() {
+        return new ErrorHandler() {
+            public Result handleError(final Throwable error) {
+                assert error != null;
+
+                displayError(error);
+
+                return Result.CONTINUE;
+            }
+        };
+    }
+
+    //
+    // Error Display
+    //
+
+    private void displayError(final Throwable error) {
+        assert error != null;
+
+        // Decode any error notifications
+        Throwable cause = error;
+        if (error instanceof ErrorNotification) {
+            cause = error.getCause();
+        }
+
+        // Spit out the terse reason why we've failed
+        io.err.print("@|bold,red ERROR| ");
+        io.err.print(cause.getClass().getSimpleName());
+        io.err.println(": @|bold,red " + cause.getMessage() + "|");
+
+        // Determine if the stack trace flag is set
+        String stackTraceProperty = System.getProperty("gshell.show.stacktrace");
+        boolean stackTraceFlag = false;
+        if (stackTraceProperty != null) {
+        	stackTraceFlag = stackTraceProperty.trim().equals("true");
+        }
+        
+        if (io.isDebug()) {
+            // If we have debug enabled then skip the fancy bits below, and log the full error, don't decode shit
+            log.debug(error.toString(), error);
+        }
+        else if (io.isVerbose() || stackTraceFlag) {
+            // Render a fancy ansi colored stack trace
+            StackTraceElement[] trace = cause.getStackTrace();
+            StringBuffer buff = new StringBuffer();
+
+            for (StackTraceElement e : trace) {
+                buff.append("        @|bold at| ").
+                    append(e.getClassName()).
+                    append(".").
+                    append(e.getMethodName()).
+                    append(" (@|bold ");
+
+                buff.append(e.isNativeMethod() ? "Native Method" :
+                        (e.getFileName() != null && e.getLineNumber() != -1 ? e.getFileName() + ":" + e.getLineNumber() :
+                            (e.getFileName() != null ? e.getFileName() : "Unknown Source")));
+
+                buff.append("|)");
+
+                io.err.println(buff);
+
+                buff.setLength(0);
+            }
+        }
+    }
+
+    //
+    // Script Processing
+    //
+
+    private void loadProfileScripts() throws Exception {
+        assert branding != null;
+
+        // Load profile scripts if they exist
+        loadSharedScript(branding.getProfileScriptName());
+        loadUserScript(branding.getProfileScriptName());
+    }
+
+    private void loadScript(final File file) throws Exception {
+        assert file != null;
+
+        //
+        // FIXME: Don't use 'source 'for right now, the shell spins out of control from plexus component loading :-(
+        //
+        // execute("source", file.toURI().toURL());
+
+        BufferedReader reader = new BufferedReader(new FileReader(file));
+
+        try {
+            String line;
+
+            while ((line = reader.readLine()) != null) {
+                execute(line);
+            }
+        }
+        finally {
+            IOUtil.close(reader);
+        }
+    }
+
+    private void loadUserScript(final String fileName) throws Exception {
+        assert fileName != null;
+
+        File file = new File(branding.getUserDirectory(), fileName);
+
+        if (file.exists()) {
+            log.debug("Loading user-script: {}", file);
+
+            loadScript(file);
+        }
+        else {
+            log.debug("User script is not present: {}", file);
+        }
+    }
+
+    private void loadSharedScript(final String fileName) throws Exception {
+        assert fileName != null;
+
+        File file = new File(branding.getUserDirectory(), fileName);
+
+        if (file.exists()) {
+            log.debug("Loading shared-script: {}", file);
+
+            loadScript(file);
+        }
+        else {
+            log.debug("Shared script is not present: {}", file);
+        }
+    }
+}
\ No newline at end of file

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShell.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.shell.ShellInfo;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Provides some runtime information about the shell.
+ *
+ * @version $Rev$ $Date$
+ */
+@Component(role=ShellInfo.class, hint="default")
+public class DefaultShellInfo
+    implements ShellInfo, Initializable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private InetAddress localHost;
+
+    private File homeDir;
+
+    public DefaultShellInfo() {}
+    
+    public File getHomeDir() {
+        if (homeDir == null) {
+            throw new IllegalStateException();
+        }
+
+        return homeDir;
+    }
+
+    public InetAddress getLocalHost() {
+        if (localHost == null) {
+            throw new IllegalStateException();
+        }
+
+        return localHost;
+    }
+
+    public String getUserName() {
+        return System.getProperty("user.name");
+    }
+
+    public void initialize() throws InitializationException {
+        homeDir = detectHomeDir();
+        
+        log.debug("Using home directory: {}", homeDir);
+
+        try {
+            localHost = InetAddress.getLocalHost();
+        }
+        catch (UnknownHostException e) {
+            throw new InitializationException("Unable to determine locahost", e);
+        }
+    }
+    
+    private File detectHomeDir() throws InitializationException {
+        String homePath = System.getProperty("user.home");
+
+        // And now lets resolve this sucker
+        File dir;
+        
+        try {
+            dir = new File(homePath).getCanonicalFile();
+        }
+        catch (IOException e) {
+            throw new InitializationException("Failed to resolve home directory: " + homePath, e);
+        }
+
+        // And some basic sanity too
+        if (!dir.exists() || !dir.isDirectory()) {
+            throw new InitializationException("Home directory configured but is not a valid directory: " + dir);
+        }
+
+        return dir;
+    }
+}

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/DefaultShellInfo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.command.CommandExecutor;
+import org.apache.geronimo.gshell.common.Arguments;
+import org.apache.geronimo.gshell.parser.ASTCommandLine;
+import org.apache.geronimo.gshell.parser.ASTExpression;
+import org.apache.geronimo.gshell.parser.ASTOpaqueString;
+import org.apache.geronimo.gshell.parser.ASTPlainString;
+import org.apache.geronimo.gshell.parser.ASTProcess;
+import org.apache.geronimo.gshell.parser.ASTQuotedString;
+import org.apache.geronimo.gshell.parser.CommandLineParserVisitor;
+import org.apache.geronimo.gshell.parser.SimpleNode;
+import org.apache.geronimo.gshell.shell.Environment;
+import org.apache.geronimo.gshell.ErrorNotification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Visitor which will execute command-lines as parsed.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExecutingVisitor
+    implements CommandLineParserVisitor
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final Environment env;
+    
+    private final CommandExecutor executor;
+
+    private final VariableInterpolator interp = new VariableInterpolator();
+
+    public ExecutingVisitor(final CommandExecutor executor, final Environment env) {
+        assert executor != null;
+        assert env != null;
+
+        this.executor = executor;
+        this.env = env;
+    }
+
+    public Object visit(final SimpleNode node, final Object data) {
+        assert node != null;
+
+        // It is an error if we forgot to implement a node handler
+        throw new Error("Unhandled node type: " + node.getClass().getName());
+    }
+
+    public Object visit(final ASTCommandLine node, final Object data) {
+        assert node != null;
+
+        //
+        // NOTE: Visiting children will execute seperate commands in serial
+        //
+
+        return node.childrenAccept(this, data);
+    }
+
+    public Object visit(final ASTExpression node, final Object data) {
+        assert node != null;
+
+        Object[][] commands = new Object[node.jjtGetNumChildren()][];
+        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
+            ASTProcess proc = (ASTProcess) node.jjtGetChild(i);
+            List<Object> list = new ArrayList<Object>(proc.jjtGetNumChildren());
+            proc.childrenAccept(this, list);
+            commands[i] = list.toArray(new Object[list.size()]);
+            assert list.size() >= 1;
+        }
+        try {
+            return executor.execute(commands);
+        }
+        catch (Exception e) {
+            String s = Arguments.asString(commands[0]);
+            for (int i = 1; i < commands.length; i++) {
+                s += " | " + Arguments.asString(commands[i]);
+            }
+            throw new ErrorNotification("Shell execution failed; commands=" + s, e);
+        }
+    }
+
+    public Object visit(ASTProcess node, Object data) {
+        return null;
+    }
+
+    @SuppressWarnings({"unchecked"})
+    private Object appendString(final String value, final Object data) {
+        assert data != null;
+        assert data instanceof List;
+
+        List<Object> args = (List<Object>)data;
+        args.add(value);
+
+        return value;
+    }
+
+    public Object visit(final ASTQuotedString node, final Object data) {
+        assert node != null;
+
+        String value = interp.interpolate(node.getValue(), env.getVariables());
+
+        return appendString(value, data);
+    }
+
+    public Object visit(final ASTPlainString node, final Object data) {
+        assert node != null;
+
+        String value = interp.interpolate(node.getValue(), env.getVariables());
+        
+        return appendString(value, data);
+    }
+
+    public Object visit(final ASTOpaqueString node, final Object data) {
+        assert node != null;
+
+        return appendString(node.getValue(), data);
+    }
+}

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/ExecutingVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/FileHistory.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/FileHistory.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/FileHistory.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/FileHistory.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import jline.History;
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Preserves command history to a file.
+ *
+ * @version $Rev: 573669 $ $Date: 2007-09-07 11:47:20 -0700 (Fri, 07 Sep 2007) $
+ */
+@Component(role=History.class, hint="file")
+public class FileHistory
+    extends History
+    implements Initializable
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private ApplicationManager applicationManager;
+
+    public FileHistory() {}
+
+    public void initialize() throws InitializationException {
+        assert applicationManager != null;
+        
+        try {
+            setHistoryFile(applicationManager.getContext().getApplication().getBranding().getHistoryFile());
+        }
+        catch (IOException e) {
+            throw new InitializationException("Failed to set history file", e);
+        }
+    }
+
+    public void setHistoryFile(final File file) throws IOException {
+        assert file != null;
+
+        File dir = file.getParentFile();
+
+        if (!dir.exists()) {
+            dir.mkdirs();
+
+            log.debug("Created base directory for history file: {}", dir);
+        }
+
+        log.debug("Using history file: {}", file);
+
+        super.setHistoryFile(file);
+    }
+
+}
\ No newline at end of file

Added: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java?rev=666796&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java (added)
+++ geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java Wed Jun 11 12:17:00 2008
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.gshell.rapture;
+
+import org.apache.geronimo.gshell.parser.ASTCommandLine;
+import org.apache.geronimo.gshell.parser.ASTExpression;
+import org.apache.geronimo.gshell.parser.ASTOpaqueString;
+import org.apache.geronimo.gshell.parser.ASTPlainString;
+import org.apache.geronimo.gshell.parser.ASTProcess;
+import org.apache.geronimo.gshell.parser.ASTQuotedString;
+import org.apache.geronimo.gshell.parser.CommandLineParserVisitor;
+import org.apache.geronimo.gshell.parser.SimpleNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Visitor whichs logs nodes in the tree.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LoggingVisitor
+    implements CommandLineParserVisitor
+{
+    public static enum Level {
+        INFO,
+        DEBUG
+    }
+
+    private final Logger log;
+
+    private final Level level;
+
+    private int indent = 0;
+
+    public LoggingVisitor() {
+        this(LoggerFactory.getLogger(LoggingVisitor.class));
+    }
+
+    public LoggingVisitor(final Logger log) {
+        this(log, Level.DEBUG);
+    }
+
+    public LoggingVisitor(final Logger log, final Level level) {
+        assert log != null;
+        assert level != null;
+
+        this.log = log;
+        this.level = level;
+    }
+
+    private Object log(final Class type, final SimpleNode node, Object data) {
+        // Short-circuit of logging level does not match
+        switch (level) {
+            case INFO:
+                if (!log.isInfoEnabled()) {
+                    return data;
+                }
+                break;
+
+            case DEBUG:
+                if (!log.isDebugEnabled()) {
+                    return data;
+                }
+                break;
+        }
+
+        StringBuffer buff = new StringBuffer();
+
+        for (int i=0; i<indent; i++) {
+            buff.append(" ");
+        }
+
+        buff.append(node).append(" (").append(type.getName()).append(")");
+        if (data != null) {
+            buff.append("; Data: ").append(data);
+        }
+
+        switch (level) {
+            case INFO:
+                log.info(buff.toString());
+                break;
+
+            case DEBUG:
+                log.debug(buff.toString());
+                break;
+        }
+
+        indent++;
+        data = node.childrenAccept(this, data);
+        indent--;
+
+        return data;
+    }
+
+    public Object visit(final SimpleNode node, Object data) {
+        return log(SimpleNode.class, node, data);
+    }
+
+    public Object visit(final ASTCommandLine node, Object data) {
+        return log(ASTCommandLine.class, node, data);
+    }
+
+    public Object visit(final ASTExpression node, Object data) {
+        return log(ASTExpression.class, node, data);
+    }
+
+    public Object visit(ASTProcess node, Object data) {
+        return log(ASTProcess.class, node, data);
+    }
+
+    public Object visit(final ASTQuotedString node, Object data) {
+        return log(ASTQuotedString.class, node, data);
+    }
+
+    public Object visit(final ASTOpaqueString node, Object data) {
+        return log(ASTOpaqueString.class, node, data);
+    }
+
+    public Object visit(final ASTPlainString node, Object data) {
+        return log(ASTPlainString.class, node, data);
+    }
+}

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/gshell/trunk/gshell-rapture/src/main/java/org/apache/geronimo/gshell/rapture/LoggingVisitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain