Author: gnodet
Date: Fri Jan  7 15:50:49 2011
New Revision: 1056363

URL: http://svn.apache.org/viewvc?rev=1056363&view=rev
Log:
[KARAF-358] When the feature service calls refresh(), it should wait for the 
refresh to happen before returning

Modified:
    
karaf/branches/karaf-2.1.x/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
    
karaf/branches/karaf-2.1.x/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java

Modified: 
karaf/branches/karaf-2.1.x/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
URL: 
http://svn.apache.org/viewvc/karaf/branches/karaf-2.1.x/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java?rev=1056363&r1=1056362&r2=1056363&view=diff
==============================================================================
--- 
karaf/branches/karaf-2.1.x/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
 (original)
+++ 
karaf/branches/karaf-2.1.x/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
 Fri Jan  7 15:50:49 2011
@@ -74,7 +74,7 @@ import static java.lang.String.format;
  * installing the needed bundles.
  *
  */
-public class FeaturesServiceImpl implements FeaturesService {
+public class FeaturesServiceImpl implements FeaturesService, FrameworkListener 
{
 
     public static final String CONFIG_KEY = 
"org.apache.karaf.features.configKey";
 
@@ -94,6 +94,8 @@ public class FeaturesServiceImpl impleme
     private List<FeaturesListener> listeners = new 
CopyOnWriteArrayList<FeaturesListener>();
     private ThreadLocal<Repository> repo = new ThreadLocal<Repository>();
     private EventAdminListener eventAdminListener;
+    private final Object refreshLock = new Object();
+    private long refreshTimeout = 5000;
 
     public FeaturesServiceImpl() {
     }
@@ -138,6 +140,14 @@ public class FeaturesServiceImpl impleme
         this.resolverTimeout = resolverTimeout;
     }
 
+    public long getRefreshTimeout() {
+        return refreshTimeout;
+    }
+
+    public void setRefreshTimeout(long refreshTimeout) {
+        this.refreshTimeout = refreshTimeout;
+    }
+
     public void registerListener(FeaturesListener listener) {
         listeners.add(listener);
         for (Repository repository : listRepositories()) {
@@ -291,7 +301,7 @@ public class FeaturesServiceImpl impleme
                     }
                     if (refresh) {
                         LOGGER.info("Refreshing bundles: {}", sb.toString());
-                        
getPackageAdmin().refreshPackages(bundlesToRefresh.toArray(new 
Bundle[bundlesToRefresh.size()]));
+                        refreshPackages(bundlesToRefresh.toArray(new 
Bundle[bundlesToRefresh.size()]));
                     }
                 }
             }
@@ -644,9 +654,7 @@ public class FeaturesServiceImpl impleme
                 b.uninstall();
             }
         }
-        if (getPackageAdmin() != null) {
-            getPackageAdmin().refreshPackages(null);
-        }
+        refreshPackages(null);
         callListeners(new FeatureEvent(feature, 
FeatureEvent.EventType.FeatureInstalled, false));
         saveState();
     }
@@ -735,6 +743,9 @@ public class FeaturesServiceImpl impleme
     }
 
     public void start() throws Exception {
+        // Register FrameworkEventListener
+        bundleContext.addFrameworkListener(this);
+        // Register EventAdmin listener
         EventAdminListener listener = null;
         try {
             
getClass().getClassLoader().loadClass("org.osgi.service.event.EventAdmin");
@@ -744,6 +755,7 @@ public class FeaturesServiceImpl impleme
             LOGGER.debug("EventAdmin package is not available, just don't use 
it");
         }
         this.eventAdminListener = listener;
+        // Load State
         if (!loadState()) {
             if (uris != null) {
                 for (URI uri : uris) {
@@ -756,6 +768,7 @@ public class FeaturesServiceImpl impleme
             }
             saveState();
         }
+        // Install boot features
         if (boot != null && !bootFeaturesInstalled) {
             new Thread() {
                 public void run() {
@@ -788,12 +801,30 @@ public class FeaturesServiceImpl impleme
     }
 
     public void stop() throws Exception {
+        bundleContext.removeFrameworkListener(this);
         uris = new HashSet<URI>(repositories.keySet());
         while (!repositories.isEmpty()) {
             internalRemoveRepository(repositories.keySet().iterator().next());
         }
     }
 
+    public void frameworkEvent(FrameworkEvent event) {
+        if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
+            synchronized (refreshLock) {
+                refreshLock.notifyAll();
+            }
+        }
+    }
+
+    protected void refreshPackages(Bundle[] bundles) throws 
InterruptedException {
+        if (getPackageAdmin() != null) {
+            synchronized (refreshLock) {
+                getPackageAdmin().refreshPackages(bundles);
+                refreshLock.wait(refreshTimeout);
+            }
+        }
+    }
+
     protected String[] parsePid(String pid) {
         int n = pid.indexOf('-');
         if (n > 0) {

Modified: 
karaf/branches/karaf-2.1.x/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
URL: 
http://svn.apache.org/viewvc/karaf/branches/karaf-2.1.x/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java?rev=1056363&r1=1056362&r2=1056363&view=diff
==============================================================================
--- 
karaf/branches/karaf-2.1.x/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
 (original)
+++ 
karaf/branches/karaf-2.1.x/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
 Fri Jan  7 15:50:49 2011
@@ -27,6 +27,7 @@ import org.apache.karaf.features.Feature
 import org.apache.felix.utils.manifest.Clause;
 import org.easymock.EasyMock;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkListener;
 
 import static org.easymock.EasyMock.*;
 
@@ -102,6 +103,8 @@ public class FeaturesServiceImplTest ext
     public void testStartDoesNotFailWithOneInvalidUri()  {
         BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
         
expect(bundleContext.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
+        
bundleContext.addFrameworkListener(EasyMock.<FrameworkListener>anyObject());
+        
bundleContext.removeFrameworkListener(EasyMock.<FrameworkListener>anyObject());
         replay(bundleContext);
         FeaturesServiceImpl service = new FeaturesServiceImpl();
         service.setBundleContext(bundleContext);


Reply via email to