You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2009/09/08 10:09:21 UTC

svn commit: r812372 - in /felix/trunk/webconsole/src/main: java/org/apache/felix/webconsole/ java/org/apache/felix/webconsole/internal/servlet/ resources/res/ui/

Author: fmeschbe
Date: Tue Sep  8 08:09:20 2009
New Revision: 812372

URL: http://svn.apache.org/viewvc?rev=812372&view=rev
Log:
FELIX-1015 Implement branding for the web console using BrandingPlugin
interface and DefaultBrandingPlugin with configuration file support

Added:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java   (with props)
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java   (with props)
    felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css   (with props)
Modified:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
    felix/trunk/webconsole/src/main/resources/res/ui/admin.css

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java?rev=812372&r1=812371&r2=812372&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java Tue Sep  8 08:09:20 2009
@@ -45,39 +45,6 @@
     /** The name of the request attribute containig the map of FileItems from the POST request */
     public static final String ATTR_FILEUPLOAD = "org.apache.felix.webconsole.fileupload";
 
-    private static final String HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
-        + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"xhtml1-transitional.dtd\">"
-        + "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
-        + "<head>"
-        + "<meta http-equiv=\"Content-Type\" content=\"text/html; utf-8\">"
-        + "<link rel=\"icon\" href=\"{6}/res/imgs/favicon.ico\">"
-        + "<title>{0} - {2}</title>"
-        + "<script src=\"{5}/res/ui/jquery-1.3.2.min.js\" language=\"JavaScript\"></script>"
-        + "<script src=\"{5}/res/ui/jquery.tablesorter-2.0.3.min.js\" language=\"JavaScript\"></script>"
-        + "<script src=\"{5}/res/ui/admin.js\" language=\"JavaScript\"></script>"
-        + "<script src=\"{5}/res/ui/ui.js\" language=\"JavaScript\"></script>"
-        + "<script language=\"JavaScript\">"
-        + "appRoot = \"{5}\";"
-        + "pluginRoot = appRoot + \"/{6}\";"
-        + "</script>"
-        + "<link href=\"{5}/res/ui/admin.css\" rel=\"stylesheet\" type=\"text/css\">"
-        + "</head>"
-        + "<body>"
-        + "<div id=\"main\">"
-        + "<div id=\"lead\">"
-        + "<h1>"
-        + "{0}<br>{2}"
-        + "</h1>"
-        + "<p>"
-        + "<a target=\"_blank\" href=\"{3}\" title=\"{1}\"><img src=\"{5}/res/imgs/logo.png\" width=\"165\" height=\"63\" border=\"0\"></a>"
-        + "</p>" + "</div>";
-
-    /*
-    String header = MessageFormat.format( HEADER, new Object[]
-         { adminTitle, productName, getTitle(), productWeb, vendorName,
-                 ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT ), getLabel() } );
-    */
-
     public static final String GET_RESOURCE_METHOD_NAME = "getResource";
 
     /**
@@ -100,10 +67,8 @@
     private BundleContext bundleContext;
 
     private String adminTitle;
-    private String productName;
-    private String productWeb;
-    private String vendorName;
 
+    private static BrandingPlugin brandingPlugin = DefaultBrandingPlugin.getInstance();
 
     //---------- HttpServlet Overwrites ----------------------------------------
 
@@ -136,9 +101,18 @@
     {
         if ( !spoolResource( request, response ) )
         {
+            // start the html response, write the header, open body and main div
             PrintWriter pw = startResponse( request, response );
+
+            // render top navigation
             renderTopNavigation( request, pw );
+
+            // wrap content in a separate div
+            pw.println( "<div id='content'>" );
             renderContent( request, response );
+            pw.println( "</div>" );
+
+            // close the main div, body, and html
             endResponse( pw );
         }
     }
@@ -152,10 +126,7 @@
 
         Dictionary headers = bundleContext.getBundle().getHeaders();
 
-        adminTitle = ( String ) headers.get( Constants.BUNDLE_NAME ); // "OSGi Management Console";
-        productName = "Apache Felix";
-        productWeb = ( String ) headers.get( Constants.BUNDLE_DOCURL );
-        vendorName = ( String ) headers.get( Constants.BUNDLE_VENDOR );
+        adminTitle = ( String ) headers.get( Constants.BUNDLE_NAME );
     }
 
 
@@ -383,9 +354,10 @@
 
         PrintWriter pw = response.getWriter();
 
-        String header = MessageFormat.format( HEADER, new Object[]
-            { adminTitle, productName, getTitle(), productWeb, vendorName,
-                ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT ), getLabel() } );
+        String header = MessageFormat.format( getHeader(), new Object[]
+            { adminTitle, getTitle(), ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT ), getLabel(),
+                brandingPlugin.getFavIcon(), brandingPlugin.getMainStyleSheet(), brandingPlugin.getProductURL(),
+                brandingPlugin.getProductName(), brandingPlugin.getProductImage() } );
         pw.println( header );
 
         return pw;
@@ -410,8 +382,8 @@
         Map labelMap = ( Map ) request.getAttribute( WebConsoleConstants.ATTR_LABEL_MAP );
         if ( labelMap != null )
         {
-            pw.println( "<div id='technav'>" );
 
+            // prepare the navigation
             SortedMap map = new TreeMap( String.CASE_INSENSITIVE_ORDER );
             for ( Iterator ri = labelMap.entrySet().iterator(); ri.hasNext(); )
             {
@@ -440,13 +412,14 @@
                 }
             }
 
+            // render the navigation
+            pw.println( "<div id='technav'>" );
             for ( Iterator li = map.values().iterator(); li.hasNext(); )
             {
-                pw.print( "<nobr>" );
+                pw.print( "<div class='technavitem'>" );
                 pw.print( li.next() );
-                pw.println( "</nobr>" );
+                pw.println( "</div>" );
             }
-
             pw.println( "</div>" );
         }
     }
@@ -454,9 +427,7 @@
 
     protected void endResponse( PrintWriter pw )
     {
-        pw.println( "</div>" ); // close the main div
-        pw.println( "</body>" );
-        pw.println( "</html>" );
+        pw.println(getFooter());
     }
 
 
@@ -554,4 +525,83 @@
         }
         response.sendRedirect(redirectUrl);
     }
+
+    /**
+     * @return the brandingPlugin
+     */
+    public static BrandingPlugin getBrandingPlugin() {
+        return AbstractWebConsolePlugin.brandingPlugin;
+    }
+
+    /**
+     * @param brandingPlugin the brandingPlugin to set
+     */
+    public static void setBrandingPlugin(BrandingPlugin brandingPlugin) {
+        if(brandingPlugin == null){
+            AbstractWebConsolePlugin.brandingPlugin = DefaultBrandingPlugin.getInstance();
+        } else {
+            AbstractWebConsolePlugin.brandingPlugin = brandingPlugin;
+        }
+    }
+
+
+    private String getHeader()
+    {
+        // MessageFormat pattern place holder
+        //  0 main title (plugin providing bundle name)
+        //  1 console plugin title
+        //  2 application root path (ATTR_APP_ROOT)
+        //  3 console plugin label (from the URI)
+        //  4 branding favourite icon (BrandingPlugin.getFavIcon())
+        //  5 branding favourite icon (BrandingPlugin.getMainStyleSheet())
+        //  6 branding favourite icon (BrandingPlugin.getProductURL())
+        //  7 branding favourite icon (BrandingPlugin.getProductName())
+        //  8 branding favourite icon (BrandingPlugin.getProductImage())
+
+        final String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
+        + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
+
+        + "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
+        + "  <head>"
+        + "    <meta http-equiv=\"Content-Type\" content=\"text/html; utf-8\">"
+        + "    <link rel=\"icon\" href=\"{2}{4}\">"
+        + "    <title>{0} - {1}</title>"
+
+        + "    <link href=\"{2}/res/ui/admin.css\" rel=\"stylesheet\" type=\"text/css\">"
+        + "    <link href=\"{2}{5}\" rel=\"stylesheet\" type=\"text/css\">"
+
+        + "    <script language=\"JavaScript\">"
+        + "      appRoot = \"{2}\";"
+        + "      pluginRoot = \"{2}/{3}\";"
+        + "    </script>"
+
+        + "    <script src=\"{2}/res/ui/jquery-1.3.2.min.js\" language=\"JavaScript\"></script>"
+        + "    <script src=\"{2}/res/ui/jquery.tablesorter-2.0.3.min.js\" language=\"JavaScript\"></script>"
+
+        + "    <script src=\"{2}/res/ui/admin.js\" language=\"JavaScript\"></script>"
+        + "    <script src=\"{2}/res/ui/ui.js\" language=\"JavaScript\"></script>"
+
+        + "  </head>"
+        + "  <body>"
+        + "    <div id=\"main\">"
+        + "      <div id=\"lead\">"
+        + "        <h1>"
+        + "          {0}<br>{1}"
+        + "        </h1>"
+        + "        <p>"
+        + "          <a target=\"_blank\" href=\"{6}\" title=\"{7}\"><img src=\"{2}{8}\" border=\"0\"></a>"
+        + "        </p>"
+        + "      </div>";
+        return header;
+    }
+
+
+    private String getFooter()
+    {
+        // close <div id="main">, body and html
+        final String footer = "    </div>"
+            + "  </body>"
+            + "</html>";
+        return footer;
+    }
 }

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java?rev=812372&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java Tue Sep  8 08:09:20 2009
@@ -0,0 +1,89 @@
+/*
+ * 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.webconsole;
+
+
+/**
+ * The <code>BrandingPlugin</code> is the service interface for the most
+ * elaborate way of branding the web console.
+ *
+ * @see #DefaultBrandingPlugin
+ */
+public interface BrandingPlugin
+{
+    /**
+     * Returns an indicative name of the branding plugin
+     */
+    String getBrandName();
+
+
+    /**
+     * Returns the name of the product in which the web console is contained
+     * and to which the web console is branded.
+     */
+    String getProductName();
+
+
+    /**
+     * Returns an (absolute) URL to a web site representing the product to
+     * which the web console is branded.
+     */
+    String getProductURL();
+
+
+    /**
+     * Returns an absolute path to an image to be rendered as the logo of the
+     * branding product.
+     */
+    String getProductImage();
+
+
+    /**
+     * Returns the name of the branding product vendor.
+     */
+    String getVendorName();
+
+
+    /**
+     * Returns an (absolute) URL to the web site of the branding product
+     * vendor.
+     */
+    String getVendorURL();
+
+
+    /**
+     * Returns an absolute path to an image to be rendered as the logo of the
+     * branding product vendor.
+     */
+    String getVendorImage();
+
+
+    /**
+     * Returns the absolute path to an icon to be used as the web console
+     * "favicon".
+     */
+    String getFavIcon();
+
+
+    /**
+     * Returns the absolute path to a CSS file to be used as the main CSS for
+     * the basic admin site.
+     */
+    String getMainStyleSheet();
+}

