felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmesc...@apache.org
Subject svn commit: r955159 - in /felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet: OsgiManager.java PluginHolder.java
Date Wed, 16 Jun 2010 08:42:29 GMT
Author: fmeschbe
Date: Wed Jun 16 08:42:28 2010
New Revision: 955159

URL: http://svn.apache.org/viewvc?rev=955159&view=rev
Log:
FELIX-2391 Move initialization of console provided plugins to the constructor and only bind
to the Http Service in the init method. Likewise move cleanup to the dispose method and only
dispose off bound (external) services in the destroy method. Further improve concurrency behaviour
with the registered plugins.

Modified:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java

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=955159&r1=955158&r2=955159&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
Wed Jun 16 08:42:28 2010
@@ -225,40 +225,6 @@ public class OsgiManager extends Generic
         // the OSGi Manager and start the initial setup
         httpServiceTracker = new HttpServiceTracker( this );
         httpServiceTracker.open();
-    }
-
-
-    public void dispose()
-    {
-        // now drop the HttpService and continue with further destroyals
-        if ( httpServiceTracker != null )
-        {
-            httpServiceTracker.close();
-            httpServiceTracker = null;
-        }
-
-        // stop listening for configuration
-        if ( configurationListener != null )
-        {
-            configurationListener.unregister();
-            configurationListener = null;
-        }
-
-        this.bundleContext = null;
-    }
-
-
-    //---------- Servlet API
-
-    /**
-     * @see javax.servlet.GenericServlet#init()
-     */
-    public void init()
-    {
-        // base class initialization not needed, since the GenericServlet.init
-        // is an empty method
-
-        holder.setServletContext( getServletContext() );
 
         // setup the included plugins
         ClassLoader classLoader = getClass().getClassLoader();
@@ -331,6 +297,68 @@ public class OsgiManager extends Generic
     }
 
 
+    public void dispose()
+    {
+        // dispose off held plugins
+        holder.close();
+
+        // dispose off the resource bundle manager
+        if ( resourceBundleManager != null )
+        {
+            resourceBundleManager.dispose();
+            resourceBundleManager = null;
+        }
+
+        // stop listening for brandings
+        if ( brandingTracker != null )
+        {
+            brandingTracker.close();
+            brandingTracker = null;
+        }
+
+        // deactivate any remaining plugins
+        for ( Iterator pi = osgiManagerPlugins.iterator(); pi.hasNext(); )
+        {
+            Object plugin = pi.next();
+            ( ( OsgiManagerPlugin ) plugin ).deactivate();
+        }
+
+        // simply remove all operations, we should not be used anymore
+        this.osgiManagerPlugins.clear();
+
+        // now drop the HttpService and continue with further destroyals
+        if ( httpServiceTracker != null )
+        {
+            httpServiceTracker.close();
+            httpServiceTracker = null;
+        }
+
+        // stop listening for configuration
+        if ( configurationListener != null )
+        {
+            configurationListener.unregister();
+            configurationListener = null;
+        }
+
+        this.bundleContext = null;
+    }
+
+
+    //---------- Servlet API
+
+    /**
+     * @see javax.servlet.GenericServlet#init()
+     */
+    public void init()
+    {
+        // base class initialization not needed, since the GenericServlet.init
+        // is an empty method
+
+        holder.setServletContext( getServletContext() );
+
+    }
+
+
     /**
      * @see javax.servlet.GenericServlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
      */
@@ -370,16 +398,7 @@ public class OsgiManager extends Generic
 
         final Locale locale = getConfiguredLocale( request );
         final String label = pathInfo.substring( 1, slash );
-        AbstractWebConsolePlugin plugin = holder.getPlugin( label );
-
-        if ( plugin == null )
-        {
-            if ( "install".equals( label ) )
-            {
-                plugin = holder.getPlugin( BundlesServlet.NAME );
-            }
-        }
-
+        AbstractWebConsolePlugin plugin = getConsolePlugin( label );
         if ( plugin != null )
         {
             final Map labelMap = holder.getLocalizedLabelMap( resourceBundleManager, locale
);
@@ -414,8 +433,22 @@ public class OsgiManager extends Generic
         }
     }
 
