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/09/29 20:09:04 UTC

svn commit: r700192 - in /geronimo/gshell/trunk/gshell-commands/gshell-bsf: ./ src/main/java/org/apache/geronimo/gshell/commands/bsf/ src/main/resources/META-INF/spring/ src/main/resources/org/apache/geronimo/gshell/commands/bsf/

Author: jdillon
Date: Mon Sep 29 11:09:03 2008
New Revision: 700192

URL: http://svn.apache.org/viewvc?rev=700192&view=rev
Log:
Re-implemented the 'script' command to use VFS
Starting to add more context to the engine which is configured 

Added:
    geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java   (with props)
Modified:
    geronimo/gshell/trunk/gshell-commands/gshell-bsf/pom.xml
    geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/ScriptAction.java
    geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/META-INF/spring/components.xml
    geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/org/apache/geronimo/gshell/commands/bsf/ScriptAction.properties

Modified: geronimo/gshell/trunk/gshell-commands/gshell-bsf/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-commands/gshell-bsf/pom.xml?rev=700192&r1=700191&r2=700192&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-commands/gshell-bsf/pom.xml (original)
+++ geronimo/gshell/trunk/gshell-commands/gshell-bsf/pom.xml Mon Sep 29 11:09:03 2008
@@ -40,13 +40,60 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.geronimo.gshell.support</groupId>
+            <artifactId>gshell-vfs</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.support</groupId>
             <artifactId>gshell-console</artifactId>
         </dependency>
 
+        <!--
+        TODO: Update to use Apache BSF 3.0
+
+        <dependency>
+            <groupId>org.apache.bsf</groupId>
+            <artifactId>bsf-api</artifactId>
+            <version>3.0-beta2</version>
+        </dependency>
+        -->
+
         <dependency>
             <groupId>bsf</groupId>
             <artifactId>bsf</artifactId>
-            <version>2.3.0</version>
+            <version>2.4.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-logging</groupId>
+                    <artifactId>commons-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl104-over-slf4j</artifactId>
+        </dependency>
+
+        <!--
+        TODO: Add commands to help install new scripting language support, for now just add some deps to get engines enabled.
+        -->
+        
+        <dependency>
+            <groupId>org.beanshell</groupId>
+            <artifactId>bsh-bsf</artifactId>
+            <version>2.0b4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-all-minimal</artifactId>
+            <version>1.5.6</version>
         </dependency>
     </dependencies>
 

Added: geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java?rev=700192&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java (added)
+++ geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java Mon Sep 29 11:09:03 2008
@@ -0,0 +1,84 @@
+/*
+ * 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.commands.bsf;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.bsf.BSFManager;
+
+import java.util.Map;
+
+/**
+ * Spring {@link FactoryBean} to construct a {@link BSFManager} instance.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BSFManagerFactoryBean
+    implements FactoryBean
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public Object getObject() throws Exception {
+        AccessibleBSFManager manager = new AccessibleBSFManager();
+
+        log.debug("BSF manager: {}", manager);
+
+        Map<String,String> engines = manager.getRegisteredEngines();
+
+        //
+        // NOTE: This is mostly useless debugging as it only shows the map of engines that could be used
+        //       not engines that are actually available (ie. have impl classes and such)
+        //
+
+        if (engines == null || engines.isEmpty()) {
+            log.warn("No engines have been registered");
+        }
+        else {
+            log.debug("Detected {} engines:", engines.size());
+            
+            for (String language : engines.keySet()) {
+                log.debug("    {} -> {}", language, engines.get(language));
+            }
+        }
+
+        return manager;
+    }
+
+    public Class getObjectType() {
+        return BSFManager.class;
+    }
+
+    public boolean isSingleton() {
+        return false;
+    }
+
+    /**
+     * Helper to expose some internal details of the BSFManager.
+     */
+    private static class AccessibleBSFManager
+        extends BSFManager
+    {
+        @SuppressWarnings({"unchecked"})
+        public Map<String,String> getRegisteredEngines() {
+            return registeredEngines;
+        }
+    }
+}

Propchange: geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Propchange: geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/BSFManagerFactoryBean.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/ScriptAction.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/ScriptAction.java?rev=700192&r1=700191&r2=700192&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/ScriptAction.java (original)
+++ geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/java/org/apache/geronimo/gshell/commands/bsf/ScriptAction.java Mon Sep 29 11:09:03 2008
@@ -20,22 +20,26 @@
 package org.apache.geronimo.gshell.commands.bsf;
 
 import org.apache.bsf.BSFEngine;
+import org.apache.bsf.BSFException;
 import org.apache.bsf.BSFManager;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileType;
+import org.apache.commons.vfs.FileUtil;
+import org.apache.geronimo.gshell.ansi.Code;
+import org.apache.geronimo.gshell.ansi.Renderer;
 import org.apache.geronimo.gshell.clp.Argument;
 import org.apache.geronimo.gshell.clp.Option;
 import org.apache.geronimo.gshell.command.CommandAction;
 import org.apache.geronimo.gshell.command.CommandContext;