Propchange: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/BrandingPlugin.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java?rev=812372&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java Tue Sep  8 08:09:20 2009
@@ -0,0 +1,213 @@
+/*
+ * 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.webconsole;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+
+/**
+ * The <code>DefaultBrandingPlugin</code> class is the default implementation
+ * of the {@link BrandingPlugin} interface. The singleton instance of this
+ * class is used as branding plugin if no BrandingPlugin service is registered
+ * in the system.
+ * <p>
+ * This default implementation provides Apache Felix based default branding
+ * as follows:
+ * <table>
+ * <tr><th>Name</th><th>Property Name</th><th>Default Value</th></tr>
+ * <tr>
+ *  <td>Product Name</td>
+ *  <td>webconsole.product.name</td>
+ *  <td>Apache Felix</td>
+ * </tr>
+ * <tr>
+ *  <td>Product URL</td>
+ *  <td>webconsole.product.url</td>
+ *  <td>http://felix.apache.org</td>
+ * </tr>
+ * <tr>
+ *  <td>Product Image</td>
+ *  <td>webconsole.product.image</td>
+ *  <td>/res/imgs/logo.png</td>
+ * </tr>
+ * <tr>
+ *  <td>Vendor Name</td>
+ *  <td>webconsole.vendor.name</td>
+ *  <td>The Apache Software Foundation</td>
+ * </tr>
+ * <tr>
+ *  <td>Vendor URL</td>
+ *  <td>webconsole.vendor.url</td>
+ *  <td>http://www.apache.org</td>
+ * </tr>
+ * <tr>
+ *  <td>Vendor Image</td>
+ *  <td>webconsole.vendor.image</td>
+ *  <td>/res/imgs/logo.png</td>
+ * </tr>
+ * <tr>
+ *  <td>Favourite Icon</td>
+ *  <td>webconsole.favicon</td>
+ *  <td>/res/imgs/favicon.ico</td>
+ * </tr>
+ * <tr>
+ *  <td>Main Stylesheet</td>
+ *  <td>webconsole.stylesheet</td>
+ *  <td>/res/ui/admin.css</td>
+ * </tr>
+ * </table>
+ * <p>
+ * If a properties file <code>META-INF/webconsole.properties</code> is available
+ * through the class loader of this class, the properties overwrite the default
+ * settings according to the property names listed above. The easiest way to
+ * add such a properties file is to provide a fragment bundle with the file.
+ */
+public class DefaultBrandingPlugin implements BrandingPlugin
+{
+
+    /**
+     * The name of the bundle entry providing branding properties for this
+     * defualt branding plugin (value is "/META-INF/webconsole.properties").
+     */
+    private static final String BRANDING_PROPERTIES = "/META-INF/webconsole.properties";
+
+    private static DefaultBrandingPlugin instance;
+
+    private final String productName;
+
+    private final String productURL;
+
+    private final String productImage;
+
+    private final String vendorName;
+
+    private final String vendorURL;
+
+    private final String vendorImage;
+
+    private final String favIcon;
+
+    private final String mainStyleSheet;
+
+
+    private DefaultBrandingPlugin()
+    {
+        Properties props = new Properties();
+
+        // try to load the branding properties
+        InputStream ins = getClass().getResourceAsStream( BRANDING_PROPERTIES );
+        if ( ins != null )
+        {
+            try
+            {
+                props.load( ins );
+            }
+            catch ( IOException ignore )
+            {
+            }
+            finally
+            {
+                try
+                {
+                    ins.close();
+                }
+                catch ( IOException ignore )
+                {
+                }
+            }
+        }
+
+        // set the fields from the properties now
+        productName = props.getProperty( "webconsole.product.name", "Apache Felix" );
+        productURL = props.getProperty( "webconsole.product.url", "http://felix.apache.org" );
+        productImage = props.getProperty( "webconsole.product.image", "/res/imgs/logo.png" );
+        vendorName = props.getProperty( "webconsole.vendor.name", "The Apache Software Foundation" );
+        vendorURL = props.getProperty( "webconsole.vendor.url", "http://www.apache.org" );
+        vendorImage = props.getProperty( "webconsole.vendor.image", "/res/imgs/logo.png" );
+        favIcon = props.getProperty( "webconsole.favicon", "/res/imgs/favicon.ico" );
+        mainStyleSheet = props.getProperty( "webconsole.stylesheet", "/res/ui/webconsole.css" );
+    }
+
+
+    public static DefaultBrandingPlugin getInstance()
+    {
+        if ( instance == null )
+        {
+            instance = new DefaultBrandingPlugin();
+        }
+        return instance;
+    }
+
+
+    public String getBrandName()
+    {
+        return "DefaultBrandingPlugin";
+    }
+
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+
+    public String getProductURL()
+    {
+        return productURL;
+    }
+
+
+    public String getProductImage()
+    {
+        return productImage;
+    }
+
+
+    public String getVendorName()
+    {
+        return vendorName;
+    }
+
+
+    public String getVendorURL()
+    {
+        return vendorURL;
+    }
+
+
+    public String getVendorImage()
+    {
+        return vendorImage;
+    }
+
+
+    public String getFavIcon()
+    {
+        return favIcon;
+    }
+
+
+    public String getMainStyleSheet()
+    {
+        return mainStyleSheet;
+    }
+}

