SLING-6001 : ProcessorManagerImpl should move to new ResourceChangeListener API. Apply patch from Rachit Kumar.
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1763348 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 2ce3d15..fb573d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,7 +45,6 @@
</scm>
<properties>
- <sling.java.version>7</sling.java.version>
<org.ops4j.pax.exam.version>4.9.1</org.ops4j.pax.exam.version>
</properties>
@@ -78,13 +77,6 @@
<Import-Package>
org.apache.cocoon.components.serializers.util;resolution:=optional,*
</Import-Package>
- <Export-Package>
- org.apache.sling.rewriter;version=1.0.0
- </Export-Package>
- <Private-Package>
- org.apache.sling.rewriter.impl,
- org.apache.sling.rewriter.impl.components
- </Private-Package>
</instructions>
</configuration>
</plugin>
@@ -138,7 +130,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.4.0</version>
+ <version>2.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/src/main/java/org/apache/sling/rewriter/impl/ProcessorManagerImpl.java b/src/main/java/org/apache/sling/rewriter/impl/ProcessorManagerImpl.java
index a3585e8..df4ce50 100644
--- a/src/main/java/org/apache/sling/rewriter/impl/ProcessorManagerImpl.java
+++ b/src/main/java/org/apache/sling/rewriter/impl/ProcessorManagerImpl.java
@@ -31,12 +31,15 @@
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingConstants;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
+import org.apache.sling.api.resource.observation.ResourceChange;
+import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
+import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.apache.sling.rewriter.PipelineConfiguration;
import org.apache.sling.rewriter.ProcessingContext;
import org.apache.sling.rewriter.Processor;
@@ -46,7 +49,6 @@
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
-import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,7 +59,7 @@
@Component
@Service(value=ProcessorManager.class)
public class ProcessorManagerImpl
- implements ProcessorManager, EventHandler {
+ implements ProcessorManager, ResourceChangeListener, ExternalResourceChangeListener {
private static final String CONFIG_REL_PATH = "config/rewriter";
private static final String CONFIG_PATH = "/" + CONFIG_REL_PATH;
@@ -76,14 +78,14 @@
/** The resource resolver. */
private ResourceResolver resourceResolver;
- /** loaded processor configurationss */
+ /** loaded processor configurations */
private final Map<String, ConfigEntry[]> processors = new HashMap<String, ConfigEntry[]>();
- /** Ordered processor configs. */
+ /** Ordered processor configurations. */
private List<ProcessorConfiguration> orderedProcessors = new ArrayList<ProcessorConfiguration>();
/** Event handler registration */
- private ServiceRegistration eventHandlerRegistration;
+ private volatile ServiceRegistration<ResourceChangeListener> eventHandlerRegistration;
/** Search paths */
private String[] searchPaths;
@@ -95,7 +97,8 @@
* Activate this component.
* @param ctx
*/
- protected void activate(final ComponentContext ctx)
+ @SuppressWarnings("deprecation")
+ protected void activate(final ComponentContext ctx)
throws LoginException, InvalidSyntaxException {
this.bundleContext = ctx.getBundleContext();
this.factoryCache = new FactoryCache(this.bundleContext);
@@ -103,20 +106,18 @@
// create array of search paths for actions and constraints
this.resourceResolver = this.resourceResolverFactory.getAdministrativeResourceResolver(null);
this.searchPaths = resourceResolver.getSearchPath();
-
this.initProcessors();
-
- // register event handler
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put("event.topics", new String[] { "org/apache/sling/api/resource/Resource/*",
- "org/apache/sling/api/resource/ResourceProvider/*" });
- props.put("service.description","Processor Configuration/Modification Handler");
- props.put("service.vendor","The Apache Software Foundation");
-
- this.eventHandlerRegistration = ctx.getBundleContext()
- .registerService(EventHandler.class.getName(), this, props);
-
- this.factoryCache.start();
+ // register event handler
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(ResourceChangeListener.CHANGES,
+ new String[] { ChangeType.ADDED.toString(), ChangeType.CHANGED.toString(),
+ ChangeType.REMOVED.toString(), ChangeType.PROVIDER_ADDED.toString(), ChangeType.PROVIDER_REMOVED.toString() });
+ props.put(ResourceChangeListener.PATHS, searchPaths);
+ props.put("service.description", "Processor Configuration/Modification Handler");
+ props.put("service.vendor", "The Apache Software Foundation");
+ this.eventHandlerRegistration = ctx.getBundleContext().registerService(ResourceChangeListener.class, this,
+ props);
+ this.factoryCache.start();
WebConsoleConfigPrinter.register(this.bundleContext, this);
}
@@ -142,48 +143,50 @@
this.bundleContext = null;
}
- /**
- * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
- */
- public void handleEvent(final org.osgi.service.event.Event event) {
- // check if the event handles something in the search paths
- String path = (String)event.getProperty(SlingConstants.PROPERTY_PATH);
- int foundPos = -1;
- for(final String sPath : this.searchPaths) {
- if ( path.startsWith(sPath) ) {
- foundPos = sPath.length();
- break;
- }
- }
- if ( foundPos != -1 ) {
- // now check if this is a rewriter config
- // relative path after the search path
- final int firstSlash = path.indexOf('/', foundPos);
- final int pattern = path.indexOf(CONFIG_PATH, foundPos);
- // only if firstSlash and pattern are at the same position, this migt be a rewriter config
- if ( firstSlash == pattern && firstSlash != -1 ) {
- // the node should be a child of CONFIG_PATH
- if ( path.length() > pattern + CONFIG_PATH.length() && path.charAt(pattern + CONFIG_PATH.length()) == '/') {
- // if a child resource is changed, make sure we have the correct path
- final int slashPos = path.indexOf('/', pattern + CONFIG_PATH.length() + 1);
- if ( slashPos != -1 ) {
- path = path.substring(0, slashPos);
- }
- // we should do the update async as we don't want to block the event delivery
- final String configPath = path;
- final Thread t = new Thread() {
- public void run() {
- if ( event.getTopic().equals(SlingConstants.TOPIC_RESOURCE_REMOVED) ) {
- removeProcessor(configPath);
- } else {
- updateProcessor(configPath);
- }
- }
- };
- t.start();
+ @Override
+ public void onChange(final List<ResourceChange> changes) {
+ for(final ResourceChange change : changes){
+ // check if the event handles something in the search paths
+ String path = change.getPath();
+ int foundPos = -1;
+ for(final String sPath : this.searchPaths) {
+ if ( path.startsWith(sPath) ) {
+ foundPos = sPath.length();
+ break;
}
}
- }
+ if ( foundPos != -1 ) {
+ // now check if this is a rewriter config
+ // relative path after the search path
+ final int firstSlash = path.indexOf('/', foundPos);
+ final int pattern = path.indexOf(CONFIG_PATH, foundPos);
+ // only if firstSlash and pattern are at the same position, this might be a rewriter config
+ if ( firstSlash == pattern && firstSlash != -1 ) {
+ // the node should be a child of CONFIG_PATH
+ if ( path.length() > pattern + CONFIG_PATH.length() && path.charAt(pattern + CONFIG_PATH.length()) == '/') {
+ // if a child resource is changed, make sure we have the correct path
+ final int slashPos = path.indexOf('/', pattern + CONFIG_PATH.length() + 1);
+ if ( slashPos != -1 ) {
+ path = path.substring(0, slashPos);
+ }
+ // we should do the update async as we don't want to block the event delivery
+ final String configPath = path;
+ final Thread t = new Thread() {
+ @Override
+ public void run() {
+ if (change.getType().equals(ChangeType.REMOVED)) {
+ removeProcessor(configPath);
+ } else {
+ updateProcessor(configPath);
+ }
+ }
+ };
+ t.start();
+ }
+ }
+ }
+ }
+
}
/**
@@ -424,6 +427,7 @@
/**
* @see org.apache.sling.rewriter.ProcessorManager#getProcessor(org.apache.sling.rewriter.ProcessorConfiguration, org.apache.sling.rewriter.ProcessingContext)
*/
+ @Override
public Processor getProcessor(ProcessorConfiguration configuration,
ProcessingContext context) {
if ( configuration == null ) {
@@ -455,6 +459,7 @@
/**
* @see org.apache.sling.rewriter.ProcessorManager#getProcessorConfigurations()
*/
+ @Override
public List<ProcessorConfiguration> getProcessorConfigurations() {
return this.orderedProcessors;
}
@@ -464,6 +469,7 @@
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
+ @Override
public int compare(ProcessorConfiguration config0, ProcessorConfiguration config1) {
final int o0 = ((ProcessorConfigurationImpl)config0).getOrder();
final int o1 = ((ProcessorConfigurationImpl)config1).getOrder();
diff --git a/src/main/java/org/apache/sling/rewriter/package-info.java b/src/main/java/org/apache/sling/rewriter/package-info.java
new file mode 100644
index 0000000..02658bb
--- /dev/null
+++ b/src/main/java/org/apache/sling/rewriter/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+@Version("1.0.0")
+package org.apache.sling.rewriter;
+
+import org.osgi.annotation.versioning.Version;
+
diff --git a/src/test/java/org/apache/sling/rewriter/it/tests/RewriterTestSupport.java b/src/test/java/org/apache/sling/rewriter/it/tests/RewriterTestSupport.java
index 951edd6..9795034 100644
--- a/src/test/java/org/apache/sling/rewriter/it/tests/RewriterTestSupport.java
+++ b/src/test/java/org/apache/sling/rewriter/it/tests/RewriterTestSupport.java
@@ -18,12 +18,6 @@
*/
package org.apache.sling.rewriter.it.tests;
-import org.apache.sling.testing.paxexam.TestSupport;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.ProbeBuilder;
-import org.ops4j.pax.exam.TestProbeBuilder;
-
import static org.apache.sling.testing.paxexam.SlingOptions.slingCommonsHtml;
import static org.apache.sling.testing.paxexam.SlingOptions.slingLaunchpadOakTar;
import static org.apache.sling.testing.paxexam.SlingOptions.slingScriptingJavascript;
@@ -31,6 +25,12 @@
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import org.apache.sling.testing.paxexam.TestSupport;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.ProbeBuilder;
+import org.ops4j.pax.exam.TestProbeBuilder;
+
public abstract class RewriterTestSupport extends TestSupport {
@Configuration
@@ -49,10 +49,10 @@
@ProbeBuilder
public TestProbeBuilder probeConfiguration(final TestProbeBuilder testProbeBuilder) {
- testProbeBuilder.setHeader("Sling-Initial-Content", String.join(",",
- "apps/esp;path:=/apps/esp;overwrite:=true;uninstall:=true",
+ testProbeBuilder.setHeader("Sling-Initial-Content",
+ "apps/esp;path:=/apps/esp;overwrite:=true;uninstall:=true" + "," +
"content;path:=/content;overwrite:=true;uninstall:=true"
- ));
+ );
return testProbeBuilder;
}