[jboss-cvs] JBossAS SVN: r90841 - in projects/jboss-osgi/projects: bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal and 9 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Jul 6 08:58:04 EDT 2009


Author: thomas.diesler at jboss.com
Date: 2009-07-06 08:58:03 -0400 (Mon, 06 Jul 2009)
New Revision: 90841

Added:
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/InstallActionExt.java
Removed:
   projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/BundleInfoImpl.java
Modified:
   projects/jboss-osgi/projects/bundles/common/trunk/pom.xml
   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/pom.xml
   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/pom.xml
   projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/WebConsole.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/DeploymentScannerService.java
Log:
[JBOSGI-66] Support bundle deployment through web console

Modified: projects/jboss-osgi/projects/bundles/common/trunk/pom.xml
===================================================================
--- projects/jboss-osgi/projects/bundles/common/trunk/pom.xml	2009-07-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/common/trunk/pom.xml	2009-07-06 12:58:03 UTC (rev 90841)
@@ -18,7 +18,7 @@
   
   <properties>
     <version.jboss.logging>2.0.5.GA</version.jboss.logging>
-    <version.jboss.osgi.spi>1.0.0.Beta2</version.jboss.osgi.spi>
+    <version.jboss.osgi.spi>1.0.0-SNAPSHOT</version.jboss.osgi.spi>
     <version.osgi>r4v41</version.osgi>
   </properties>
   

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-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/DeployerServiceDelegate.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -27,6 +27,7 @@
 
 import org.jboss.osgi.spi.service.BundleInfo;
 import org.jboss.osgi.spi.service.DeployerService;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.InvalidSyntaxException;
@@ -49,6 +50,18 @@
       this.context = context;
    }
 
+   public Bundle getBundle(BundleInfo info) throws BundleException
+   {
+      DeployerService service = getDefaultDeployerService();
+      return service.getBundle(info);
+   }
+
+   public BundleInfo getBundleInfo(URL url) throws BundleException
+   {
+      DeployerService service = getDefaultDeployerService();
+      return service.getBundleInfo(url);
+   }
+
    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-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/common/trunk/src/main/java/org/jboss/osgi/common/internal/SystemDeployerService.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -23,11 +23,15 @@
 
 //$Id$
 
+import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
 
 import org.jboss.osgi.common.log.LogServiceTracker;
 import org.jboss.osgi.spi.management.ManagedBundleService;
@@ -36,6 +40,7 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -58,6 +63,51 @@
       this.context = context;
    }
 
+   public BundleInfo getBundleInfo(URL url) throws BundleException
+   {
+      Manifest manifest;
+      try
+      {
+         JarFile jarFile = new JarFile(url.getPath());
+         manifest = jarFile.getManifest();
+         jarFile.close();
+      }
+      catch (IOException ex)
+      {
+         throw new BundleException("Cannot get manifest from: " + url);
+
+      }
+
+      Attributes attribs = manifest.getMainAttributes();
+      String symbolicName = attribs.getValue(Constants.BUNDLE_SYMBOLICNAME);
+      if (symbolicName == null)
+         throw new BundleException("Cannot obtain Bundle-SymbolicName for: " + url);
+
+      String version = attribs.getValue(Constants.BUNDLE_VERSION);
+      return new BundleInfoImpl(url, symbolicName, version);
+   }
+
+   public Bundle getBundle(BundleInfo info) throws BundleException
+   {
+      String symbolicName = info.getSymbolicName();
+      String version = info.getVersion();
+      
+      Bundle bundle = null;
+      for (Bundle aux : context.getBundles())
+      {
+         if (aux.getSymbolicName().equals(symbolicName))
+         {
+            String auxVersion = (String)aux.getHeaders().get(Constants.BUNDLE_VERSION);
+            if (version == null || version.equals(auxVersion))
+            {
+               bundle = aux;
+               break;
+            }
+         }
+      }
+      return bundle;
+   }
+
    public void deploy(BundleInfo[] bundleInfos) throws BundleException
    {
       // Install the NEW bundles
@@ -156,4 +206,35 @@
          log.log(LogService.LOG_DEBUG, "No ManagedBundleService. Cannot unregister managed bundle: " + bundle);
       }
    }