Propchange: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java?rev=812372&r1=812371&r2=812372&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java Tue Sep  8 08:09:20 2009
@@ -46,20 +46,21 @@
      * property set to a non-empty String values are accepted by the OSGi
      * Manager as a plugin.
      *
-     * @since 1.2.12
+     * @since 2.0.0
      */
     public static final String PLUGIN_TITLE = "felix.webconsole.title";
 
     /**
      * The name of the request attribute providing the absolute path of the
      * Web Console root (value is "felix.webconsole.appRoot"). This consists of
-     * the servlet context path (from <code>ServletRequest.getContextPath()</code>)
-     * and the configured path of the web console root (<code>/system/console</code>
-     * by default).
+     * the servlet context path (from <code>HttpServletRequest.getContextPath()</code>)
+     * and the Web Console servlet path (from
+     * <code>HttpServletRequest.getServletPath()</code>,
+     * <code>/system/console</code> by default).
      * <p>
      * The type of this request attribute is <code>String</code>.
      *
-     * @since 1.2.12
+     * @since 2.0.0
      */
     public static final String ATTR_APP_ROOT = "felix.webconsole.appRoot";
 
@@ -85,7 +86,7 @@
      * <p>
      * The type of this request attribute is <code>Map<String, String></code>.
      *
-     * @since 1.2.12
+     * @since 2.0.0
      */
     public static final String ATTR_LABEL_MAP = "felix.webconsole.labelMap";
 

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java?rev=812372&r1=812371&r2=812372&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java Tue Sep  8 08:09:20 2009
@@ -143,6 +143,8 @@
 
     private ServiceTracker pluginsTracker;
 