+
+    private final AbstractWebConsolePlugin getConsolePlugin( final String label )
+    {
+        // backwards compatibility for the former "install" action which is
+        // used by the Maven Sling Plugin
+        if ( "install".equals( label ) )
+        {
+            return holder.getPlugin( BundlesServlet.NAME );
+        }
+
+        return holder.getPlugin( label );
+    }
+
+
     // See https://issues.apache.org/jira/browse/FELIX-2267
-    private final Locale getConfiguredLocale(HttpServletRequest request)
+    private final Locale getConfiguredLocale( HttpServletRequest request )
     {
         Locale locale = null;
 
@@ -447,32 +480,7 @@ public class OsgiManager extends Generic
         // base class destroy not needed, since the GenericServlet.destroy
         // is an empty method
 
-        // dispose off held plugins
-        holder.close();
-
-        // dispose off the resource bundle manager
-        if ( resourceBundleManager != null )
-        {
-            resourceBundleManager.dispose();
-            resourceBundleManager = null;
-        }
-
-        // stop listening for brandings
-        if ( brandingTracker != null )
-        {
-            brandingTracker.close();
-            brandingTracker = null;
-        }
-
-        // deactivate any remaining plugins
-        for ( Iterator pi = osgiManagerPlugins.iterator(); pi.hasNext(); )
-        {
-            Object plugin = pi.next();
-            ( ( OsgiManagerPlugin ) plugin ).deactivate();
-        }
-
-        // simply remove all operations, we should not be used anymore
-        this.osgiManagerPlugins.clear();
+        holder.setServletContext( null );
     }
 
 

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java?rev=955159&r1=955158&r2=955159&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
(original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
Wed Jun 16 08:42:28 2010
@@ -21,7 +21,6 @@ package org.apache.felix.webconsole.inte
 
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -120,10 +119,10 @@ class PluginHolder implements ServiceLis
     {
         bundleContext.removeServiceListener( this );
 
-        Plugin[] plugin = ( Plugin[] ) plugins.values().toArray( new Plugin[plugins.size()]
);
+        Plugin[] plugin = getPlugins();
         for ( int i = 0; i < plugin.length; i++ )
         {
-            plugin[i].ungetService();
+            plugin[i].dispose();
         }
 
         plugins.clear();
@@ -152,28 +151,13 @@ class PluginHolder implements ServiceLis
 
 
     /**
-     * Returns the default plugin as identified by the {@link #getDefaultPlugin()}
-     * or any plugin if no plugin is registered with that label
-     *
-     * @return The default plugin or <code>null</code> if no plugin is
-     *      registered at all
-     */
-    AbstractWebConsolePlugin getDefaultPlugin()
-    {
-        return getPlugin( defaultPluginLabel );
-    }
-
-
-    /**
      * Adds an internal Web Console plugin
      * @param consolePlugin The internal Web Console plugin to add
      */
     void addOsgiManagerPlugin( final AbstractWebConsolePlugin consolePlugin )
     {
         final String label = consolePlugin.getLabel();
-        final Plugin plugin = new Plugin( this, null, label );
-        plugin.setTitle( consolePlugin.getTitle() );
-        plugin.setConsolePlugin( consolePlugin );
+        final Plugin plugin = new Plugin( this, consolePlugin, label );
         addPlugin( label, plugin );
     }
 
@@ -200,24 +184,30 @@ class PluginHolder implements ServiceLis
      */
     AbstractWebConsolePlugin getPlugin( final String label )
     {
-        if ( label == null || label.length() == 0 )
+        AbstractWebConsolePlugin consolePlugin = null;
+        if ( label != null && label.length() > 0 )
         {
-            if ( !plugins.isEmpty() )
+            final Plugin plugin;
+            synchronized ( plugins )
             {
-                return ( ( Plugin ) plugins.values().iterator().next() ).getConsolePlugin();
+                plugin = ( Plugin ) plugins.get( label );
+            }
+
+            if ( plugin != null )
+            {
+                consolePlugin = plugin.getConsolePlugin();
             }
         }
         else
         {
-            Plugin plugin = ( Plugin ) plugins.get( label );
-            if ( plugin != null )
+            Plugin[] plugins = getPlugins();
+            for ( int i = 0; i < plugins.length && consolePlugin == null; i++
)
             {
-                return plugin.getConsolePlugin();
+                consolePlugin = plugins[i].getConsolePlugin();
             }
         }
 
-        // no such plugin (or not any more)
-        return null;
+        return consolePlugin;
     }
 
 
@@ -238,9 +228,10 @@ class PluginHolder implements ServiceLis
     Map getLocalizedLabelMap( final ResourceBundleManager resourceBundleManager, final Locale
locale )
     {
         final Map map = new HashMap();
-        for ( Iterator pi = plugins.values().iterator(); pi.hasNext(); )
+        Plugin[] plugins = getPlugins();
+        for ( int i = 0; i < plugins.length; i++ )
         {
-            final Plugin plugin = ( Plugin ) pi.next();
+            final Plugin plugin = plugins[i];
             final String label = plugin.getLabel();
             String title = plugin.getTitle();
             if ( title.startsWith( "%" ) )
@@ -280,6 +271,29 @@ class PluginHolder implements ServiceLis
     void setServletContext( ServletContext servletContext )
     {
         this.servletContext = servletContext;
+
+        final Plugin[] plugin = getPlugins();
+        if ( servletContext != null )
+        {
+            for ( int i = 0; i < plugin.length; i++ )
+            {
+                try
+                {
+                    plugin[i].init();
+                }
+                catch ( ServletException se )
+                {
+                    // TODO: log !!
+                }
+            }
+        }
+        else
+        {
+            for ( int i = 0; i < plugin.length; i++ )
+            {
+                plugin[i].destroy();
+            }
+        }
     }
 
 
@@ -325,7 +339,7 @@ class PluginHolder implements ServiceLis
         final String label = getProperty( serviceReference, WebConsoleConstants.PLUGIN_LABEL
);
         if ( label != null )
         {
-            addPlugin( label, new Plugin( this, serviceReference, label ) );
+            addPlugin( label, new ServletPlugin( this, serviceReference, label ) );
         }
     }
 
@@ -342,16 +356,33 @@ class PluginHolder implements ServiceLis
 
     private void addPlugin( final String label, final Plugin plugin )
     {
-        plugins.put( label, plugin );
+        synchronized ( plugins )
+        {
+            plugins.put( label, plugin );
+        }
     }
 
 
     private void removePlugin( final String label )
     {
-        final Plugin oldPlugin = ( Plugin ) plugins.remove( label );
+        final Plugin oldPlugin;
+        synchronized ( plugins )
+        {
+            oldPlugin = ( Plugin ) plugins.remove( label );
+        }
+
         if ( oldPlugin != null )
         {
-            oldPlugin.ungetService();
+            oldPlugin.dispose();
+        }
+    }
+
+
+    private Plugin[] getPlugins()
+    {
+        synchronized ( plugins )
+        {
+            return ( Plugin[] ) plugins.values().toArray( new Plugin[plugins.size()] );
         }
     }
 
@@ -367,30 +398,80 @@ class PluginHolder implements ServiceLis
         return null;
     }
 
-    private static final class Plugin implements ServletConfig
+    private static class Plugin implements ServletConfig
     {
         private final PluginHolder holder;
-        private final ServiceReference serviceReference;
         private final String label;
         private String title;
         private AbstractWebConsolePlugin consolePlugin;
 
 
-        Plugin( final PluginHolder holder, final ServiceReference serviceReference, final
String label )
+        protected Plugin( final PluginHolder holder, final String label )
         {
             this.holder = holder;
-            this.serviceReference = serviceReference;
             this.label = label;
         }
 
 
-        final Bundle getBundle()
+        protected Plugin( final PluginHolder holder, final AbstractWebConsolePlugin plugin,
final String label )
         {
-            if ( serviceReference != null )
+            this( holder, label );
+
+            if ( plugin == null )
             {
-                return serviceReference.getBundle();
+                throw new NullPointerException( "plugin" );
+            }
+
+            this.consolePlugin = plugin;
+        }
+
+        void init() throws ServletException {
+            if (consolePlugin != null) {
+                consolePlugin.init( this );
             }
-            return holder.getBundleContext().getBundle();
+        }
+
+        void destroy()
+        {
+            if (consolePlugin != null) {
+                consolePlugin.destroy();
+            }
+        }
+
+        /**
+         * Cleans up this plugin when it is not used any longer. This means
+         * destroying the plugin servlet and, if it was registered as an OSGi
+         * service, ungetting the service.
+         */
+        final void dispose()
+        {
+            if ( consolePlugin != null )
+            {
+                try
+                {
+                    consolePlugin.destroy();
+                }
+                catch ( Exception e )
+                {
+                    // TODO: handle
+                }
+
+                doUngetConsolePlugin( consolePlugin );
+
+                consolePlugin = null;
+            }
+        }
+
+
+        protected PluginHolder getHolder()
+        {
+            return holder;
+        }
+
+
+        Bundle getBundle()
+        {
+            return getHolder().getBundleContext().getBundle();
         }
 
 
@@ -400,7 +481,7 @@ class PluginHolder implements ServiceLis
         }
 
 
-        void setTitle( String title )
+        protected void setTitle( String title )
         {
             this.title = title;
         }
@@ -410,75 +491,58 @@ class PluginHolder implements ServiceLis
         {
             if ( title == null )
             {
-                // assumption: serviceReference is only null for WebConsole
-                // internal plugins, for which the title field will always be set
-
-                // check service Reference
-                title = getProperty( serviceReference, WebConsoleConstants.PLUGIN_TITLE );
-                if ( title == null )
-                {
-                    // temporarily set the title to a non-null value to prevent
-                    // recursion issues if this method or the getServletName
-                    // method is called while the servlet is being acquired
-                    title = label;
-
-                    // get the service now
-                    acquireServlet();
-
-                    // reset the title:
-                    // - null if the servlet cannot be loaded
-                    // - to the servlet's actual title if the servlet is loaded
-                    title = ( consolePlugin != null ) ? consolePlugin.getTitle() : null;
-                }
+                final String title = doGetTitle();
+                this.title = ( title == null ) ? getLabel() : title;
             }
             return title;
         }
 
 
-        final AbstractWebConsolePlugin getConsolePlugin()
+        protected String doGetTitle()
         {
-            acquireServlet();
-            return consolePlugin;
+            // get the service now
+            final AbstractWebConsolePlugin consolePlugin = getConsolePlugin();
+
+            // reset the title:
+            // - null if the servlet cannot be loaded
+            // - to the servlet's actual title if the servlet is loaded
+            return ( consolePlugin != null ) ? consolePlugin.getTitle() : null;
         }
 
 
-        void setConsolePlugin( AbstractWebConsolePlugin service )
+        final AbstractWebConsolePlugin getConsolePlugin()
         {
-            try
-            {
-                service.init( this );
-                this.consolePlugin = service;
-            }
-            catch ( ServletException se )
+            if ( consolePlugin == null )
             {
-                // TODO:
-                // log( LogService.LOG_WARNING, "Initialization of plugin '" + plugin.getTitle()
+ "' (" + plugin.getLabel()
-                //      + ") failed; not using this plugin", se );
+                final AbstractWebConsolePlugin consolePlugin = doGetConsolePlugin();
+                if ( consolePlugin != null )
+                {
+                    try
+                    {
+                        this.consolePlugin = consolePlugin;
+                        init();
+                    }
+                    catch ( ServletException se )
+                    {
+                        // TODO: log
+                        this.consolePlugin = null;
+                    }
+                } else {
+                    // TODO: log !!
+                }
             }
-
+            return consolePlugin;
         }
 
 
-        final void ungetService()
+        protected AbstractWebConsolePlugin doGetConsolePlugin()
         {
-            if ( consolePlugin != null )
-            {
-                try
-                {
-                    consolePlugin.destroy();
-                }
-                catch ( Exception e )
-                {
-                    // TODO: handle
-                }
-                consolePlugin = null;
+            return consolePlugin;
+        }
 
-                // service reference may be null for WebConsole internal plugins
-                if ( serviceReference != null )
-                {
-                    holder.getBundleContext().ungetService( serviceReference );
-                }
-            }
+
+        protected void doUngetConsolePlugin( AbstractWebConsolePlugin consolePlugin )
+        {
         }
 
 
@@ -486,49 +550,31 @@ class PluginHolder implements ServiceLis
 
         public String getInitParameter( String name )
         {
-            if ( serviceReference != null )
-            {
-                Object property = serviceReference.getProperty( name );
-                if ( property != null && !property.getClass().isArray() )
-                {
-                    return property.toString();
-                }
-            }
-
             return null;
         }
 
 
         public Enumeration getInitParameterNames()
         {
-            final String[] keys = ( serviceReference == null ) ? new String[0] : serviceReference.getPropertyKeys();
             return new Enumeration()
             {
-                int idx = 0;
-
-
                 public boolean hasMoreElements()
                 {
-                    return idx < keys.length;
+                    return false;
                 }
 
 
                 public Object nextElement()
                 {
-                    if ( hasMoreElements() )
-                    {
-                        return keys[idx++];
-                    }
                     throw new NoSuchElementException();
                 }
-
             };
         }
 
 
         public ServletContext getServletContext()
         {
-            return holder.getServletContext();
+            return getHolder().getServletContext();
         }
 
 
@@ -538,30 +584,123 @@ class PluginHolder implements ServiceLis
         }
 
 
-        private void acquireServlet()
+    }
+
+    private static class ServletPlugin extends Plugin
+    {
+        private final ServiceReference serviceReference;
+
+
+        ServletPlugin( final PluginHolder holder, final ServiceReference serviceReference,
final String label )
         {
-            if ( consolePlugin == null )
+            super(holder, label);
+            this.serviceReference = serviceReference;
+        }
+
+
+
+
+        Bundle getBundle()
+        {
+            return serviceReference.getBundle();
+        }
+
+
+        protected String doGetTitle() {
+            // check service Reference
+            final String title = getProperty( serviceReference, WebConsoleConstants.PLUGIN_TITLE
);
+            if ( title != null )
             {
-                // assumption: serviceReference is only null for WebConsole
-                // internal plugins, for which the consolePlugin field will
-                // always be set
+                return title;
+            }
 
-                Object service = holder.getBundleContext().getService( serviceReference );
-                if ( service instanceof Servlet )
+            // temporarily set the title to a non-null value to prevent
+            // recursion issues if this method or the getServletName
+            // method is called while the servlet is being acquired
+            setTitle(getLabel());
+
+            return super.doGetTitle();
+        }
+
+        /**
+         * If the plugin is registered as a regular OSGi service, this method
+         * behaves the same as {@link #dispose()}. If the plugin is built
+         * into the web console, this method does nothing.
+         * <p>
+         * After this method is called, the plugin may still be used because
+         * the {@link #getConsolePlugin()} method will re-acquire the service
+         * again on-demand.
+         */
+        final void ungetService()
+        {
+            dispose();
+        }
+
+
+        protected AbstractWebConsolePlugin doGetConsolePlugin()
+        {
+            Object service = getHolder().getBundleContext().getService( serviceReference
);
+            if ( service instanceof Servlet )
+            {
+                final AbstractWebConsolePlugin servlet;
+                if ( service instanceof AbstractWebConsolePlugin )
                 {
-                    final AbstractWebConsolePlugin servlet;
-                    if ( service instanceof AbstractWebConsolePlugin )
-                    {
-                        servlet = ( AbstractWebConsolePlugin ) service;
-                    }
-                    else
+                    servlet = ( AbstractWebConsolePlugin ) service;
+                }
+                else
+                {
+                    servlet = new WebConsolePluginAdapter( getLabel(), ( Servlet ) service,
serviceReference );
+                }
+
+                return servlet;
+            }
+            return null;
+        }
+
+        protected void doUngetConsolePlugin( AbstractWebConsolePlugin consolePlugin )
+        {
+            getHolder().getBundleContext().ungetService( serviceReference );
+        }
+
+        //---------- ServletConfig overwrite (based on ServletReference)
+
+        public String getInitParameter( String name )
+        {
+            Object property = serviceReference.getProperty( name );
+            if ( property != null && !property.getClass().isArray() )
+            {
+                return property.toString();
+            }
+
+            return super.getInitParameter( name );
+        }
+
+
+        public Enumeration getInitParameterNames()
+        {
+            final String[] keys = serviceReference.getPropertyKeys();
+            return new Enumeration()
+            {
+                int idx = 0;
+
+
+                public boolean hasMoreElements()
+                {
+                    return idx < keys.length;
+                }
+
+
+                public Object nextElement()
+                {
+                    if ( hasMoreElements() )
                     {
-                        servlet = new WebConsolePluginAdapter( label, ( Servlet ) service,
serviceReference );
+                        return keys[idx++];
                     }
-
-                    setConsolePlugin( servlet );
+                    throw new NoSuchElementException();
                 }
-            }
+
+            };
         }
+
     }
 }



Mime
View raw message