added scripting support (FELIX-2339).
moved registration of all commands and converters from runtime to shell (FELIX-2328).



git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@943947 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/runtime/pom.xml b/gogo/runtime/pom.xml
index 3955972..d3c87bc 100644
--- a/gogo/runtime/pom.xml
+++ b/gogo/runtime/pom.xml
@@ -24,7 +24,7 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>bundle</packaging>
-    <name>Apache Felix Gogo Shell Runtime</name>
+    <name>Apache Felix Gogo Runtime</name>
     <artifactId>org.apache.felix.gogo.runtime</artifactId>
     <version>0.5.0-SNAPSHOT</version>
     <dependencies>
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Activator.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Activator.java
index 75cee01..b3e6370 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Activator.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Activator.java
@@ -18,11 +18,14 @@
  */
 package org.apache.felix.gogo.runtime;
 
-import org.apache.felix.gogo.runtime.osgi.OSGiCommands;
-import org.apache.felix.gogo.runtime.osgi.OSGiConverters;
-import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
-import org.apache.felix.gogo.runtime.shell.CommandProxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.felix.gogo.runtime.shell.CommandProcessorImpl;
+import org.apache.felix.gogo.runtime.shell.CommandProxy;
+import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
@@ -35,11 +38,6 @@
 import org.osgi.service.threadio.ThreadIO;
 import org.osgi.util.tracker.ServiceTracker;
 
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
 public class Activator implements BundleActivator
 {
     private CommandProcessorImpl processor;
@@ -50,13 +48,10 @@
     private ServiceRegistration processorRegistration;
     private ServiceRegistration threadioRegistration;
     private Map<ServiceReference, ServiceRegistration> felixRegistrations;
-    private OSGiCommands commands;
-    private OSGiConverters converters;
-    private ServiceRegistration convertersRegistration;
     
-    protected CommandProcessorImpl newProcessor(ThreadIO tio)
+    protected CommandProcessorImpl newProcessor(ThreadIO tio, BundleContext context)
     {
-        return new CommandProcessorImpl(threadio);
+        return new CommandProcessorImpl(tio, context);
     }
 
     public void start(final BundleContext context) throws Exception
@@ -66,7 +61,7 @@
         threadioRegistration = context.registerService(ThreadIO.class.getName(),
             threadio, null);
 
-        processor = newProcessor(threadio);
+        processor = newProcessor(threadio, context);
         processorRegistration = context.registerService(CommandProcessor.class.getName(),
             processor, null);
         
@@ -95,17 +90,10 @@
             }
         };
         converterTracker.open();
