/*
 * 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;

import java.util.UUID;

import org.apache.geronimo.gshell.command.Command;
import org.apache.geronimo.gshell.command.CommandContext;
import org.apache.geronimo.gshell.command.CommandExecutor;
import org.apache.geronimo.gshell.command.CommandNotFoundException;
import org.apache.geronimo.gshell.command.IO;
import org.apache.geronimo.gshell.command.Variables;
import org.apache.geronimo.gshell.command.descriptor.CommandDescriptor;
import org.apache.geronimo.gshell.common.Arguments;
import org.apache.geronimo.gshell.common.StopWatch;
import org.apache.geronimo.gshell.layout.LayoutManager;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The default command executor.
 *
 * @version $Rev$ $Date$
 */
@Component(role=CommandExecutor.class, hint="default")
public class DefaultCommandExecutor
    implements CommandExecutor
{
    private Logger log = LoggerFactory.getLogger(getClass());

    @Requirement
    private PlexusContainer container;

    @Requirement
    private LayoutManager layoutManager;

    @Requirement
    private CommandLineBuilder commandLineBuilder;

    @Requirement
    private Environment env;

    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));
    }

    public Object execute(final String path, final Object[] args) throws Exception {
        assert path != null;
        assert args != null;

        log.info("Executing ({}): [{}]", path, Arguments.asString(args));

        // Look up the command descriptor for the given path
        final Command command = layoutManager.find(path);
        if (command == null) {
            throw new CommandNotFoundException(path);
        }

        // Create a new child container for the invocation and lookup the command instance
        String realmId = "gshell:" + UUID.randomUUID();

        log.debug("Child container realm: {}", realmId);

        // 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());

            public IO getIO() {
                return env.getIO();
            }

            public Variables getVariables() {
                return vars;
            }

        };

        // Setup command timings
        StopWatch watch = new StopWatch(true);

        Object result;
        try {
            result = command.execute(context, args);

            log.debug("Command completed with result: {}, after: {}", result, watch);
        }
        finally {
            // Make sure that the commands output has been flushed
            try {
                env.getIO().flush();
            }
            catch (Exception ignore) {}
        }

        return result;
    }
}
@@ -842,32 +842,8 @@
 l;%0A%0A
-import java.util.UUID;%0A%0A
 impo
@@ -889,16 +889,16 @@
 ommand;%0A
+
 import o
@@ -1177,80 +1177,8 @@
 es;%0A
-import org.apache.geronimo.gshell.command.descriptor.CommandDescriptor;%0A
 impo
@@ -1390,52 +1390,8 @@
 nt;%0A
-import org.codehaus.plexus.PlexusContainer;%0A
 impo
@@ -1759,16 +1759,16 @@
 cutor%0A%7B%0A
+
     priv
@@ -1826,65 +1826,8 @@
 );%0A%0A
-    @Requirement%0A    private PlexusContainer container;%0A%0A
     
@@ -3490,214 +3490,8 @@
  %7D%0A%0A
-        // Create a new child container for the invocation and lookup the command instance%0A        String realmId = %22gshell:%22 + UUID.randomUUID();%0A%0A        log.debug(%22Child container realm: %7B%7D%22, realmId);%0A%0A
     

Drop unused bits from previous refactor