FELIX-1988 Apply 15.config_render_plugin.patch by Valentin Valchev (thanks)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@911564 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
index 2a1df16..e13332a 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
@@ -791,7 +791,9 @@
                     for ( int i = 0; i < ubList.length; i++ )
                     {
                         Bundle ub = ubList[i];
-                        usingBundles.put( ub.getSymbolicName(), ub );
+                        String name = ub.getSymbolicName();
+                        if (name == null) name = ub.getLocation();
+                        usingBundles.put( name, ub );
                     }
                 }
             }
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
index 27b3ea3..eb8ef9a 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
@@ -31,20 +31,23 @@
 import org.apache.commons.io.IOUtils;
 import org.apache.felix.webconsole.*;
 import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
+import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
 import org.apache.felix.webconsole.internal.Util;
 import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
 
 
-public class ConfigurationRender extends BaseWebConsolePlugin
+/**
+ * ConfigurationRender plugin renders the configuration status - a textual 
+ * representation of the current framework status. The content itself is
+ *  internally generated by the {@link ConfigurationPrinter} plugins.
+ */
+public class ConfigurationRender extends SimpleWebConsolePlugin implements OsgiManagerPlugin
 {
 
-    public static final String LABEL = "config";
-
-    public static final String TITLE = "Configuration Status";
-
-    private static final String[] CSS_REFS =
-        { "res/ui/configurationrender.css" };
+    private static final String LABEL = "config";
+    private static final String TITLE = "Configuration Status";
+    private static final String[] CSS_REFS = { "res/ui/configurationrender.css" };
 
     /**
      * Formatter pattern to generate a relative path for the generation
@@ -57,8 +60,8 @@
     /**
      * Formatter pattern to render the current time of status generation.
      */
-    private static final DateFormat DISPLAY_DATE_FORMAT = SimpleDateFormat.getDateTimeInstance( SimpleDateFormat.LONG,
-        SimpleDateFormat.LONG, Locale.US );
+    private static final DateFormat DISPLAY_DATE_FORMAT = DateFormat.getDateTimeInstance( DateFormat.LONG,
+        DateFormat.LONG, Locale.US );
 
     private ServiceTracker cfgPrinterTracker;
 
@@ -66,20 +69,17 @@
 
     private SortedMap configurationPrinters = new TreeMap();
 
-
-    public String getTitle()
+    /** Default constructor */
+    public ConfigurationRender()
     {
-        return TITLE;
+        super(LABEL, TITLE, CSS_REFS);
     }
 
 
-    public String getLabel()
-    {
-        return LABEL;
-    }
-
-
-    protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+    /**
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    protected final void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
         IOException
     {
         if ( request.getPathInfo().endsWith( ".txt" ) )
@@ -116,55 +116,66 @@
     }
 
 
-    protected String[] getCssReferences()
-    {
-        return CSS_REFS;
-    }
-
-
-    protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
+    /**
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    protected final void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
     {
 
         ConfigurationWriter pw = new HtmlConfigurationWriter( response.getWriter() );
 
-        String appRoot = ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT );
-        Util.script( pw, appRoot, "tw-1.1.js" );
+        Util.startScript(pw);
+        pw.println("$(document).ready(function() {$('#tabs').tabs()} );");
+        Util.endScript(pw);
 
-        Util.startScript( pw );
-        pw.println( "    $(document).ready(function(){" );
-        //                   set up the tabs (still hidden)
-        pw.println( "        $('#cfgprttabs').tabworld({speed:0});" );
-        //                   show the finished tabs
-        pw.println( "        $('#divcfgprttabs').removeClass('divcfgprttabshidden');" );
-        //                   hide the "please wait" message
-        pw.println( "        $('#divcfgprttabswait').addClass('divcfgprttabshidden');" );
-        pw.println( "    });" );
-        Util.endScript( pw );
+        pw.println("<br/><p class=\"statline\">");
 
         final Date currentTime = new Date();
         synchronized ( DISPLAY_DATE_FORMAT )
         {
-            pw.println( "<p>Date: " + DISPLAY_DATE_FORMAT.format( currentTime ) + "</p>" );
+            pw.print("Date: ");
+            pw.println(DISPLAY_DATE_FORMAT.format(currentTime));
         }
 
         synchronized ( FILE_NAME_FORMAT )
         {
             String fileName = FILE_NAME_FORMAT.format( currentTime );
-            pw.println( "<p>Download as <a href='" + fileName + ".txt'>[Single File]</a> or as <a href='" + fileName
-                + ".zip'>[ZIP]</a></p>" );
+            pw.print("<br/>Download as <a href='");
+            pw.print(fileName);
+            pw.print(".txt'>[Single File]</a> or as <a href='");
+            pw.print(fileName);
+            pw.println(".zip'>[ZIP]</a>");
         }
 
-        // display some information while the data is loading
-        pw.println( "<div id='divcfgprttabswait'>Loading status information. Please wait....</div>" );
+        pw.println("</p>"); // status line
 
+        // display some information while the data is loading
         // load the data (hidden to begin with)
-        pw.println( "<div id='divcfgprttabs' class='divcfgprttabshidden'>" );
-        pw.println( "<ul id='cfgprttabs'>" );
+        pw.println("<div id='tabs'> <!-- tabs container -->");
+        pw.println("<ul> <!-- tabs on top -->");
+
+        // print headers only
+        pw.println("<li><a href='#tabs1'>System properties</a></li>");
+        pw.println("<li><a href='#tabs2'>Threads</a></li>");
+
+        // print header for printers
+        Collection printers = getConfigurationPrinters();
+        int id = 3; // skip system properties & threads
+        for (Iterator i = printers.iterator(); i.hasNext();)
+        {
+            final PrinterDesc desc = (PrinterDesc) i.next();
+            pw.print("<li><a href='#tabs");
+            pw.print(id++);
+            pw.print("'>");
+            pw.print(desc.printer.getTitle());
+            pw.print("</a></li>");
+        }
+        pw.println("</ul> <!-- end tabs on top -->");
+        pw.println();
 
         printConfigurationStatus( pw, ConfigurationPrinter.MODE_WEB );
 
-        pw.println( "</ul>" );
-        pw.println( "</div>" );
+        pw.println("</div> <!-- end tabs container -->");
 
         pw.flush();
     }
@@ -172,8 +183,8 @@
 
     private void printConfigurationStatus( ConfigurationWriter pw, final String mode )
     {
-        this.printSystemProperties( pw );
-        this.printThreads( pw );
+        printSystemProperties( pw );
+        printThreads( pw );
 
         for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
         {
@@ -186,7 +197,7 @@
     }
 
 
-    private Collection getConfigurationPrinters()
+    private final Collection getConfigurationPrinters()
     {
         if ( cfgPrinterTracker == null )
         {
@@ -218,7 +229,7 @@
     }
 
 
-    private void printSystemProperties( ConfigurationWriter pw )
+    private static final void printSystemProperties( ConfigurationWriter pw )
     {
         pw.title( "System properties" );
 
@@ -266,7 +277,7 @@
     //    }
 
 
-    private void printConfigurationPrinter( final ConfigurationWriter pw,
+    private static final void printConfigurationPrinter( final ConfigurationWriter pw,
                                             final ConfigurationPrinter cp,
                                             final String mode )
     {
@@ -283,7 +294,21 @@
     }
 
 
-    public static void infoLine( PrintWriter pw, String indent, String label, Object value )
+    /**
+     * Renders an info line - element in the framework configuration. The info line will
+     * look like:
+     * <pre>
+     * label = value
+     * </pre>
+     * 
+     * Optionally it can be indented by a specific string.
+     * 
+     * @param pw the writer to print to
+     * @param indent indentation string
+     * @param label the label data
+     * @param value the data itself.
+     */
+    public static final void infoLine( PrintWriter pw, String indent, String label, Object value )
     {
         if ( indent != null )
         {
@@ -302,7 +327,7 @@
     }
 
 
-    private static String asString( final Object value )
+    private static final String asString( final Object value )
     {
         if ( value == null )
         {
@@ -327,7 +352,7 @@
     }
 
 
-    private void printThreads( ConfigurationWriter pw )
+    private static final void printThreads( ConfigurationWriter pw )
     {
         // first get the root thread group
         ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
@@ -352,7 +377,7 @@
     }
 
 
-    private void printThreadGroup( PrintWriter pw, ThreadGroup group )
+    private static final void printThreadGroup( PrintWriter pw, ThreadGroup group )
     {
         if ( group != null )
         {
@@ -390,7 +415,7 @@
     }
 
 
-    private void printThread( PrintWriter pw, Thread thread )
+    private static final void printThread( PrintWriter pw, Thread thread )
     {
         if ( thread != null )
         {
@@ -435,6 +460,7 @@
 
         // whether or not to filter "<" signs in the output
         private boolean doFilter;
+        private int index = 1; // tab index, needed to generate ID
 
 
         HtmlConfigurationWriter( Writer delegatee )
@@ -445,9 +471,9 @@
 
         public void title( String title )
         {
-            println( "<li>" );
-            println( title );
-            println( "<q>" );
+            print("<div id='tabs");
+            print(index++);
+            println("'>");
             doFilter = true;
         }
 
@@ -455,8 +481,7 @@
         public void end()
         {
             doFilter = false;
-            println( "</q>" );
-            println( "</li>" );
+            println("</div>");
         }