+    private ServiceTracker brandingTracker;
+
     private ServiceRegistration configurationListener;
 
     private Map plugins = new HashMap();
@@ -251,6 +253,10 @@
                     {
                         bindRender( ( Render ) plugin );
                     }
+                    if ( plugin instanceof BrandingPlugin )
+                    {
+                        AbstractWebConsolePlugin.setBrandingPlugin((BrandingPlugin) plugin);
+                    }
                 }
             }
             catch ( Throwable t )
@@ -266,6 +272,8 @@
         rendersTracker.open();
         pluginsTracker = new PluginServiceTracker( this );
         pluginsTracker.open();
+        brandingTracker = new BrandingServiceTracker(this);
+        brandingTracker.open();
     }
 
     public void service( ServletRequest req, ServletResponse res ) throws ServletException, IOException
@@ -344,6 +352,11 @@
             pluginsTracker.close();
             pluginsTracker = null;
         }
+        if( brandingTracker != null )
+        {
+            brandingTracker.close();
+            brandingTracker = null;
+        }
 
         // deactivate any remaining plugins
         for ( Iterator pi = plugins.values().iterator(); pi.hasNext(); )
@@ -595,6 +608,34 @@
         }
     }
 
+    private static class BrandingServiceTracker extends ServiceTracker
+    {
+        private final OsgiManager osgiManager;
+        
+        BrandingServiceTracker( OsgiManager osgiManager ){
+            super( osgiManager.getBundleContext(), BrandingPlugin.class.getName(), null );
+            this.osgiManager = osgiManager;
+        }
+
+        public Object addingService( ServiceReference reference ){
+            Object plugin = super.addingService( reference );
+            if ( plugin instanceof BrandingPlugin )
+            {
+                AbstractWebConsolePlugin.setBrandingPlugin((BrandingPlugin) plugin);
+            }
+            return plugin;
+        }
+
+        public void removedService( ServiceReference reference, Object service ){
+            if ( service instanceof BrandingPlugin )
+            {
+                AbstractWebConsolePlugin.setBrandingPlugin(null);
+            }
+            super.removedService( reference, service );
+        }
+
+    }
+
 
     protected synchronized void bindHttpService( HttpService httpService )
     {

Modified: felix/trunk/webconsole/src/main/resources/res/ui/admin.css
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/admin.css?rev=812372&r1=812371&r2=812372&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/admin.css (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/admin.css Tue Sep  8 08:09:20 2009
@@ -13,96 +13,19 @@
  * 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.
- */ /* CSS Document */
-#main {
-    font-family: Verdana, Arial, Helvetica, sans-serif;
-    font-size: 10px;
-    color: black;
-    background-color: white;
-    border-collapse: collapse;
-    padding: 0px;
-    margin: 30px;
-    position: absolute;
-    text-align: left;
-    border-color: black;
-}
-
-#lead {
-    color: #00678C;
-    /* color: #ffffff; */
-    margin: 0px 0px 26px 0px;
-    padding: 0px;
-    height: 100px;
-}
-
-#lead h1 { /*
-    background-image: url(../imgs/banner_left.jpg);
-    background-repeat: no-repeat;
-    */
-    margin: 0px;
-    padding: 5px 0 0 8px;
-    font-size: 300%;
-    font-weight: bold;
-    line-height: 120%;
-    height: 95px;
-    /* account for 5px top marging to get a total of 100px */
-    float: left;
-}
-
-#lead br {
-    line-height: 20px;
-}
-
-#lead p { /*
-    background-image: url(../imgs/banner_right.jpg);
-    background-repeat: no-repeat;
-    border-left: 1px solid;
-        */
-    margin: 0px;
-    padding: 0px;
-    height: 100px;
-    float: right;
-}
+ */
 
