[jboss-cvs] JBossAS SVN: r90894 - in projects/jboss-osgi/projects: bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal and 6 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Jul 7 07:58:41 EDT 2009


Author: thomas.diesler at jboss.com
Date: 2009-07-07 07:58:40 -0400 (Tue, 07 Jul 2009)
New Revision: 90894

Added:
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
Removed:
   projects/jboss-osgi/projects/integration/jbossas/trunk/src/main/java/org/jboss/osgi/jbossas/
Modified:
   projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/DeployerServiceDelegate.java
   projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/SystemDeployerService.java
   projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/DeploymentScannerImpl.java
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/BundlesPlugin.java
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/InstallActionExt.java
   projects/jboss-osgi/projects/integration/jbossas/trunk/src/main/java/org/jboss/osgi/integration/jbossas/AbstractMicrocontainerService.java
   projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeployerService.java
   projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/util/BundleInfo.java
Log:
[JBOSGI-66] Support bundle deployment through web console

Modified: projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/DeployerServiceDelegate.java
===================================================================
--- projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/DeployerServiceDelegate.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/DeployerServiceDelegate.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -56,12 +56,18 @@
       return service.getBundle(info);
    }
 
-   public BundleInfo createBundleInfo(URL url) throws BundleException
+   public BundleInfo getBundleInfo(URL url) throws BundleException
    {
       DeployerService service = getDefaultDeployerService();
-      return service.createBundleInfo(url);
+      return service.getBundleInfo(url);
    }
 
+   public BundleInfo getBundleInfo(Bundle bundle)
+   {
+      DeployerService service = getDefaultDeployerService();
+      return service.getBundleInfo(bundle);
+   }
+
    public void deploy(BundleInfo[] bundles) throws BundleException
    {
       DeployerService service = getDefaultDeployerService();

Modified: projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/SystemDeployerService.java
===================================================================
--- projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/SystemDeployerService.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/SystemDeployerService.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -24,6 +24,7 @@
 //$Id$
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -54,7 +55,6 @@
 {
    private LogServiceTracker log;
    private BundleContext context;
-
    private Map<String, Bundle> deployments = new HashMap<String, Bundle>();
 
    public SystemDeployerService(BundleContext context)
@@ -63,7 +63,7 @@
       this.context = context;
    }
 
-   public BundleInfo createBundleInfo(URL url) throws BundleException
+   public BundleInfo getBundleInfo(URL url) throws BundleException
    {
       Manifest manifest;
       try
@@ -87,6 +87,32 @@
       return new BundleInfo(url, symbolicName, version);
    }
 
+   public BundleInfo getBundleInfo(Bundle bundle)
+   {
+      if (bundle == null)
+         throw new IllegalArgumentException("Cannot obtain bundle info for: null");
+      
+      URL location = null;
+      for (String auxLoc : deployments.keySet())
+      {
+         Bundle auxBnd = deployments.get(auxLoc);
+         if (auxBnd.equals(bundle))
+         {
+            location = toURL(auxLoc);
+            break;
+         }
+      }
+      
+      BundleInfo info = null;
+      if (location != null)
+      {
+         String symbolicName = bundle.getSymbolicName();
+         String version = (String)bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+         info = new BundleInfo(location, symbolicName, version);
+      }
+      return info;
+   }
+
    public Bundle getBundle(BundleInfo info)
    {
       String symbolicName = info.getSymbolicName();
@@ -148,7 +174,24 @@
    public void undeploy(BundleInfo[] bundleInfos) throws BundleException
    {
       for (BundleInfo info : bundleInfos)
-         undeploy(info.getLocation());
+      {
+         URL location = info.getLocation();
+         if (location != null)
+         {
+            undeploy(location);
+         }
+         else
+         {
+            Bundle bundle = getBundle(info);
+            if (bundle == null)
+               throw new IllegalStateException("Cannot obtain bundle for: " + info);
+            
+            unregisterManagedBundle(bundle);
+            bundle.uninstall();
+            
+            log.log(LogService.LOG_INFO, "Uninstalled: " + bundle);
+         }
+      }
    }
 
    // Note, in contrary to deploy(BundleInfo[]) this
@@ -206,4 +249,16 @@
          log.log(LogService.LOG_DEBUG, "No ManagedBundleService. Cannot unregister managed bundle: " + bundle);
       }
    }
+
+   private URL toURL(String location)
+   {
+      try
+      {
+         return new URL(location);
+      }
+      catch (MalformedURLException e)
+      {
+         throw new IllegalArgumentException("Invalid URL location: " + location);
+      }
+   }
 }
\ No newline at end of file

