You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ma...@apache.org on 2008/11/25 01:09:57 UTC

svn commit: r720360 - in /felix/trunk/dependencymanager.shell: pom.xml src/main/java/org/apache/felix/dependencymanager/shell/Activator.java src/main/java/org/apache/felix/dependencymanager/shell/DMCommand.java

Author: marrs
Date: Mon Nov 24 16:09:57 2008
New Revision: 720360

URL: http://svn.apache.org/viewvc?rev=720360&view=rev
Log:
Added some extra options after feedback from initial users.

Modified:
    felix/trunk/dependencymanager.shell/pom.xml
    felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/Activator.java
    felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/DMCommand.java

Modified: felix/trunk/dependencymanager.shell/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager.shell/pom.xml?rev=720360&r1=720359&r2=720360&view=diff
==============================================================================
--- felix/trunk/dependencymanager.shell/pom.xml (original)
+++ felix/trunk/dependencymanager.shell/pom.xml Mon Nov 24 16:09:57 2008
@@ -65,7 +65,7 @@
             <Bundle-SymbolicName>org.apache.felix.dependencymanager.shell</Bundle-SymbolicName>
             <Bundle-Activator>org.apache.felix.dependencymanager.shell.Activator</Bundle-Activator>
             <Bundle-Name>Apache Felix Dependency Manager Shell</Bundle-Name>
-            <Bundle-Description>Shell commands for the dependency manager.</Bundle-Description>
+            <Bundle-Description>Shell command for the dependency manager.</Bundle-Description>
             <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
           </instructions>
         </configuration>

