Author: cschneider
Date: Tue Dec  6 10:58:30 2011
New Revision: 1210856

URL: http://svn.apache.org/viewvc?rev=1210856&view=rev
Log:
KARAF-1077 Moving old service:list to bundle:services. Adding new service:list 
and completer for objectClass

Added:
    
karaf/trunk/shell/bundles/src/main/java/org/apache/karaf/shell/bundles/ListBundleServices.java
   (contents, props changed)
      - copied, changed from r1210508, 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java
    
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/ListServicesTest.java
   (contents, props changed)
      - copied, changed from r1210413, 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java
    
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/TestBundleFactory.java
    
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassCompleter.java
    
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassMatcher.java
    
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServiceNamesTest.java
    
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ObjectClassMatcherTest.java
    
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/TestBundleFactory.java
Modified:
    karaf/trunk/shell/bundles/pom.xml
    
karaf/trunk/shell/bundles/src/main/resources/OSGI-INF/blueprint/shell-bundles.xml
    
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java
    
karaf/trunk/shell/services/src/main/resources/OSGI-INF/blueprint/shell-services.xml
    karaf/trunk/shell/services/src/main/resources/OSGI-INF/bundle.info
    
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java

Modified: karaf/trunk/shell/bundles/pom.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/bundles/pom.xml?rev=1210856&r1=1210855&r2=1210856&view=diff
==============================================================================
--- karaf/trunk/shell/bundles/pom.xml (original)
+++ karaf/trunk/shell/bundles/pom.xml Tue Dec  6 10:58:30 2011
@@ -65,6 +65,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.utils</artifactId>
             <scope>provided</scope>

Copied: 
karaf/trunk/shell/bundles/src/main/java/org/apache/karaf/shell/bundles/ListBundleServices.java
 (from r1210508, 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java)
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/bundles/src/main/java/org/apache/karaf/shell/bundles/ListBundleServices.java?p2=karaf/trunk/shell/bundles/src/main/java/org/apache/karaf/shell/bundles/ListBundleServices.java&p1=karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java&r1=1210508&r2=1210856&rev=1210856&view=diff
==============================================================================
--- 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java
 (original)
+++ 
karaf/trunk/shell/bundles/src/main/java/org/apache/karaf/shell/bundles/ListBundleServices.java
 Tue Dec  6 10:58:30 2011
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.karaf.shell.services;
+package org.apache.karaf.shell.bundles;
 
 import java.util.List;
 
@@ -23,15 +23,14 @@ import org.apache.karaf.shell.commands.C
 import org.apache.karaf.shell.commands.Option;
 import org.apache.karaf.shell.console.OsgiCommandSupport;
 import org.apache.felix.service.command.Function;
-import org.apache.karaf.shell.bundles.BundleSelector;
 import org.apache.karaf.util.ShellUtil;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