+
+   static class BundleInfoImpl implements BundleInfo
+   {
+      private URL location;
+      private String symbolicName;
+      private String version;
+
+      public BundleInfoImpl(URL location, String symbolicName, String version)
+      {
+         super();
+         this.location = location;
+         this.symbolicName = symbolicName;
+         this.version = version;
+      }
+
+      public URL getLocation()
+      {
+         return location;
+      }
+
+      public String getSymbolicName()
+      {
+         return symbolicName;
+      }
+
+      public String getVersion()
+      {
+         return version;
+      }
+
+   }
 }
\ No newline at end of file

Modified: projects/jboss-osgi/projects/bundles/hotdeploy/trunk/pom.xml
===================================================================
--- projects/jboss-osgi/projects/bundles/hotdeploy/trunk/pom.xml	2009-07-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/hotdeploy/trunk/pom.xml	2009-07-06 12:58:03 UTC (rev 90841)
@@ -18,8 +18,8 @@
   </parent>
 
   <properties>
-    <version.jboss.osgi.common>1.0.0.Beta2</version.jboss.osgi.common>
-    <version.jboss.osgi.spi>1.0.0.Beta2</version.jboss.osgi.spi>
+    <version.jboss.osgi.common>1.0.0-SNAPSHOT</version.jboss.osgi.common>
+    <version.jboss.osgi.spi>1.0.0-SNAPSHOT</version.jboss.osgi.spi>
     <version.osgi>r4v41</version.osgi>
   </properties>
   

Deleted: projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/BundleInfoImpl.java
===================================================================
--- projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/BundleInfoImpl.java	2009-07-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/BundleInfoImpl.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -1,123 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.osgi.service.hotdeploy.internal;
-
-//$Id$
-
-import java.net.URL;
-import java.util.Dictionary;
-
-import org.jboss.osgi.spi.service.BundleInfo;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-
-/**
- * An abstraction of a bundle in the scan folder
- * 
- * @author thomas.diesler at jboss.com
- * @since 27-May-2009
- */
-public class BundleInfoImpl implements BundleInfo
-{
-   private URL location;
-   private String symbolicName;
-   private String version;
-   private State state;
-
-   public BundleInfoImpl(URL bundleURL, String symbolicName, String version)
-   {
-      this.symbolicName = symbolicName;
-      this.location = bundleURL;
-      this.state = State.NEW;
-
-      this.version = (version != null ? version : "0.0.0");
-   }
-
-   @SuppressWarnings("unchecked")
-   public void initFromBundle(Bundle bundle)
-   {
-      Dictionary headers = bundle.getHeaders();
-      String bundleVersion = (String)headers.get(Constants.BUNDLE_VERSION);
-      if (bundleVersion != null)
-         this.version = bundleVersion;
-      
-      int bundleState = bundle.getState();
-      switch (bundleState)
-      {
-         case Bundle.INSTALLED:
-         case Bundle.RESOLVED:
-         case Bundle.STARTING:
-         case Bundle.STOPPING:
-            state = State.INSTALLED;
-            break;
-            
-         case Bundle.ACTIVE:
-            state = State.ACTIVE;
-            break;
-            
-         case Bundle.UNINSTALLED:
-            state = State.UNINSTALLED;
-            break;
-      }
-   }
-
-   public URL getLocation()
-   {
-      return location;
-   }
-
-   public State getState()
-   {
-      return state;
-   }
-
-   public String getSymbolicName()
-   {
-      return symbolicName;
-   }
-
-   public String getVersion()
-   {
-      return version;
-   }
-
-   @Override
-   public boolean equals(Object obj)
-   {
-      if ((obj instanceof BundleInfoImpl) == false)
-         return false;
-      
-      BundleInfoImpl other = (BundleInfoImpl)obj;
-      return symbolicName.equals(other.symbolicName) && version.equals(other.version);
-   }
-
-   @Override
-   public int hashCode()
-   {
-      return toString().hashCode();
-   }
-
-   public String toString()
-   {
-      return "[" + state + "," + symbolicName + "," + version + "]";
-   }
-}
\ 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-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/hotdeploy/trunk/src/main/java/org/jboss/osgi/service/hotdeploy/internal/DeploymentScannerImpl.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -26,7 +26,6 @@
 import static org.jboss.osgi.spi.Constants.OSGI_HOME;
 
 import java.io.File;
