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/08/01 08:37:03 UTC
svn commit: r681611 [2/2] - in /geronimo/gshell/trunk/gshell-wisdom/src/main:
java/org/apache/geronimo/gshell/wisdom/
java/org/apache/geronimo/gshell/wisdom/application/
java/org/apache/geronimo/gshell/wisdom/command/
java/org/apache/geronimo/gshell/wi...
Added: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java?rev=681611&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java (added)
+++ geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java Thu Jul 31 23:37:02 2008
@@ -0,0 +1,394 @@
+/*
+ * 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.wisdom.shell;
+
+import jline.History;
+import org.apache.geronimo.gshell.ansi.Renderer;
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.command.Variables;
+import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
+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.notification.ErrorNotification;
+import org.apache.geronimo.gshell.notification.ExitNotification;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.geronimo.gshell.shell.ShellInfo;
+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$
+ */
+public class ShellImpl
+ implements Shell
+{
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private ApplicationManager applicationManager;
+
+ private ShellInfo shellInfo;
+
+ private CommandLineExecutor executor;
+
+ private History history;
+
+ private Variables variables;
+
+ private IO io;
+
+ private Branding branding;
+
+ private Prompter prompter;
+
+ private ErrorHandler errorHandler;
+
+ public ShellImpl() {}
+
+ public ShellImpl(final ApplicationManager applicationManager, final ShellInfo shellInfo, final CommandLineExecutor 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 Variables getVariables() {
+ return variables;
+ }
+
+ public ShellInfo getInfo() {
+ 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.variables = context.getVariables();
+ 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 = ShellImpl.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.
+ *
+ * @return Interactive properter.
+ */
+ 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("|)");
+
+ //
+ // FIXME: This does not properly display the full exception detail when cause contains nested exceptions
+ //
+
+ 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-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java?rev=681611&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java (added)
+++ geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java Thu Jul 31 23:37:02 2008
@@ -0,0 +1,102 @@
+/*
+ * 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.wisdom.shell;
+
+import org.apache.geronimo.gshell.shell.ShellInfo;
+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$
+ */
+public class ShellInfoImpl
+ implements ShellInfo, Initializable
+{
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private InetAddress localHost;
+
+ private File homeDir;
+
+ public ShellInfoImpl() {}
+
+ 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;
+ }
+}
\ No newline at end of file
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/java/org/apache/geronimo/gshell/wisdom/shell/ShellInfoImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml?rev=681611&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml (added)
+++ geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml Thu Jul 31 23:37:02 2008
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
+
+ <!--
+ TODO:
+ -->
+
+</beans>
\ No newline at end of file
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: geronimo/gshell/trunk/gshell-wisdom/src/main/resources/META-INF/spring/components.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml