Add commands, fix parser, remove DS dependency, remove equinox support

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@790958 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/gogo.runtime/pom.xml b/gogo/gogo.runtime/pom.xml
index 22c6dfb..b2f0362 100644
--- a/gogo/gogo.runtime/pom.xml
+++ b/gogo/gogo.runtime/pom.xml
@@ -59,7 +59,6 @@
                             org.osgi.service.threadio; version=1.0.0
                         </Export-Package>
                         <Import-Package>
-                            org.osgi.service.component*; resolution:=optional,
                             org.osgi.service.log*; resolution:=optional,
                             org.osgi.service.packageadmin*; resolution:=optional,
                             org.osgi.service.startlevel*; resolution:=optional,
@@ -69,6 +68,7 @@
                         <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
                         <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
                         <Bundle-Activator>org.apache.felix.gogo.runtime.Activator</Bundle-Activator>
+                        <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
                     </instructions>
                 </configuration>
             </plugin>
diff --git a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/equinox/Equinox.java b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/equinox/Equinox.java
deleted file mode 100644
index 8187496..0000000
--- a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/equinox/Equinox.java
+++ /dev/null
@@ -1,476 +0,0 @@
-package org.apache.felix.gogo.runtime.equinox;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.command.CommandProcessor;
-import org.osgi.service.command.CommandSession;
-import org.osgi.service.command.Converter;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogReaderService;
-import org.osgi.service.log.LogService;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.service.startlevel.StartLevel;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.*;
-
-public class Equinox implements Converter
-{
-    BundleContext context;
-    PackageAdmin pka;
-    LogReaderService lrs;
-    StartLevel sls;
-    final static String[] functions = {"active", "bundles", "close", "diag", "exec", "exit", "fork", "gc", "getprop", "headers", "init", "install", "launch", "log", "packages", "packages", "refresh", "services", "setbsl", "setfwsl", "setibsl", "setprop", "shutdown", "sl", "ss", "start", "status", "stop", "uninstall", "update"};
-
-    protected void activate(ComponentContext context)
-    {
-        this.context = context.getBundleContext();
-        Dictionary<String, Object> dict = new Hashtable<String, Object>();
-        dict.put(CommandProcessor.COMMAND_SCOPE, "eqx");
-        dict.put(CommandProcessor.COMMAND_FUNCTION, functions);
-        this.context.registerService(Converter.class.getName(), this, dict);
-    }
-
-    BundleContext getContext()
-    {
-        return context;
-    }
-
-    public void setPka(PackageAdmin pka)
-    {
-        this.pka = pka;
-    }
-
-    public void setLrs(LogReaderService lrs)
-    {
-        this.lrs = lrs;
-    }
-
-    public void setSls(StartLevel sls)
-    {
-        this.sls = sls;
-    }
-
-    /**
-     * - Displays unsatisfied constraints for the specified bundle(s).
-     */
-    public void diag()
-    {
-    }
-
-    /*
-     * active - Displays a list of all bundles currently in the ACTIVE state.
-     */
-    public List<Bundle> active()
-    {
-        List<Bundle> result = new ArrayList<Bundle>();
-        Bundle[] bundles = getContext().getBundles();
-        for (Bundle b : bundles)
-        {
-            if (b.getState() == Bundle.ACTIVE)
-            {
-                result.add(b);
-            }
-        }
-        return result;
-    }
-
-    /*
-     * getprop { name } - Displays the system properties with the given name, or
-     * all of them.
-     */
-
-    public Object getprop(CharSequence name)
-    {
-        if (name == null)
-        {
-            return System.getProperties();
-        }
-        else
-        {
-            return System.getProperty(name.toString());
-        }
-    }
-
-    /**
-     * launch - start the OSGi Framework
-     */
-
-    public void launch()
-    {
-        throw new IllegalStateException("Already running");
-    }
-
-    /**
-     * shutdown - shutdown the OSGi Framework
-     */
-    public void shutdown() throws BundleException
-    {
-        getContext().getBundle().stop();
-    }
-
-    /**
-     * close - shutdown and exit
-     */
-    public void close(CommandSession session)
-    {
-        session.close();
-    }
-
-    /**
-     * exit - exit immediately (System.exit)
-     */
-
-    public void exit(int exitValue)
-    {
-        exit(exitValue);
-    }
-
-    /**
-     * gc - perform a garbage collection
-     */
-    public long gc()
-    {
-        Runtime.getRuntime().gc();
-        return Runtime.getRuntime().freeMemory();
-    }
-
-    /**
-     * init - uninstall all bundles
-     */
-
-    public void init() throws Exception
-    {
-        Bundle bundles[] = getContext().getBundles();
-        for (Bundle b : bundles)
-        {
-            if (b.getBundleId() != 0)
-            {
-                b.uninstall();
-            }
-        }
-    }
-
-    /**
-     * setprop <key>=<value> - set the OSGi property
-     */
-    public void setprop(CommandSession session, String key, String value)
-    {
-        session.put(key, value);
-    }
-
-    /**
-     * install - install and optionally start bundle from the given URL
-     *
-     * @throws BundleException
-     */
-
-    public Bundle install(URL url) throws BundleException
-    {
-        return getContext().installBundle(url.toExternalForm());
-    }
-
-    /**
-     * uninstall - uninstall the specified bundle(s)
-     *
-     * @throws BundleException
-     */
-    public void uninstall(Bundle[] bundles) throws BundleException
-    {
-        for (Bundle b : bundles)
-        {
-            b.uninstall();
-        }
-    }
-
-    /**
-     * start - start the specified bundle(s)
-     */
-    public void start(Bundle[] bundles) throws BundleException
-    {
-        for (Bundle b : bundles)
-        {
-            b.start();
-        }
-    }
-
-    /**
-     * stop - stop the specified bundle(s)
-     */
-    public void stop(Bundle[] bundles) throws BundleException
-    {
-        for (Bundle b : bundles)
-        {
-            b.stop();
-        }
-    }
-
-    /**
-     * refresh - refresh the packages of the specified bundles
-     */
-    public void refresh(Bundle[] bundles) throws Exception
-    {
-        if (pka != null)
-        {
-            pka.refreshPackages(bundles);
-        }
-        else
-        {
-            throw new RuntimeException("No PackageAdmin service registered");
-        }
-    }
-
-    /**
-     * update - update the specified bundle(s)
-     */
-    public void update(Bundle[] bundles) throws BundleException
-    {
-        for (Bundle b : bundles)
-        {
-            b.update();
-        }
-    }
-
-    /**
-     * status - display installed bundles and registered services
-     */
-    public List<Object> status() throws Exception
-    {
-        List<Object> status = new ArrayList<Object>();
-        status.addAll(Arrays.asList(getContext().getBundles()));
-        status.addAll(Arrays.asList(getContext().getServiceReferences(null, null)));
-        return status;
-    }
-
-    /**
-     * ss - display installed bundles (short status)
-     */
-    public Bundle[] ss()
-    {
-        return getContext().getBundles();
-    }
-
-    /**
-     * services {filter} - display registered service details
-     */
-    public ServiceReference[] services(String filter) throws Exception
-    {
-        return getContext().getServiceReferences(null, filter);
-    }
-
-    /**
-     * packages {<pkgname>|<id>|<location>} - display imported/exported
-     * package details
-     */
-    public ExportedPackage[] packages(Bundle bundle) throws Exception
-    {
-        if (pka != null)
-        {
-            return pka.getExportedPackages(bundle);
-        }
-        else
-        {
-            throw new RuntimeException("No PackageAdmin service registered");
-        }
-    }
-
-    public ExportedPackage[] packages(String packageName) throws Exception
-    {
-        if (pka != null)
-        {
-            return pka.getExportedPackages(packageName);
-        }
-        return null;
-    }
-
-    /**
-     * bundles - display details for all installed bundles
-     */
-    public Bundle[] bundles()
-    {
-        return ss();
-    }
-
-    /**
-     * bundle (<id>|<location>) - display details for the specified bundle(s)
-     */
-
-    /**
-     * headers (<id>|<location>) - print bundle headers
-     */
-
-    @SuppressWarnings("unchecked")
-    public Dictionary headers(Bundle b, String locale)
-    {
-        return b.getHeaders(locale);
-    }
-
-    /**
-     * log (<id>|<location>) - display log entries
-     */
-
-    @SuppressWarnings("unchecked")
-    public Collection<LogEntry> log(Bundle bundle) throws Exception
-    {
-        if (lrs != null)
-        {
-            return Collections.list((Enumeration<LogEntry>) lrs.getLog());
-        }
-        else
-        {
-            throw new RuntimeException("LogReader not available");
-        }
-    }
-
-    /**
-     * exec <command> - execute a command in a separate process and wait
-     *
-     * @throws IOException
-     */
-
-    public int exec(Object[] args, boolean fork) throws IOException
-    {
-        StringBuffer sb = new StringBuffer();
-        String del = "";
-        for (Object arg : args)
-        {
-            sb.append(del);
-            sb.append(arg);
-            del = " ";
-        }
-        Process p = Runtime.getRuntime().exec(sb.toString());
-        if (fork)
-        {
-            int c;
-            while ((c = p.getInputStream().read()) > 0)
-            {
-                System.out.print(c);
-            }
-        }
-        return p.exitValue();
-    }
-
-    /**
-     * fork <command> - execute a command in a separate process
-     */
-
-    public void fork(Object args[]) throws Exception
-    {
-        exec(args, true);
-    }
-
-    /**
-     * sl {(<id>|<location>)} - display the start level for the specified
-     * bundle, or for the framework if no bundle specified
-     */
-    public int sl(Bundle b) throws Exception
-    {
-        if (sls == null)
-        {
-            throw new RuntimeException("No StartLevel service registered");
-        }
-        if (b == null)
-        {
-            return sls.getStartLevel();
-        }
-        else
-        {
-            return sls.getBundleStartLevel(b);
-        }
-    }
-
-    /**
-     * setfwsl <start level> - set the framework start level
-     */
-    public int setfwsl(int n) throws Exception
-    {
-        if (sls == null)
-        {
-            throw new RuntimeException("No StartLevel service registered");
-        }
-        int old = sls.getStartLevel();
-        sls.setStartLevel(n);
-        return old;
-    }
-
-    /**
-     * setbsl <start level> (<id>|<location>) - set the start level for the
-     * bundle(s)
-     */
-    public int setbsl(Bundle b, int n) throws Exception
-    {
-        if (sls == null)
-        {
-            throw new RuntimeException("No StartLevel service registered");
-        }
-        int old = sls.getBundleStartLevel(b);
-        sls.setBundleStartLevel(b, n);
-        return old;
-    }
-
-    /**
-     * setibsl <start level> - set the initial bundle start level
-     */
-    public int setibsl(int n) throws Exception
-    {
-        if (sls == null)
-        {
-            throw new RuntimeException("No StartLevel service registered");
-        }
-        int old = sls.getInitialBundleStartLevel();
-        sls.setInitialBundleStartLevel(n);
-        return old;
-    }
-
-    public Object convert(Class<?> desiredType, Object in) throws Exception
-    {
-        return null;
-    }
-
-    String getLevel(int index)
-    {
-        switch (index)
-        {
-            case LogService.LOG_DEBUG:
-                return "DEBUG";
-            case LogService.LOG_INFO:
-                return "INFO ";
-            case LogService.LOG_WARNING:
-                return "WARNI";
-            case LogService.LOG_ERROR:
-                return "ERROR";
-            default:
-                return "<" + index + ">";
-        }
-    }
-
-    public CharSequence format(Object target, int level, Converter escape)
-    {
-        if (target instanceof LogEntry)
-        {
-            LogEntry entry = (LogEntry) target;
-            switch (level)
-            {
-                case LINE:
-                    Formatter f = new Formatter();
-                    f.format("%tT %04d %s %s", entry.getTime(), entry.getBundle().getBundleId(), getLevel(entry.getLevel()) + "", entry.getMessage() + "");
-                    return f.toString();
-
-                case PART:
-                    Formatter f2 = new Formatter();
-                    f2.format("%tT %s", entry.getTime(), entry.getMessage());
-                    return f2.toString();
-            }
-        }
-        return null;
-    }
-    /**
-     * profilelog - Display & flush the profile log messages
-     */
-
-}
diff --git a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java
index 75bdcf6..e968740 100644
--- a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java
+++ b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java
@@ -26,7 +26,6 @@
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.command.Converter;
-import org.osgi.service.component.ComponentContext;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.service.threadio.ThreadIO;
 
@@ -35,16 +34,6 @@
     Bundle bundle;
     OSGiCommands commands;
 
-    protected void activate(ComponentContext context) throws Exception
-    {
-        this.bundle = context.getBundleContext().getBundle();
-        if (threadIO == null)
-        {
-            threadIO = (ThreadIO) context.locateService("x");
-        }
-        start();
-    }
-
     public void start() throws Exception
     {
         commands = new OSGiCommands(bundle);
@@ -84,11 +73,6 @@
         }
     }
 
-    protected void deactivate(ComponentContext context)
-    {
-        System.out.println("Deactivating");
-    }
-
     public Object get(String name)
     {
         if (bundle.getBundleContext() != null)
diff --git a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
index e479bac..3bc61a5 100644
--- a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
+++ b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
@@ -235,7 +235,7 @@
                 {
                     return false;
                 }
-                return seq;
+                return result;
         }
     }
 
diff --git a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
index 6d6e7cd..44a5153 100644
--- a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
+++ b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
@@ -28,7 +28,7 @@
     int current = 0;
     CharSequence text;
     boolean escaped;
-    static final String SPECIAL = "<;|{[\"'$'`(=";
+    static final String SPECIAL = "<;|{[\"'$`(=";
 
     public Parser(CharSequence program)
     {
@@ -71,24 +71,29 @@
 
     char peek()
     {
+        return peek(false);
+    }
+
+    char peek(boolean increment)
+    {
         escaped = false;
         if (eof())
         {
             return 0;
         }
 
-        char c = text.charAt(current);
+        int last = current;
+        char c = text.charAt(current++);
 
         if (c == '\\')
         {
             escaped = true;
-            ++current;
             if (eof())
             {
                 throw new RuntimeException("Eof found after \\"); // derek
             }
 
-            c = text.charAt(current);
+            c = text.charAt(current++);
 
             switch (c)
             {
@@ -113,12 +118,16 @@
                     break;
                 case 'u':
                     c = unicode();
+                    current += 4;
                     break;
                 default:
                     // We just take the next character literally
                     // but have the escaped flag set, important for {},[] etc
             }
         }
+        if (!increment) {
+            current = last;
+        }
         return c;
     }
 
@@ -200,7 +209,6 @@
                 }
                 next();
             }