-import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -34,18 +33,13 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
 
 import org.jboss.osgi.common.log.LogServiceTracker;
 import org.jboss.osgi.spi.service.BundleInfo;
 import org.jboss.osgi.spi.service.DeployerService;
 import org.jboss.osgi.spi.service.DeploymentScannerService;
-import org.jboss.osgi.spi.service.BundleInfo.State;
-import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
+import org.osgi.framework.BundleException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -139,11 +133,11 @@
    public void scan()
    {
       // Use a copy so listeners can remove themselves from within the callback
-      List<ScanListener> listenerArr = new ArrayList<ScanListener>(listeners);
-      for (ScanListener listener : listenerArr)
+      List<ScanListener> scanListeners = new ArrayList<ScanListener>(listeners);
+      for (ScanListener listener : scanListeners)
          listener.beforeScan(this);
       
-      List<BundleInfo> currScan = Arrays.asList(getBundles());
+      List<BundleInfo> currScan = Arrays.asList(getBundleInfos());
 
       if (traceBundles)
          logBundleInfos("Current Scan", currScan);
@@ -157,7 +151,7 @@
       lastScan = currScan;
       scanCount++;
 
-      for (ScanListener listener : listenerArr)
+      for (ScanListener listener : scanListeners)
          listener.afterScan(this);
    }
 
@@ -177,7 +171,7 @@
       // Detect OLD bundles that are not in the current scan  
       for (BundleInfo info : lastScan)
       {
-         if ((info.getState() == State.INSTALLED || info.getState() == State.ACTIVE) && currScan.contains(info) == false)
+         if (currScan.contains(info) == false)
             diff.add(info);
       }
 
@@ -205,7 +199,7 @@
       // Detect NEW bundles that are not in the last scan  
       for (BundleInfo info : currScan)
       {
-         if (info.getState() == BundleInfo.State.NEW && lastScan.contains(info) == false)
+         if (lastScan.contains(info) == false)
             diff.add(info);
       }
 
@@ -226,7 +220,7 @@
       return diff.size();
    }
 
-   public BundleInfo[] getBundles()
+   public BundleInfo[] getBundleInfos()
    {
       List<BundleInfo> bundles = new ArrayList<BundleInfo>();
       
@@ -238,17 +232,19 @@
       {
          for (File file : listFiles)
          {
-            BundleInfoImpl info = getBundleInfo(file);
-            
-            Bundle bundle = getInstalledBundle(info);
-            if (bundle != null)
-               info.initFromBundle(bundle);
-            
-            bundles.add(info);
+            try
+            {
+               BundleInfo info = deployer.getBundleInfo(toURL(file));
+               bundles.add(info);
+            }
+            catch (BundleException ex)
+            {
+               log.log(LogService.LOG_WARNING, "Cannot obtain bundle info for: " + file);
+            }
          }
       }
       
-      BundleInfo[] arr = new BundleInfoImpl[bundles.size()];
+      BundleInfo[] arr = new BundleInfo[bundles.size()];
       return bundles.toArray(arr);
    }
    
@@ -287,51 +283,6 @@
       scanLocation = scanFile;
    }
 
