[FELIX-3398] Track new versions of artifact listener and optionally update all bundles when a new version is detected
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1310180 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
index e1759c1..1e8fc51 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
@@ -101,6 +101,7 @@
public final static String ENABLE_CONFIG_SAVE = "felix.fileinstall.enableConfigSave";
public final static String START_LEVEL = "felix.fileinstall.start.level";
public final static String ACTIVE_LEVEL = "felix.fileinstall.active.level";
+ public final static String UPDATE_WITH_LISTENERS = "felix.fileinstall.bundles.updateWithListeners";
static final SecureRandom random = new SecureRandom();
@@ -120,6 +121,7 @@
boolean noInitialDelay;
int startLevel;
int activeLevel;
+ boolean updateWithListeners;
// Map of all installed artifacts
Map/* <File, Artifact> */ currentManagedArtifacts = new HashMap/* <File, Artifact> */();
@@ -155,6 +157,7 @@
noInitialDelay = getBoolean(properties, NO_INITIAL_DELAY, false);
startLevel = getInt(properties, START_LEVEL, 0); // by default, do not touch start level
activeLevel = getInt(properties, ACTIVE_LEVEL, 0); // by default, always scan
+ updateWithListeners = getBoolean(properties, UPDATE_WITH_LISTENERS, false); // Do not update bundles when listeners are updated
this.context.addBundleListener(this);
FilenameFilter flt;
@@ -338,8 +341,11 @@
List/*<Artifact>*/ created = new ArrayList/*<Artifact>*/();
// Try to process again files that could not be processed
- files.addAll(processingFailures);
- processingFailures.clear();
+ synchronized (processingFailures)
+ {
+ files.addAll(processingFailures);
+ processingFailures.clear();
+ }
for (Iterator it = files.iterator(); it.hasNext(); )
{
@@ -401,7 +407,10 @@
// processing for this artifact until one is found
if (listener == null)
{
- processingFailures.add(file);
+ synchronized (processingFailures)
+ {
+ processingFailures.add(file);
+ }
continue;
}
artifact.setListener(listener);
@@ -440,7 +449,10 @@
// processing for this artifact until one is found
if (listener == null)
{
- processingFailures.add(file);
+ synchronized (processingFailures)
+ {
+ processingFailures.add(file);
+ }
continue;
}
// Create the artifact
@@ -1355,4 +1367,50 @@
return result;
}
+ public void addListener(ArtifactListener listener, long stamp)
+ {
+ if (updateWithListeners)
+ {
+ for (Iterator it = currentManagedArtifacts.values().iterator(); it.hasNext(); )
+ {
+ Artifact artifact = (Artifact) it.next();
+ if (artifact.getListener() == null && artifact.getBundleId() > 0)
+ {
+ Bundle bundle = context.getBundle(artifact.getBundleId());
+ if (bundle != null && bundle.getLastModified() < stamp)
+ {
+ File path = artifact.getPath();
+ if (listener.canHandle(path))
+ {
+ synchronized (processingFailures)
+ {
+ processingFailures.add(path);
+ }
+ }
+ }
+ }
+ }
+ }
+ synchronized (this)
+ {
+ this.notifyAll();
+ }
+ }
+
+ public void removeListener(ArtifactListener listener)
+ {
+ for (Iterator it = currentManagedArtifacts.values().iterator(); it.hasNext(); )
+ {
+ Artifact artifact = (Artifact) it.next();
+ if (artifact.getListener() == listener)
+ {
+ artifact.setListener(null);
+ }
+ }
+ synchronized (this)
+ {
+ this.notifyAll();
+ }
+ }
+
}
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
index 7e9ccbe..0099276 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
@@ -48,6 +48,7 @@
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* This clever little bundle watches a directory and will install any jar file
@@ -55,7 +56,7 @@
* fragment).
*
*/
-public class FileInstall implements BundleActivator
+public class FileInstall implements BundleActivator, ServiceTrackerCustomizer
{
static ServiceTracker padmin;
static ServiceTracker startLevel;
@@ -80,28 +81,11 @@
padmin.open();
startLevel = new ServiceTracker(context, StartLevel.class.getName(), null);
startLevel.open();
+
String flt = "(|(" + Constants.OBJECTCLASS + "=" + ArtifactInstaller.class.getName() + ")"
+ "(" + Constants.OBJECTCLASS + "=" + ArtifactTransformer.class.getName() + ")"
+ "(" + Constants.OBJECTCLASS + "=" + ArtifactUrlTransformer.class.getName() + "))";
- listenersTracker = new ServiceTracker(context, FrameworkUtil.createFilter(flt), null)
- {
- public Object addingService(ServiceReference serviceReference)
- {
- ArtifactListener listener = (ArtifactListener) super.addingService(serviceReference);
- addListener(serviceReference, listener);
- return listener;
- }
- public void modifiedService(ServiceReference reference, Object service)
- {
- super.modifiedService(reference, service);
- removeListener(reference);
- addListener(reference, (ArtifactListener) service);
- }
- public void removedService(ServiceReference serviceReference, Object o)
- {
- removeListener(serviceReference);
- }
- };
+ listenersTracker = new ServiceTracker(context, FrameworkUtil.createFilter(flt), this);
listenersTracker.open();
try
@@ -157,6 +141,22 @@
}
}
+ public Object addingService(ServiceReference serviceReference)
+ {
+ ArtifactListener listener = (ArtifactListener) context.getService(serviceReference);
+ addListener(serviceReference, listener);
+ return listener;
+ }
+ public void modifiedService(ServiceReference reference, Object service)
+ {
+ removeListener(reference, (ArtifactListener) service);
+ addListener(reference, (ArtifactListener) service);
+ }
+ public void removedService(ServiceReference serviceReference, Object service)
+ {
+ removeListener(serviceReference, (ArtifactListener) service);
+ }
+
// Adapted for FELIX-524
private void set(Hashtable ht, String key)
{
@@ -267,20 +267,9 @@
{
listeners.put(reference, listener);
}
- notifyWatchers();
- }
+
+ long currentStamp = reference.getBundle().getLastModified();
- private void removeListener(ServiceReference reference)
- {
- synchronized (listeners)
- {
- listeners.remove(reference);
- }
- notifyWatchers();
- }
-
- private void notifyWatchers()
- {
List /*<DirectoryWatcher>*/ toNotify = new ArrayList /*<DirectoryWatcher>*/();
synchronized (watchers)
{
@@ -289,10 +278,25 @@
for (Iterator w = toNotify.iterator(); w.hasNext();)
{
DirectoryWatcher dir = (DirectoryWatcher) w.next();
- synchronized (dir)
- {
- dir.notifyAll();
- }
+ dir.addListener( listener, currentStamp );
+ }
+ }
+
+ private void removeListener(ServiceReference reference, ArtifactListener listener)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(reference);
+ }
+ List /*<DirectoryWatcher>*/ toNotify = new ArrayList /*<DirectoryWatcher>*/();
+ synchronized (watchers)
+ {
+ toNotify.addAll(watchers.values());
+ }
+ for (Iterator w = toNotify.iterator(); w.hasNext();)
+ {
+ DirectoryWatcher dir = (DirectoryWatcher) w.next();
+ dir.removeListener( listener );
}
}