-
             return text.subSequence(start, current);
         }
         else
@@ -215,59 +223,45 @@
 
         int start = current;
         char c = next();
-        switch (c)
-        {
-            case '{':
-                return text.subSequence(start, find('}', '{'));
-            case '(':
-                return text.subSequence(start, find(')', '('));
-            case '[':
-                return text.subSequence(start, find(']', '['));
-            case '"':
-                return text.subSequence(start + 1, quote('"'));
-            case '\'':
-                return text.subSequence(start + 1, quote('\''));
-            case '<':
-                return text.subSequence(start, find('>', '<'));
-            case '$':
-                value();
-                return text.subSequence(start, current);
-        }
-
-        if (Character.isJavaIdentifierPart(c))
-        {
-            // Some identifier or number
-            while (!eof())
+        if (!escaped) {
+            switch (c)
             {
-                c = peek();
-                if (c != ':' && !Character.isJavaIdentifierPart(c) && c != '.')
-                {
-                    break;
-                }
-                next();
-            }
-        }
-        else
-        {
-            // Operator, repeat while in operator class
-            while (!eof())
-            {
-                c = peek();
-                if (Character.isWhitespace(c) || Character.isJavaIdentifierPart(c))
-                {
-                    break;
-                }
+                case '{':
+                    return text.subSequence(start, find('}', '{'));
+                case '(':
+                    return text.subSequence(start, find(')', '('));
+                case '[':
+                    return text.subSequence(start, find(']', '['));
+                case '"':
+                    return text.subSequence(start + 1, quote('"'));
+                case '\'':
+                    return text.subSequence(start + 1, quote('\''));
+                case '<':
+                    return text.subSequence(start, find('>', '<'));
+                case '$':
+                    value();
+                    return text.subSequence(start, current);
+                case '=':
+                    return text.subSequence(start, current);
             }
         }
 
+        // Some identifier or number
+        while (!eof())
+        {
+            c = peek();
+            if ((!escaped && SPECIAL.indexOf(c) >= 0) || Character.isWhitespace(c))
+            {
+                break;
+            }
+            next();
+        }
         return text.subSequence(start, current);
     }
 
     char next()
     {
-        char c = peek();
-        current++;
-        return c;
+        return peek(true);
     }
 
     char unicode()