-@Command(scope = "service", name = "list", description = "Lists OSGi 
services.")
-public class ListServices extends OsgiCommandSupport {
+@Command(scope = "bundle", name = "services", description = "Lists OSGi 
services per Bundle")
+public class ListBundleServices extends OsgiCommandSupport {
     @Argument(index = 0, name = "ids", description = "The list of bundle 
(identified by IDs or name or name/version) separated by whitespaces", required 
= false, multiValued = true)
     List<String> ids;
 

Propchange: 
karaf/trunk/shell/bundles/src/main/java/org/apache/karaf/shell/bundles/ListBundleServices.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
karaf/trunk/shell/bundles/src/main/resources/OSGI-INF/blueprint/shell-bundles.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/bundles/src/main/resources/OSGI-INF/blueprint/shell-bundles.xml?rev=1210856&r1=1210855&r2=1210856&view=diff
==============================================================================
--- 
karaf/trunk/shell/bundles/src/main/resources/OSGI-INF/blueprint/shell-bundles.xml
 (original)
+++ 
karaf/trunk/shell/bundles/src/main/resources/OSGI-INF/blueprint/shell-bundles.xml
 Tue Dec  6 10:58:30 2011
@@ -43,6 +43,9 @@
             </action>
         </command>
         <command>
+            <action class="org.apache.karaf.shell.bundles.ListBundleServices"/>
+        </command>
+        <command>
             <action class="org.apache.karaf.shell.bundles.Refresh"/>
         </command>
         <command>

Copied: 
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/ListServicesTest.java
 (from r1210413, 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java)
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/ListServicesTest.java?p2=karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/ListServicesTest.java&p1=karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java&r1=1210413&r2=1210856&rev=1210856&view=diff
==============================================================================
--- 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java
 (original)
+++ 
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/ListServicesTest.java
 Tue Dec  6 10:58:30 2011
@@ -1,17 +1,7 @@
-package org.apache.karaf.shell.services;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
+package org.apache.karaf.shell.bundles;
 import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
 
 import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
 
 public class ListServicesTest {
 
@@ -19,66 +9,31 @@ public class ListServicesTest {
         
     }
     
-    ServiceReference<?> createServiceRef(String ... objectClass) {
-        ServiceReference<?> serviceRef = createMock(ServiceReference.class);
-        
expect(serviceRef.getProperty("objectClass")).andReturn(objectClass).atLeastOnce();
-        expect(serviceRef.getPropertyKeys()).andReturn(new 
String[]{"objectClass"});
-        replay(serviceRef);
-        return serviceRef;
-    }
-    
-    Bundle createBundle(long id, String name, ServiceReference<?>[] 
providedServices, ServiceReference<?>[] usedServices) {
-        Bundle bundle = createMock(Bundle.class);
-        expect(bundle.getRegisteredServices()).andReturn(providedServices);
-        expect(bundle.getServicesInUse()).andReturn(usedServices);
-        expect(bundle.getBundleId()).andReturn(id);
-        Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(Constants.BUNDLE_NAME, name);
-        expect(bundle.getHeaders()).andReturn(headers).atLeastOnce();
-        replay(bundle);
-        return bundle;
-    }
-    
-    private Bundle[] createBundles() {
-        Bundle bundle1 = createBundle(1, "ABundle", new 
ServiceReference<?>[]{createServiceRef("org.example.MyService")}, new 
ServiceReference<?>[]{});
-        Bundle bundle2 = createBundle(2, "AnotherBundle", new 
ServiceReference<?>[]{}, new 
ServiceReference<?>[]{createServiceRef("org.example.MyService")});
-        return new Bundle[] { bundle1, bundle2 };
-    }
-    
-    private BundleContext createBundleContext() {
-        BundleContext bundleContext = createMock(BundleContext.class);
-        Bundle[] bundles = createBundles();
-        expect(bundleContext.getBundle(0)).andReturn(null);
-        expect(bundleContext.getBundles()).andReturn(bundles);
-        expect(bundleContext.getBundle(1)).andReturn(bundles[0]);
-        expect(bundleContext.getBundle(2)).andReturn(bundles[1]);
-        replay(bundleContext);
-        return bundleContext;
-    }
-
-    
     @Test
     public void listAllShort() throws Exception {
-        ListServices listServices = new ListServices();
-        listServices.setBundleContext(createBundleContext());
+        System.out.println("listAllShort");
+        ListBundleServices listServices = new ListBundleServices();
+        listServices.setBundleContext(new 
TestBundleFactory().createBundleContext());
         listServices.doExecute();
     }
 
     
     @Test
     public void listAllLong() throws Exception {
-        ListServices listServices = new ListServices();
+        System.out.println("listAllLong");
+        ListBundleServices listServices = new ListBundleServices();
         listServices.ids = Arrays.asList(new String[]{"1", "2"});
-        listServices.setBundleContext(createBundleContext());
+        listServices.setBundleContext(new 
TestBundleFactory().createBundleContext());
         listServices.doExecute();
     }
-    
+
     @Test
     public void listAllLongServiceUse() throws Exception {
-        ListServices listServices = new ListServices();
+        System.out.println("listAllLongServicesUse");
+        ListBundleServices listServices = new ListBundleServices();
         listServices.ids = Arrays.asList(new String[]{"1", "2"});
         listServices.inUse = true;
-        listServices.setBundleContext(createBundleContext());
+        listServices.setBundleContext(new 
TestBundleFactory().createBundleContext());
         listServices.doExecute();
     }
 

Propchange: 
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/ListServicesTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/TestBundleFactory.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/TestBundleFactory.java?rev=1210856&view=auto
==============================================================================
--- 
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/TestBundleFactory.java
 (added)
+++ 
karaf/trunk/shell/bundles/src/test/java/org/apache/karaf/shell/bundles/TestBundleFactory.java
 Tue Dec  6 10:58:30 2011
@@ -0,0 +1,88 @@
+package org.apache.karaf.shell.bundles;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class TestBundleFactory {
+    ServiceReference<?> createServiceRef(Object ... keyProp) {
+        ServiceReference<?> serviceRef = createMock(ServiceReference.class);
+        if (keyProp.length % 2 != 0) {
+            throw new IllegalArgumentException("");
+        }
+        Hashtable<String, Object> keyPropMap = new Hashtable<String, Object>();
+        int c = 0;
+        while (c < keyProp.length) {
+            String key = (String)keyProp[c++];
+            Object value = (Object)keyProp[c++];
+            keyPropMap.put(key, value);
+            expect(serviceRef.getProperty(key)).andReturn(value).anyTimes();
+        }
+        
expect(serviceRef.getPropertyKeys()).andReturn(Collections.list(keyPropMap.keys()).toArray(new
 String[]{})).anyTimes();
+        return serviceRef;
+    }
+    
+    Bundle createBundle(long id, String name) {
+        Bundle bundle = createMock(Bundle.class);
+        expect(bundle.getBundleId()).andReturn(id).anyTimes();
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(Constants.BUNDLE_NAME, name);
+        expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+        return bundle;
+    }
+    
+    private Bundle[] createBundles() {
+        Bundle bundle1 = createBundle(1, "Bundle A");
+        Bundle bundle2 = createBundle(2, "Bundle B");
+        Bundle bundle3 = createBundle(3, "Bundle C");
+
+        ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new 
String[]{"org.example.MyService"},
+            "key1", "value1");
+        ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new 
String[]{"org.example.OtherService"}, "key2", 1);
+
+        addRegisteredServices(bundle1, ref1, ref2);
+        addRegisteredServices(bundle2, ref2);
+        expect(bundle3.getRegisteredServices()).andReturn(null).anyTimes();
+
+        expect(bundle1.getServicesInUse()).andReturn(null).anyTimes();
+        addUsedServices(bundle2, ref1);
+        addUsedServices(bundle3, ref1, ref2);
+        
+        expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, 
bundle3}).anyTimes();
+        expect(ref2.getUsingBundles()).andReturn(new 
Bundle[]{bundle3}).anyTimes();
+
+        replay(bundle1, bundle2, bundle3, ref1, ref2);
+        return new Bundle[] { bundle1, bundle2, bundle3 };
+    }
+    
+    private void addUsedServices(Bundle bundle, ServiceReference<?> ... refs) {
+        expect(bundle.getServicesInUse()).andReturn(refs).anyTimes();
+    }
+    
+    private void addRegisteredServices(Bundle bundle, ServiceReference<?> ... 
refs) {
+        expect(bundle.getRegisteredServices()).andReturn(refs).anyTimes();
+        for (ServiceReference<?> ref : refs) {
+            expect(ref.getBundle()).andReturn(bundle);
+        }
+    }
+
+    public BundleContext createBundleContext() {
+        BundleContext bundleContext = createMock(BundleContext.class);
+        Bundle[] bundles = createBundles();
+        expect(bundleContext.getBundles()).andReturn(bundles).anyTimes();
+        expect(bundleContext.getBundle(0)).andReturn(null).anyTimes();
+        expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes();
+        expect(bundleContext.getBundle(2)).andReturn(bundles[1]).anyTimes();
+        replay(bundleContext);
+        return bundleContext;
+    }
+}

Modified: 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java?rev=1210856&r1=1210855&r2=1210856&view=diff
==============================================================================
--- 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java
 (original)
+++ 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ListServices.java
 Tue Dec  6 10:58:30 2011
@@ -16,88 +16,110 @@
  */
 package org.apache.karaf.shell.services;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import org.apache.felix.service.command.Function;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.apache.karaf.shell.commands.Option;
 import org.apache.karaf.shell.console.OsgiCommandSupport;
-import org.apache.felix.service.command.Function;
-import org.apache.karaf.shell.bundles.BundleSelector;
 import org.apache.karaf.util.ShellUtil;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
 @Command(scope = "service", name = "list", description = "Lists OSGi 
services.")
 public class ListServices extends OsgiCommandSupport {
-    @Argument(index = 0, name = "ids", description = "The list of bundle 
(identified by IDs or name or name/version) separated by whitespaces", required 
= false, multiValued = true)
-    List<String> ids;
-
+    @Argument(index = 0, name = "objectClass", description = "Name of service 
objectClass to filter for", required = false, 
+        multiValued = false)
+    String objectClass;
+    
     @Option(name = "-a", aliases = {}, description = "Shows all services. (By 
default Karaf commands are hidden)", required = false, multiValued = false)
     boolean showAll;
-
-    @Option(name = "-u", aliases = {}, description = "Shows the services each 
bundle uses. (By default the provided services are shown)", required = false, 
multiValued = false)
-    boolean inUse;
+    
+    @Option(name = "-n", aliases = {}, description = "Shows only service class 
names", required = false, multiValued = false)
+    boolean onlyNames;
 
     protected Object doExecute() throws Exception {
-        BundleContext bundleContext = getBundleContext();
-        BundleSelector selector = new BundleSelector(bundleContext, session);
-        List<Bundle> bundles = selector.selectBundles(ids, true);
-        if (bundles == null || bundles.isEmpty()) {
-            Bundle[] allBundles = bundleContext.getBundles();
-            printBundles(allBundles, false);
-        } else {
-            printBundles(bundles.toArray(new Bundle[]{}), true);
+        if (onlyNames) {
+            listNames();
+            return null;
         }
-        return null;
-    }
-
-    private void printBundles(Bundle[] bundles, boolean showProperties) {
+        List<ServiceReference<?>> serviceRefs = new 
ArrayList<ServiceReference<?>>();
+        Bundle[] bundles = getBundleContext().getBundles();
         for (Bundle bundle : bundles) {
-            ServiceReference<?>[] refs = (inUse) ? bundle.getServicesInUse() : 
bundle.getRegisteredServices();
-            printServices(bundle, refs, showProperties);
+            ServiceReference<?>[] services = bundle.getRegisteredServices();
+            if (services != null) {
+                for (ServiceReference<?> ref : services) {
+                    String[] objectClasses = 
(String[])ref.getProperty(Constants.OBJECTCLASS);
+                    if (objectClass == null || 
ObjectClassMatcher.matchesAtLeastOneName(objectClasses, objectClass)) {
+                        serviceRefs.add(ref);
+                    }
+                } 
+            }
         }
+        
+        Collections.sort(serviceRefs, new ServiceClassComparator());
+        
+        for (ServiceReference<?> serviceRef : serviceRefs) {
+            if 
(!isCommand((String[])serviceRef.getProperty(Constants.OBJECTCLASS))) {
+                printServiceRef(serviceRef);
+            }
+        }
+        return null;
     }
     
-    private void printServices(Bundle bundle, ServiceReference<?>[] refs, 
boolean showProperties) {
-        boolean headerPrinted = false;
-        boolean needSeparator = false;
-        
-        if (refs == null) {
-            return;
+    private void listNames() {
+        Map<String, Integer> serviceNames = 
getServiceNamesMap(getBundleContext());
+        ArrayList<String> serviceNamesList = new 
ArrayList<String>(serviceNames.keySet());
+        Collections.sort(serviceNamesList);
+        for (String name : serviceNamesList) {
+            System.out.println(name + " (" + serviceNames.get(name) + ")");
         }
-
-        for (ServiceReference<?> serviceRef : refs) {
-            String[] objectClass = (String[]) 
serviceRef.getProperty(Constants.OBJECTCLASS);
-
-            boolean print = showAll || !isCommand(objectClass);
-
-            // Print header if we have not already done so.
-            if (!headerPrinted) {
-                headerPrinted = true;
-                System.out.println("");
-                String title = ShellUtil.getBundleName(bundle) + ((inUse) ? " 
uses:" : " provides:");
-                System.out.println(title);
-                System.out.println(ShellUtil.getUnderlineString(title));
-            }
-
-            if (print) {
-                // Print service separator if necessary.
-                if (needSeparator && showProperties) {
-                    System.out.println("----");
-                }
-
-                if (showProperties) {
-                    printProperties(serviceRef);
-                } else {
-                    System.out.println(ShellUtil.getValueString(objectClass));
+    }
+    
+    public static Map<String, Integer> getServiceNamesMap(BundleContext 
bundleContext) {
+        Map<String, Integer> serviceNames = new HashMap<String, Integer>();
+        Bundle[] bundles = bundleContext.getBundles();
+        for (Bundle bundle : bundles) {
+            ServiceReference<?>[] services = bundle.getRegisteredServices();
+            if (services != null) {
+                for (ServiceReference<?> serviceReference : services) {
+                    String[] names = 
(String[])serviceReference.getProperty(Constants.OBJECTCLASS);
+                    for (String name : names) {
+                        int curCount = (serviceNames.containsKey(name)) ? 
serviceNames.get(name) : 0;
+                        serviceNames.put(name, curCount + 1);
+                    }
                 }
+            }
+        }
+        return serviceNames;
+    }
 
-                needSeparator = true;
+    private void printServiceRef(ServiceReference<?> serviceRef) {
+        String[] objectClass = (String[]) 
serviceRef.getProperty(Constants.OBJECTCLASS);
+        String serviceClasses = ShellUtil.getValueString(objectClass);
+        System.out.println(serviceClasses);
+        System.out.println(ShellUtil.getUnderlineString(serviceClasses));
+        
+        printProperties(serviceRef);
+        
+        String bundleName = ShellUtil.getBundleName(serviceRef.getBundle());
+        System.out.println("Provided by : ");
+        System.out.println(" " + bundleName);
+        if (serviceRef.getUsingBundles() != null) {
+        System.out.println("Used by: ");
+            for (Bundle bundle : serviceRef.getUsingBundles()) {
+                System.out.println(" " + ShellUtil.getBundleName(bundle));
             }
         }
+        System.out.println();
     }
 
     private boolean isCommand(String[] objectClasses) {
@@ -111,8 +133,19 @@ public class ListServices extends OsgiCo
 
     private void printProperties(ServiceReference<?> serviceRef) {
         for (String key : serviceRef.getPropertyKeys()) {
-            System.out.println(key + " = " + 
ShellUtil.getValueString(serviceRef.getProperty(key)));
+            if (!Constants.OBJECTCLASS.equals(key)) {
+                System.out.println(" " + key + " = " + 
ShellUtil.getValueString(serviceRef.getProperty(key)));
+            }
         }
     }
 
+    public final class ServiceClassComparator implements 
Comparator<ServiceReference<?>> {
+        @Override
+        public int compare(ServiceReference<?> o1, ServiceReference<?> o2) {
+            String[] classes1 = 
(String[])o1.getProperty(Constants.OBJECTCLASS);
+            String[] classes2 = 
(String[])o2.getProperty(Constants.OBJECTCLASS);
+            return classes1[0].compareTo(classes2[0]);
+        }
+    }
+    
 }

Added: 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassCompleter.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassCompleter.java?rev=1210856&view=auto
==============================================================================
--- 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassCompleter.java
 (added)
+++ 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassCompleter.java
 Tue Dec  6 10:58:30 2011
@@ -0,0 +1,54 @@
+/*
+ * 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.karaf.shell.services;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.osgi.framework.BundleContext;
+
+public class ObjectClassCompleter implements Completer {
+
+    private final StringsCompleter delegate = new StringsCompleter();
+
+    private BundleContext context;
+
+    public void setContext(BundleContext context) {
+        this.context = context;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public int complete(final String buffer, final int cursor, final List 
candidates) {
+        delegate.getStrings().clear();
+        Map<String, Integer> serviceNamesMap = 
ListServices.getServiceNamesMap(context);
+        Set<String> serviceNames = serviceNamesMap.keySet();
+        for (String name : serviceNames) {
+            delegate.getStrings().add(ObjectClassMatcher.getShortName(name));
+        }
+        delegate.getStrings().addAll(serviceNames);
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+
+
+}

Added: 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassMatcher.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassMatcher.java?rev=1210856&view=auto
==============================================================================
--- 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassMatcher.java
 (added)
+++ 
karaf/trunk/shell/services/src/main/java/org/apache/karaf/shell/services/ObjectClassMatcher.java
 Tue Dec  6 10:58:30 2011
@@ -0,0 +1,43 @@
+/*
+ * 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.karaf.shell.services;
+
+public class ObjectClassMatcher {
+    private ObjectClassMatcher() {
+    }
+    
+    static boolean matchesAtLeastOneName(String[] names, String pattern) {
+        for (String objectClass : names) {
+            if (matchesName(objectClass, pattern)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static boolean matchesName(String name, String pattern) {
+        return name.equals(pattern) || getShortName(name).equals(pattern);
+    }
+    
+    static String getShortName(String name) {
+        int idx = name.lastIndexOf(".");
+        if (idx + 1 > name.length()) {
+            idx = 0;
+        }
+        return name.substring(idx + 1);
+    }
+}

Modified: 
karaf/trunk/shell/services/src/main/resources/OSGI-INF/blueprint/shell-services.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/main/resources/OSGI-INF/blueprint/shell-services.xml?rev=1210856&r1=1210855&r2=1210856&view=diff
==============================================================================
--- 
karaf/trunk/shell/services/src/main/resources/OSGI-INF/blueprint/shell-services.xml
 (original)
+++ 
karaf/trunk/shell/services/src/main/resources/OSGI-INF/blueprint/shell-services.xml
 Tue Dec  6 10:58:30 2011
@@ -17,15 +17,23 @@
     limitations under the License.
 
 -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
+           default-activation="lazy">
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0";>
         <command>
             <action class="org.apache.karaf.shell.services.ListServices"/>
+            <completers>
+                <ref component-id="objectClassCompleter" />
+                <null/>
+            </completers>
         </command>
         <command>
             <action class="org.apache.karaf.shell.services.Wait"/>
         </command>
     </command-bundle>
 
+    <bean id="objectClassCompleter" 
class="org.apache.karaf.shell.services.ObjectClassCompleter">
+        <property name="context" ref="blueprintBundleContext"/>
+    </bean>
 </blueprint>
\ No newline at end of file

Modified: karaf/trunk/shell/services/src/main/resources/OSGI-INF/bundle.info
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/main/resources/OSGI-INF/bundle.info?rev=1210856&r1=1210855&r2=1210856&view=diff
==============================================================================
--- karaf/trunk/shell/services/src/main/resources/OSGI-INF/bundle.info 
(original)
+++ karaf/trunk/shell/services/src/main/resources/OSGI-INF/bundle.info Tue Dec  
6 10:58:30 2011
@@ -12,7 +12,7 @@ h1. Description
 This bundle provides the shell commands to manipulate OSGi services.
 
 The following commands are available:
-* services:list - Gets the list of OSGi services available.
+* services:list - Gets the list of OSGi services available
 * service:wait - Wait for a given OSGi service
 
 h1. See also

Added: 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServiceNamesTest.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServiceNamesTest.java?rev=1210856&view=auto
==============================================================================
--- 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServiceNamesTest.java
 (added)
+++ 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServiceNamesTest.java
 Tue Dec  6 10:58:30 2011
@@ -0,0 +1,34 @@
+/*
+ * 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.karaf.shell.services;
+import org.junit.Test;
+
+public class ListServiceNamesTest {
+
+    public ListServiceNamesTest() {
+        
+    }
+    
+    @Test
+    public void listAll() throws Exception {
+        ListServices listServices = new ListServices();
+        listServices.setBundleContext(new 
TestBundleFactory().createBundleContext());
+        listServices.onlyNames = true;
+        listServices.doExecute();
+    }
+
+}

Modified: 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java?rev=1210856&r1=1210855&r2=1210856&view=diff
==============================================================================
--- 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java
 (original)
+++ 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ListServicesTest.java
 Tue Dec  6 10:58:30 2011
@@ -1,86 +1,35 @@
-package org.apache.karaf.shell.services;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class ListServicesTest {
-
-    public ListServicesTest() {
-        
-    }
-    
-    ServiceReference<?> createServiceRef(String ... objectClass) {
-        ServiceReference<?> serviceRef = createMock(ServiceReference.class);
-        
expect(serviceRef.getProperty("objectClass")).andReturn(objectClass).atLeastOnce();
-        expect(serviceRef.getPropertyKeys()).andReturn(new 
String[]{"objectClass"});
-        replay(serviceRef);
-        return serviceRef;
-    }
-    
-    Bundle createBundle(long id, String name, ServiceReference<?>[] 
providedServices, ServiceReference<?>[] usedServices) {
-        Bundle bundle = createMock(Bundle.class);
-        expect(bundle.getRegisteredServices()).andReturn(providedServices);
-        expect(bundle.getServicesInUse()).andReturn(usedServices);
-        expect(bundle.getBundleId()).andReturn(id);
-        Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(Constants.BUNDLE_NAME, name);
-        expect(bundle.getHeaders()).andReturn(headers).atLeastOnce();
-        replay(bundle);
-        return bundle;
-    }
-    
-    private Bundle[] createBundles() {
-        Bundle bundle1 = createBundle(1, "ABundle", new 
ServiceReference<?>[]{createServiceRef("org.example.MyService")}, new 
ServiceReference<?>[]{});
-        Bundle bundle2 = createBundle(2, "AnotherBundle", new 
ServiceReference<?>[]{}, new 
ServiceReference<?>[]{createServiceRef("org.example.MyService")});
-        return new Bundle[] { bundle1, bundle2 };
-    }
-    
-    private BundleContext createBundleContext() {
-        BundleContext bundleContext = createMock(BundleContext.class);
-        Bundle[] bundles = createBundles();
-        expect(bundleContext.getBundle(0)).andReturn(null);
-        expect(bundleContext.getBundles()).andReturn(bundles);
-        expect(bundleContext.getBundle(1)).andReturn(bundles[0]);
-        expect(bundleContext.getBundle(2)).andReturn(bundles[1]);
-        replay(bundleContext);
-        return bundleContext;
-    }
-
-    
-    @Test
-    public void listAllShort() throws Exception {
-        ListServices listServices = new ListServices();
-        listServices.setBundleContext(createBundleContext());
-        listServices.doExecute();
-    }
-
-    
-    @Test
-    public void listAllLong() throws Exception {
-        ListServices listServices = new ListServices();
-        listServices.ids = Arrays.asList(new String[]{"1", "2"});
-        listServices.setBundleContext(createBundleContext());
-        listServices.doExecute();
-    }
-    
-    @Test
-    public void listAllLongServiceUse() throws Exception {
-        ListServices listServices = new ListServices();
-        listServices.ids = Arrays.asList(new String[]{"1", "2"});
-        listServices.inUse = true;
-        listServices.setBundleContext(createBundleContext());
-        listServices.doExecute();
-    }
-
-
-}
+/*
+ * 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.karaf.shell.services;
+
+import org.junit.Test;
+
+public class ListServicesTest {
+
+    public ListServicesTest() {
+        
+    }
+    
+    @Test
+    public void listAll() throws Exception {
+        ListServices listServices = new ListServices();
+        listServices.setBundleContext(new 
TestBundleFactory().createBundleContext());
+        listServices.doExecute();
+    }
+    
+
+}

Added: 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ObjectClassMatcherTest.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ObjectClassMatcherTest.java?rev=1210856&view=auto
==============================================================================
--- 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ObjectClassMatcherTest.java
 (added)
+++ 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/ObjectClassMatcherTest.java
 Tue Dec  6 10:58:30 2011
@@ -0,0 +1,45 @@
+/*
+ * 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.karaf.shell.services;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class ObjectClassMatcherTest {
+
+    @Test
+    public void testGetShortName() {
+        Assert.assertEquals("TestClass", 
ObjectClassMatcher.getShortName("org.apache.TestClass"));
+        Assert.assertEquals("", ObjectClassMatcher.getShortName("test."));
+        Assert.assertEquals("TestClass", 
ObjectClassMatcher.getShortName("TestClass"));
+    }
+
+    @Test
+    public void testMatchesName() {
+        
Assert.assertTrue(ObjectClassMatcher.matchesName("org.apache.TestClass", 
"TestClass"));
+        Assert.assertTrue(ObjectClassMatcher.matchesName("TestClass", 
"TestClass"));
+    }
+
+    @Test
+    public void testMatchesAtLeastOneName() {
+        Assert.assertTrue(ObjectClassMatcher.matchesAtLeastOneName(new 
String[]{"other", "org.apache.TestClass"}, "TestClass"));
+        Assert.assertFalse(ObjectClassMatcher.matchesAtLeastOneName(new 
String[]{"TestClass2"}, "TestClass"));
+    }
+
+    
+}

Added: 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/TestBundleFactory.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/TestBundleFactory.java?rev=1210856&view=auto
==============================================================================
--- 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/TestBundleFactory.java
 (added)
+++ 
karaf/trunk/shell/services/src/test/java/org/apache/karaf/shell/services/TestBundleFactory.java
 Tue Dec  6 10:58:30 2011
@@ -0,0 +1,104 @@
+/*
+ * 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.karaf.shell.services;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class TestBundleFactory {
+    ServiceReference<?> createServiceRef(Object ... keyProp) {
+        ServiceReference<?> serviceRef = createMock(ServiceReference.class);
+        if (keyProp.length % 2 != 0) {
+            throw new IllegalArgumentException("");
+        }
+        Hashtable<String, Object> keyPropMap = new Hashtable<String, Object>();
+        int c = 0;
+        while (c < keyProp.length) {
+            String key = (String)keyProp[c++];
+            Object value = (Object)keyProp[c++];
+            keyPropMap.put(key, value);
+            expect(serviceRef.getProperty(key)).andReturn(value).anyTimes();
+        }
+        
expect(serviceRef.getPropertyKeys()).andReturn(Collections.list(keyPropMap.keys()).toArray(new
 String[]{})).anyTimes();
+        return serviceRef;
+    }
+    
+    Bundle createBundle(long id, String name) {
+        Bundle bundle = createMock(Bundle.class);
+        expect(bundle.getBundleId()).andReturn(id).anyTimes();
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(Constants.BUNDLE_NAME, name);
+        expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+        return bundle;
+    }
+    
+    private Bundle[] createBundles() {
+        Bundle bundle1 = createBundle(1, "Bundle A");
+        Bundle bundle2 = createBundle(2, "Bundle B");
+        Bundle bundle3 = createBundle(3, "Bundle C");
+
+        ServiceReference<?> ref1 = createServiceRef(Constants.OBJECTCLASS, new 
String[]{"org.example.MyService"},
+            "key1", "value1");
+        ServiceReference<?> ref2 = createServiceRef(Constants.OBJECTCLASS, new 
String[]{"org.example.OtherService"}, "key2", 1);
+
+        addRegisteredServices(bundle1, ref1, ref2);
+        addRegisteredServices(bundle2, ref2);
+        expect(bundle3.getRegisteredServices()).andReturn(null).anyTimes();
+
+        expect(bundle1.getServicesInUse()).andReturn(null).anyTimes();
+        addUsedServices(bundle2, ref1);
+        addUsedServices(bundle3, ref1, ref2);
+        
+        expect(ref1.getUsingBundles()).andReturn(new Bundle[]{bundle2, 
bundle3}).anyTimes();
+        expect(ref2.getUsingBundles()).andReturn(new 
Bundle[]{bundle3}).anyTimes();
+
+        replay(bundle1, bundle2, bundle3, ref1, ref2);
+        return new Bundle[] { bundle1, bundle2, bundle3 };
+    }
+    
+    private void addUsedServices(Bundle bundle, ServiceReference<?> ... refs) {
+        expect(bundle.getServicesInUse()).andReturn(refs).anyTimes();
+    }
+    
+    private void addRegisteredServices(Bundle bundle, ServiceReference<?> ... 
refs) {
+        expect(bundle.getRegisteredServices()).andReturn(refs).anyTimes();
+        for (ServiceReference<?> ref : refs) {
+            expect(ref.getBundle()).andReturn(bundle);
+        }
+    }
+
+    public BundleContext createBundleContext() {
+        BundleContext bundleContext = createMock(BundleContext.class);
+        Bundle[] bundles = createBundles();
+        expect(bundleContext.getBundles()).andReturn(bundles).anyTimes();
+        expect(bundleContext.getBundle(0)).andReturn(null).anyTimes();
+        expect(bundleContext.getBundle(1)).andReturn(bundles[0]).anyTimes();
+        expect(bundleContext.getBundle(2)).andReturn(bundles[1]).anyTimes();
+        replay(bundleContext);
+        return bundleContext;
+    }
+}


Reply via email to