-   private BundleInfoImpl getBundleInfo(File file)
-   {
-      Manifest manifest;
-      try
-      {
-         JarFile jarFile = new JarFile(file);
-         manifest = jarFile.getManifest();
-         jarFile.close();
-      }
-      catch (IOException ex)
-      {
-         throw new IllegalStateException("Cannot obtain manifest from: " + file, ex);
-      }
-      
-      Attributes attribs = manifest.getMainAttributes();
-
-      String symbolicName = attribs.getValue(Constants.BUNDLE_SYMBOLICNAME);
-      if (symbolicName == null)
-         throw new IllegalStateException("Cannot obtain '" + Constants.BUNDLE_SYMBOLICNAME + "' from: " + file);
-
-      String version = attribs.getValue(Constants.BUNDLE_VERSION);
-      
-      return new BundleInfoImpl(toURL(file), symbolicName, version);
-   }
-
-   private Bundle getInstalledBundle(BundleInfo info)
-   {
-      Bundle bundle = null;
-      for (Bundle aux : context.getBundles())
-      {
-         String name = aux.getSymbolicName();
-         
-         String version = (String)aux.getHeaders().get(Constants.BUNDLE_VERSION);
-         if (version == null)
-            version = "0.0.0";
-         
-         if (name.equals(info.getSymbolicName()) && version.equals(info.getVersion()))
-         {
-            bundle = aux;
-            break;
-         }
-      }
-      return bundle;
-   }
-   
    private URL toURL(File file)
    {
       try

Modified: projects/jboss-osgi/projects/bundles/webconsole/trunk/pom.xml
===================================================================
--- projects/jboss-osgi/projects/bundles/webconsole/trunk/pom.xml	2009-07-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/pom.xml	2009-07-06 12:58:03 UTC (rev 90841)
@@ -18,6 +18,7 @@
 
   <!-- Properties -->
   <properties>
+    <version.jboss.osgi.spi>1.0.0-SNAPSHOT</version.jboss.osgi.spi>
     <version.commons.fileupload>1.1.1</version.commons.fileupload>
     <version.commons.io>1.4</version.commons.io>
     <version.felix.bundlerepository>1.0.3</version.felix.bundlerepository>
@@ -31,6 +32,12 @@
   <!-- Dependencies  -->
   <dependencies>
     <dependency>
+      <groupId>org.jboss.osgi</groupId>
+      <artifactId>jboss-osgi-spi</artifactId>
+      <version>${version.jboss.osgi.spi}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>${version.javax.servlet}</version>

Added: projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java
===================================================================
--- projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java	                        (rev 0)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/apache/felix/webconsole/internal/core/InstallAction.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -0,0 +1,390 @@
+/*
+ * 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.*;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.felix.webconsole.AbstractWebConsolePlugin;
+import org.apache.felix.webconsole.Action;
+import org.apache.felix.webconsole.internal.BaseManagementPlugin;
+import org.osgi.framework.*;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+
+/**
+ * The <code>InstallAction</code> TODO
+ */
+public class InstallAction extends BaseManagementPlugin implements Action
+{
+
+    public static final String NAME = "install";
+
+    public static final String LABEL = "Install or Update";
+
+    public static final String FIELD_STARTLEVEL = "bundlestartlevel";
+
+    public static final String FIELD_START = "bundlestart";
+
+    public static final String FIELD_BUNDLEFILE = "bundlefile";
+
+    // set to ask for PackageAdmin.refreshPackages() after install/update
+    public static final String FIELD_REFRESH_PACKAGES = "refreshPackages";
+
+
+    public String getName()
+    {
+        return NAME;
+    }
+
+
+    public String getLabel()
+    {
+        return LABEL;
+    }
+
+
+    public boolean performAction( HttpServletRequest request, HttpServletResponse response )
+    throws IOException
+    {
+
+        // get the uploaded data
+        Map params = ( Map ) request.getAttribute( AbstractWebConsolePlugin.ATTR_FILEUPLOAD );
+        if ( params == null )
+        {
+            return true;
+        }
+
+        FileItem startItem = getFileItem( params, FIELD_START, true );
+        FileItem startLevelItem = getFileItem( params, FIELD_STARTLEVEL, true );
+        FileItem bundleItem = getFileItem( params, FIELD_BUNDLEFILE, false );
+        FileItem refreshPackagesItem = getFileItem( params, FIELD_REFRESH_PACKAGES, true );
+
+        // don't care any more if not bundle item
+        if ( bundleItem == null || bundleItem.getSize() <= 0 )
+        {
+            return true;
+        }
+
+        // default values
+        // it exists
+        int startLevel = -1;
+        String bundleLocation = "inputstream:";
+
+        // convert the start level value
+        if ( startLevelItem != null )
+        {
+            try
+            {
+                startLevel = Integer.parseInt( startLevelItem.getString() );
+            }
+            catch ( NumberFormatException nfe )
+            {
+                getLog().log( LogService.LOG_INFO,
+                    "Cannot parse start level parameter " + startLevelItem + " to a number, not setting start level" );
+            }
+        }
+
+        // write the bundle data to a temporary file to ease processing
+        File tmpFile = null;
+        try
+        {
+            // copy the data to a file for better processing
+            tmpFile = File.createTempFile( "install", ".tmp" );
+            bundleItem.write( tmpFile );
+        }
+        catch ( Exception e )
+        {
+            getLog().log( LogService.LOG_ERROR, "Problem accessing uploaded bundle file", e );
+
+            // remove the tmporary file
+            if ( tmpFile != null )
+            {
+                tmpFile.delete();
+                tmpFile = null;
+            }
+        }
+
+        // install or update the bundle now
+        if ( tmpFile != null )
+        {
+            // start, refreshPackages just needs to exist, don't care for value
+            boolean start = startItem != null;
+            boolean refreshPackages = refreshPackagesItem != null;
+
+            bundleLocation = "inputstream:" + bundleItem.getName();
+            installBundle( bundleLocation, tmpFile, startLevel, start, refreshPackages );
+        }
+
+        return true;
+    }
+
+
+    private FileItem getFileItem( Map params, String name, boolean isFormField )
+    {
+        FileItem[] items = ( FileItem[] ) params.get( name );
+        if ( items != null )
+        {
+            for ( int i = 0; i < items.length; i++ )
+            {
+                if ( items[i].isFormField() == isFormField )
+                {
+                    return items[i];
+                }
+            }
+        }
+
+        // nothing found, fail
+        return null;
+    }
+
+
+    protected void installBundle( String location, File bundleFile, int startLevel, boolean start, boolean refreshPackages )
+    throws IOException
+    {
+        if ( bundleFile != null )
+        {
+
+            // try to get the bundle name, fail if none
+            String symbolicName = getSymbolicName( bundleFile );
+            if ( symbolicName == null )
+            {
+                bundleFile.delete();
+                throw new IOException(Constants.BUNDLE_SYMBOLICNAME + " header missing, cannot install bundle");
+            }
+
+            // check for existing bundle first
+            Bundle updateBundle = null;
+            if ( Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals( symbolicName ) )
+            {
+                updateBundle = getBundleContext().getBundle( 0 );
+            }
+            else
+            {
+                Bundle[] bundles = getBundleContext().getBundles();
+                for ( int i = 0; i < bundles.length; i++ )
+                {
+                    if ( ( bundles[i].getLocation() != null && bundles[i].getLocation().equals( location ) )
+                        || ( bundles[i].getSymbolicName() != null && bundles[i].getSymbolicName().equals( symbolicName ) ) )
+                    {
+                        updateBundle = bundles[i];
+                        break;
+                    }
+                }
+            }
+
+            if ( updateBundle != null )
+            {
+
+                updateBackground( updateBundle, bundleFile, refreshPackages );
+
+            }
+            else
+            {
+
+                installBackground( bundleFile, location, startLevel, start, refreshPackages );
+
+            }
+        }
+    }
+
+
+    private String getSymbolicName( File bundleFile )
+    {
+        JarFile jar = null;
+        try
+        {
+            jar = new JarFile( bundleFile );
+            Manifest m = jar.getManifest();
+            if ( m != null )
+            {
+                return m.getMainAttributes().getValue( Constants.BUNDLE_SYMBOLICNAME );
+            }
+        }
+        catch ( IOException ioe )
+        {
+            getLog().log( LogService.LOG_WARNING, "Cannot extract symbolic name of bundle file " + bundleFile, ioe );
+        }
+        finally
+        {
+            if ( jar != null )
+            {
+                try
+                {
+                    jar.close();
+                }
+                catch ( IOException ioe )
+                {
+                    // ignore
+                }
+            }
+        }
+
+        // fall back to "not found"
+        return null;
+    }
+
+
+    protected void installBackground( final File bundleFile, final String location, final int startlevel,
+        final boolean doStart, final boolean refreshPackages )
+    {
+
+        Thread t = new InstallHelper( this, "Background Install " + bundleFile, bundleFile, refreshPackages )
+        {
+
+            protected Bundle doRun( InputStream bundleStream ) throws BundleException
+            {
+                Bundle bundle = getBundleContext().installBundle( location, bundleStream );
+
+                if ( startlevel > 0 )
+                {
+                    StartLevel sl = getStartLevel();
+                    if ( sl != null )
+                    {
+                        sl.setBundleStartLevel( bundle, startlevel );
+                    }
+                }
+
+                if ( doStart )
+                {
+                    bundle.start();
+                }
+
+                return bundle;
+            }
+        };
+
+        t.start();
+    }
+
+
+    protected void updateBackground( final Bundle bundle, final File bundleFile, final boolean refreshPackages )
+    {
+        Thread t = new InstallHelper( this, "Background Update" + bundle.getSymbolicName() + " ("
+            + bundle.getBundleId() + ")", bundleFile, refreshPackages )
+        {
+
+            protected Bundle doRun( InputStream bundleStream ) throws BundleException
+            {
+                bundle.update( bundleStream );
+                return bundle;
+            }
+        };
+
+        t.start();
+    }
+
+    public static abstract class InstallHelper extends Thread
+    {
+
+        private final InstallAction installAction;
+
+        private final File bundleFile;
+
+        private final boolean refreshPackages;
+
+
+        public 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
+            {
+                // 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 )
+                {
+                    try
+                    {
+                        bundleStream.close();
+                    }
+                    catch ( IOException ignore )
+                    {
+                    }
+                }
+                bundleFile.delete();
+            }
+        }
+
+
+        protected void sleepSilently( long msecs )
+        {
+            try
+            {
+                sleep( msecs );
+            }
+            catch ( InterruptedException ie )
+            {
+                // don't care
+            }
+        }
+    }
+}