-import org.apache.geronimo.gshell.command.CommandException;
 import org.apache.geronimo.gshell.console.Console;
 import org.apache.geronimo.gshell.console.JLineConsole;
 import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.spring.BeanContainer;
+import org.apache.geronimo.gshell.spring.BeanContainerAware;
+import org.apache.geronimo.gshell.vfs.FileSystemAccess;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URL;
-import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Provides generic scripting language integration via <a href="http://http://jakarta.apache.org/bsf">BSF</a>.
@@ -43,10 +47,18 @@
  * @version $Rev$ $Date$
  */
 public class ScriptAction
-    implements CommandAction
+    implements CommandAction, BeanContainerAware
 {
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    @Autowired
+    private BSFManager manager;
+
+    @Autowired
+    private FileSystemAccess fileSystemAccess;
+
+    private BeanContainer container;
+
     private String language;
 
     @Option(name="-l", aliases={"--language"})
@@ -60,104 +72,170 @@
         this.language = language;
     }
 
-    @Option(name="-i", aliases={"--interactive"})
-    private boolean interactive;
-
     @Option(name="-e", aliases={"--expression"})
     private String expression;
-    
+
     @Argument
-    private List<String> args = null;
+    private String path;
+
+    public void setBeanContainer(final BeanContainer container) {
+        assert container != null;
+
+        this.container = container;
+    }
 
     public Object execute(final CommandContext context) throws Exception {
         assert context != null;
+        IO io = context.getIo();
+
+        if (expression != null && path != null) {
+            io.error("Can only specify an expression or a script file");
+            return Result.FAILURE;
+        }
+        else if (expression != null) {
+            return eval(context);
+        }
+        else if (path != null){
+        	return exec(context);
+        }
+
+        return console(context);
+    }
 