Modified: felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/Activator.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/Activator.java?rev=720360&r1=720359&r2=720360&view=diff
==============================================================================
--- felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/Activator.java (original)
+++ felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/Activator.java Mon Nov 24 16:09:57 2008
@@ -1,3 +1,21 @@
+/*
+ * 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.dependencymanager.shell;
 
 import org.apache.felix.shell.Command;
@@ -5,6 +23,11 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
+/**
+ * Bundle activator for the dependency manager shell command.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
 public class Activator implements BundleActivator {
     private ServiceRegistration m_serviceRegistration;
 

Modified: felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/DMCommand.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/DMCommand.java?rev=720360&r1=720359&r2=720360&view=diff
==============================================================================
--- felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/DMCommand.java (original)
+++ felix/trunk/dependencymanager.shell/src/main/java/org/apache/felix/dependencymanager/shell/DMCommand.java Mon Nov 24 16:09:57 2008
@@ -1,17 +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.felix.dependencymanager.shell;
 
 import java.io.PrintStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.StringTokenizer;
 
 import org.apache.felix.dependencymanager.ServiceComponent;
 import org.apache.felix.dependencymanager.ServiceComponentDependency;
 import org.apache.felix.shell.Command;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
+/**
+ * Shell command for showing all services and dependencies that are managed
+ * by the dependency manager.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
 public class DMCommand implements Command {
+    private static final BundleIdSorter SORTER = new BundleIdSorter();
     private final BundleContext m_context;
 
     public DMCommand(BundleContext context) {
@@ -19,47 +47,160 @@
     }
 
     public void execute(String line, PrintStream out, PrintStream err) {
-        // lookup all dependency manager service components
-        try {
-            ServiceReference[] references = m_context.getServiceReferences(ServiceComponent.class.getName(), null);
-            // show their state
-            if (references != null) {
-                Arrays.sort(references, new Comparator() {
-                    public int compare(Object o1, Object o2) {
-                        ServiceReference r1 = (ServiceReference) o1;
-                        ServiceReference r2 = (ServiceReference) o2;
-                        long id1 = r1.getBundle().getBundleId();
-                        long id2 = r2.getBundle().getBundleId();
-                        return id1 > id2 ? 1 : -1;
-                    }});
-                for (int i = 0; i < references.length; i++) {
-                    ServiceReference ref = references[i];
-                    ServiceComponent sc = (ServiceComponent) m_context.getService(ref);
-                    if (sc != null) {
-                        String name = sc.getName();
-                        int state = sc.getState();
-                        out.println("[" + ref.getBundle().getBundleId() + "] " + ref.getBundle().getSymbolicName() + " " + name + " " + ServiceComponent.STATE_NAMES[state]);
-                        if (line.indexOf("deps") != -1) {
-                            ServiceComponentDependency[] dependencies = sc.getComponentDependencies();
-                            if (dependencies != null) {
-                                for (int j = 0; j < dependencies.length; j++) {
-                                    ServiceComponentDependency dep = dependencies[j];
-                                    String depName = dep.getName();
-                                    String depType = dep.getType();
-                                    int depState = dep.getState();
-                                    out.println(" " + depName + " " + depType + " " + ServiceComponentDependency.STATE_NAMES[depState]);
+        boolean nodeps = false;
+        boolean notavail = false;
+        boolean compact = false;
+        ArrayList ids = new ArrayList();
+
+        // parse the command line
+        StringTokenizer st = new StringTokenizer(line);
+        if (st.hasMoreTokens()) {
+            st.nextToken();
+            while (st.hasMoreTokens()) {
+                String token = st.nextToken();
+                if ("nodeps".equals(token)) {
+                    nodeps = true;
+                }
+                else if ("notavail".equals(token)) {
+                    notavail = true;
+                }
+                else if ("compact".equals(token)) {
+                    compact = true;
+                }
+                else {
+                    try {
+                        ids.add(Long.valueOf(token));
+                    }
+                    catch (NumberFormatException e) {
+                        // if it's not a number, we abort with an error
+                        err.println("Argument " + token + " is not a valid number.");
+                        return;
+                    }
+                }
+            }
+            // lookup all dependency manager service components
+            try {
+                ServiceReference[] references = m_context.getServiceReferences(ServiceComponent.class.getName(), null);
+                // show their state
+                if (references != null) {
+                    Arrays.sort(references, SORTER);
+                    long lastBundleId = -1;
+                    for (int i = 0; i < references.length; i++) {
+                        ServiceReference ref = references[i];
+                        ServiceComponent sc = (ServiceComponent) m_context.getService(ref);
+                        if (sc != null) {
+                            String name = sc.getName();
+                            int state = sc.getState();
+                            Bundle bundle = ref.getBundle();
+                            long bundleId = bundle.getBundleId();
+                            if (ids.size() == 0 || ids.contains(Long.valueOf(bundleId))) {
+                                if (!notavail || (notavail && sc.getState() == ServiceComponent.STATE_UNREGISTERED)) {
+                                    if (lastBundleId != bundleId) {
+                                        lastBundleId = bundleId;
+                                        if (compact) {
+                                            out.println("[" + bundleId + "] " + compactName(bundle.getSymbolicName()));
+                                        }
+                                        else {
+                                            out.println("[" + bundleId + "] " + bundle.getSymbolicName());
+                                        }
+                                    }
+                                    if (compact) {
+                                        out.print(" " + compactName(name) + " " + compactState(ServiceComponent.STATE_NAMES[state]));
+                                    }
+                                    else {
+                                        out.println("  " + name + " " + ServiceComponent.STATE_NAMES[state]);
+                                    }
+                                    if (!nodeps) {
+                                        ServiceComponentDependency[] dependencies = sc.getComponentDependencies();
+                                        if (dependencies != null && dependencies.length > 0) {
+                                            if (compact) {
+                                                out.print('(');
+                                            }
+                                            for (int j = 0; j < dependencies.length; j++) {
+                                                ServiceComponentDependency dep = dependencies[j];
+                                                String depName = dep.getName();
+                                                String depType = dep.getType();
+                                                int depState = dep.getState();
+                                                if (compact) {
+                                                    if (j > 0) {
+                                                        out.print(' ');
+                                                    }
+                                                    out.print(compactName(depName) + " " + compactState(depType) + " " + compactState(ServiceComponentDependency.STATE_NAMES[depState]));
+                                                }
+                                                else {
+                                                    out.println("    " + depName + " " + depType + " " + ServiceComponentDependency.STATE_NAMES[depState]);
+                                                }
+                                            }
+                                            if (compact) {
+                                                out.print(')');
+                                            }
+                                        }
+                                    }
+                                    if (compact) {
+                                        out.println();
+                                    }
                                 }
                             }
+                            m_context.ungetService(ref);
                         }
                     }
                 }
             }
+            catch (InvalidSyntaxException e) {
+                // very weird since I'm not specifying a filter
+                e.printStackTrace(err);
+            }
         }
-        catch (InvalidSyntaxException e) {
-            // very weird since I'm not specifying a filter
-            e.printStackTrace(err);
+        else {
+            err.println("Invalid command line: " + line);
         }
     }
+    
+    /**
+     * Compact names that look like state strings. State strings consist of
+     * one or more words. Each word will be shortened to the first letter,
+     * all letters concatenated and uppercased.
+     */
+    private String compactState(String input) {
+        StringBuffer output = new StringBuffer();
+        StringTokenizer st = new StringTokenizer(input);
+        while (st.hasMoreTokens()) {
+            output.append(st.nextToken().toUpperCase().charAt(0));
+        }
+        return output.toString();
+    }
+    
+    /**
+     * Compacts names that look like fully qualified class names. All packages
+     * will be shortened to the first letter, except for the last one. So
+     * something like "org.apache.felix.MyClass" will become "o.a.f.MyClass".
+     */
+    private String compactName(String input) {
+        StringBuffer output = new StringBuffer();
+        int lastIndex = 0;
+        for (int i = 0; i < input.length(); i++) {
+            char c = input.charAt(i);
+            switch (c) {
+                case '.':
+                    output.append(input.charAt(lastIndex));
+                    output.append('.');
+                    lastIndex = i + 1;
+                    break;
+                case ' ':
+                case ',':
+                    if (lastIndex < i) {
+                        output.append(input.substring(lastIndex, i));
+                    }
+                    output.append(c);
+                    lastIndex = i + 1;
+                    break;
+            }
+        }
+        if (lastIndex < input.length()) {
+            output.append(input.substring(lastIndex));
+        }
+        return output.toString();
+    }
 
     public String getName() {
         return "dm";
@@ -70,7 +211,16 @@
     }
 
     public String getUsage() {
-        return "dm [deps]";
+        return "dm [nodeps] [notavail] [compact] [<bundleid> ...]";
     }
+}
 
+final class BundleIdSorter implements Comparator {
+    public int compare(Object o1, Object o2) {
+        ServiceReference r1 = (ServiceReference) o1;
+        ServiceReference r2 = (ServiceReference) o2;
+        long id1 = r1.getBundle().getBundleId();
+        long id2 = r2.getBundle().getBundleId();
+        return id1 > id2 ? 1 : -1;
+    }
 }