FELIX-1993 : Enhance configuration printer support - add mode support for configuration printers.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@902075 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/ConfigurationPrinter.java b/webconsole/src/main/java/org/apache/felix/webconsole/ConfigurationPrinter.java
index 13505f8..9f994e8 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/ConfigurationPrinter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/ConfigurationPrinter.java
@@ -26,6 +26,11 @@
  * The <code>ConfigurationPrinter</code> is a service interface to be used by
  * providers which want to hook into the display of the current configuration
  * of the OSGi framework.
+ * A configuration printer is currently used in three modes: displayed in
+ * a tab of the configuration web console plugin, included in a downloadable
+ * zip of the configuration or a downloadable txt file.
+ * With the {@link #PROPERTY_MODES} property this service can specify when
+ * it should be included. The default mode is {@link #MODE_ALWAYS}.
  */
 public interface ConfigurationPrinter
 {
@@ -34,11 +39,36 @@
      * The service name under which services of this class must be registered
      * to be picked for inclusion in the configuration report.
      */
-    static final String SERVICE = ConfigurationPrinter.class.getName();
+    String SERVICE = ConfigurationPrinter.class.getName();
 
+    /** The default mode - this printer is used in the web console and the zip.
+     * @since 2.2 */
+    String MODE_ALWAYS = "always";
+
+    /** The web mode - this printer is used in the web console.
+     * since 2.2 */
+    String MODE_WEB = "web";
+
+    /** The zip mode - this printer is used in the zip.
+     * @since 2.2 */
+    String MODE_ZIP = "zip";
+
+    /** The txt mode - this printer is used in the txt.
+     * @since 2.2 */
+    String MODE_TXT = "txt";
 
     /**
-     * Returns a human readable title string to be place in front of the configuration
+     * The service property specifying the modes of the printer. If this
+     * property is missing or contains an unknown value, the default
+     * {@link #MODE_ALWAYS} is used.
+     * The value of this property is either a single string or an
+     * array of strings.
+     * @since 2.2
+     */
+    String PROPERTY_MODES = "modes";
+
+    /**
+     * Returns a human readable title string to be placed in front of the configuration
      * report generated by the {@link #printConfiguration(PrintWriter)} method.
      */
     String getTitle();
@@ -50,5 +80,4 @@
      * The <code>printWriter</code> may be flushed but must not be closed.
      */
     void printConfiguration( PrintWriter printWriter );
-
 }
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 6c8ea60..b2ea79c 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
@@ -17,23 +17,9 @@
 package org.apache.felix.webconsole.internal.misc;
 
 
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.text.DateFormat;
-import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.io.*;
+import java.text.*;
+import java.util.*;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
@@ -45,6 +31,7 @@
 import org.apache.felix.webconsole.WebConsoleConstants;
 import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
 import org.apache.felix.webconsole.internal.Util;
+import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
 
 
@@ -98,7 +85,7 @@
         {
             response.setContentType( "text/plain; charset=utf-8" );
             ConfigurationWriter pw = new PlainTextConfigurationWriter( response.getWriter() );
-            printConfigurationStatus( pw );
+            printConfigurationStatus( pw, ConfigurationPrinter.MODE_TXT );
             pw.flush();
         }
         else if ( request.getPathInfo().endsWith( ".zip" ) )
@@ -115,7 +102,7 @@
             zip.setMethod( ZipOutputStream.DEFLATED );
 
             ConfigurationWriter pw = new ZipConfigurationWriter( zip );
-            printConfigurationStatus( pw );
+            printConfigurationStatus( pw, ConfigurationPrinter.MODE_ZIP );
             pw.flush();
 
             zip.finish();
@@ -172,7 +159,7 @@
         pw.println( "<div id='divcfgprttabs' class='divcfgprttabshidden'>" );
         pw.println( "<ul id='cfgprttabs'>" );
 
-        printConfigurationStatus( pw );
+        printConfigurationStatus( pw, ConfigurationPrinter.MODE_WEB );
 
         pw.println( "</ul>" );
         pw.println( "</div>" );
@@ -181,14 +168,18 @@
     }
 
 
-    private void printConfigurationStatus( ConfigurationWriter pw )
+    private void printConfigurationStatus( ConfigurationWriter pw, final String mode )
     {
         this.printSystemProperties( pw );
         this.printThreads( pw );
 
         for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
         {
-            printConfigurationPrinter( pw, ( ConfigurationPrinter ) cpi.next() );
+            final PrinterDesc desc = (PrinterDesc) cpi.next();
+            if ( desc.match(mode) )
+            {
+                printConfigurationPrinter( pw, desc.printer );
+            }
         }
     }
 
@@ -205,14 +196,16 @@
         if ( cfgPrinterTrackerCount != cfgPrinterTracker.getTrackingCount() )
         {
             SortedMap cp = new TreeMap();
-            Object[] services = cfgPrinterTracker.getServices();
-            if ( services != null )
+            ServiceReference[] refs = cfgPrinterTracker.getServiceReferences();
+            if ( refs != null )
             {
-                for ( int i = 0; i < services.length; i++ )
+                for ( int i = 0; i < refs.length; i++ )
                 {
-                    Object srv = services[i];
-                    ConfigurationPrinter cfgPrinter = ( ConfigurationPrinter ) srv;
-                    cp.put( cfgPrinter.getTitle(), cfgPrinter );
+                    ConfigurationPrinter cfgPrinter =  ( ConfigurationPrinter ) cfgPrinterTracker.getService(refs[i]);
+                    if ( cfgPrinter != null )
+                    {
+                        cp.put( cfgPrinter.getTitle(), new PrinterDesc(cfgPrinter, refs[i].getProperty(ConfigurationPrinter.PROPERTY_MODES)) );
+                    }
                 }
             }
             configurationPrinters = cp;
@@ -540,6 +533,80 @@
         }
     }
 
+    private static final class PrinterDesc
+    {
+        private final String[] modes;
+        public final ConfigurationPrinter printer;
+
+        private static final List CUSTOM_MODES = new ArrayList();
+        static
+        {
+            CUSTOM_MODES.add(ConfigurationPrinter.MODE_TXT);
+            CUSTOM_MODES.add(ConfigurationPrinter.MODE_WEB);
+            CUSTOM_MODES.add(ConfigurationPrinter.MODE_ZIP);
+        }
+
+        public PrinterDesc(final ConfigurationPrinter printer, final Object modes)
+        {
+            this.printer = printer;
+            if ( modes == null || !(modes instanceof String || modes instanceof String[]) )
+            {
+                this.modes = null;
+            }
+            else
+            {
+                if ( modes instanceof String )
+                {
+                    if ( CUSTOM_MODES.contains(modes) )
+                    {
+                        this.modes = new String[] {modes.toString()};
+                    }
+                    else
+                    {
+                        this.modes = null;
+                    }
+                }
+                else
+                {
+                    final String[] values = (String[])modes;
+                    boolean valid = values.length > 0;
+                    for(int i=0; i<values.length; i++)
+                    {
+                        if ( !CUSTOM_MODES.contains(values[i]) )
+                        {
+                            valid = false;
+                            break;
+                        }
+                    }
+                    if ( valid)
+                    {
+                        this.modes = values;
+                    }
+                    else
+                    {
+                        this.modes = null;
+                    }
+                }
+            }
+        }
+
+        public boolean match(final String mode)
+        {
+            if ( this.modes == null)
+            {
+                return true;
+            }
+            for(int i=0; i<this.modes.length; i++)
+            {
+                if ( this.modes[i].equals(mode) )
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
     private static class PlainTextConfigurationWriter extends ConfigurationWriter
     {