-#technav {
-    border-bottom: 1px solid #6181A9;
-    border-top: 1px solid #6181A9;
-    color: black;
-    font-size: 10px;
-    font-weight: bold;
-    /*
-    border-top: 1px solid black;
-    */
-    line-height: 21px;
-    padding: 0;
-    margin: 0;
-}
-
-#technav a {
-    /*
-    display: block;
-    float: left;
-    */
-    text-decoration: none;
-    padding: 3px 10px 3px 10px;
-    color: #6181A9;
-    text-decoration: none;
-}
-
-#technav a:hover {
-    background-color: black;
-}
+/*
+ * The admin.css is currently a collection of a lot of CSS styles, which should
+ * be cleaned up for more appropriate and targeted stylings.
+ *
+ * This stylesheet is loaded by the AbstractWebConsolePlugin before the
+ * stylesheet addressed by the BrandingPlugin.getMainStyleSheet() method, which
+ * is the webconsole.css by default.
+ *
+ * See also http://felix.apache.org/site/branding-the-web-console.html
+ */
 
-#technav .technavat {
-    /*
-    display: block;
-    float: left;
-    */
-    text-decoration: none;
-    padding: 3px 10px 3px 10px;
-    background-color: #B6CAE4;
-    color: black;
-}
 
 #claim {
     color: white;