-
-        // FIXME: optional?
-        commands = new OSGiCommands(context);
-        commands.registerCommands(processor, context.getBundle());
-        converters = new OSGiConverters(context);
-        convertersRegistration = context.registerService(Converter.class.getCanonicalName(), converters, null);
     }
 
     public void stop(BundleContext context) throws Exception
     {
-        convertersRegistration.unregister();
         processorRegistration.unregister();
         threadioRegistration.unregister();
         
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java
deleted file mode 100644
index e1dc8d8..0000000
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.felix.gogo.runtime.osgi;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.regex.Pattern;
-
-import org.apache.felix.gogo.runtime.shell.CommandProcessorImpl;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.command.CommandSession;
-import org.osgi.service.packageadmin.PackageAdmin;
-
-public class OSGiCommands
-{
-    final BundleContext context;
-
-    public OSGiCommands(BundleContext context)
-    {
-        this.context = context;
-    }
-
-    private Object service(String clazz, String filter) throws InvalidSyntaxException
-    {
-        ServiceReference ref[] = context.getServiceReferences(clazz, filter);
-        if (ref != null)
-        {
-            return context.getService(ref[0]);
-        }
-
-        return null;
-    }
-
-    public void registerCommands(CommandProcessorImpl processor, Bundle bundle)
-    {
-        processor.addCommand("osgi", this);
-        processor.addCommand("osgi", new Procedural());
-//        processor.addCommand("osgi", bundle);
-        processor.addCommand("osgi", context, BundleContext.class);
-
-	if (false) {
-        try
-        {
-            processor.addCommand("osgi",
-                this.service(PackageAdmin.class.getName(), null), PackageAdmin.class);
-
-            try
-            {
-                // dynamically load StartLevel to avoid import dependency
-                String sl = "org.osgi.service.startlevel.StartLevel";
-                Class<?> slClass = bundle.loadClass(sl);
-                processor.addCommand("osgi", this.service(sl, null), slClass);
-            }
-            catch (ClassNotFoundException e)
-            {
-            }
-
-            try
-            {
-                // dynamically load PermissionAdmin to avoid import dependency
-                String pa = "org.osgi.service.permissionadmin.PermissionAdmin";
-                Class<?> paClass = bundle.loadClass(pa);
-                processor.addCommand("osgi", this.service(pa, null), paClass);
-            }
-            catch (ClassNotFoundException e)
-            {
-            }
-        }
-        catch (InvalidSyntaxException e)
-        {
-            // can't happen with null filter
-        }
-	}
-    }
-
-    public Bundle bundle(Bundle i)
-    {
-        return i;
-    }
-
-    public void start(Bundle b) throws BundleException
-    {
-        b.start();
-    }
-
-    public void stop(Bundle b) throws BundleException
-    {
-        b.stop();
-    }
-
-    public CharSequence echo(CommandSession session, Object args[])
-    {
-        StringBuilder sb = new StringBuilder();
-        String del = "";
-        for (Object arg : args)
-        {
-            sb.append(del);
-            if (arg != null)
-            {
-                sb.append(arg);
-                del = " ";
-            }
-        }
-        return sb;
-    }
-
-    public Object cat(CommandSession session, File f) throws Exception
-    {
-        File cwd = (File) session.get("_cwd");
-        if (cwd == null)
-        {
-            cwd = new File("").getAbsoluteFile();
-        }
-
-        if (!f.isAbsolute())
-        {
-            f = new File(cwd, f.getPath());
-        }
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        FileInputStream in = new FileInputStream(f);
-        byte[] buffer = new byte[(int) (f.length() % 100000)];
-        int size = in.read(buffer);
-        while (size > 0)
-        {
-            bout.write(buffer, 0, size);
-            size = in.read(buffer);
-        }
-        return new String(bout.toByteArray());
-    }
-
-    public void grep(String match) throws IOException
-    {
-        Pattern p = Pattern.compile(match);
-        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
-        String s = rdr.readLine();
-        while (s != null)
-        {
-            if (p.matcher(s).find())
-            {
-                System.out.println(s);
-            }
-            s = rdr.readLine();
-        }
-    }
-
-}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiConverters.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiConverters.java
deleted file mode 100644
index db9971f..0000000
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiConverters.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * 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.felix.gogo.runtime.osgi;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Arrays;
-import java.util.Formatter;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.command.Converter;
-import org.osgi.service.command.Function;
-import org.osgi.service.startlevel.StartLevel;
-
-public class OSGiConverters implements Converter
-{
-    private final BundleContext context;
-    public OSGiConverters(BundleContext context)
-    {
-        this.context = context;
-    }
-
-    private CharSequence print(Bundle bundle)
-    {
-        // [ ID ] [STATE      ] [ SL ] symname
-        StartLevel sl = null;
-        ServiceReference ref = context.getServiceReference(StartLevel.class.getName());
-        if (ref != null)
-        {
-            sl = (StartLevel) context.getService(ref);
-        }
-
-        if (sl == null)
-        {
-            return String.format("%5d|%-11s|%s (%s)", bundle.getBundleId(),
-                getState(bundle), bundle.getSymbolicName(), bundle.getVersion());
-        }
-
-        int level = sl.getBundleStartLevel(bundle);
-        context.ungetService(ref);
-
-        return String.format("%5d|%-11s|%5d|%s (%s)", bundle.getBundleId(),
-            getState(bundle), level, bundle.getSymbolicName(), bundle.getVersion());
-    }
-
-    private CharSequence print(ServiceReference ref)
-    {
-        StringBuilder sb = new StringBuilder();
-        Formatter f = new Formatter(sb);
-
-        String spid = "";
-        Object pid = ref.getProperty("service.pid");
-        if (pid != null)
-        {
-            spid = pid.toString();
-        }
-
-        f.format("%06d %3s %-40s %s", ref.getProperty("service.id"),
-            ref.getBundle().getBundleId(),
-            getShortNames((String[]) ref.getProperty("objectclass")), spid);
-        return sb;
-    }
-
-    private CharSequence getShortNames(String[] list)
-    {
-        StringBuilder sb = new StringBuilder();
-        String del = "";
-        for (String s : list)
-        {
-            sb.append(del + getShortName(s));
-            del = " | ";
-        }
-        return sb;
-    }
-
-    private CharSequence getShortName(String name)
-    {
-        int n = name.lastIndexOf('.');
-        if (n < 0)
-        {
-            n = 0;
-        }
-        else
-        {
-            n++;
-        }
-        return name.subSequence(n, name.length());
-    }
-
-    private String getState(Bundle bundle)
-    {
-        switch (bundle.getState())
-        {
-            case Bundle.ACTIVE:
-                return "Active";
-
-            case Bundle.INSTALLED:
-                return "Installed";
-
-            case Bundle.RESOLVED:
-                return "Resolved";
-
-            case Bundle.STARTING:
-                return "Starting";
-
-            case Bundle.STOPPING:
-                return "Stopping";
-
-            case Bundle.UNINSTALLED:
-                return "Uninstalled ";
-        }
-        return null;
-    }
-
-    public Bundle bundle(Bundle i)
-    {
-        return i;
-    }
-
-    public Object convert(Class<?> desiredType, final Object in) throws Exception
-    {
-        if (desiredType == Bundle.class)
-        {
-            return convertBundle(in);
-        }
-
-        if (desiredType == ServiceReference.class)
-        {
-            return convertServiceReference(in);
-        }
-
-        if (desiredType == Class.class)
-        {
-            try
-            {
-                return Class.forName(in.toString());
-            }
-            catch (ClassNotFoundException e)
-            {
-                return null;
-            }
-        }
-
-        if (desiredType.isAssignableFrom(String.class) && in instanceof InputStream)
-        {
-            return read(((InputStream) in));
-        }
-
-        if (in instanceof Function && desiredType.isInterface()
-            && desiredType.getDeclaredMethods().length == 1)
-        {
-            return Proxy.newProxyInstance(desiredType.getClassLoader(),
-                new Class[] { desiredType }, new InvocationHandler()
-                {
-                    Function command = ((Function) in);
-
-                    public Object invoke(Object proxy, Method method, Object[] args)
-                        throws Throwable
-                    {
-                        return command.execute(null, Arrays.asList(args));
-                    }
-                });
-        }
-
-        return null;
-    }
-
-    private Object convertServiceReference(Object in) throws InvalidSyntaxException
-    {
-        String s = in.toString();
-        if (s.startsWith("(") && s.endsWith(")"))
-        {
-            ServiceReference refs[] = context.getServiceReferences(null, String.format(
-                "(|(service.id=%s)(service.pid=%s))", in, in));
-            if (refs != null && refs.length > 0)
-            {
-                return refs[0];
-            }
-        }
-
-        ServiceReference refs[] = context.getServiceReferences(null, String.format(
-            "(|(service.id=%s)(service.pid=%s))", in, in));
-        if (refs != null && refs.length > 0)
-        {
-            return refs[0];
-        }
-        return null;
-    }
-
-    private Object convertBundle(Object in)
-    {
-        String s = in.toString();
-        try
-        {
-            long id = Long.parseLong(s);
-            return context.getBundle(id);
-        }
-        catch (NumberFormatException nfe)
-        {
-            // Ignore
-        }
-
-        Bundle bundles[] = context.getBundles();
-        for (Bundle b : bundles)
-        {
-            if (b.getLocation().equals(s))
-            {
-                return b;
-            }
-
-            if (b.getSymbolicName().equals(s))
-            {
-                return b;
-            }
-        }
-
-        return null;
-    }
-
-    public CharSequence format(Object target, int level, Converter converter)
-        throws IOException
-    {
-        if (level == INSPECT && target instanceof InputStream)
-        {
-            return read(((InputStream) target));
-        }
-        if (level == LINE && target instanceof Bundle)
-        {
-            return print((Bundle) target);
-        }
-        if (level == LINE && target instanceof ServiceReference)
-        {
-            return print((ServiceReference) target);
-        }
-        if (level == PART && target instanceof Bundle)
-        {
-            return ((Bundle) target).getSymbolicName();
-        }
-        if (level == PART && target instanceof ServiceReference)
-        {
-            return getShortNames((String[]) ((ServiceReference) target).getProperty("objectclass"));
-        }
-        return null;
-    }
-
-    private CharSequence read(InputStream in) throws IOException
-    {
-        int c;
-        StringBuffer sb = new StringBuffer();
-        while ((c = in.read()) > 0)
-        {
-            if (c >= 32 && c <= 0x7F || c == '\n' || c == '\r')
-            {
-                sb.append((char) c);
-            }
-            else
-            {
-                String s = Integer.toHexString(c).toUpperCase();
-                sb.append("\\");
-                if (s.length() < 1)
-                {
-                    sb.append(0);
-                }
-                sb.append(s);
-            }
-        }
-        return sb;
-    }
-
-}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/Procedural.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/Procedural.java
deleted file mode 100644
index 2ef5325..0000000
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/Procedural.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.felix.gogo.runtime.osgi;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.service.command.CommandSession;
-import org.osgi.service.command.Function;
-
-public class Procedural
-{
-    public String tac() throws IOException
-    {
-        StringWriter sw = new StringWriter();
-        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
-        String s = rdr.readLine();
-        while (s != null)
-        {
-            sw.write(s);
-            s = rdr.readLine();
-        }
-        return sw.toString();
-    }
-    
-    public void each(CommandSession session, Collection<Object> list, Function closure)
-        throws Exception
-    {
-        List<Object> args = new ArrayList<Object>();
-        args.add(null);
-        for (Object x : list)
-        {
-            args.set(0, x);
-            closure.execute(session, args);
-        }
-    }
-
-    public Object _if(CommandSession session, Function condition, Function ifTrue,
-        Function ifFalse) throws Exception
-    {
-        Object result = condition.execute(session, null);
-        if (isTrue(result))
-        {
-            return ifTrue.execute(session, null);
-        }
-        else
-        {
-            if (ifFalse != null)
-            {
-                return ifFalse.execute(session, null);
-            }
-        }
-        return null;
-    }
-
-    public Object _new(String name, Bundle bundle) throws Exception
-    {
-        if (bundle == null)
-        {
-            return Class.forName(name).newInstance();
-        }
-        else
-        {
-            return bundle.loadClass(name).newInstance();
-        }
-    }
-
-    private boolean isTrue(Object result)
-    {
-        if (result == null)
-        {
-            return false;
-        }
-
-        if (result instanceof String && ((String) result).equals(""))
-        {
-            return false;
-        }
-
-        if (result instanceof Boolean)
-        {
-            return ((Boolean) result).booleanValue();
-        }
-
-        return true;
-    }
-}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandProcessorImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandProcessorImpl.java
index e8e3bf7..f0c7e95 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandProcessorImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandProcessorImpl.java
@@ -29,6 +29,7 @@
 import java.util.TreeSet;
 import java.util.Map.Entry;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.service.command.CommandProcessor;
 import org.osgi.service.command.CommandSession;
 import org.osgi.service.command.Converter;
@@ -39,13 +40,15 @@
 {
     protected final Set<Converter> converters = new HashSet<Converter>();
     protected final Map<String, Object> commands = new LinkedHashMap<String, Object>();
+    protected final BundleContext context;
     protected final ThreadIO threadIO;
 
-    public CommandProcessorImpl(ThreadIO tio)
+    public CommandProcessorImpl(ThreadIO tio, BundleContext context)
     {
         threadIO = tio;
-        addCommand("shell", this, "addCommand");
-        addCommand("shell", this, "removeCommand");
+        this.context = context;
+        addCommand("osgi", this, "addCommand");
+        addCommand("osgi", this, "removeCommand");
     }
 
     public CommandSession createSession(InputStream in, PrintStream out, PrintStream err)
@@ -63,12 +66,17 @@
         converters.remove(c);
     }
     
-    public Set<String> getCommands()
+    Set<String> getCommands()
     {
         return commands.keySet();
     }
+    
+    BundleContext getContext()
+    {
+        return context;
+    }
 
-    public Function getCommand(String name, final Object path)
+    Function getCommand(String name, final Object path)
     {
         int colon = name.indexOf(':');
 
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
index 55c78a9..fa09534 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
@@ -35,6 +35,7 @@
 {
     public static final String VARIABLES = ".variables";
     public static final String COMMANDS = ".commands";
+    public static final String CONTEXT = ".context";
     private static final String COLUMN = "%-20s %s\n";
     
     protected InputStream in;
@@ -90,12 +91,17 @@
         {
             return variables.keySet();
         }
-        
+
         if (COMMANDS.equals(name))
         {
             return processor.getCommands();
         }
 
+        if (CONTEXT.equals(name))
+        {
+            return processor.getContext();
+        }
+
         if (variables.containsKey(name))
         {
             return variables.get(name);
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
index 260d1f5..d683fcc 100644
--- a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
@@ -36,7 +36,7 @@
 
     public Context()
     {
-        super(threadio);
+        super(threadio, null);
         session = (CommandSessionImpl) createSession(System.in, System.out, System.err);
     }