Modified: projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/DeploymentScannerImpl.java
===================================================================
--- projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/DeploymentScannerImpl.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/DeploymentScannerImpl.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -252,7 +252,7 @@
             {
                try
                {
-                  info = deployer.createBundleInfo(bundleURL);
+                  info = deployer.getBundleInfo(bundleURL);
                   bundleInfoCache.put(bundleURL.toExternalForm(), info);
                }
                catch (BundleException ex)

Added: projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
===================================================================
--- projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java	                        (rev 0)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -0,0 +1,1080 @@
+/*
+ * 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.internal.core;
+
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.*;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.bundlerepository.*;
+import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
+import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.internal.servlet.OsgiManager;
+import org.json.*;
+import org.osgi.framework.*;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+
+/**
+ * The <code>BundlesServlet</code> TODO
+ */
+public class BundlesServlet extends BaseWebConsolePlugin
+{
+
+    public static final String NAME = "bundles";
+
+    public static final String LABEL = "Bundles";
+
+    public static final String BUNDLE_ID = "bundleId";
+
+    // bootdelegation property entries. wildcards are converted to package
+    // name prefixes. whether an entry is a wildcard or not is set as a flag
+    // in the bootPkgWildcards array.
+    // see #activate and #isBootDelegated
+    private String[] bootPkgs;
+
+    // a flag for each entry in bootPkgs indicating whether the respective
+    // entry was declared as a wildcard or not
+    // see #activate and #isBootDelegated
+    private boolean[] bootPkgWildcards;
+
+
+    public void activate( BundleContext bundleContext )
+    {
+        super.activate( bundleContext );
+
+        // bootdelegation property parsing from Apache Felix R4SearchPolicyCore
+        String bootDelegation = bundleContext.getProperty( Constants.FRAMEWORK_BOOTDELEGATION );
+        bootDelegation = ( bootDelegation == null ) ? "java.*" : bootDelegation + ",java.*";
+        StringTokenizer st = new StringTokenizer( bootDelegation, " ," );
+        bootPkgs = new String[st.countTokens()];
+        bootPkgWildcards = new boolean[bootPkgs.length];
+        for ( int i = 0; i < bootPkgs.length; i++ )
+        {
+            bootDelegation = st.nextToken();
+            if ( bootDelegation.endsWith( "*" ) )
+            {
+                bootPkgWildcards[i] = true;
+                bootDelegation = bootDelegation.substring( 0, bootDelegation.length() - 1 );
+            }
+            bootPkgs[i] = bootDelegation;
+        }
+    }
+
+
+    public String getLabel()
+    {
+        return NAME;
+    }
+
+
+    public String getTitle()
+    {
+        return LABEL;
+    }
+
+
+    protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
+    {
+        final RequestInfo reqInfo = new RequestInfo(request);
+        if ( reqInfo.bundle == null && reqInfo.bundleRequested ) {
+            response.sendError(404);
+            return;
+        }
+        if ( reqInfo.extension.equals("json")  )
+        {
+            this.renderJSON(response, reqInfo.bundle);
+
+            // nothing more to do
+            return;
+        }
+
+        super.doGet( request, response );
+    }
+
+
+    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
+    {
+        final RequestInfo reqInfo = new RequestInfo(req);
+        if ( reqInfo.bundle == null && reqInfo.bundleRequested ) {
+            resp.sendError(404);
+            return;
+        }
+
+        boolean success = false;
+
+        final String action = req.getParameter( "action" );
+
+        Bundle bundle = getBundle( req.getPathInfo() );
+
+        if ( bundle != null )
+        {
+            if ( action == null )
+            {
+                success = true;
+            }
+            else if ( "start".equals( action ) )
+            {
+                // start bundle
+                success = true;
+                try
+                {
+                    bundle.start();
+                }
+                catch ( BundleException be )
+                {
+                    getLog().log( LogService.LOG_ERROR, "Cannot start", be );
+                }
+            }
+            else if ( "stop".equals( action ) )
+            {
+                // stop bundle
+                success = true;
+                try
+                {
+                    bundle.stop();
+                }
+                catch ( BundleException be )
+                {
+                    getLog().log( LogService.LOG_ERROR, "Cannot stop", be );
+                }
+            }
+            else if ( "refresh".equals( action ) )
+            {
+                // refresh bundle wiring
+                refresh( bundle );
+                success = true;
+            }
+            else if ( "uninstall".equals( action ) )
+            {
+                success = actionUninstall(bundle);
+                bundle = null; // bundle has gone !
+            }
+        }
+
+        if ( "refreshPackages".equals( action ) )
+        {
+            getPackageAdmin().refreshPackages( null );
+            success = true;
+        }
+
+        if ( success )
+        {
+            // let's wait a little bit to give the framework time
+            // to process our request
+            try {
+                Thread.sleep(800);
+            } catch (InterruptedException e) {
+                // we ignore this
+            }
+            this.renderJSON(resp, null);
+        }
+        else
+        {
+            super.doPost( req, resp );
+        }
+    }
+
+
+   protected boolean actionUninstall(Bundle bundle)
+   {
+       try
+       {
+           bundle.uninstall();
+           return true;
+       }
+       catch ( BundleException be )
+       {
+           getLog().log( LogService.LOG_ERROR, "Cannot uninstall", be );
+           return false;
+       }
+   }
+
+
+    private Bundle getBundle( String pathInfo )
+    {
+        // only use last part of the pathInfo
+        pathInfo = pathInfo.substring( pathInfo.lastIndexOf( '/' ) + 1 );
+
+        // assume bundle Id
+        try
+        {
+            final long bundleId = Long.parseLong( pathInfo );
+            if ( bundleId >= 0 )
+            {
+                return getBundleContext().getBundle( bundleId );
+            }
+        }
+        catch ( NumberFormatException nfe )
+        {
+            // check if this follows the pattern {symbolic-name}[:{version}]
+            final int pos = pathInfo.indexOf(':');
+            final String symbolicName;
+            final String version;
+            if ( pos == -1 ) {
+                symbolicName = pathInfo;
+                version = null;
+            } else {
+                symbolicName = pathInfo.substring(0, pos);
+                version = pathInfo.substring(pos+1);
+            }
+
+            // search
+            final Bundle[] bundles = getBundleContext().getBundles();
+            for(int i=0; i<bundles.length; i++)
+            {
+                final Bundle bundle = bundles[i];
+                // check symbolic name first
+                if ( symbolicName.equals(bundle.getSymbolicName()) )
+                {
+                    if ( version == null || version.equals(bundle.getHeaders().get(Constants.BUNDLE_VERSION)) )
+                    {
+                        return bundle;
+                    }
+                }
+            }
+        }
+
+
+        return null;
+    }
+
+
+    private void appendBundleInfoCount( final StringBuffer buf, String msg, int count )
+    {
+        buf.append(count);
+        buf.append(" bundle");
+        if ( count != 1 )
+            buf.append( 's' );
+        buf.append(' ');
+        buf.append(msg);
+    }
+
+    protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
+    {
+        // get request info from request attribute
+        final RequestInfo reqInfo = getRequestInfo(request);
+        final PrintWriter pw = response.getWriter();
+
+        final String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT );
+        Util.script(pw, appRoot, "bundles.js");
+
+        Util.startScript( pw );
+        pw.println( "var imgRoot = '" + appRoot + "/res/imgs';");
+        pw.println( "var startLevel = " + getStartLevel().getInitialBundleStartLevel() + ";");
+        pw.println( "var drawDetails = " + reqInfo.bundleRequested + ";");
+        Util.endScript( pw );
+
+        Util.script(pw, appRoot, "bundles.js");
+
+        pw.println( "<div id='plugin_content'/>");
+        Util.startScript( pw );
+        pw.print( "renderBundles(");
+        writeJSON(pw, reqInfo.bundle);
+        pw.println(");" );
+        Util.endScript( pw );
+    }
+
+    private void renderJSON( final HttpServletResponse response, final Bundle bundle ) throws IOException
+    {
+        response.setContentType( "application/json" );
+        response.setCharacterEncoding( "UTF-8" );
+
+        final PrintWriter pw = response.getWriter();
+        writeJSON(pw, bundle);
+    }
+
+    private void writeJSON( final PrintWriter pw, final Bundle bundle) throws IOException
+    {
+        final Bundle[] allBundles = this.getBundles();
+        final String statusLine = this.getStatusLine(allBundles);
+        final Bundle[] bundles = ( bundle != null ) ? new Bundle[]
+            { bundle } : allBundles;
+        Util.sort( bundles );
+
+        final JSONWriter jw = new JSONWriter( pw );
+
+        try
+        {
+            jw.object();
+
+            jw.key( "status" );
+            jw.value( statusLine );
+
+            jw.key( "data" );
+
+            jw.array();
+
+            for ( int i = 0; i < bundles.length; i++ )
+            {
+                bundleInfo( jw, bundles[i], bundle != null );
+            }
+
+            jw.endArray();
+
+            jw.endObject();
+
+        }
+        catch ( JSONException je )
+        {
+            throw new IOException( je.toString() );
+        }
+
+    }
+
+    private String getStatusLine(final Bundle[] bundles)
+    {
+        int active = 0, installed = 0, resolved = 0, fragments = 0;
+        for ( int i = 0; i < bundles.length; i++ )
+        {
+            switch ( bundles[i].getState() )
+            {
+                case Bundle.ACTIVE:
+                    active++;
+                    break;
+                case Bundle.INSTALLED:
+                    installed++;
+                    break;
+                case Bundle.RESOLVED:
+                    if ( bundles[i].getHeaders().get(Constants.FRAGMENT_HOST) != null )
+                    {
+                        fragments++;
+                    }
+                    else
+                    {
+                        resolved++;
+                    }
+                    break;
+            }
+        }
+        final StringBuffer buffer = new StringBuffer();
+        buffer.append("Bundle information: ");
+        appendBundleInfoCount(buffer, "in total", bundles.length);
+        if ( active == bundles.length || active + fragments == bundles.length )
+        {
+            buffer.append(" - all ");
+            appendBundleInfoCount(buffer, "active.", bundles.length);
+        }
+        else
+        {
+            if ( active != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "active", active);
+            }
+            if ( fragments != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "active fragments", fragments);
+            }
+            if ( resolved != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "resolved", resolved);
+            }
+            if ( installed != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "installed", installed);
+            }
+            buffer.append('.');
+        }
+        return buffer.toString();
+    }
+
+    private void bundleInfo( JSONWriter jw, Bundle bundle, boolean details ) throws JSONException
+    {
+        jw.object();
+        jw.key( "id" );
+        jw.value( bundle.getBundleId() );
+        jw.key( "name" );
+        jw.value( Util.getName( bundle ) );
+        jw.key( "state" );
+        jw.value( toStateString( bundle ) );
+        jw.key( "version" );
+        jw.value( Util.getHeaderValue(bundle, Constants.BUNDLE_VERSION) );
+        jw.key( "symbolicName" );
+        jw.value( Util.getHeaderValue(bundle, Constants.BUNDLE_SYMBOLICNAME) );
+
+        jw.key( "actions" );
+        jw.array();
+
+        if ( bundle.getBundleId() != 0 )
+        {
+            if ( hasStart(bundle) )
+            {
+                action( jw, hasStart( bundle ), "start", "Start", "start" );
+            }
+            else
+            {
+                action( jw, hasStop( bundle ), "stop", "Stop", "stop" );
+            }
+            action( jw, true, "refresh", "Refresh Package Imports", "refresh" );
+            action( jw, hasUninstall( bundle ), "uninstall", "Uninstall", "delete" );
+        }
+        jw.endArray();
+
+        if ( details )
+        {
+            bundleDetails( jw, bundle );
+        }
+
+        jw.endObject();
+    }
+
+
+    protected Bundle[] getBundles()
+    {
+        return getBundleContext().getBundles();
+    }
+
+
+    private String toStateString( final Bundle bundle )
+    {
+        switch ( bundle.getState() )
+        {
+            case Bundle.INSTALLED:
+                return "Installed";
+            case Bundle.RESOLVED:
+                if ( isFragmentBundle(bundle) )
+                {
+                    return "Fragment";
+                }
+                return "Resolved";
+            case Bundle.STARTING:
+                return "Starting";
+            case Bundle.ACTIVE:
+                return "Active";
+            case Bundle.STOPPING:
+                return "Stopping";
+            case Bundle.UNINSTALLED:
+                return "Uninstalled";
+            default:
+                return "Unknown: " + bundle.getState();
+        }
+    }
+
+
+    private void action( JSONWriter jw, boolean enabled, String op, String opLabel, String image ) throws JSONException
+    {
+        jw.object();
+        jw.key( "enabled" ).value( enabled );
+        jw.key( "name" ).value( opLabel );
+        jw.key( "link" ).value( op );
+        jw.key( "image" ).value( image );
+        jw.endObject();
+    }
+
+    private boolean isFragmentBundle( Bundle bundle)
+    {
+        return bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null;
+    }
+
+    private boolean hasStart( Bundle bundle )
+    {
+        if ( isFragmentBundle(bundle) )
+        {
+            return false;
+        }
+        return bundle.getState() == Bundle.INSTALLED || bundle.getState() == Bundle.RESOLVED;
+    }
+
+
+    private boolean hasStop( Bundle bundle )
+    {
+        if ( isFragmentBundle(bundle) )
+        {
+            return false;
+        }
+        return bundle.getState() == Bundle.ACTIVE;
+    }
+
+
+    private boolean hasUninstall( Bundle bundle )
+    {
+        return bundle.getState() == Bundle.INSTALLED || bundle.getState() == Bundle.RESOLVED
+            || bundle.getState() == Bundle.ACTIVE;
+
+    }
+
+
+    private void bundleDetails( JSONWriter jw, Bundle bundle ) throws JSONException
+    {
+        Dictionary headers = bundle.getHeaders();
+
+        jw.key( "props" );
+        jw.array();
+        keyVal( jw, "Symbolic Name", bundle.getSymbolicName() );
+        keyVal( jw, "Version", headers.get( Constants.BUNDLE_VERSION ) );
+        keyVal( jw, "Location", bundle.getLocation() );
+        keyVal( jw, "Last Modification", new Date( bundle.getLastModified() ) );
+
+        String docUrl = ( String ) headers.get( Constants.BUNDLE_DOCURL );
+        if ( docUrl != null )
+        {
+            keyVal( jw, "Bundle Documentation", docUrl );
+        }
+
+        keyVal( jw, "Vendor", headers.get( Constants.BUNDLE_VENDOR ) );
+        keyVal( jw, "Copyright", headers.get( Constants.BUNDLE_COPYRIGHT ) );
+        keyVal( jw, "Description", headers.get( Constants.BUNDLE_DESCRIPTION ) );
+
+        keyVal( jw, "Start Level", getStartLevel( bundle ) );
+
+        keyVal( jw, "Bundle Classpath", headers.get( Constants.BUNDLE_CLASSPATH ) );
+
+        if ( bundle.getState() == Bundle.INSTALLED )
+        {
+            listImportExportsUnresolved( jw, bundle );
+        }
+        else
+        {
+            listImportExport( jw, bundle );
+        }
+
+        listServices( jw, bundle );
+        
+        listHeaders( jw, bundle );
+
+        jw.endArray();
+    }
+
+
+    private Integer getStartLevel( Bundle bundle )
+    {
+        StartLevel sl = getStartLevel();
+        return ( sl != null ) ? new Integer( sl.getBundleStartLevel( bundle ) ) : null;
+    }
+
+
+    private void listImportExport( JSONWriter jw, Bundle bundle ) throws JSONException
+    {
+        PackageAdmin packageAdmin = getPackageAdmin();
+        if ( packageAdmin == null )
+        {
+            return;
+        }
+
+        Map usingBundles = new TreeMap();
+
+        ExportedPackage[] exports = packageAdmin.getExportedPackages( bundle );
+        if ( exports != null && exports.length > 0 )
+        {
+            // do alphabetical sort
+            Arrays.sort( exports, new Comparator()
+            {
+                public int compare( ExportedPackage p1, ExportedPackage p2 )
+                {
+                    return p1.getName().compareTo( p2.getName() );
+                }
+
+
+                public int compare( Object o1, Object o2 )
+                {
+                    return compare( ( ExportedPackage ) o1, ( ExportedPackage ) o2 );
+                }
+            } );
+
+            JSONArray val = new JSONArray();
+            for ( int j = 0; j < exports.length; j++ )
+            {
+                ExportedPackage export = exports[j];
+                collectExport( val, export.getName(), export.getVersion() );
+                Bundle[] ubList = export.getImportingBundles();
+                if ( ubList != null )
+                {
+                    for ( int i = 0; i < ubList.length; i++ )
+                    {
+                        Bundle ub = ubList[i];
+                        usingBundles.put( ub.getSymbolicName(), ub );
+                    }
+                }
+            }
+            keyVal( jw, "Exported Packages", val );
+        }
+        else
+        {
+            keyVal( jw, "Exported Packages", "None" );
+        }
+
+        exports = packageAdmin.getExportedPackages( ( Bundle ) null );
+        if ( exports != null && exports.length > 0 )
+        {
+            // collect import packages first
+            final List imports = new ArrayList();
+            for ( int i = 0; i < exports.length; i++ )
+            {
+                final ExportedPackage ep = exports[i];
+                final Bundle[] importers = ep.getImportingBundles();
+                for ( int j = 0; importers != null && j < importers.length; j++ )
+                {
+                    if ( importers[j].getBundleId() == bundle.getBundleId() )
+                    {
+                        imports.add( ep );
+
+                        break;
+                    }
+                }
+            }
+            // now sort
+            JSONArray val = new JSONArray();
+            if ( imports.size() > 0 )
+            {
+                final ExportedPackage[] packages = ( ExportedPackage[] ) imports.toArray( new ExportedPackage[imports
+                    .size()] );
+                Arrays.sort( packages, new Comparator()
+                {
+                    public int compare( ExportedPackage p1, ExportedPackage p2 )
+                    {
+                        return p1.getName().compareTo( p2.getName() );
+                    }
+
+
+                    public int compare( Object o1, Object o2 )
+                    {
+                        return compare( ( ExportedPackage ) o1, ( ExportedPackage ) o2 );
+                    }
+                } );
+                // and finally print out
+                for ( int i = 0; i < packages.length; i++ )
+                {
+                    ExportedPackage ep = packages[i];
+                    collectImport( val, ep.getName(), ep.getVersion(), false, ep );
+                }
+            }
+            else
+            {
+                // add description if there are no imports
+                val.put( "None" );
+            }
+
+            keyVal( jw, "Imported Packages", val );
+        }
+
+        if ( !usingBundles.isEmpty() )
+        {
+            JSONArray val = new JSONArray();
+            for ( Iterator ui = usingBundles.values().iterator(); ui.hasNext(); )
+            {
+                Bundle usingBundle = ( Bundle ) ui.next();
+                val.put( getBundleDescriptor( usingBundle ) );
+            }
+            keyVal( jw, "Importing Bundles", val );
+        }
+    }
+
+
+    private void listImportExportsUnresolved( JSONWriter jw, Bundle bundle ) throws JSONException
+    {
+        Dictionary dict = bundle.getHeaders();
+
+        String target = ( String ) dict.get( Constants.EXPORT_PACKAGE );
+        if ( target != null )
+        {
+            R4Package[] pkgs = R4Package.parseImportOrExportHeader( target );
+            if ( pkgs != null && pkgs.length > 0 )
+            {
+                // do alphabetical sort
+                Arrays.sort( pkgs, new Comparator()
+                {
+                    public int compare( R4Package p1, R4Package p2 )
+                    {
+                        return p1.getName().compareTo( p2.getName() );
+                    }
+
+
+                    public int compare( Object o1, Object o2 )
+                    {
+                        return compare( ( R4Package ) o1, ( R4Package ) o2 );
+                    }
+                } );
+
+                JSONArray val = new JSONArray();
+                for ( int i = 0; i < pkgs.length; i++ )
+                {
+                    R4Export export = new R4Export( pkgs[i] );
+                    collectExport( val, export.getName(), export.getVersion() );
+                }
+                keyVal( jw, "Exported Packages", val );
+            }
+            else
+            {
+                keyVal( jw, "Exported Packages", "None" );
+            }
+        }
+
+        target = ( String ) dict.get( Constants.IMPORT_PACKAGE );
+        if ( target != null )
+        {
+            R4Package[] pkgs = R4Package.parseImportOrExportHeader( target );
+            if ( pkgs != null && pkgs.length > 0 )
+            {
+                Map imports = new TreeMap();
+                for ( int i = 0; i < pkgs.length; i++ )
+                {
+                    R4Package pkg = pkgs[i];
+                    imports.put( pkg.getName(), new R4Import( pkg ) );
+                }
+
+                // collect import packages first
+                final Map candidates = new HashMap();
+                PackageAdmin packageAdmin = getPackageAdmin();
+                if ( packageAdmin != null )
+                {
+                    ExportedPackage[] exports = packageAdmin.getExportedPackages( ( Bundle ) null );
+                    if ( exports != null && exports.length > 0 )
+                    {
+
+                        for ( int i = 0; i < exports.length; i++ )
+                        {
+                            final ExportedPackage ep = exports[i];
+
+                            R4Import imp = ( R4Import ) imports.get( ep.getName() );
+                            if ( imp != null && imp.isSatisfied( toR4Export( ep ) ) )
+                            {
+                                candidates.put( ep.getName(), ep );
+                            }
+                        }
+                    }
+                }
+
+                // now sort
+                JSONArray val = new JSONArray();
+                if ( imports.size() > 0 )
+                {
+                    for ( Iterator ii = imports.values().iterator(); ii.hasNext(); )
+                    {
+                        R4Import r4Import = ( R4Import ) ii.next();
+                        ExportedPackage ep = ( ExportedPackage ) candidates.get( r4Import.getName() );
+
+                        // if there is no matching export, check whether this
+                        // bundle has the package, ignore the entry in this case
+                        if ( ep == null )
+                        {
+                            String path = r4Import.getName().replace( '.', '/' );
+                            if ( bundle.getResource( path ) != null )
+                            {
+                                continue;
+                            }
+                        }
+
+                        collectImport( val, r4Import.getName(), r4Import.getVersion(), r4Import.isOptional(), ep );
+                    }
+                }
+                else
+                {
+                    // add description if there are no imports
+                    val.put( "None" );
+                }
+
+                keyVal( jw, "Imported Packages", val );
+            }
+        }
+    }
+
+
+    private void listServices( JSONWriter jw, Bundle bundle ) throws JSONException
+    {
+        ServiceReference[] refs = bundle.getRegisteredServices();
+        if ( refs == null || refs.length == 0 )
+        {
+            return;
+        }
+        
+        for ( int i = 0; i < refs.length; i++ )
+        {
+            String key = "Service ID " + refs[i].getProperty( Constants.SERVICE_ID );
+            
+            JSONArray val = new JSONArray();
+            
+            appendProperty( val, refs[i], Constants.OBJECTCLASS, "Types" );
+            appendProperty( val, refs[i], Constants.SERVICE_PID, "PID" );
+            appendProperty( val, refs[i], ConfigurationAdmin.SERVICE_FACTORYPID, "Factory PID" );
+            appendProperty( val, refs[i], ComponentConstants.COMPONENT_NAME, "Component Name" );
+            appendProperty( val, refs[i], ComponentConstants.COMPONENT_ID, "Component ID" );
+            appendProperty( val, refs[i], ComponentConstants.COMPONENT_FACTORY, "Component Factory" );
+            appendProperty( val, refs[i], Constants.SERVICE_DESCRIPTION, "Description" );
+            appendProperty( val, refs[i], Constants.SERVICE_VENDOR, "Vendor" );
+            
+            keyVal( jw, key, val);
+        }
+    }
+    
+    
+    private void listHeaders( JSONWriter jw, Bundle bundle ) throws JSONException
+    {
+        JSONArray val = new JSONArray();
+
+        Dictionary headers = bundle.getHeaders();
+        Enumeration he = headers.keys();
+        while ( he.hasMoreElements() )
+        {
+            Object header = he.nextElement();
+            String value = String.valueOf(headers.get( header ));
+            // Package headers may be long, support line breaking by
+            // ensuring blanks after comma and semicolon.
+            value = value.replaceAll( "([;,])", "$1 " );
+            val.put( header + ": " + value );
+        }
+
+        keyVal( jw, "Manifest Headers", val );
+    }
+
+
+    private void appendProperty( JSONArray array, ServiceReference ref, String name, String label )
+    {
+        StringBuffer dest = new StringBuffer();
+        Object value = ref.getProperty( name );
+        if ( value instanceof Object[] )
+        {
+            Object[] values = ( Object[] ) value;
+            dest.append( label ).append( ": " );
+            for ( int j = 0; j < values.length; j++ )
+            {
+                if ( j > 0 )
+                    dest.append( ", " );
+                dest.append( values[j] );
+            }
+            array.put(dest.toString());
+        }
+        else if ( value != null )
+        {
+            dest.append( label ).append( ": " ).append( value );
+            array.put(dest.toString());
+        }
+    }
+
+
+    private void keyVal( JSONWriter jw, String key, Object value ) throws JSONException
+    {
+        if ( key != null && value != null )
+        {
+            jw.object();
+            jw.key( "key" );
+            jw.value( key );
+            jw.key( "value" );
+            jw.value( value );
+            jw.endObject();
+        }
+    }
+
+
+    private void collectExport( JSONArray array, String name, Version version )
+    {
+        StringBuffer val = new StringBuffer();
+        boolean bootDel = isBootDelegated( name );
+        if ( bootDel )
+        {
+            val.append( "!! " );
+        }
+
+        val.append( name );
+        val.append( ",version=" );
+        val.append( version );
+
+        if ( bootDel )
+        {
+            val.append( " -- Overwritten by Boot Delegation" );
+        }
+
+        array.put(val.toString());
+    }
+
+
+    private void collectImport( JSONArray array, String name, Version version, boolean optional, ExportedPackage export )
+    {
+        StringBuffer val = new StringBuffer();
+        boolean bootDel = isBootDelegated( name );
+
+        String marker = null;
+        val.append( name );
+        val.append( ",version=" ).append( version );
+        val.append( " from " );
+
+        if ( export != null )
+        {
+            val.append( getBundleDescriptor( export.getExportingBundle() ) );
+
+            if ( bootDel )
+            {
+                val.append( " -- Overwritten by Boot Delegation" );
+                marker = "INFO";
+            }
+        }
+        else
+        {
+            val.append( " -- Cannot be resolved" );
+            marker = "ERROR";
+
+            if ( optional )
+            {
+                val.append( " but is not required" );
+            }
+
+            if ( bootDel )
+            {
+                val.append( " and overwritten by Boot Delegation" );
+            }
+        }
+
+        if ( marker != null ) {
+            val.insert(0, ": ");
+            val.insert(0, marker);
+        }
+
+        array.put(val);
+    }
+
+
+    // returns true if the package is listed in the bootdelegation property
+    private boolean isBootDelegated( String pkgName )
+    {
+
+        // bootdelegation analysis from Apache Felix R4SearchPolicyCore
+
+        // Only consider delegation if we have a package name, since
+        // we don't want to promote the default package. The spec does
+        // not take a stand on this issue.
+        if ( pkgName.length() > 0 )
+        {
+
+            // Delegate any packages listed in the boot delegation
+            // property to the parent class loader.
+            for ( int i = 0; i < bootPkgs.length; i++ )
+            {
+
+                // A wildcarded boot delegation package will be in the form of
+                // "foo.", so if the package is wildcarded do a startsWith() or
+                // a regionMatches() to ignore the trailing "." to determine if
+                // the request should be delegated to the parent class loader.
+                // If the package is not wildcarded, then simply do an equals()
+                // test to see if the request should be delegated to the parent
+                // class loader.
+                if ( ( bootPkgWildcards[i] && ( pkgName.startsWith( bootPkgs[i] ) || bootPkgs[i].regionMatches( 0,
+                    pkgName, 0, pkgName.length() ) ) )
+                    || ( !bootPkgWildcards[i] && bootPkgs[i].equals( pkgName ) ) )
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    private R4Export toR4Export( ExportedPackage export )
+    {
+        R4Attribute version = new R4Attribute( Constants.VERSION_ATTRIBUTE, export.getVersion().toString(), false );
+        return new R4Export( export.getName(), null, new R4Attribute[]
+            { version } );
+    }
+
+
+    private String getBundleDescriptor( Bundle bundle )
+    {
+        StringBuffer val = new StringBuffer();
+        if ( bundle.getSymbolicName() != null )
+        {
+            // list the bundle name if not null
+            val.append( bundle.getSymbolicName() );
+            val.append( " (" ).append( bundle.getBundleId() );
+            val.append( ")" );
+        }
+        else if ( bundle.getLocation() != null )
+        {
+            // otherwise try the location
+            val.append( bundle.getLocation() );
+            val.append( " (" ).append( bundle.getBundleId() );
+            val.append( ")" );
+        }
+        else
+        {
+            // fallback to just the bundle id
+            // only append the bundle
+            val.append( bundle.getBundleId() );
+        }
+        return val.toString();
+    }
+
+
+    private void refresh( final Bundle bundle )
+    {
+        getPackageAdmin().refreshPackages( new Bundle[]
+            { bundle } );
+    }
+
+    private final class RequestInfo
+    {
+        public final String extension;
+        public final Bundle bundle;
+        public final boolean bundleRequested;
+
+        protected RequestInfo( final HttpServletRequest request )
+        {
+            String info = request.getPathInfo();
+            // remove label and starting slash
+            info = info.substring(getLabel().length() + 1);
+
+            // get extension
+            if ( info.endsWith(".json") )
+            {
+                extension = "json";
+                info = info.substring(0, info.length() - 5);
+            }
+            else
+            {
+                extension = "html";
+            }
+
+            // we only accept direct requests to a bundle if they have a slash after the label
+            String bundleInfo = null;
+            if (info.startsWith("/") )
+            {
+                bundleInfo = info.substring(1);
+            }
+            if ( bundleInfo == null )
+            {
+                bundle = null;
+                bundleRequested = false;
+            }
+            else
+            {
+                bundle = getBundle(bundleInfo);
+                bundleRequested = true;
+            }
+            request.setAttribute(BundlesServlet.class.getName(), this);
+        }
+
+    }
+
+    public static RequestInfo getRequestInfo(final HttpServletRequest request)
+    {
+        return (RequestInfo)request.getAttribute(BundlesServlet.class.getName());
+    }
+}

Modified: projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/BundlesPlugin.java
===================================================================
--- projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/BundlesPlugin.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/BundlesPlugin.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -23,16 +23,18 @@
 
 //$Id$
 
-import java.io.IOException;
 import java.io.PrintWriter;
-import java.text.MessageFormat;
 
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
-import org.apache.felix.webconsole.internal.Util;
 import org.apache.felix.webconsole.internal.core.BundlesServlet;
-import org.apache.felix.webconsole.internal.servlet.OsgiManager;
+import org.jboss.osgi.spi.service.DeployerService;
+import org.jboss.osgi.spi.util.BundleInfo;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
 
 /**
  * A Console plugin
@@ -51,11 +53,42 @@
    }
 
    @Override
+   protected boolean actionUninstall(Bundle bundle)
+   {
+      BundleContext context = getBundleContext();
+      ServiceReference sref = context.getServiceReference(DeployerService.class.getName());
+      if (sref == null)
+      {
+         getLog().log(LogService.LOG_WARNING, "Cannot obtain service: " + DeployerService.class.getName());
+         return super.actionUninstall(bundle);
+      }
+
+      DeployerService service = (DeployerService)context.getService(sref);
+      BundleInfo info = service.getBundleInfo(bundle);
+      if (info == null)
+      {
+         getLog().log(LogService.LOG_WARNING, "Cannot find bundle info for: " + bundle);
+         return super.actionUninstall(bundle);
+      }
+      
+      try
+      {
+         service.undeploy(new BundleInfo[] { info });
+         return true;
+      }
+      catch (BundleException be)
+      {
+         getLog().log(LogService.LOG_ERROR, "Cannot uninstall", be);
+         return false;
+      }
+   }
+
+   @Override
    protected void endResponse(HttpServletRequest request, PrintWriter pw)
    {
       // Footer redered before content in bundle plugin
       // https://issues.apache.org/jira/browse/FELIX-1020
-         
+
       //String appRoot = (String)request.getAttribute(OsgiManager.ATTR_APP_ROOT);
       //String footer = MessageFormat.format(PluginHelper.getFooter(), new Object[]{ appRoot });
       //pw.println(footer);

Modified: projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/InstallActionExt.java
===================================================================
--- projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/InstallActionExt.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/InstallActionExt.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -53,7 +53,7 @@
       final ServiceReference sref = context.getServiceReference(DeployerService.class.getName());
       if (sref == null)
       {
-         getLog().log(LogService.LOG_WARNING, "Cannot obtain server: " + DeployerService.class.getName());
+         getLog().log(LogService.LOG_WARNING, "Cannot obtain service: " + DeployerService.class.getName());
          super.installBackground(bundleFile, location, startlevel, doStart, refreshPackages);
          return;
       }
@@ -64,7 +64,7 @@
          {
             DeployerService service = (DeployerService)context.getService(sref);
             URL bundleURL = getBundleURL(bundleFile);
-            BundleInfo info = service.createBundleInfo(bundleURL);
+            BundleInfo info = service.getBundleInfo(bundleURL);
 
             service.deploy(new BundleInfo[] { info });
             Bundle bundle = service.getBundle(info);

Modified: projects/jboss-osgi/projects/integration/jbossas/trunk/src/main/java/org/jboss/osgi/integration/jbossas/AbstractMicrocontainerService.java
===================================================================
--- projects/jboss-osgi/projects/integration/jbossas/trunk/src/main/java/org/jboss/osgi/integration/jbossas/AbstractMicrocontainerService.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/integration/jbossas/trunk/src/main/java/org/jboss/osgi/integration/jbossas/AbstractMicrocontainerService.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -26,6 +26,7 @@
 import static org.jboss.osgi.spi.management.MicrocontainerServiceMBean.MBEAN_MICROCONTAINER_SERVICE;
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -73,7 +74,7 @@
 public abstract class AbstractMicrocontainerService implements DeployerService, MicrocontainerService
 {
    private VFSDeploymentFactory deploymentFactory = VFSDeploymentFactory.getInstance();
-   private Map<URL, String> contextMap = Collections.synchronizedMap(new HashMap<URL, String>());
+   private Map<String, BundleDeployment> deployments = Collections.synchronizedMap(new HashMap<String, BundleDeployment>());
 
    public abstract Kernel getKernel();
 
@@ -112,7 +113,7 @@
       return (T)getRegisteredBean(beanName);
    }
 
-   public BundleInfo createBundleInfo(URL url) throws BundleException
+   public BundleInfo getBundleInfo(URL url) throws BundleException
    {
       Manifest manifest;
       try
@@ -136,12 +137,40 @@
       return new BundleInfo(url, symbolicName, version);
    }
 
+   public BundleInfo getBundleInfo(Bundle bundle)
+   {
+      if (bundle == null)
+         throw new IllegalArgumentException("Cannot obtain bundle info for: null");
+
+      String sname = bundle.getSymbolicName();
+      String version = (String)bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+
+      URL location = null;
+      for (String auxLoc : deployments.keySet())
+      {
+         BundleDeployment auxDep = deployments.get(auxLoc);
+         BundleInfo auxInfo = auxDep.getBundleInfo();
+         if (sname.equals(auxInfo.getSymbolicName()) && version.equals(auxInfo.getVersion()))
+         {
+            location = toURL(auxLoc);
+            break;
+         }
+      }
+
+      BundleInfo info = null;
+      if (location != null)
+      {
+         info = new BundleInfo(location, sname, version);
+      }
+      return info;
+   }
+
    public Bundle getBundle(BundleInfo info)
    {
       BundleContext context = getRegisteredBean(BundleContext.class, BEAN_SYSTEM_BUNDLE_CONTEXT);
       String symbolicName = info.getSymbolicName();
       String version = info.getVersion();
-      
+
       Bundle bundle = null;
       for (Bundle aux : context.getBundles())
       {
@@ -165,8 +194,8 @@
 
    public boolean undeploy(URL url) throws BundleException
    {
-      String deploymentName = contextMap.remove(url);
-      if (deploymentName == null)
+      BundleDeployment dep = deployments.remove(url.toExternalForm());
+      if (dep == null)
       {
          logWarning("Package not deployed: " + url);
          return false;
@@ -175,14 +204,10 @@
       try
       {
          MainDeployer mainDeployer = (MainDeployer)getRegisteredBean("MainDeployer");
-         mainDeployer.removeDeployment(deploymentName);
+         mainDeployer.removeDeployment(dep.getName());
          mainDeployer.process();
          return true;
       }
-      catch (RuntimeException rte)
-      {
-         throw rte;
-      }
       catch (Exception ex)
       {
          logWarning("Cannot undeploy bundle", ex);
@@ -206,22 +231,27 @@
       {
          Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
 
-         List<Deployment> deployments = new ArrayList<Deployment>();
+         List<Deployment> depList = new ArrayList<Deployment>();
          MainDeployer mainDeployer = (MainDeployer)getRegisteredBean("MainDeployer");
          for (URL location : urls)
          {
+            BundleInfo info = getBundleInfo(location);
+            
             VirtualFile file = VFS.createNewRoot(location);
             VFSDeployment deployment = deploymentFactory.createVFSDeployment(file);
             mainDeployer.addDeployment(deployment);
-            deployments.add(deployment);
-            contextMap.put(location, deployment.getName());
+            
+            String depName = deployment.getName();
+            BundleDeployment dep = new BundleDeployment(depName, info);
+            deployments.put(location.toExternalForm(), dep);
+            depList.add(deployment);
          }
 
          // Process the deployments
          mainDeployer.process();
 
          // Check for completeness
-         Deployment[] depArr = deployments.toArray(new Deployment[deployments.size()]);
+         Deployment[] depArr = depList.toArray(new Deployment[depList.size()]);
          mainDeployer.checkComplete(depArr);
       }
       catch (RuntimeException rte)
@@ -238,21 +268,22 @@
       }
    }
 
-   public void undeploy(BundleInfo[] bundles) throws BundleException
+   public void undeploy(BundleInfo[] infos) throws BundleException
    {
       try
       {
          MainDeployer mainDeployer = (MainDeployer)getRegisteredBean("MainDeployer");
-         for (BundleInfo bundle : bundles)
+         for (BundleInfo info : infos)
          {
-            String deploymentName = contextMap.remove(bundle.getLocation());
-            if (deploymentName != null)
+            URL location = info.getLocation();
+            BundleDeployment dep = deployments.remove(location.toExternalForm());
+            if (dep != null)
             {
-               mainDeployer.removeDeployment(deploymentName);
+               mainDeployer.removeDeployment(dep.getName());
             }
             else
             {
-               logWarning("Package not deployed: " + bundle.getLocation());
+               logWarning("Package not deployed: " + location);
             }
          }
          mainDeployer.process();
@@ -313,6 +344,40 @@
       }
    }
 
+   private URL toURL(String location)
+   {
+      try
+      {
+         return new URL(location);
+      }
+      catch (MalformedURLException e)
+      {
+         throw new IllegalArgumentException("Invalid URL location: " + location);
+      }
+   }
+
+   static class BundleDeployment 
+   {
+      private String name;
+      private BundleInfo info;
+      
+      public BundleDeployment(String depName, BundleInfo bundleInfo)
+      {
+         this.name = depName;
+         this.info = bundleInfo;
+      }
+      
+      public String getName()
+      {
+         return name;
+      }
+      
+      public BundleInfo getBundleInfo()
+      {
+         return info;
+      }
+   }
+
    static class PreInstalledControllerContext extends AbstractControllerContext
    {
       public PreInstalledControllerContext(Object name, ControllerContextActions actions, Object target)

Modified: projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeployerService.java
===================================================================
--- projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeployerService.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeployerService.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -46,11 +46,17 @@
    ObjectName MBEAN_DEPLOYER_SERVICE = ObjectNameFactory.create("jboss.osgi:service=DeployerService");
 
    /**
-    * Create the bundle info for the given bundle URL
+    * Get the bundle info for the given bundle URL
     */
-   BundleInfo createBundleInfo(URL url) throws BundleException;
+   BundleInfo getBundleInfo(URL url) throws BundleException;
    
    /**
+    * Get the bundle info for the given bundle
+    * @return null, if this service does not maintain the bundle info
+    */
+   BundleInfo getBundleInfo(Bundle bundle);
+   
+   /**
     * Get the installed bundle for the given bundle info 
     * @return null, if there is no bundle that matches the given bundle info
     */

Modified: projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/util/BundleInfo.java
===================================================================
--- projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/util/BundleInfo.java	2009-07-07 10:48:39 UTC (rev 90893)
+++ projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/util/BundleInfo.java	2009-07-07 11:58:40 UTC (rev 90894)
@@ -21,10 +21,10 @@
  */
 package org.jboss.osgi.spi.util;
 
+import java.net.URL;
+
 //$Id$
 
-import java.net.URL;
-
 /**
  * An abstraction of a bundle
  * 
@@ -39,14 +39,15 @@
 
    public BundleInfo(URL location, String symbolicName, String version)
    {
+      if (location == null)
+         throw new IllegalArgumentException("Location cannot be null");
+      if (symbolicName == null)
+         throw new IllegalArgumentException("Symbolic name cannot be null");
+      
       this.symbolicName = symbolicName;
       this.location = location;
+      
       this.version = (version != null ? version : "0.0.0");
-      
-      if (symbolicName == null)
-         throw new IllegalArgumentException("Symbolic name cannot be null");
-      if (location == null)
-         throw new IllegalArgumentException("Location cannot be null");
    }
 
    /**




More information about the jboss-cvs-commits mailing list