@@ -587,10 +510,7 @@
 
 table.tablelayout thead tr th, table.tablelayout tfoot tr th {
     background-color: #e6EEEE;
-    border-left: 1px solid #6181A9;
-    border-right: 1px solid #6181A9;
-    border-top: 1px solid #FFF;
-    border-bottom: 1px solid #FFF;
+    border: 1px solid #6181A9;
     font-size: 8pt;
     padding: 4px;
 }
@@ -629,6 +549,8 @@
 .col_Actions {
     width: 95px;
 }
+
+/** Added for new Install stuff */
 #plugin_content {
     margin-top: 26px;
     margin-bottom: 26px;

Added: felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css?rev=812372&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css (added)
+++ felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css Tue Sep  8 08:09:20 2009
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+/*
+ * The webconsole.css is the main CSS which sets up the following parts
+ *
+ *   div main -> outermost div just inside body
+ *   div lead -> the page lead with title and logo
+ *   div technav -> the top navigation
+ *   div content -> the div surrounding the content being rendered by
+ *      the plugin in the renderContent (or service) method
+ *
+ * See also http://felix.apache.org/site/branding-the-web-console.html
+ */
+
+#main {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size: 10px;
+    color: black;
+    background-color: white;
+    border-collapse: collapse;
+    padding: 0px;
+    margin: 30px;
+    position: absolute;
+    text-align: left;
+    border-color: black;
+}
+
+#lead {
+    color: #00678C;
+    /* color: #ffffff; */
+    margin: 0px 0px 26px 0px;
+    padding: 0px;
+    height: 100px;
+}
+
+/* This contains the page title */
+#lead h1 {
+    margin: 0px;
+    padding: 5px 0 0 8px;
+    font-size: 300%;
+    font-weight: bold;
+    line-height: 120%;
+    /* account for 5px top padding to get a total of 100px */
+    height: 95px;
+    float: left;
+}
+
+#lead br {
+    line-height: 20px;
+}
+
+/* This contains the logo */
+#lead p {
+    margin: 0px;
+    padding: 0px;
+    height: 100px;
+    position:absolute;
+    right: 0px;
+}
+
+/* This contains the top navigation */
+#technav {
+    border-bottom: 1px solid #6181A9;
+    border-top: 1px solid #6181A9;
+    color: black;
+    font-size: 10px;
+    font-weight: bold;
+    line-height: 21px;
+    padding: 0;
+    margin: 0;
+}
+
+#technav a {
+    text-decoration: none;
+    padding: 3px 10px 3px 10px;
+    color: #6181A9;
+    text-decoration: none;
+}
+
+#technav a:hover {
+    background-color: black;
+}
+
+/* Special rendering of the "button" for the current page */
+#technav .technavat {
+    text-decoration: none;
+    padding: 3px 10px 3px 10px;
+    background-color: #B6CAE4;
+    color: black;
+}
+
+#technav .technavitem {
+    display: inline;
+    white-space: nowrap;
+}
+
+
+/* CENTRAL CONTENT AREA STYLING */
+#content {
+    position: relative;
+}
+
+#content A:link {
+    color: #336600;
+    text-decoration: underline;
+}
+
+#content A:visited {
+    color: #666666;
+    text-decoration: underline;
+}
+
+#content A:hover {
+    color: #ffffff;
+    background-color: #336600;
+    text-decoration: none;
+}
+
+#content A:active {
+    color: #ffffff;
+    background-color: #000000;
+    text-decoration: none;
+}
+

Propchange: felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/webconsole/src/main/resources/res/ui/webconsole.css
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url