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/25 22:26:01 UTC

svn commit: r818995 - in /felix/trunk/webconsole/src/main: java/org/apache/felix/webconsole/internal/core/ java/org/apache/felix/webconsole/internal/obr/ resources/res/imgs/ resources/res/ui/

Author: fmeschbe
Date: Fri Sep 25 20:26:00 2009
New Revision: 818995

URL: http://svn.apache.org/viewvc?rev=818995&view=rev
Log:
FELIX-1644 Reintroduce update button to update a bundle from its
location or from OBR

Added:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java   (with props)
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallHelper.java   (with props)
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/bundle_update.png   (with props)
Modified:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/obr/DeployerThread.java
    felix/trunk/webconsole/src/main/resources/res/ui/admin.css

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java?rev=818995&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java Fri Sep 25 20:26:00 2009
@@ -0,0 +1,145 @@
+/*
+ * Copyright 1997-2009 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+package org.apache.felix.webconsole.internal.core;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.felix.webconsole.internal.Logger;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+
+abstract class BaseUpdateInstallHelper extends Thread
+{
+
+    private final File bundleFile;
+
+    private final boolean refreshPackages;
+
+
+    BaseUpdateInstallHelper( String name, File bundleFile, boolean refreshPackages )
+    {
+        super( name );
+        setDaemon( true );
+
+        this.bundleFile = bundleFile;
+        this.refreshPackages = refreshPackages;
+    }
+
+
+    protected File getBundleFile()
+    {
+        return bundleFile;
+    }
+
+
+    protected abstract Bundle doRun( InputStream bundleStream ) throws BundleException;
+
+
+    protected abstract Logger getLog();
+
+
+    protected abstract Object getService( String serviceName );
+
+
+    /**
+     * @return the installed bundle or <code>null</code> if no bundle was touched
+     * @throws BundleException
+     * @throws IOException
+     */
+    protected Bundle doRun() throws BundleException, IOException
+    {
+        // now deploy the resolved bundles
+        InputStream bundleStream = null;
+        try
+        {
+            bundleStream = new FileInputStream( bundleFile );
+            return doRun( bundleStream );
+        }
+        finally
+        {
+            if ( bundleStream != null )
+            {
+                try
+                {
+                    bundleStream.close();
+                }
+                catch ( IOException ignore )
+                {
+                }
+            }
+        }
+
+    }
+
+
+    public void run()
+    {
+        // wait some time for the request to settle
+        sleepSilently( 500L );
+
+        // now deploy the resolved bundles
+        try
+        {
+            // we need the package admin before we call the bundle
+            // installation or update, since we might be updating
+            // our selves in which case the bundle context will be
+            // invalid by the time we want to call the update
+            PackageAdmin pa = ( refreshPackages ) ? ( PackageAdmin ) getService( PackageAdmin.class.getName() ) : null;
+
+            Bundle bundle = doRun();
+
+            if ( pa != null && bundle != null )
+            {
+                // wait for asynchronous bundle start tasks to finish
+                sleepSilently( 2000L );
+
+                pa.refreshPackages( new Bundle[]
+                    { bundle } );
+            }
+        }
+        catch ( IOException ioe )
+        {
+            getLog().log( LogService.LOG_ERROR, "Cannot install or update bundle from " + bundleFile, ioe );
+        }
+        catch ( BundleException be )
+        {
+            getLog().log( LogService.LOG_ERROR, "Cannot install or update bundle from " + bundleFile, be );
+        }
+        finally
+        {
+            if ( bundleFile != null )
+            {
+                bundleFile.delete();
+            }
+        }
+    }
+
+
+    protected void sleepSilently( long msecs )
+    {
+        try
+        {
+            sleep( msecs );
+        }
+        catch ( InterruptedException ie )
+        {
+            // don't care
+        }
+    }
+}
\ No newline at end of file

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

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

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java?rev=818995&r1=818994&r2=818995&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java Fri Sep 25 20:26:00 2009
@@ -46,6 +46,7 @@
 import org.apache.felix.webconsole.ConfigurationPrinter;
 import org.apache.felix.webconsole.WebConsoleConstants;
 import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
