You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2016/11/13 11:07:45 UTC

svn commit: r1769486 - in /sling/trunk/bundles/extensions/fsresource: pom.xml src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java

Author: cziegeler
Date: Sun Nov 13 11:07:45 2016
New Revision: 1769486

URL: http://svn.apache.org/viewvc?rev=1769486&view=rev
Log:
SLING-6279 : Switch from event admin to Sling Resource Observation API

Modified:
    sling/trunk/bundles/extensions/fsresource/pom.xml
    sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java
    sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java

Modified: sling/trunk/bundles/extensions/fsresource/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/pom.xml?rev=1769486&r1=1769485&r2=1769486&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/fsresource/pom.xml (original)
+++ sling/trunk/bundles/extensions/fsresource/pom.xml Sun Nov 13 11:07:45 2016
@@ -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>

Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java?rev=1769486&r1=1769485&r2=1769486&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java (original)
+++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FileMonitor.java Sun Nov 13 11:07:45 2016
@@ -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 TimerTa
     /**
      * @see java.util.TimerTask#run()
      */
+    @Override
     public void run() {
         synchronized (timer) {
             stopped = false;
@@ -102,10 +104,10 @@ public class FileMonitor extends TimerTa
         }
         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 TimerTa
     /**
      * 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 TimerTa
                 // 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 TimerTa
                     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 TimerTa
                                         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 TimerTa
     /**
      * 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);
+            }
+        }
     }
 
     /**

Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java?rev=1769486&r1=1769485&r2=1769486&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java (original)
+++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java Sun Nov 13 11:07:45 2016
@@ -21,28 +21,28 @@ package org.apache.sling.fsprovider.inte
 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 implemen
     /** 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 implemen
      * 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 implemen
 
                 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 implemen
                     return result;
                 }
 
+                @Override
                 public void remove() {
                     throw new UnsupportedOperationException("remove");
                 }
@@ -210,33 +213,28 @@ public class FsResourceProvider implemen
     }
 
     // ---------- 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 implemen
         this.providerFile = null;
     }
 
-    EventAdmin getEventAdmin() {
-        return this.eventAdmin;
-    }
-
     File getRootFile() {
         return this.providerFile;
     }
@@ -325,4 +319,12 @@ public class FsResourceProvider implemen
         // 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;
+    }
 }