diff --git a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java
index b9cab7a..2f15984 100644
--- a/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java
+++ b/gogo/gogo.runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java
@@ -19,7 +19,6 @@
 // DWB20: ThreadIO should check and reset IO if something (e.g. jetty) overrides
 package org.apache.felix.gogo.runtime.threadio;
 
-import org.osgi.service.component.ComponentContext;
 import org.osgi.service.threadio.ThreadIO;
 
 import java.io.InputStream;
@@ -34,23 +33,6 @@
     ThreadInputStream in = new ThreadInputStream(System.in);
     ThreadLocal<Marker> current = new ThreadLocal<Marker>();
 
-    protected void activate(ComponentContext context)
-    {
-        start();
-    }
-
-    protected void deactivate()
-    {
-        stop();
-    }
-
-    public void stop()
-    {
-        System.setErr(err.dflt);
-        System.setOut(out.dflt);
-        System.setIn(in.dflt);
-    }
-
     public void start()
     {
         if (System.out instanceof ThreadPrintStream)
@@ -62,6 +44,13 @@
         System.setErr(err);
     }
 
+    public void stop()
+    {
+        System.setErr(err.dflt);
+        System.setOut(out.dflt);
+        System.setIn(in.dflt);
+    }
+
     private void checkIO()
     {    // derek
         if (System.in != in)
diff --git a/gogo/gogo.runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java b/gogo/gogo.runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
index aea28f1..0aa294c 100644
--- a/gogo/gogo.runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
+++ b/gogo/gogo.runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
@@ -35,6 +35,15 @@
 {
     int beentheredonethat = 0;
 
+    public void testScope() throws Exception
+    {
+        Context c= new Context();
+        c.addCommand("echo", this);
+        c.addCommand("capture", this);
+        assertEquals("$a", c.execute("test:echo \\$a | capture"));
+        assertEquals("file://poo", c.execute("test:echo file://poo|capture"));
+    }
+
     public void testPipe() throws Exception
     {
         Context c = new Context();
@@ -98,6 +107,7 @@
         CharSequence cs = parser.messy();
         assertEquals("a|b;c", cs.toString());
         assertEquals("a|b;c", new Parser(cs).unescape());
+        assertEquals("$a", new Parser("\\$a").unescape());
     }