+import org.apache.felix.webconsole.internal.Logger;
 import org.apache.felix.webconsole.internal.Util;
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -285,6 +286,12 @@
                 refresh( bundle );
                 success = true;
             }
+            else if ( "update".equals( action ) )
+            {
+                // update the bundle
+                update( bundle );
+                success = true;
+            }
             else if ( "uninstall".equals( action ) )
             {
                 // uninstall bundle
@@ -573,6 +580,7 @@
                 action( jw, hasStop( bundle ), "stop", "Stop", "stop" );
             }
             action( jw, true, "refresh", "Refresh Package Imports", "refresh" );
+            action( jw, true, "update", "Update", "update" );
             action( jw, hasUninstall( bundle ), "uninstall", "Uninstall", "delete" );
         }
         jw.endArray();
@@ -1179,6 +1187,26 @@
             { bundle } );
     }
 
+
+    private void update( final Bundle bundle )
+    {
+        Thread t = new UpdateHelper( bundle, false )
+        {
+            protected Logger getLog()
+            {
+                return BundlesServlet.this.getLog();
+            }
+
+
+            protected Object getService( String serviceName )
+            {
+                return BundlesServlet.this.getService( serviceName );
+            }
+        };
+
+        t.start();
+    }
+
     private final class RequestInfo
     {
         public final String extension;

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java?rev=818995&r1=818994&r2=818995&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java Fri Sep 25 20:26:00 2009
@@ -29,6 +29,7 @@
 import org.apache.felix.webconsole.AbstractWebConsolePlugin;
 import org.apache.felix.webconsole.Action;
 import org.apache.felix.webconsole.internal.BaseManagementPlugin;
+import org.apache.felix.webconsole.internal.Logger;
 import org.osgi.framework.*;
 import org.osgi.service.log.LogService;
 import org.osgi.service.packageadmin.PackageAdmin;
@@ -273,28 +274,26 @@
         final boolean doStart, final boolean refreshPackages )
     {
 
-        Thread t = new InstallHelper( this, "Background Install " + bundleFile, bundleFile, refreshPackages )
+        Thread t = new InstallHelper( getBundleContext(), bundleFile, location, startlevel, doStart, refreshPackages )
         {
-
-            protected Bundle doRun( InputStream bundleStream ) throws BundleException
+            protected Logger getLog()
             {
-                Bundle bundle = getBundleContext().installBundle( location, bundleStream );
+                return InstallAction.this.getLog();
+            }
 
-                if ( startlevel > 0 )
+
+            protected Object getService( String serviceName )
+            {
+                if ( serviceName.equals( PackageAdmin.class.getName() ) )
                 {
-                    StartLevel sl = getStartLevel();
-                    if ( sl != null )
-                    {
-                        sl.setBundleStartLevel( bundle, startlevel );
-                    }
+                    return InstallAction.this.getPackageAdmin();
                 }
-
-                if ( doStart )
+                else if ( serviceName.equals( StartLevel.class.getName() ) )
                 {
-                    bundle.start();
+                    return InstallAction.this.getStartLevel();
                 }
 
-                return bundle;
+                return null;
             }
         };
 
@@ -304,108 +303,25 @@
 
     private void updateBackground( final Bundle bundle, final File bundleFile, final boolean refreshPackages )
     {
-        Thread t = new InstallHelper( this, "Background Update " + bundle.getSymbolicName() + " ("
-            + bundle.getBundleId() + ")", bundleFile, refreshPackages )
+        Thread t = new UpdateHelper( bundle, bundleFile, refreshPackages )
         {
-
-            protected Bundle doRun( InputStream bundleStream ) throws BundleException
+            protected Logger getLog()
             {
-                bundle.update( bundleStream );
-                return bundle;
+                return InstallAction.this.getLog();
             }
-        };
-
-        t.start();
-    }
-
-    private static abstract class InstallHelper extends Thread
-    {
 
-        private final InstallAction installAction;
 
-        private final File bundleFile;
-
-        private final boolean refreshPackages;
-
-
-        InstallHelper( InstallAction installAction, String name, File bundleFile, boolean refreshPackages )
-        {
-            super( name );
-            setDaemon( true );
-
-            this.installAction = installAction;
-            this.bundleFile = bundleFile;
-            this.refreshPackages = refreshPackages;
-        }
-
-
-        protected abstract Bundle doRun( InputStream bundleStream ) throws BundleException;
-
-
-        public void run()
-        {
-            // wait some time for the request to settle
-            sleepSilently( 500L );
-
-            // now deploy the resolved bundles
-            InputStream bundleStream = null;
-            try
+            protected Object getService( String serviceName )
             {
-                // we need the package admin before we call the bundle
-                // installation or update, since we might be updating
-                // our selves in which case the bundle context will be
-                // invalid by the time we want to call the update
-                PackageAdmin pa = ( refreshPackages ) ? installAction.getPackageAdmin() : null;
-
-                bundleStream = new FileInputStream( bundleFile );
-                Bundle bundle = doRun( bundleStream );
-
-                if ( pa != null )
-                {
-                    // wait for asynchronous bundle start tasks to finish
-                    sleepSilently( 2000L );
-
-                    pa.refreshPackages( new Bundle[]
-                        { bundle } );
-                }
-            }
-            catch ( IOException ioe )
-            {
-                installAction.getLog().log( LogService.LOG_ERROR, "Cannot install or update bundle from " + bundleFile,
-                    ioe );
-            }
-            catch ( BundleException be )
-            {
-                installAction.getLog().log( LogService.LOG_ERROR, "Cannot install or update bundle from " + bundleFile,
-                    be );
-            }
-            finally
-            {
-                if ( bundleStream != null )
+                if ( serviceName.equals( PackageAdmin.class.getName() ) )
                 {
-                    try
-                    {
-                        bundleStream.close();
-                    }
-                    catch ( IOException ignore )
-                    {
-                    }
+                    return InstallAction.this.getPackageAdmin();
                 }
-                bundleFile.delete();
-            }
-        }
-
 
-        protected void sleepSilently( long msecs )
-        {
-            try
-            {
-                sleep( msecs );
+                return null;
             }
-            catch ( InterruptedException ie )
-            {
-                // don't care
-            }
-        }
+        };
+
+        t.start();
     }
 }

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallHelper.java?rev=818995&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallHelper.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/InstallHelper.java Fri Sep 25 20:26:00 2009
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1997-2009 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+package org.apache.felix.webconsole.internal.core;
+
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.service.startlevel.StartLevel;
+
+
+abstract class InstallHelper extends BaseUpdateInstallHelper
+{
+    private final BundleContext bundleContext;
+    private final String location;
+    private final int startlevel;
+    private final boolean doStart;
+
+    InstallHelper( final BundleContext bundleContext, final File bundleFile, final String location, final int startlevel,
+        final boolean doStart, final boolean refreshPackages )
+    {
+        super( "Background Install " + bundleFile, bundleFile, refreshPackages );
+
+        this.bundleContext = bundleContext;
+        this.location = location;
+        this.startlevel = startlevel;
+        this.doStart = doStart;
+    }
+
+
+    protected Bundle doRun( InputStream bundleStream ) throws BundleException
+    {
+        Bundle bundle = bundleContext.installBundle( location, bundleStream );
+
+        if ( startlevel > 0 )
+        {
+            StartLevel sl = ( StartLevel ) getService( StartLevel.class.getName() );
+            if ( sl != null )
+            {
+                sl.setBundleStartLevel( bundle, startlevel );
+            }
+        }
+
+        if ( doStart )
+        {
+            bundle.start();
+        }
+
+        return bundle;
+    }
+}
\ No newline at end of file

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

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

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java?rev=818995&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java Fri Sep 25 20:26:00 2009
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1997-2009 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+package org.apache.felix.webconsole.internal.core;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import org.apache.felix.webconsole.internal.obr.DeployerThread;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.service.log.LogService;
+import org.osgi.service.obr.RepositoryAdmin;
+import org.osgi.service.obr.Resolver;
+import org.osgi.service.obr.Resource;
+
+
+abstract class UpdateHelper extends BaseUpdateInstallHelper
+{
+
+    private final Bundle bundle;
+
+
+    UpdateHelper( final Bundle bundle, boolean refreshPackages )
+    {
+        this( bundle, null, refreshPackages );
+    }
+
+
+    UpdateHelper( final Bundle bundle, final File bundleFile, boolean refreshPackages )
+    {
+        super( "Background Update " + bundle.getSymbolicName() + " (" + bundle.getBundleId() + ")", bundleFile,
+            refreshPackages );
+        this.bundle = bundle;
+    }
+
+
+    protected Bundle doRun( final InputStream bundleStream ) throws BundleException
+    {
+        bundle.update( bundleStream );
+        return bundle;
+    }
+
+
+    protected Bundle doRun() throws BundleException, IOException
+    {
+        // update the bundle from the file if defined
+        if ( getBundleFile() != null )
+        {
+            return super.doRun();
+        }
+
+        // try updating from the bundle location
+        if ( updateFromBundleLocation() )
+        {
+            return bundle;
+        }
+
+        // ensure we have a symbolic name for the OBR update to follow
+        if ( bundle.getSymbolicName() == null )
+        {
+            throw new BundleException( "Cannot update bundle: Symbolic Name is required for OBR update" );
+        }
+
+        // try updating from OBR
+        if ( updateFromOBR() )
+        {
+            return bundle;
+        }
+
+        // bundle was not updated, return nothing
+        return null;
+    }
+
+
+    private boolean updateFromBundleLocation() throws BundleException
+    {
+        final String location = bundle.getLocation();
+        getLog().log( LogService.LOG_DEBUG, "Trying to update from bundle location " + location );
+
+        InputStream input = null;
+        try
+        {
+            final URL locationURL = new URL( location );
+            input = locationURL.openStream();
+            if ( input != null )
+            {
+                doRun( input );
+                getLog().log( LogService.LOG_INFO, "Bundle updated from bundle location " + location );
+                return true;
+            }
+        }
+        catch ( IOException ioe )
+        {
+            // MalformedURLException: cannot create an URL/input for the location, use OBR
+            // IOException: cannot open stream on URL ? lets use OBR then
+            getLog().log( LogService.LOG_DEBUG, "Update failure from bundle location " + location, ioe );
+        }
+        finally
+        {
+            if ( input != null )
+            {
+                try
+                {
+                    input.close();
+                }
+                catch ( IOException ignore )
+                {
+                }
+            }
+        }
+
+        // not installed from the bundle location
+        return false;
+    }
+
+
+    private boolean updateFromOBR()
+    {
+        RepositoryAdmin ra = ( RepositoryAdmin ) getService( RepositoryAdmin.class.getName() );
+        if ( ra != null )
+        {
+            getLog().log( LogService.LOG_DEBUG, "Trying to update from OSGi Bundle Repository" );
+
+            final Resolver resolver = ra.resolver();
+
+            String version = ( String ) bundle.getHeaders().get( Constants.BUNDLE_VERSION );
+            if ( version == null )
+            {
+                version = "0.0.0";
+            }
+            final String filter = "(&(symbolicname=" + bundle.getSymbolicName() + ")(!(version=" + version
+                + "))(version>=" + version + "))";
+
+            final Resource[] resources = ra.discoverResources( filter );
+            final Resource resource = selectHighestVersion( resources );
+            if ( resource != null )
+            {
+                resolver.add( resource );
+
+                if ( !resolver.resolve() )
+                {
+                    DeployerThread.logRequirements( getLog(),
+                        "Cannot updated bundle from OBR due to unsatisfied requirements", resolver
+                            .getUnsatisfiedRequirements() );
+                }
+                else
+                {
+                    DeployerThread.logResource( getLog(), "Installing Requested Resources", resolver
+                        .getAddedResources() );
+                    DeployerThread.logResource( getLog(), "Installing Required Resources", resolver
+                        .getRequiredResources() );
+                    DeployerThread.logResource( getLog(), "Installing Optional Resources", resolver
+                        .getOptionalResources() );
+
+                    // deploy the resolved bundles and ensure they are started
+                    resolver.deploy( true );
+                    getLog().log( LogService.LOG_INFO, "Bundle updated from OSGi Bundle Repository" );
+
+                    return true;
+                }
+            }
+            else
+            {
+                getLog().log( LogService.LOG_INFO,
+                    "Nothing to update, OSGi Bundle Repository does not provide more recent version" );
+            }
+        }
+        else
+        {
+            getLog().log( LogService.LOG_DEBUG, "Cannot updated from OSGi Bundle Repository: Service not available" );
+        }
+
+        // fallback to false, nothing done
+        return false;
+    }
+
+
+    private Resource selectHighestVersion( final Resource[] candidates )
+    {
+        if ( candidates == null || candidates.length == 0 )
+        {
+            // nothing to do if there are none
+            return null;
+        }
+        else if ( candidates.length == 1 )
+        {
+            // simple choice if there is a single one
+            return candidates[0];
+        }
+
+        // now go on looking for the highest version
+        Resource best = candidates[0];
+        for ( int i = 1; i < candidates.length; i++ )
+        {
+            if ( best.getVersion().compareTo( candidates[i].getVersion() ) < 0)
+            {
+                best = candidates[i];
+            }
+        }
+        return best;
+    }
+}

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

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

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/obr/DeployerThread.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/obr/DeployerThread.java?rev=818995&r1=818994&r2=818995&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/obr/DeployerThread.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/obr/DeployerThread.java Fri Sep 25 20:26:00 2009
@@ -58,16 +58,16 @@
             if ( obrResolver.resolve() )
             {
 
-                logResource( "Installing Requested Resources", obrResolver.getAddedResources() );
-                logResource( "Installing Required Resources", obrResolver.getRequiredResources() );
-                logResource( "Installing Optional Resources", obrResolver.getOptionalResources() );
+                logResource( logger, "Installing Requested Resources", obrResolver.getAddedResources() );
+                logResource( logger, "Installing Required Resources", obrResolver.getRequiredResources() );
+                logResource( logger, "Installing Optional Resources", obrResolver.getOptionalResources() );
 
                 obrResolver.deploy( startBundles );
             }
             else
             {
-                logRequirements( "Cannot Install requested bundles due to unsatisfied requirements", obrResolver
-                    .getUnsatisfiedRequirements() );
+                logRequirements( logger, "Cannot Install requested bundles due to unsatisfied requirements",
+                    obrResolver.getUnsatisfiedRequirements() );
             }
         }
         catch ( Exception ie )
@@ -78,7 +78,7 @@
     }
 
 
-    private void logResource( String message, Resource[] res )
+    public static void logResource( Logger logger, String message, Resource[] res )
     {
         if ( res != null && res.length > 0 )
         {
@@ -92,7 +92,7 @@
     }
 
 
-    private void logRequirements( String message, Requirement[] req )
+    public static void logRequirements( Logger logger, String message, Requirement[] req )
     {
         logger.log( LogService.LOG_ERROR, message );
         for ( int i = 0; req != null && i < req.length; i++ )

Added: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_update.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/bundle_update.png?rev=818995&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_update.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

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=818995&r1=818994&r2=818995&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/admin.css (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/admin.css Fri Sep 25 20:26:00 2009
@@ -561,7 +561,7 @@
 	width: 50px;
 }
 .col_Actions {
-    width: 95px;
+    width: 121px;
 }
 
 /** Added for new Install stuff */