You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:37:00 UTC
[sling-org-apache-sling-fsresource] 09/15: SLING-6279 : Switch from
event admin to Sling Resource Observation API
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.fsresource-1.2.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-fsresource.git
commit dde630e7617a0bbf696d76d043156d8248ba293c
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun Nov 13 11:07:45 2016 +0000
SLING-6279 : Switch from event admin to Sling Resource Observation API
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/fsresource@1769486 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 31 +---
.../sling/fsprovider/internal/FileMonitor.java | 54 +++----
.../fsprovider/internal/FsResourceProvider.java | 170 +++++++++++----------
3 files changed, 118 insertions(+), 137 deletions(-)
diff --git a/pom.xml b/pom.xml
index 896f9f8..0b84370 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.sling</groupId>
<artifactId>sling</artifactId>
- <version>26</version>
+ <version>29</version>
<relativePath/>
</parent>
@@ -45,13 +45,6 @@
<build>
<plugins>
<plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-scr-plugin</artifactId>
- <configuration>
- <specVersion>1.1</specVersion>
- </configuration>
- </plugin>
- <plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<executions>
@@ -68,25 +61,18 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
- <configuration>
- <instructions>
- <Private-Package>
- org.apache.sling.fsprovider.internal
- </Private-Package>
- </instructions>
- </configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
+ <artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.3.0</version>
+ <version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
@@ -95,11 +81,7 @@
</dependency>
<dependency>
<groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
+ <artifactId>osgi.core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -115,10 +97,5 @@
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <scope>compile</scope>
- </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java b/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java
index 336f1c1..5729b7c 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java
@@ -19,13 +19,14 @@
package org.apache.sling.fsprovider.internal;
import java.io.File;
-import java.util.Dictionary;
-import java.util.Hashtable;
+import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
-import org.apache.sling.api.SlingConstants;
-import org.osgi.service.event.EventAdmin;
+import org.apache.sling.api.resource.observation.ResourceChange;
+import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
+import org.apache.sling.spi.resource.provider.ObservationReporter;
+import org.apache.sling.spi.resource.provider.ObserverConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -91,6 +92,7 @@ public class FileMonitor extends TimerTask {
/**
* @see java.util.TimerTask#run()
*/
+ @Override
public void run() {
synchronized (timer) {
stopped = false;
@@ -102,10 +104,10 @@ public class FileMonitor extends TimerTask {
}
synchronized ( this ) {
try {
- // if we don't have an event admin, we just skip the check
- final EventAdmin localEA = this.provider.getEventAdmin();
- if ( localEA != null ) {
- this.check(this.root, localEA);
+ // if we don't have an observation reporter, we just skip the check
+ final ObservationReporter reporter = this.provider.getObservationReporter();
+ if ( reporter != null ) {
+ this.check(this.root, reporter);
}
} catch (Exception e) {
// ignore this
@@ -120,9 +122,9 @@ public class FileMonitor extends TimerTask {
/**
* Check the monitorable
* @param monitorable The monitorable to check
- * @param localEA The event admin
+ * @param reporter The ObservationReporter
*/
- private void check(final Monitorable monitorable, final EventAdmin localEA) {
+ private void check(final Monitorable monitorable, final ObservationReporter reporter) {
logger.debug("Checking {}", monitorable.file);
// if the file is non existing, check if it has been readded
if ( monitorable.status instanceof NonExistingStatus ) {
@@ -130,16 +132,16 @@ public class FileMonitor extends TimerTask {
// new file and reset status
createStatus(monitorable);
sendEvents(monitorable,
- SlingConstants.TOPIC_RESOURCE_ADDED,
- localEA);
+ ChangeType.ADDED,
+ reporter);
}
} else {
// check if the file has been removed
if ( !monitorable.file.exists() ) {
// removed file and update status
sendEvents(monitorable,
- SlingConstants.TOPIC_RESOURCE_REMOVED,
- localEA);
+ ChangeType.REMOVED,
+ reporter);
monitorable.status = NonExistingStatus.SINGLETON;
} else {
// check for changes
@@ -149,15 +151,15 @@ public class FileMonitor extends TimerTask {
fs.lastModified = monitorable.file.lastModified();
// changed
sendEvents(monitorable,
- SlingConstants.TOPIC_RESOURCE_CHANGED,
- localEA);
+ ChangeType.CHANGED,
+ reporter);
changed = true;
}
if ( fs instanceof DirStatus ) {
// directory
final DirStatus ds = (DirStatus)fs;
for(int i=0; i<ds.children.length; i++) {
- check(ds.children[i], localEA);
+ check(ds.children[i], reporter);
}
// if the dir changed we have to update
if ( changed ) {
@@ -178,7 +180,7 @@ public class FileMonitor extends TimerTask {
monitorable.path + '/'
+ files[i].getName(), files[i]);
children[i].status = NonExistingStatus.SINGLETON;
- check(children[i], localEA);
+ check(children[i], reporter);
}
}
ds.children = children;
@@ -194,17 +196,17 @@ public class FileMonitor extends TimerTask {
/**
* Send the event async via the event admin.
*/
- private void sendEvents(final Monitorable monitorable, final String topic, final EventAdmin localEA) {
+ private void sendEvents(final Monitorable monitorable, final ChangeType changeType, final ObservationReporter reporter) {
if ( logger.isDebugEnabled() ) {
- logger.debug("Detected change for resource {} : {}", monitorable.path, topic);
+ logger.debug("Detected change for resource {} : {}", monitorable.path, changeType);
}
- final Dictionary<String, String> properties = new Hashtable<String, String>();
- properties.put(SlingConstants.PROPERTY_PATH, monitorable.path);
- final String type = monitorable.status instanceof FileStatus ?
- FsResource.RESOURCE_TYPE_FILE : FsResource.RESOURCE_TYPE_FOLDER;
- properties.put(SlingConstants.PROPERTY_RESOURCE_TYPE, type);
- localEA.postEvent(new org.osgi.service.event.Event(topic, properties));
+ for(final ObserverConfiguration config : reporter.getObserverConfigurations()) {
+ if ( config.matches(monitorable.path) ) {
+ final ResourceChange change = new ResourceChange(changeType, monitorable.path, false);
+ reporter.reportChanges(config, Collections.singleton(change), false);
+ }
+ }
}
/**
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java b/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
index 4b96f05..ef30e3d 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
@@ -21,28 +21,28 @@ package org.apache.sling.fsprovider.internal;
import java.io.File;
import java.util.Collections;
import java.util.Iterator;
-import java.util.Map;
import java.util.NoSuchElementException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.spi.resource.provider.ObservationReporter;
+import org.apache.sling.spi.resource.provider.ProviderContext;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.osgi.framework.BundleContext;
-import org.osgi.service.event.EventAdmin;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
/**
* The <code>FsResourceProvider</code> is a resource provider which maps
- * filesystem files and folders into the virtual resource tree. The provider is
+ * file system files and folders into the virtual resource tree. The provider is
* implemented in terms of a component factory, that is multiple instances of
* this provider may be created by creating respective configuration.
* <p>
@@ -51,40 +51,49 @@ import org.osgi.service.event.EventAdmin;
* and the file system path from where files and folders are mapped into the
* resource ({@link #PROP_PROVIDER_FILE}).
*/
-@Component(
- name="org.apache.sling.fsprovider.internal.FsResourceProvider",
- label="%resource.resolver.name",
- description="%resource.resolver.description",
- configurationFactory=true,
- policy=ConfigurationPolicy.REQUIRE,
- metatype=true
- )
-@Service(ResourceProvider.class)
-@Properties({
- @Property(name="service.description", value="Sling Filesystem Resource Provider"),
- @Property(name="service.vendor", value="The Apache Software Foundation"),
- @Property(name=ResourceProvider.ROOTS),
- @Property(name = "webconsole.configurationFactory.nameHint",
- value = "Root paths: {" + ResourceProvider.ROOTS + "}")
-})
-public class FsResourceProvider implements ResourceProvider {
-
- /**
- * The name of the configuration property providing file system path of
- * files and folders mapped into the resource tree (value is
- * "provider.file").
- */
- @Property
- public static final String PROP_PROVIDER_FILE = "provider.file";
-
- /**
- * The name of the configuration property providing the check interval
- * for file changes (value is "provider.checkinterval").
- */
- @Property(longValue=FsResourceProvider.DEFAULT_CHECKINTERVAL)
- public static final String PROP_PROVIDER_CHECKINTERVAL = "provider.checkinterval";
-
- public static final long DEFAULT_CHECKINTERVAL = 1000;
+@Component(name="org.apache.sling.fsprovider.internal.FsResourceProvider",
+ service=ResourceProvider.class,
+ configurationPolicy=ConfigurationPolicy.REQUIRE,
+ property={
+ Constants.SERVICE_DESCRIPTION + "=Sling Filesystem Resource Provider",
+ Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
+ "webconsole.configurationFactory.nameHint=Root paths: {" + ResourceProvider.PROPERTY_ROOT + "}"
+ })
+@Designate(ocd=FsResourceProvider.Config.class, factory=true)
+public class FsResourceProvider extends ResourceProvider<Object> {
+
+ @ObjectClassDefinition(name = "Apache Sling Filesystem Resource Provider",
+ description = "Configure an instance of the filesystem " +
+ "resource provider in terms of provider root and filesystem location")
+ public @interface Config {
+ /**
+ * The name of the configuration property providing file system path of
+ * files and folders mapped into the resource tree (value is
+ * "provider.file").
+ */
+ @AttributeDefinition(name = "Provider Root",
+ description = "Location in the virtual resource tree where the " +
+ "filesystem resources are mapped in. This property must not be an empty string.")
+ String provider_file();
+
+ /**
+ * The name of the configuration property providing the check interval
+ * for file changes (value is "provider.checkinterval").
+ */
+ @AttributeDefinition(name = "Check Interval",
+ description = "If the interval has a value higher than 100, the provider will " +
+ "check the file system for changes periodically. This interval defines the period in milliseconds " +
+ "(the default is 1000). If a change is detected, resource events are sent through the event admin.")
+ long provider_checkinterval() default 1000;
+
+ @AttributeDefinition(name = "Filesystem Root",
+ description = "Filesystem directory mapped to the virtual " +
+ "resource tree. This property must not be an empty string. If the path is " +
+ "relative it is resolved against sling.home or the current working directory. " +
+ "The path may be a file or folder. If the path does not address an existing " +
+ "file or folder, an empty folder is created.")
+ String provider_root();
+ }
// The location in the resource tree where the resources are mapped
private String providerRoot;
@@ -98,22 +107,8 @@ public class FsResourceProvider implements ResourceProvider {
/** The monitor to detect file changes. */
private FileMonitor monitor;
- @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
- private volatile EventAdmin eventAdmin;
-
- /**
- * Same as {@link #getResource(ResourceResolver, String)}, i.e. the
- * <code>request</code> parameter is ignored.
- *
- * @see #getResource(ResourceResolver, String)
- */
- public Resource getResource(ResourceResolver resourceResolver,
- HttpServletRequest request, String path) {
- return getResource(resourceResolver, path);
- }
-
/**
- * Returns a resource wrapping a filesystem file or folder for the given
+ * Returns a resource wrapping a file system file or folder for the given
* path. If the <code>path</code> is equal to the configured resource tree
* location of this provider, the configured file system file or folder is
* used for the resource. Otherwise the configured resource tree location
@@ -121,14 +116,19 @@ public class FsResourceProvider implements ResourceProvider {
* to access the file or folder. If no such file or folder exists, this
* method returns <code>null</code>.
*/
- public Resource getResource(ResourceResolver resourceResolver, String path) {
- return getResource(resourceResolver, path, getFile(path));
+ @Override
+ public Resource getResource(final ResolveContext<Object> ctx,
+ final String path,
+ final ResourceContext resourceContext,
+ final Resource parent) {
+ return getResource(ctx.getResourceResolver(), path, getFile(path));
}
/**
* Returns an iterator of resources.
*/
- public Iterator<Resource> listChildren(Resource parent) {
+ @Override
+ public Iterator<Resource> listChildren(final ResolveContext<Object> ctx, final Resource parent) {
File parentFile = parent.adaptTo(File.class);
// not a FsResource, try to create one from the resource
@@ -171,10 +171,12 @@ public class FsResourceProvider implements ResourceProvider {
Resource next = seek();
+ @Override
public boolean hasNext() {
return next != null;
}
+ @Override
public Resource next() {
if (!hasNext()) {
throw new NoSuchElementException();
@@ -185,6 +187,7 @@ public class FsResourceProvider implements ResourceProvider {
return result;
}
+ @Override
public void remove() {
throw new UnsupportedOperationException("remove");
}
@@ -210,33 +213,28 @@ public class FsResourceProvider implements ResourceProvider {
}
// ---------- SCR Integration
-
- protected void activate(BundleContext bundleContext, Map<?, ?> props) {
- String providerRoot = (String) props.get(ROOTS);
+ @Activate
+ protected void activate(BundleContext bundleContext, final Config config) {
+ String providerRoot = config.provider_root();
if (providerRoot == null || providerRoot.length() == 0) {
- throw new IllegalArgumentException(ROOTS + " property must be set");
+ throw new IllegalArgumentException("provider.root property must be set");
}
- String providerFileName = (String) props.get(PROP_PROVIDER_FILE);
+ String providerFileName = config.provider_file();
if (providerFileName == null || providerFileName.length() == 0) {
- throw new IllegalArgumentException(PROP_PROVIDER_FILE
- + " property must be set");
+ throw new IllegalArgumentException("provider.file property must be set");
}
this.providerRoot = providerRoot;
this.providerRootPrefix = providerRoot.concat("/");
this.providerFile = getProviderFile(providerFileName, bundleContext);
// start background monitor if check interval is higher than 100
- long checkInterval = DEFAULT_CHECKINTERVAL;
- final Object interval = props.get(PROP_PROVIDER_CHECKINTERVAL);
- if ( interval != null && interval instanceof Long ) {
- checkInterval = (Long)interval;
- }
- if ( checkInterval > 100 ) {
- this.monitor = new FileMonitor(this, checkInterval);
+ if ( config.provider_checkinterval() > 100 ) {
+ this.monitor = new FileMonitor(this, config.provider_checkinterval());
}
}
+ @Deactivate
protected void deactivate() {
if ( this.monitor != null ) {
this.monitor.stop();
@@ -247,10 +245,6 @@ public class FsResourceProvider implements ResourceProvider {
this.providerFile = null;
}
- EventAdmin getEventAdmin() {
- return this.eventAdmin;
- }
-
File getRootFile() {
return this.providerFile;
}
@@ -325,4 +319,12 @@ public class FsResourceProvider implements ResourceProvider {
// not applicable or not an existing file path
return null;
}
+
+ public ObservationReporter getObservationReporter() {
+ final ProviderContext ctx = this.getProviderContext();
+ if ( ctx != null ) {
+ return ctx.getObservationReporter();
+ }
+ return null;
+ }
}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.