Author: gnodet
Date: Fri Apr 6 06:27:38 2012
New Revision: 1310180
URL: http://svn.apache.org/viewvc?rev=1310180&view=rev
Log:
[FELIX-3398] Track new versions of artifact listener and optionally update all
bundles when a new version is detected
Modified:
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
Modified:
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
URL:
http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java?rev=1310180&r1=1310179&r2=1310180&view=diff
==============================================================================
---
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
(original)
+++
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
Fri Apr 6 06:27:38 2012
@@ -101,6 +101,7 @@ public class DirectoryWatcher extends Th
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 @@ public class DirectoryWatcher extends Th
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 @@ public class DirectoryWatcher extends Th
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 @@ public class DirectoryWatcher extends Th
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 @@ public class DirectoryWatcher extends Th
// 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 @@ public class DirectoryWatcher extends Th
// 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 @@ public class DirectoryWatcher extends Th
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();
+ }
+ }
+
}
Modified:
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
URL:
http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java?rev=1310180&r1=1310179&r2=1310180&view=diff
==============================================================================
---
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
(original)
+++
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
Fri Apr 6 06:27:38 2012
@@ -48,6 +48,7 @@ import org.osgi.service.cm.ManagedServic
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 @@ import org.osgi.util.tracker.ServiceTrac
* fragment).
*
*/
-public class FileInstall implements BundleActivator
+public class FileInstall implements BundleActivator, ServiceTrackerCustomizer
{
static ServiceTracker padmin;
static ServiceTracker startLevel;
@@ -80,28 +81,11 @@ public class FileInstall implements Bund
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 class FileInstall implements Bund
}
}
+ 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,27 @@ public class FileInstall implements Bund
{
listeners.put(reference, listener);
}
- notifyWatchers();
+
+ long currentStamp = reference.getBundle().getLastModified();
+
+ 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.addListener( listener, currentStamp );
+ }
}
- private void removeListener(ServiceReference reference)
+ private void removeListener(ServiceReference reference, ArtifactListener
listener)
{
synchronized (listeners)
{
listeners.remove(reference);
}
- notifyWatchers();
- }
-
- private void notifyWatchers()
- {
List /*<DirectoryWatcher>*/ toNotify = new ArrayList
/*<DirectoryWatcher>*/();
synchronized (watchers)
{
@@ -289,10 +296,7 @@ public class FileInstall implements Bund
for (Iterator w = toNotify.iterator(); w.hasNext();)
{
DirectoryWatcher dir = (DirectoryWatcher) w.next();
- synchronized (dir)
- {
- dir.notifyAll();
- }
+ dir.removeListener( listener );
}
}