Modified: projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/WebConsole.java
===================================================================
--- projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/WebConsole.java	2009-07-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/WebConsole.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -24,8 +24,6 @@
 //$Id$
 
 import org.apache.felix.webconsole.internal.compendium.ComponentConfigurationPrinter;
-import org.apache.felix.webconsole.internal.compendium.ComponentsServlet;
-import org.apache.felix.webconsole.internal.core.InstallAction;
 import org.apache.felix.webconsole.internal.core.SetStartLevelAction;
 import org.apache.felix.webconsole.internal.misc.ConfigurationRender;
 import org.apache.felix.webconsole.internal.obr.BundleRepositoryRender;
@@ -37,6 +35,7 @@
 import org.jboss.osgi.service.webconsole.internal.plugins.BundlesPlugin;
 import org.jboss.osgi.service.webconsole.internal.plugins.ConfigManagerPlugin;
 import org.jboss.osgi.service.webconsole.internal.plugins.EventAdminPlugin;
+import org.jboss.osgi.service.webconsole.internal.plugins.InstallActionExt;
 import org.jboss.osgi.service.webconsole.internal.plugins.LicensePlugin;
 import org.jboss.osgi.service.webconsole.internal.plugins.LogServicePlugin;
 import org.osgi.framework.BundleContext;
