SLING-9841: Adding support for skipping the loading of a path when a runmode matches
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoader.java
index 84dbeb6..d8160e9 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoader.java
@@ -33,6 +33,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.StringTokenizer;
import javax.jcr.Item;
@@ -62,10 +63,13 @@
// bundles whose registration failed and should be retried
private List<Bundle> delayedBundles;
- public BundleContentLoader(BundleHelper bundleHelper, ContentReaderWhiteboard contentReaderWhiteboard) {
+ private Set<String> runmodes;
+
+ public BundleContentLoader(BundleHelper bundleHelper, ContentReaderWhiteboard contentReaderWhiteboard, Set<String> runmodes) {
super(contentReaderWhiteboard);
this.bundleHelper = bundleHelper;
this.delayedBundles = new LinkedList<>();
+ this.runmodes = runmodes;
}
public void dispose() {
@@ -215,7 +219,7 @@
try {
while (pathIter.hasNext()) {
final PathEntry pathEntry = pathIter.next();
- if (!contentAlreadyLoaded || pathEntry.isOverwrite()) {
+ if (validRunmode(pathEntry) && (!contentAlreadyLoaded || pathEntry.isOverwrite())) {
String workspace = pathEntry.getWorkspace();
final Session targetSession;
if (workspace != null) {
@@ -290,13 +294,25 @@
}
/**
+ * Checks if the path entry has a runmode restriction set and the runmode isn't set in the Sling instance.
+ *
+ * @param pathEntry the path entry to check
+ * @return true if the required runmode setting is not set or the instance runmodes doesn't contain the runmode
+ */
+ private boolean validRunmode(PathEntry pathEntry) {
+ return pathEntry.getSkipRunmode() == null || "".equals(pathEntry.getSkipRunmode())
+ || !runmodes.contains(pathEntry.getSkipRunmode());
+ }
+
+ /**
* Handle content installation for a single path.
*
* @param bundle The bundle containing the content.
* @param path The path
* @param configuration
* @param parent The parent node.
- * @param createdNodes An optional list to store all new nodes. This list is used for an uninstall
+ * @param createdNodes An optional list to store all new nodes. This list is
+ * used for an uninstall
* @throws RepositoryException
*/
private void installFromPath(final Bundle bundle, final String path, final PathEntry configuration, final Node parent, final List<String> createdNodes, final DefaultContentCreator contentCreator) throws RepositoryException {
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index d68d605..a9874aa 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -94,6 +94,9 @@
@Reference
private ContentReaderWhiteboard contentReaderWhiteboard;
+ @Reference
+ private SlingSettingsService slingSettings;
+
/**
* The initial content loader which is called to load initial content up
* into the repository when the providing bundle is installed.
@@ -222,7 +225,7 @@
@Activate
protected synchronized void activate(BundleContext bundleContext) {
this.slingId = this.settingsService.getSlingId();
- this.bundleContentLoader = new BundleContentLoader(this, contentReaderWhiteboard);
+ this.bundleContentLoader = new BundleContentLoader(this, contentReaderWhiteboard, slingSettings.getRunModes());
bundleContext.addBundleListener(this);
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
index 38898ae..4bf7d78 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -93,6 +93,14 @@
*/
public static final String IGNORE_CONTENT_READERS_DIRECTIVE = "ignoreImportProviders";
+ /**
+ * If the content should be skipped with a particular runmode. By
+ * default this will be an empty string which means the content will be
+ * installed regardless of the runmode
+ * @since 2.4.0
+ */
+ public static final String SKIP_RUNMODE = "skipRunmode";
+
private final boolean propertyMerge;
private final boolean nodeMerge;
@@ -106,6 +114,9 @@
/** Should existing content properties be overwritten? */
private final boolean overwriteProperties;
+ /** The content at the path will be skipped for this runmode */
+ private final String skipRunmode;
+
/** Should existing content be uninstalled? */
private final boolean uninstall;
@@ -233,6 +244,9 @@
}
// workspace directive
+ this.skipRunmode = entry.getDirectiveValue(SKIP_RUNMODE);
+
+ // workspace directive
final String workspaceValue = entry.getDirectiveValue(WORKSPACE_DIRECTIVE);
if (pathValue != null) {
this.workspace = workspaceValue;
@@ -293,6 +307,10 @@
return this.ignoreContentReaders.contains(extension);
}
+ public String getSkipRunmode(){
+ return this.skipRunmode;
+ }
+
public String getTarget() {
return target;
}
@@ -301,12 +319,10 @@
return workspace;
}
-
public boolean isPropertyMerge() {
return this.propertyMerge;
}
-
public boolean isMerge() {
return this.nodeMerge;
}
diff --git a/src/test/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoaderTest.java b/src/test/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoaderTest.java
index a985701..5004254 100644
--- a/src/test/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoaderTest.java
+++ b/src/test/java/org/apache/sling/jcr/contentloader/internal/BundleContentLoaderTest.java
@@ -21,8 +21,11 @@
import static java.util.Collections.singletonMap;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
+import java.util.Collections;
+
import javax.jcr.Session;
import org.apache.sling.api.resource.Resource;
@@ -60,7 +63,7 @@
ContentReaderWhiteboard whiteboard = context.getService(ContentReaderWhiteboard.class);
- contentLoader = new BundleContentLoader(bundleHelper, whiteboard);
+ contentLoader = new BundleContentLoader(bundleHelper, whiteboard, Collections.singleton("seed"));
}
@@ -77,6 +80,31 @@
assertThat("sling:resourceType was not properly set", imported.getResourceType(), equalTo("sling:Folder"));
}
+
+ @Test
+ public void skippedRunmode() throws Exception {
+ Bundle mockBundle = newBundleWithInitialContent("SLING-INF/libs/app/skipped;path:=/libs/app/skipped;skipRunmode:=seed");
+ contentLoader.registerBundle(context.resourceResolver().adaptTo(Session.class), mockBundle, false);
+ Resource imported = context.resourceResolver().getResource("/libs/app/skipped");
+ assertThat("Import should have been skipped", imported, nullValue());
+ }
+
+ @Test
+ public void passedRunmode() throws Exception {
+ Bundle mockBundle = newBundleWithInitialContent("SLING-INF/libs/app/passed;path:=/libs/app/passed;skipRunmode:=runtime");
+ contentLoader.registerBundle(context.resourceResolver().adaptTo(Session.class), mockBundle, false);
+ Resource imported = context.resourceResolver().getResource("/libs/app/passed");
+ assertThat("Resource was not imported", imported, notNullValue());
+ }
+
+ @Test
+ public void emptyRunmode() throws Exception {
+ Bundle mockBundle = newBundleWithInitialContent("SLING-INF/libs/app/empty;path:=/libs/app/empty");
+ contentLoader.registerBundle(context.resourceResolver().adaptTo(Session.class), mockBundle, false);
+ Resource imported = context.resourceResolver().getResource("/libs/app/empty");
+ assertThat("Resource was not imported", imported, notNullValue());
+ }
+
@Test
public void loadContentWithRootPath() throws Exception {