You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2021/10/27 09:23:35 UTC
[sling-org-apache-sling-resourceresolver] 01/01: SLING-7975 support
ordering of resources
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch feature/order-resource-api
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git
commit 7178783fc2a801f13b6f382d119008e666bede2e
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Wed Oct 27 11:23:23 2021 +0200
SLING-7975 support ordering of resources
---
pom.xml | 2 +-
.../impl/ResourceResolverImpl.java | 11 +++-
.../impl/helper/ResourceResolverControl.java | 28 ++++++++
.../stateful/AuthenticatedResourceProvider.java | 75 ++++++++++++++++------
4 files changed, 92 insertions(+), 24 deletions(-)
diff --git a/pom.xml b/pom.xml
index 309835e..074f496 100644
--- a/pom.xml
+++ b/pom.xml
@@ -106,7 +106,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.21.0</version>
+ <version>2.23.7-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
index 255176d..940ac1f 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
@@ -32,11 +32,10 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
-import org.apache.commons.lang3.StringUtils;
-import org.jetbrains.annotations.Nullable;
import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.lang3.StringUtils;
import org.apache.sling.adapter.annotations.Adaptable;
import org.apache.sling.adapter.annotations.Adapter;
import org.apache.sling.api.SlingException;
@@ -64,6 +63,8 @@ import org.apache.sling.resourceresolver.impl.mapping.ResourceMapperImpl;
import org.apache.sling.resourceresolver.impl.params.ParsedParameters;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -989,6 +990,12 @@ public class ResourceResolverImpl extends SlingAdaptable implements ResourceReso
return this.factory.getResourceDecoratorTracker().decorate(rsrc);
}
+ @Override
+ public boolean orderBefore(@NotNull Resource parent, @NotNull String name, @Nullable String followingSiblingName)
+ throws UnsupportedOperationException, PersistenceException, IllegalArgumentException {
+ return this.control.orderBefore(this.context, parent, name, followingSiblingName);
+ }
+
/**
* @see org.apache.sling.api.resource.ResourceResolver#revert()
*/
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
index efe76f5..10c3522 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
@@ -395,6 +395,34 @@ public class ResourceResolverControl {
throw new UnsupportedOperationException("create '" + ResourceUtil.getName(path) + "' at " + ResourceUtil.getParent(path));
}
+ /*
+ * @see ResourceResolver#orderBefore(Resource, String, String)
+ */
+ public boolean orderBefore(@NotNull final ResourceResolverContext context, @NotNull final Resource parent, @NotNull final String name, @Nullable final String followingSiblingName)
+ throws UnsupportedOperationException, PersistenceException, IllegalArgumentException {
+ final AuthenticatedResourceProvider provider = getBestMatchingModifiableProvider(context, parent.getPath());
+ if (provider != null) {
+ // make sure all children are from the same provider and both names are valid
+ AuthenticatedResourceProvider childProvider = getBestMatchingModifiableProvider(context, parent.getPath() + "/" + name);
+ if (childProvider == null) {
+ throw new IllegalArgumentException("The given name '" + name + "' is not a valid child name in resource " + parent.getPath());
+ }
+ if (provider != childProvider) {
+ throw new UnsupportedOperationException("orderBefore '" + name + "' at " + parent.getPath() + " as children are not provided by the same provider as the parent resource");
+ }
+ if (followingSiblingName != null) {
+ childProvider = getBestMatchingModifiableProvider(context, parent.getPath() + "/" + followingSiblingName);
+ if (childProvider == null) {
+ throw new IllegalArgumentException("The given name '" + followingSiblingName + "' is not a valid child name in resource " + parent.getPath());
+ }
+ if (provider != childProvider) {
+ throw new UnsupportedOperationException("orderBefore '" + name + "' at " + parent.getPath() + " as sibling child resources are not provided by the same provider");
+ }
+ }
+ return provider.orderBefore(parent, name, followingSiblingName);
+ }
+ throw new UnsupportedOperationException("orderBefore '" + name + "' at " + parent.getPath());
+ }
/**
* Delete the resource. Iterate over all modifiable ResourceProviders
* giving each an opportunity to delete the resource if they are able.
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
index 1b0807c..9b49c3d 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
@@ -44,9 +44,9 @@ import org.slf4j.LoggerFactory;
/**
* This {@link AuthenticatedResourceProvider} implementation keeps a resource
- * provider and the authentication information (through the {@link ResolveContext}.
+ * provider and the authentication information (through the {@link ResolveContext}).
*
- * The methods are similar to {@link ResourceProvider}.
+ * The methods are similar to those of {@link ResourceProvider}.
*/
public class AuthenticatedResourceProvider {
@@ -81,7 +81,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#refresh(ResolveContext)}
+ * @see {@link ResourceProvider#refresh(ResolveContext)}
*/
public void refresh() {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -91,7 +91,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#isLive(ResolveContext)}
+ * @see {@link ResourceProvider#isLive(ResolveContext)}
*/
public boolean isLive() {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -102,7 +102,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#getParent(ResolveContext, Resource)}
+ * @see {@link ResourceProvider#getParent(ResolveContext, Resource)}
*/
public Resource getParent(final Resource child) {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -113,7 +113,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#getResource(ResolveContext, String, ResourceContext, Resource)}
+ * @see {@link ResourceProvider#getResource(ResolveContext, String, ResourceContext, Resource)}
*/
public Resource getResource(final String path, final Resource parent, final Map<String, String> parameters) {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -136,7 +136,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#listChildren(ResolveContext, Resource)}
+ * @see {@link ResourceProvider#listChildren(ResolveContext, Resource)}
*/
public Iterator<Resource> listChildren(final Resource parent) {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -147,7 +147,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#getAttributeNames(ResolveContext)}
+ * @see {@link ResourceProvider#getAttributeNames(ResolveContext)}
*/
public void getAttributeNames(final Set<String> attributeNames) {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -160,7 +160,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#getAttribute(ResolveContext, String)}
+ * @see {@link ResourceProvider#getAttribute(ResolveContext, String)}
*/
public Object getAttribute(final String name) {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -171,7 +171,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#create(ResolveContext, String, Map)}
+ * @see {@link ResourceProvider#create(ResolveContext, String, Map)}
*/
public Resource create(final ResourceResolver resolver,
final String path,
@@ -185,7 +185,20 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#delete(ResolveContext, Resource)}
+ * @see {@link ResourceProvider#orderBefore(ResolveContext, Resource, String, String)
+ */
+ public boolean orderBefore(final @NotNull Resource parent, final @NotNull String name, final @Nullable String followingSiblingName)
+ throws PersistenceException {
+ final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
+ if (rp != null && this.canReorderChildren(parent)) {
+ return rp.orderBefore(this.resolveContext, parent, name, followingSiblingName);
+ } else {
+ throw new PersistenceException("Unable to order child resources of " + parent.getPath());
+ }
+ }
+
+ /**
+ * @see {@link ResourceProvider#delete(ResolveContext, Resource)}
*/
public void delete(final Resource resource) throws PersistenceException {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -197,7 +210,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#revert(ResolveContext)}
+ * @see {@link ResourceProvider#revert(ResolveContext)}
*/
public void revert() {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -207,7 +220,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#commit(ResolveContext)}
+ * @see {@link ResourceProvider#commit(ResolveContext)}
*/
public void commit() throws PersistenceException {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -217,7 +230,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#hasChanges(ResolveContext)}
+ * @see {@link ResourceProvider#hasChanges(ResolveContext)}
*/
public boolean hasChanges() {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -228,7 +241,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#getQueryLanguageProvider()}
+ * @see {@link ResourceProvider#getQueryLanguageProvider()}
*/
private QueryLanguageProvider<Object> getQueryLanguageProvider() {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -239,7 +252,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link QueryLanguageProvider#getSupportedLanguages(ResolveContext)}
+ * @see {@link QueryLanguageProvider#getSupportedLanguages(ResolveContext)}
*/
public String[] getSupportedLanguages() {
final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
@@ -250,7 +263,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link QueryLanguageProvider}{@link #findResources(String, String)}
+ * @see {@link QueryLanguageProvider}{@link #findResources(String, String)}
*/
public Iterator<Resource> findResources(final String query, final String language) {
final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
@@ -261,7 +274,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link QueryLanguageProvider#queryResources(ResolveContext, String, String)}
+ * @see {@link QueryLanguageProvider#queryResources(ResolveContext, String, String)}
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Iterator<Map<String, Object>> queryResources(final String query, final String language) {
@@ -273,7 +286,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#adaptTo(ResolveContext, Class)}
+ * @see {@link ResourceProvider#adaptTo(ResolveContext, Class)}
*/
public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -284,7 +297,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#copy(ResolveContext, String, String)}
+ * @see {@link ResourceProvider#copy(ResolveContext, String, String)}
*/
public boolean copy(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -295,7 +308,7 @@ public class AuthenticatedResourceProvider {
}
/**
- * #see {@link ResourceProvider#move(ResolveContext, String, String)}
+ * @see {@link ResourceProvider#move(ResolveContext, String, String)}
*/
public boolean move(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
@@ -325,6 +338,26 @@ public class AuthenticatedResourceProvider {
return allowed;
}
+ private boolean canReorderChildren(final Resource resource) {
+ boolean allowed = true;
+ if ( this.useRAS ) {
+ final ResourceAccessSecurity security = tracker.getProviderResourceAccessSecurity();
+ if ( security != null ) {
+ allowed = security.canReorderChildren(resource);
+ } else {
+ allowed = false;
+ }
+ }
+
+ if ( allowed ) {
+ final ResourceAccessSecurity security = tracker.getApplicationResourceAccessSecurity();
+ if (security != null) {
+ allowed = security.canReorderChildren(resource);
+ }
+ }
+ return allowed;
+ }
+
private boolean canDelete(final Resource resource) {
boolean allowed = true;
if ( this.useRAS ) {