Fixed FELIX-3417 Web Console Inconsistent status text
https://issues.apache.org/jira/browse/FELIX-3417

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1308371 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java
index 05acf2e..72220c3 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java
@@ -16,11 +16,12 @@
  */
 package org.apache.felix.webconsole.internal.compendium;
 
-
 import java.io.PrintWriter;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 import java.util.TreeMap;
@@ -32,7 +33,6 @@
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
 
-
 /**
  * ConfigurationAdminConfigurationPrinter uses the {@link ConfigurationAdmin} service
  * to print the available configurations.
@@ -42,7 +42,6 @@
 
     private static final String TITLE = "Configurations";
 
-
     /**
      * @see org.apache.felix.webconsole.ConfigurationPrinter#getTitle()
      */
@@ -51,79 +50,97 @@
         return TITLE;
     }
 
-
     /**
      * @see org.apache.felix.webconsole.ConfigurationPrinter#printConfiguration(java.io.PrintWriter)
      */
-    public void printConfiguration( PrintWriter pw )
+    public void printConfiguration(PrintWriter pw)
     {
-        ServiceReference sr = getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
-        if ( sr == null )
+        ServiceReference sr = getBundleContext().getServiceReference(
+            ConfigurationAdmin.class.getName());
+        if (sr == null)
         {
-            pw.println( "  Configuration Admin Service not registered" );
+            pw.println("Status: Configuration Admin Service not available");
         }
         else
         {
 
-            ConfigurationAdmin ca = ( ConfigurationAdmin ) getBundleContext().getService( sr );
+            ConfigurationAdmin ca = (ConfigurationAdmin) getBundleContext().getService(sr);
             try
             {
-                Configuration[] configs = ca.listConfigurations( null );
-                if ( configs != null && configs.length > 0 )
-                {
-                    SortedMap sm = new TreeMap();
-                    for ( int i = 0; i < configs.length; i++ )
-                    {
-                        sm.put( configs[i].getPid(), configs[i] );
-                    }
+                Configuration[] configs = ca.listConfigurations(null);
 
-                    for ( Iterator mi = sm.values().iterator(); mi.hasNext(); )
+                if (configs != null && configs.length > 0)
+                {
+                    Set factories = new HashSet();
+                    SortedMap sm = new TreeMap();
+                    for (int i = 0; i < configs.length; i++)
                     {
-                        this.printConfiguration( pw, ( Configuration ) mi.next() );
+                        sm.put(configs[i].getPid(), configs[i]);
+                        String fpid = configs[i].getFactoryPid();
+                        if (null != fpid)
+                        {
+                            factories.add(fpid);
+                        }
+                    }
+                    if (factories.isEmpty())
+                    {
+                        pw.println("Status: " + configs.length
+                            + " configurations available");
+                    }
+                    else
+                    {
+                        pw.println("Status: " + configs.length + " configurations and "
+                            + factories.size() + " factories available");
+                    }
+                    pw.println();
+
+                    for (Iterator mi = sm.values().iterator(); mi.hasNext();)
+                    {
+                        this.printConfiguration(pw, (Configuration) mi.next());
                     }
                 }
                 else
                 {
-                    pw.println( "  No Configurations available" );
+                    pw.println("Status: No Configurations available");
                 }
             }
-            catch ( Exception e )
+            catch (Exception e)
             {
-                // todo or not :-)
+                pw.println("Status: Configuration Admin Service not accessible");
             }
             finally
             {
-                getBundleContext().ungetService( sr );
+                getBundleContext().ungetService(sr);
             }
         }
     }
 
-
-    private void printConfiguration( PrintWriter pw, Configuration config )
+    private void printConfiguration(PrintWriter pw, Configuration config)
     {
-        ConfigurationRender.infoLine( pw, "", "PID", config.getPid() );
+        ConfigurationRender.infoLine(pw, "", "PID", config.getPid());
 
-        if ( config.getFactoryPid() != null )
+        if (config.getFactoryPid() != null)
         {
-            ConfigurationRender.infoLine( pw, "  ", "Factory PID", config.getFactoryPid() );
+            ConfigurationRender.infoLine(pw, "  ", "Factory PID", config.getFactoryPid());
         }
 
-        String loc = ( config.getBundleLocation() != null ) ? config.getBundleLocation() : "Unbound";
-        ConfigurationRender.infoLine( pw, "  ", "BundleLocation", loc );
+        String loc = (config.getBundleLocation() != null) ? config.getBundleLocation()
+            : "Unbound";
+        ConfigurationRender.infoLine(pw, "  ", "BundleLocation", loc);
 
         Dictionary props = config.getProperties();
-        if ( props != null )
+        if (props != null)
         {
             SortedSet keys = new TreeSet();
-            for ( Enumeration ke = props.keys(); ke.hasMoreElements(); )
+            for (Enumeration ke = props.keys(); ke.hasMoreElements();)
             {
-                keys.add( ke.nextElement() );
+                keys.add(ke.nextElement());
             }
 
-            for ( Iterator ki = keys.iterator(); ki.hasNext(); )
+            for (Iterator ki = keys.iterator(); ki.hasNext();)
             {
-                String key = ( String ) ki.next();
-                ConfigurationRender.infoLine( pw, "  ", key, props.get( key ) );
+                String key = (String) ki.next();
+                ConfigurationRender.infoLine(pw, "  ", key, props.get(key));
             }
         }
 
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/PreferencesConfigurationPrinter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/PreferencesConfigurationPrinter.java
index 1898041..cf0b00d 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/PreferencesConfigurationPrinter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/PreferencesConfigurationPrinter.java
@@ -16,7 +16,6 @@
  */
 package org.apache.felix.webconsole.internal.compendium;
 
-
 import java.io.PrintWriter;
 
 import org.apache.felix.webconsole.internal.AbstractConfigurationPrinter;
@@ -26,7 +25,6 @@
 import org.osgi.service.prefs.Preferences;
 import org.osgi.service.prefs.PreferencesService;
 
-
 /**
  * PreferencesConfigurationPrinter uses the {@link Preferences} service
  * to print the store bundle preferences.
@@ -36,7 +34,6 @@
 
     private static final String TITLE = "Preferences";
 
-
     /**
      * @see org.apache.felix.webconsole.ConfigurationPrinter#getTitle()
      */
@@ -45,64 +42,64 @@
         return TITLE;
     }
 
-
     /**
      * @see org.apache.felix.webconsole.ConfigurationPrinter#printConfiguration(java.io.PrintWriter)
      */
-    public void printConfiguration( PrintWriter printWriter )
+    public void printConfiguration(PrintWriter printWriter)
     {
-        ServiceReference sr = getBundleContext().getServiceReference( PreferencesService.class.getName() );
-        if ( sr == null )
+        ServiceReference sr = getBundleContext().getServiceReference(
+            PreferencesService.class.getName());
+        if (sr == null)
         {
-            printWriter.println( "  Preferences Service not registered" );
+            printWriter.println("Status: Preferences Service not available");
         }
         else
         {
-            PreferencesService ps = ( PreferencesService ) getBundleContext().getService( sr );
+            PreferencesService ps = (PreferencesService) getBundleContext().getService(sr);
             try
             {
-                printPreferences( printWriter, ps.getSystemPreferences() );
+                printPreferences(printWriter, ps.getSystemPreferences());
 
                 String[] users = ps.getUsers();
-                for ( int i = 0; users != null && i < users.length; i++ )
+                for (int i = 0; users != null && i < users.length; i++)
                 {
-                    printWriter.println( "*** User Preferences " + users[i] + ":" );
-                    printPreferences( printWriter, ps.getUserPreferences( users[i] ) );
+                    printWriter.println("*** User Preferences " + users[i] + ":");
+                    printPreferences(printWriter, ps.getUserPreferences(users[i]));
                 }
             }
-            catch ( BackingStoreException bse )
+            catch (BackingStoreException bse)
             {
                 // todo or not :-)
             }
             finally
             {
-                getBundleContext().ungetService( sr );
+                getBundleContext().ungetService(sr);
             }
         }
     }
 
-
-    private static final void printPreferences( PrintWriter pw, Preferences prefs ) throws BackingStoreException
+    private static final void printPreferences(PrintWriter pw, Preferences prefs)
+        throws BackingStoreException
     {
 
         final String[] children = prefs.childrenNames();
         final String[] keys = prefs.keys();
 
-        if ( children.length == 0 && keys.length == 0 )
+        if (children.length == 0 && keys.length == 0)
         {
-            pw.println( "No Preferences available" );
+            pw.println("Status: No Preferences available");
         }
         else
         {
-            for ( int i = 0; i < children.length; i++ )
+            for (int i = 0; i < children.length; i++)
             {
-                printPreferences( pw, prefs.node( children[i] ) );
+                printPreferences(pw, prefs.node(children[i]));
             }
 
-            for ( int i = 0; i < keys.length; i++ )
+            for (int i = 0; i < keys.length; i++)
             {
-                ConfigurationRender
-                    .infoLine( pw, null, prefs.absolutePath() + "/" + keys[i], prefs.get( keys[i], null ) );
+                ConfigurationRender.infoLine(pw, null, prefs.absolutePath() + "/"
+                    + keys[i], prefs.get(keys[i], null));
             }
         }
 
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/WireAdminConfigurationPrinter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/WireAdminConfigurationPrinter.java
index acf26d5..c7d8e26 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/WireAdminConfigurationPrinter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/WireAdminConfigurationPrinter.java
@@ -64,7 +64,7 @@
             final Object service = ref != null ? bc.getService(ref) : null;

             if (service == null)

             {

-                pw.println("No Wire Admin service available");

+                pw.println("Status: Wire Admin service not available");

             }

             else

             {

@@ -73,7 +73,7 @@
 

                 if (null == wires || 0 == wires.length)

                 {

-                    pw.println("No wires available");

+                    pw.println("Status: No wires available");

                 }

                 else

                 {

diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesConfigurationPrinter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesConfigurationPrinter.java
index d1abb70..b7cd16c 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesConfigurationPrinter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesConfigurationPrinter.java
@@ -144,7 +144,7 @@
 
         }
         final StringBuffer buffer = new StringBuffer();
-        buffer.append("Bundlelist: ");
+        buffer.append("Status: ");
         appendBundleInfoCount(buffer, "in total", bundles.length);
         if ( active == bundles.length || active + fragments == bundles.length )
         {
@@ -175,7 +175,7 @@
             }
         }
         pw.println(buffer.toString());
-        pw.println("-----------------------------------------------------------------------------");
+        pw.println();
         final Iterator i = bundlesMap.entrySet().iterator();
         while ( i.hasNext() )
         {
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
index 2771c72..512f674 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
@@ -170,7 +170,6 @@
     {
         final int count = services.length;
         final StringBuffer buffer = new StringBuffer();
-        buffer.append( "Services information: " );
         buffer.append( count );
         buffer.append( " service" );
         if ( count != 1 )
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ThreadPrinter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ThreadPrinter.java
index 2fb49d4..8e8c89e 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ThreadPrinter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ThreadPrinter.java
@@ -19,6 +19,7 @@
 package org.apache.felix.webconsole.internal.misc;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 
@@ -30,7 +31,7 @@
     private static final String TITLE = "Threads";
 
     private static final String LABEL = "_threads";
-
+    
     public String getTitle()
     {
         return TITLE;
@@ -45,18 +46,78 @@
             rootGroup = rootGroup.getParent();
         }
 
-        printThreadGroup(pw, rootGroup);
-
         int numGroups = rootGroup.activeGroupCount();
         ThreadGroup[] groups = new ThreadGroup[2 * numGroups];
         rootGroup.enumerate(groups);
         Arrays.sort(groups, ThreadGroupComparator.getInstance());
+
+        printStatusLine(pw, rootGroup, groups);
+        printThreadGroup(pw, rootGroup);
+
         for (int i = 0; i < groups.length; i++)
         {
             printThreadGroup(pw, groups[i]);
         }
     }
 
+    private void printStatusLine(PrintWriter pw, ThreadGroup rootGroup,
+        ThreadGroup[] groups)
+    {
+        int alive = 0;
+        int daemon = 0;
+        int interrupted = 0;
+
+        int threadCount = 0;
+        int threadGroupCount = 0;
+        int threadGroupDestroyed = 0;
+
+        ArrayList/*<ThreadGroup>*/list = new ArrayList(groups.length + 1);
+        list.add(rootGroup);
+        list.addAll(Arrays.asList(groups));
+        for (int j = 0; j < list.size(); j++)
+        {
+            ThreadGroup group = (ThreadGroup) list.get(j);
+            if (null == group)
+            {
+                continue;
+            }
+            threadGroupCount++;
+            if (group.isDestroyed())
+            {
+                threadGroupDestroyed++;
+            }
+
+            Thread[] threads = new Thread[group.activeCount()];
+            group.enumerate(threads);
+            for (int i = 0, size = threads.length; i < size; i++)
+            {
+                Thread thread = threads[i];
+                if (null != thread)
+                {
+                    if (thread.isAlive())
+                    {
+                        alive++;
+                    }
+                    if (thread.isDaemon())
+                    {
+                        daemon++;
+                    }
+                    if (thread.isInterrupted())
+                    {
+                        interrupted++;
+                    }
+                    threadCount++;
+                }
+            }
+        }
+
+        ConfigurationRender.infoLine(pw, "", null, "Status: " + threadCount
+            + " threads (" + alive + " alive/" + daemon + " daemon/" + interrupted
+            + " interrupted) in " + threadGroupCount + " groups ("
+            + threadGroupDestroyed + " destroyed).");
+        pw.println();
+    }
+
     private static final void printThreadGroup(PrintWriter pw, ThreadGroup group)
     {
         if (group != null)
@@ -131,7 +192,8 @@
 
     public int compare(Object thread1, Object thread2)
     {
-        if (null == thread1 || null == thread2) return -1;
+        if (null == thread1 || null == thread2)
+            return -1;
         String t1 = ((Thread) thread1).getName();
         String t2 = ((Thread) thread2).getName();
         if (null == t1)
@@ -165,7 +227,8 @@
 
     public int compare(Object thread1, Object thread2)
     {
-        if (null == thread1 || null == thread2) return -1;
+        if (null == thread1 || null == thread2)
+            return -1;
         String t1 = ((ThreadGroup) thread1).getName();
         String t2 = ((ThreadGroup) thread2).getName();
         if (null == t1)
@@ -180,4 +243,4 @@
         return t1.compareTo(t2);
     }
 
-}
\ No newline at end of file
+}