+    private String detectLanguage(final FileObject file) throws Exception {
+        assert file != null;
+
+        return BSFManager.getLangFromFilename(file.getName().getBaseName());
+    }
+
+    private BSFEngine createEngine(final CommandContext context) throws BSFException {
+        assert context != null;
+
+        // Bind some stuff into the scripting engine's namespace
+        manager.declareBean("container", container, BeanContainer.class);
+        manager.declareBean("context", context, CommandContext.class);
+
+        BSFEngine engine = manager.loadScriptingEngine(language);
+
+        log.debug("Created engine: {}", engine);
+
+        return engine;
+    }
+
+    private Object eval(final CommandContext context) throws Exception {
+        assert context != null;
         IO io = context.getIo();
 
-        //
-        // TODO: When given a file/url, try to figure out language from ext if language not given
-        //       https://issues.apache.org/jira/browse/GSHELL-49
-        //
-        
-        String path = null;
-        String filename = null;
+        if (language == null) {
+            io.error("The scripting language must be configured via --language to evaluate an expression");
+            return Result.FAILURE;
+        }
 
-    	if (args != null) {
-    		path = args.get(0); // Only allowing one script for now
-    		filename = ((path.lastIndexOf('/')) == -1) ? path : path.substring(path.lastIndexOf('/') + 1) ; // Just the filename, please   		
-    	}
-    	
-    	if (language == null) {
-    		if (filename == null) {
-    			throw new CommandException("If a file/URL is not provided, language must" +
-    					" be specified using the -l (--language) option.");
-    		}
-    		language = BSFManager.getLangFromFilename(filename);   		
-    	}
-
-    	BSFManager manager = new BSFManager();
-        final BSFEngine engine = manager.loadScriptingEngine(language);
+        log.debug("Evaluating script ({}): {}", language, expression);
 
-        if (this.expression != null) {
-            log.info("Evaluating expression: " + expression);
+        BSFEngine engine = createEngine(context);
 
-            Object obj = engine.eval("<unknown>", 1, 1, expression);
+        try {
+            return engine.eval("<script.expression>", 1, 1, expression);
+        }
+        finally {
+            engine.terminate();
+        }
+    }
 
-            log.info("Expression result: " + obj);
+    private Object exec(final CommandContext context) throws Exception {
+        assert context != null;
+        IO io = context.getIo();
+
+        FileObject cwd = fileSystemAccess.getCurrentDirectory(context.getVariables());
+        FileObject file = fileSystemAccess.resolveFile(cwd, path);
+
+        if (!file.exists()) {
+            io.error("File not found: {}", file.getName());
+            return Result.FAILURE;
+        }
+        else if (file.getType() == FileType.FOLDER) {
+            io.error("File is a directory: {}", file.getName());
+            return Result.FAILURE;
+        }
+        else if (!file.isReadable()) {
+            io.error("File is not readable: {}", file.getName());
+            return Result.FAILURE;
         }
-        else if (path != null){
-        	log.info("Evaluating file: " + path);
-        	//Make a file.  Is it really a file?  Sweet, execute it.
-        	//Is it not a file?  Make a URI, convert that to a URL, or maybe just make a URL, check on that.  Execute it.
-        	//Do it in a nifty way so mother would be proud.
-        	File pathFile = new File(path);
-        	URL pathURL;
-        	if (pathFile.isFile()) {
-        		pathURL = pathFile.toURI().toURL();
-        	} else {
-        		URI pathURI = new URI(path);
-        		pathURL = pathURI.toURL();
-        	}
-        	
-        	engine.exec(path, 1, 1, pathURL.getContent());
-        	
-        	log.info("Finished executing script: " + filename);
-        }
-
-        if (this.interactive) {
-            log.debug("Starting interactive console...");
-            
-            Console.Executor executor = new Console.Executor() {
-                public Result execute(final String line) throws Exception {
-                    // Execute unless the line is just blank
-                    
-                    if (!line.trim().equals("")) {
-                        engine.exec("<unknown>", 1, 1, line);
-                    }
 
-                    return Result.CONTINUE;
-                }
-            };
+        if (language == null) {
+            language = detectLanguage(file);
+        }
 
-            JLineConsole runner = new JLineConsole(executor, io);
+        BSFEngine engine = createEngine(context);
 
-            runner.setErrorHandler(new Console.ErrorHandler() {
-                public Result handleError(final Throwable error) {
-                    log.error("Script evalutation failed: " + error, error);
+        byte[] bytes = FileUtil.getContent(file);
+        String script = new String(bytes);
 
-                    return Result.CONTINUE;
-                }
-            });
+        log.info("Evaluating file ({}): {}", language, path);
 
-            runner.setPrompter(new Console.Prompter() {
-                public String prompt() {
-                    return language + "> ";
-                }
-            });
+        try {
+            return engine.eval(file.getName().getBaseName(), 1, 1, script);
+        }
+        finally {
+            engine.terminate();
+        }
+    }
+
+    private Object console(final CommandContext context) throws Exception {
+        assert context != null;
+        IO io = context.getIo();
 
-            runner.run();
+        if (language == null) {
+            io.error("The scripting language must be configured via --language to run an interactive console");
+            return Result.FAILURE;
         }
 
-        return Result.SUCCESS;
+        log.debug("Starting console ({})...", language);
+
+        final BSFEngine engine = createEngine(context);
+        final ResultHolder holder = new ResultHolder();
+
+        Console.Executor executor = new Console.Executor() {
+            public Result execute(final String line) throws Exception {
+                if (line == null || line.trim().equals("exit") || line.trim().equals("quit")) {
+                    return Result.STOP;
+                }
+                else if (!line.trim().equals("")) {
+                    holder.result = engine.eval("<script.console>", 1, 1, line);
+                }
+
+                return Result.CONTINUE;
+            }
+        };
+
+        JLineConsole runner = new JLineConsole(executor, io);
+
+        runner.setErrorHandler(new Console.ErrorHandler() {
+            public Result handleError(final Throwable error) {
+                log.error("Script evalutation failed: " + error, error);
+
+                return Result.CONTINUE;
+            }
+        });
+
+        runner.setPrompter(new Console.Prompter() {
+            Renderer renderer = new Renderer();
+
+            public String prompt() {
+                return renderer.render(Renderer.encode(language, Code.BOLD) + "> ");
+            }
+        });
+
+        runner.run();
+
+        engine.terminate();
+
+        return holder.result;
+    }
+
+    private class ResultHolder
+    {
+        public Object result;
     }
 }

Modified: geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/META-INF/spring/components.xml
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/META-INF/spring/components.xml?rev=700192&r1=700191&r2=700192&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/META-INF/spring/components.xml (original)
+++ geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/META-INF/spring/components.xml Mon Sep 29 11:09:03 2008
@@ -31,8 +31,14 @@
         <gshell:command-bundle name="default">
             <gshell:command name="script">
                 <gshell:action class="org.apache.geronimo.gshell.commands.bsf.ScriptAction"/>
+                <gshell:completers>
+                    <ref bean="fileObjectNameCompleter"/>
+                    <null/>
+                </gshell:completers>
             </gshell:command>
         </gshell:command-bundle>
     </gshell:plugin>
 
+    <bean id="bsfManager" class="org.apache.geronimo.gshell.commands.bsf.BSFManagerFactoryBean"/>
+
 </beans>
\ No newline at end of file

Modified: geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/org/apache/geronimo/gshell/commands/bsf/ScriptAction.properties
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/org/apache/geronimo/gshell/commands/bsf/ScriptAction.properties?rev=700192&r1=700191&r2=700192&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/org/apache/geronimo/gshell/commands/bsf/ScriptAction.properties (original)
+++ geronimo/gshell/trunk/gshell-commands/gshell-bsf/src/main/resources/org/apache/geronimo/gshell/commands/bsf/ScriptAction.properties Mon Sep 29 11:09:03 2008
@@ -23,15 +23,16 @@
 
 command.name=script
 
-command.description=Provides generic scripting language execution support.
+command.description=Scripting language support.
 
 command.option.setLanguage=Specify the scripting language
-
-command.option.interactive=Run interactive mode
+command.option.setLanguage.token=LANG
 
 command.option.expression=Evaluate the given expression
+command.option.expression.token=EXPR
 
-command.argument.args=A file or URL to execute
+command.argument.path=Path of file to execute
+command.argument.path.token=FILE
 
 command.manual=\
   TODO: script manual
\ No newline at end of file