@@ -97,7 +96,7 @@
             ConfigManagerPlugin.class.getName(),
             LogServicePlugin.class.getName(),
             BundlesPlugin.class.getName(),
-            InstallAction.class.getName(), 
+            InstallActionExt.class.getName(), 
             SetStartLevelAction.class.getName(),
             // DepPackServlet.class.getName(),
             EventAdminPlugin.class.getName(),

Added: 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	                        (rev 0)
+++ projects/jboss-osgi/projects/bundles/webconsole/trunk/src/main/java/org/jboss/osgi/service/webconsole/internal/plugins/InstallActionExt.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.osgi.service.webconsole.internal.plugins;
+
+//$Id: EventAdminPlugin.java 86577 2009-04-01 07:53:06Z thomas.diesler at jboss.com $
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.felix.webconsole.internal.core.InstallAction;
+import org.jboss.osgi.spi.service.BundleInfo;
+import org.jboss.osgi.spi.service.DeployerService;
+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;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * A Console plugin
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 06-Jul-2009
+ */
+public class InstallActionExt extends InstallAction
+{
+   @Override
+   protected void installBackground(final File bundleFile, final String location, final int startlevel, final boolean doStart, boolean refreshPackages)
+   {
+      final BundleContext context = getBundleContext();
+      final ServiceReference sref = context.getServiceReference(DeployerService.class.getName());
+      if (sref == null)
+      {
+         getLog().log(LogService.LOG_WARNING, "Cannot obtain server: " + DeployerService.class.getName());
+         super.installBackground(bundleFile, location, startlevel, doStart, refreshPackages);
+         return;
+      }
+
+      Thread t = new InstallHelper(this, "Background Install " + bundleFile, bundleFile, refreshPackages)
+      {
+         protected Bundle doRun(InputStream bundleStream) throws BundleException
+         {
+            DeployerService service = (DeployerService)context.getService(sref);
+            URL bundleURL = getBundleURL(bundleFile);
+            
+            service.deploy(bundleURL);
+            BundleInfo info = service.getBundleInfo(bundleURL);
+            Bundle bundle = service.getBundle(info);
+
+            if (startlevel > 0)
+            {
+               StartLevel sl = getStartLevel();
+               if (sl != null)
+               {
+                  sl.setBundleStartLevel(bundle, startlevel);
+               }
+            }
+
+            if (doStart)
+            {
+               bundle.start();
+            }
+
+            return bundle;
+         }
+
+      };
+
+      t.start();
+   }
+
+   private URL getBundleURL(final File bundleFile) throws BundleException
+   {
+      URL bundleURL;
+      try
+      {
+         bundleURL = bundleFile.toURL();
+      }
+      catch (MalformedURLException ex)
+      {
+         throw new BundleException(ex.getMessage());
+      }
+      return bundleURL;
+   }
+}
\ No newline at end of file

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-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/integration/jbossas/trunk/src/main/java/org/jboss/osgi/integration/jbossas/AbstractMicrocontainerService.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -25,12 +25,16 @@
 
 import static org.jboss.osgi.spi.management.MicrocontainerServiceMBean.MBEAN_MICROCONTAINER_SERVICE;
 
+import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
 
 import javax.management.MBeanServer;
 import javax.management.StandardMBean;
@@ -55,7 +59,10 @@
 import org.jboss.osgi.spi.service.MicrocontainerService;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VirtualFile;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
 
 /**
  * An OSGi Service the gives access to the Kernel.
@@ -105,6 +112,52 @@
       return (T)getRegisteredBean(beanName);
    }
 
+   public BundleInfo getBundleInfo(URL url) throws BundleException
+   {
+      Manifest manifest;
+      try
+      {
+         JarFile jarFile = new JarFile(url.getPath());
+         manifest = jarFile.getManifest();
+         jarFile.close();
+      }
+      catch (IOException ex)
+      {
+         throw new BundleException("Cannot get manifest from: " + url);
+
+      }
+
+      Attributes attribs = manifest.getMainAttributes();
+      String symbolicName = attribs.getValue(Constants.BUNDLE_SYMBOLICNAME);
+      if (symbolicName == null)
+         throw new BundleException("Cannot obtain Bundle-SymbolicName for: " + url);
+
+      String version = attribs.getValue(Constants.BUNDLE_VERSION);
+      return new BundleInfoImpl(url, symbolicName, version);
+   }
+
+   public Bundle getBundle(BundleInfo info) throws BundleException
+   {
+      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())
+      {
+         if (aux.getSymbolicName().equals(symbolicName))
+         {
+            String auxVersion = (String)aux.getHeaders().get(Constants.BUNDLE_VERSION);
+            if (version == null || version.equals(auxVersion))
+            {
+               bundle = aux;
+               break;
+            }
+         }
+      }
+      return bundle;
+   }
+
    public void deploy(URL url) throws BundleException
    {
       deployInternal(new URL[] { url });
@@ -267,4 +320,35 @@
          super(name, actions, null, target);
       }
    }
+
+   static class BundleInfoImpl implements BundleInfo
+   {
+      private URL location;
+      private String symbolicName;
+      private String version;
+
+      public BundleInfoImpl(URL location, String symbolicName, String version)
+      {
+         super();
+         this.location = location;
+         this.symbolicName = symbolicName;
+         this.version = version;
+      }
+
+      public URL getLocation()
+      {
+         return location;
+      }
+
+      public String getSymbolicName()
+      {
+         return symbolicName;
+      }
+
+      public String getVersion()
+      {
+         return version;
+      }
+
+   }
 }
\ No newline at end of file

Modified: projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeploymentScannerService.java
===================================================================
--- projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeploymentScannerService.java	2009-07-06 12:56:35 UTC (rev 90840)
+++ projects/jboss-osgi/projects/spi/trunk/src/main/java/org/jboss/osgi/spi/service/DeploymentScannerService.java	2009-07-06 12:58:03 UTC (rev 90841)
@@ -74,7 +74,7 @@
    /**
     * Returns the array of bundles currently known to the deployemtn scanner. 
     */
-   BundleInfo[] getBundles();
+   BundleInfo[] getBundleInfos();
    
    /**
     * Add a scan listener to this service




More information about the jboss-cvs-commits mailing list