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:59:40 UTC
[sling-org-apache-sling-resourceresolver] 10/47: SLING-2530 :
Implement CRUD based on resources (WiP)
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.resourceresolver-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git
commit 5454cb57000ae8083832e926e27630bbf7a9046d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Jul 12 15:11:06 2012 +0000
SLING-2530 : Implement CRUD based on resources (WiP)
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/resourceresolver@1360715 13f79535-47bb-0310-9956-ffa450edef68
---
.../impl/ResourceResolverImpl.java | 48 +++++
.../impl/helper/ResourceIterator.java | 2 +-
.../impl/helper/ResourceResolverContext.java | 25 +++
.../impl/tree/ProviderHandler.java | 2 +
.../impl/tree/ResourceProviderEntry.java | 198 ++++++++++++---------
.../impl/tree/ResourceProviderHandler.java | 7 +
.../impl/tree/ProviderHandlerTest.java | 6 +
.../impl/tree/ResourceProviderEntryTest.java | 28 ++-
8 files changed, 228 insertions(+), 88 deletions(-)
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 a84af79..0b8c431 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
@@ -37,6 +37,7 @@ import org.apache.sling.adapter.annotations.Adapter;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.adapter.SlingAdaptable;
import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceNotFoundException;
@@ -994,4 +995,51 @@ public class ResourceResolverImpl extends SlingAdaptable implements ResourceReso
return absPath;
}
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#delete(org.apache.sling.api.resource.Resource)
+ */
+ public boolean delete(final Resource resource) {
+ final String path = resource.getPath();
+ final ModifyingResourceProvider mrp = this.factory.getRootProviderEntry().getModifyingProvider(this.context,
+ this,
+ path);
+ return mrp.delete(this, path);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#addChild(org.apache.sling.api.resource.Resource, java.lang.String, org.apache.sling.api.resource.ValueMap)
+ */
+ public Resource addChild(final Resource parent, final String name, final ValueMap properties) {
+ final String path = parent.getPath() + '/' + name;
+ final ModifyingResourceProvider mrp = this.factory.getRootProviderEntry().getModifyingProvider(this.context,
+ this,
+ path);
+ return mrp.create(this, path, properties);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#update(org.apache.sling.api.resource.Resource, org.apache.sling.api.resource.ValueMap)
+ */
+ public void update(final Resource resource, final ValueMap properties) {
+ final String path = resource.getPath();
+ final ModifyingResourceProvider mrp = this.factory.getRootProviderEntry().getModifyingProvider(this.context,
+ this,
+ path);
+ mrp.update(this, path, properties);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#revert()
+ */
+ public void revert() {
+ this.context.revert();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#commit()
+ */
+ public void commit() {
+ this.context.commit();
+ }
}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
index 322b5de..0c84e0a 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
@@ -276,7 +276,7 @@ public class ResourceIterator implements Iterator<Resource> {
final Set<ProviderHandler> providers) {
// collect providers along the ancestor path segements
- final String[] elements = ResourceProviderEntry.split(path, '/');
+ final String[] elements = ResourceProviderEntry.split(path);
ResourceProviderEntry base = rootProviderEntry;
for (final String element : elements) {
if (base.containsKey(element)) {
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
index dfabaa0..219b9c4 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.sling.api.resource.DynamicResourceProvider;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.ResourceProvider;
/**
@@ -38,6 +39,9 @@ public class ResourceResolverContext {
/** A set of all dynamic providers (for closing them later on) */
private final Set<DynamicResourceProvider> dynamicProviders = new HashSet<DynamicResourceProvider>();
+ /** A set of all modifying providers */
+ private final Set<ModifyingResourceProvider> modifyingProviders = new HashSet<ModifyingResourceProvider>();
+
/** Is this a resource resolver for an admin? */
private final boolean isAdmin;
@@ -78,6 +82,9 @@ public class ResourceResolverContext {
if (provider instanceof DynamicResourceProvider) {
this.dynamicProviders.add((DynamicResourceProvider) provider);
}
+ if (provider instanceof ModifyingResourceProvider) {
+ this.modifyingProviders.add((ModifyingResourceProvider) provider);
+ }
}
/**
@@ -113,4 +120,22 @@ public class ResourceResolverContext {
this.dynamicProviders.clear();
this.providers.clear();
}
+
+ /**
+ * Revert all transient changes.
+ */
+ public void revert() {
+ for(final ModifyingResourceProvider provider : this.modifyingProviders) {
+ provider.revert();
+ }
+ }
+
+ /**
+ * Commit all transient changes
+ */
+ public void commit() {
+ for(final ModifyingResourceProvider provider : this.modifyingProviders) {
+ provider.commit();
+ }
+ }
}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java
index b5eb3d7..ed50acb 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java
@@ -142,6 +142,8 @@ public abstract class ProviderHandler implements Comparable<ProviderHandler> {
*/
public abstract Iterator<Resource> listChildren(final ResourceResolverContext ctx, final Resource parent);
+ public abstract ResourceProvider getResourceProvider(final ResourceResolverContext ctx);
+
/**
* Return a name of the resource provider/factory.
*/
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java
index 76d9afc..12b0295 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Set;
import org.apache.commons.collections.FastTreeMap;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
@@ -116,32 +117,12 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
* @throws org.apache.sling.api.SlingException
* if an error occurrs trying to access an existing resource.
*/
- public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+ public Resource getResource(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver,
+ final String path) {
return getInternalResource(ctx, resourceResolver, path);
}
- /**
- * Adds the given resource provider into the tree for the given prefix.
- *
- * @return <code>true</code> if the provider could be entered into the
- * subtree below this entry. Otherwise <code>false</code> is
- * returned.
- */
- public synchronized boolean addResourceProvider(final String prefix, final ProviderHandler provider) {
- final String[] elements = split(prefix, '/');
- final List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
- entryPath.add(this); // add this the start so if the list is empty
- // we have a position to add to
- populateProviderPath(entryPath, elements);
- for (int i = entryPath.size() - 1; i < elements.length; i++) {
- final String stubPrefix = elements[i];
- final ResourceProviderEntry rpe2 = new ResourceProviderEntry(stubPrefix, new ProviderHandler[0]);
- entryPath.get(i).put(stubPrefix, rpe2);
- entryPath.add(rpe2);
- }
- return entryPath.get(elements.length).addInternalProvider(provider);
- }
-
// ------------------ Map methods, here so that we can delegate 2 maps
// together
@SuppressWarnings("unchecked")
@@ -164,19 +145,9 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
return storageMapValues;
}
- public synchronized boolean removeResourceProvider(final String prefix, final ProviderHandler resourceProvider) {
- final String[] elements = split(prefix, '/');
- final List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
- populateProviderPath(entryPath, elements);
- if (entryPath.size() > 0 && entryPath.size() == elements.length) {
- // the last element is a perfect match;
- return entryPath.get(entryPath.size() - 1).removeInternalProvider(resourceProvider);
- }
- return false;
- }
-
- // ---------- Comparable<ResourceProviderEntry> interface ------------------
-
+ /**
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
public int compareTo(final ResourceProviderEntry o) {
return prefix.compareTo(o.prefix);
}
@@ -191,9 +162,8 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
private boolean addInternalProvider(final ProviderHandler provider) {
final int before = providers.length;
final Set<ProviderHandler> set = new HashSet<ProviderHandler>();
- if (providers != null) {
- set.addAll(Arrays.asList(providers));
- }
+ set.addAll(Arrays.asList(providers));
+
LOGGER.debug("Adding provider {} at {} ", provider, path);
set.add(provider);
providers = conditionalSort(set);
@@ -208,15 +178,54 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
private boolean removeInternalProvider(final ProviderHandler provider) {
final int before = providers.length;
final Set<ProviderHandler> set = new HashSet<ProviderHandler>();
- if (providers != null) {
- set.addAll(Arrays.asList(providers));
- }
+ set.addAll(Arrays.asList(providers));
+
+ LOGGER.debug("Removing provider {} at {} ", provider, path);
set.remove(provider);
providers = conditionalSort(set);
return providers.length < before;
}
/**
+ * Adds the given resource provider into the tree for the given prefix.
+ *
+ * @return <code>true</code> if the provider could be entered into the
+ * subtree below this entry. Otherwise <code>false</code> is
+ * returned.
+ */
+ protected synchronized boolean addResourceProvider(final String prefix, final ProviderHandler provider) {
+ final String[] elements = split(prefix);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
+
+ // add this=root to the start so if the list is empty
+ // we have a position to add to
+ entries.add(0, this);
+ for (int i = entries.size() - 1; i < elements.length; i++) {
+ final String stubPrefix = elements[i];
+ final ResourceProviderEntry rpe2 = new ResourceProviderEntry(stubPrefix, new ProviderHandler[0]);
+ entries.get(i).put(stubPrefix, rpe2);
+ entries.add(rpe2);
+ }
+ return entries.get(elements.length).addInternalProvider(provider);
+ }
+
+ /**
+ * Remove the given resource provider from the tree
+ */
+ protected synchronized boolean removeResourceProvider(final String prefix, final ProviderHandler resourceProvider) {
+ final String[] elements = split(prefix);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
+
+ if (entries.size() > 0 && entries.size() == elements.length) {
+ // the last element is a perfect match;
+ return entries.get(entries.size() - 1).removeInternalProvider(resourceProvider);
+ }
+ return false;
+ }
+
+ /**
* Return a sorted array of handlers.
*/
private ProviderHandler[] conditionalSort(final Set<ProviderHandler> set) {
@@ -229,23 +238,19 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
}
/**
- * Get a of ResourceProvidersEntries leading to the fullPath in reverse
- * order.
- *
- * @param fullPath
- * the full path
+ * Get a list of resource provider entries in reverse order.
+ * @param entries List to add the entries to
+ * @param elements The path already split into segments.
*/
- private void populateProviderPath(final List<ResourceProviderEntry> providerEntryPath, final String[] elements) {
+ private void populateProviderPath(final List<ResourceProviderEntry> entries, final String[] elements) {
ResourceProviderEntry base = this;
- if (elements != null) {
- for (final String element : elements) {
- if (element != null) {
- if (base.containsKey(element)) {
- base = base.get(element);
- providerEntryPath.add(base);
- } else {
- break;
- }
+ for (final String element : elements) {
+ if (element != null) {
+ if (base.containsKey(element)) {
+ base = base.get(element);
+ entries.add(base);
+ } else {
+ break;
}
}
}
@@ -254,28 +259,27 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
/**
* Resolve a resource from a path into a Resource
*
- * @param resolver
- * the ResourceResolver.
- * @param fullPath
- * the Full path
+ * @param ctx The resource resolver context
+ * @param resourceResolver the ResourceResolver.
+ * @param fullPath the Full path
* @return null if no resource was found, a resource if one was found.
*/
- private Resource getInternalResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String fullPath) {
- final long start = System.currentTimeMillis();
+ private Resource getInternalResource(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver,
+ final String fullPath) {
try {
if (fullPath == null || fullPath.length() == 0 || fullPath.charAt(0) != '/') {
- LOGGER.debug("Not absolute {} :{}", fullPath, (System.currentTimeMillis() - start));
+ LOGGER.debug("Not absolute {}", fullPath);
return null; // fullpath must be absolute
}
- final String[] elements = split(fullPath, '/');
+ final String[] elements = split(fullPath);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
- final List<ResourceProviderEntry> list = new ArrayList<ResourceProviderEntry>();
- populateProviderPath(list, elements);
// the path is in reverse order end first
-
- for (int i = list.size() - 1; i >= 0; i--) {
- final ProviderHandler[] rps = list.get(i).getResourceProviders();
+ for (int i = entries.size() - 1; i >= 0; i--) {
+ final ProviderHandler[] rps = entries.get(i).getResourceProviders();
for (final ProviderHandler rp : rps) {
final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
@@ -284,6 +288,7 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
return resource;
}
}
+ // TODO stop handling if provider claims subtree!
}
// resolve against this one
@@ -296,8 +301,8 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
// resource Provider: libs/sling/servlet/default/GET.servlet
// list will match libs, sling, servlet, default
// and there will be no resource provider at the end
- if (list.size() > 0 && list.size() == elements.length) {
- if (list.get(list.size() - 1).getResourceProviders().length == 0) {
+ if (entries.size() > 0 && entries.size() == elements.length) {
+ if (entries.get(entries.size() - 1).getResourceProviders().length == 0) {
LOGGER.debug("Resolved Synthetic {}", fullPath);
return new SyntheticResource(resourceResolver, fullPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
}
@@ -311,7 +316,8 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
}
}
- public Resource getResourceFromProviders(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String fullPath) {
+ public Resource getResourceFromProviders(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver, final String fullPath) {
final ProviderHandler[] rps = getResourceProviders();
for (final ProviderHandler rp : rps) {
final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
@@ -323,32 +329,56 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
return null;
}
+ public ModifyingResourceProvider getModifyingProvider(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver,
+ final String fullPath) {
+ final String[] elements = split(fullPath);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
+
+ for (int i = entries.size() - 1; i >= 0; i--) {
+ final ProviderHandler[] rps = entries.get(i).getResourceProviders();
+ for (final ProviderHandler rp : rps) {
+ final ResourceProvider provider = rp.getResourceProvider(ctx);
+ if ( provider instanceof ModifyingResourceProvider ) {
+ return (ModifyingResourceProvider) provider;
+ }
+ }
+ // TODO stop handling if provider claims subtree!
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ private static final char SPLIT_SEP = '/';
+ private static final String[] EMPTY_RESULT = new String[0];
+
/**
- * @param st
- * @param sep
+ * Split the string by slash.
+ * This method never returns null.
+ * @param st The string to split
* @return an array of the strings between the separator
*/
- public static String[] split(final String st, final char sep) {
+ public static String[] split(final String st) {
if (st == null) {
- return new String[0];
+ return EMPTY_RESULT;
}
final char[] pn = st.toCharArray();
if (pn.length == 0) {
- return new String[0];
+ return EMPTY_RESULT;
}
- if (pn.length == 1 && pn[0] == sep) {
- return new String[0];
+ if (pn.length == 1 && pn[0] == SPLIT_SEP) {
+ return EMPTY_RESULT;
}
int n = 1;
int start = 0;
int end = pn.length;
- while (start < end && sep == pn[start])
+ while (start < end && SPLIT_SEP == pn[start])
start++;
- while (start < end && sep == pn[end - 1])
+ while (start < end && SPLIT_SEP == pn[end - 1])
end--;
for (int i = start; i < end; i++) {
- if (sep == pn[i]) {
+ if (SPLIT_SEP == pn[i]) {
n++;
}
}
@@ -356,7 +386,7 @@ public class ResourceProviderEntry implements Comparable<ResourceProviderEntry>
int s = start;
int j = 0;
for (int i = start; i < end; i++) {
- if (pn[i] == sep) {
+ if (pn[i] == SPLIT_SEP) {
e[j++] = new String(pn, s, i - s);
s = i + 1;
}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
index eb5b67b..3b4c0c7 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
@@ -65,6 +65,13 @@ public class ResourceProviderHandler extends ProviderHandler {
}
/**
+ * @see org.apache.sling.resourceresolver.impl.tree.ProviderHandler#getResourceProvider(org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext)
+ */
+ public ResourceProvider getResourceProvider(final ResourceResolverContext ctx) {
+ return this.getResourceProvider();
+ }
+
+ /**
* {@inheritDoc}
* @see java.lang.Object#hashCode()
*/
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java
index 5d2b08e..abbde40 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java
@@ -94,5 +94,11 @@ public class ProviderHandlerTest {
return null;
}
+ @Override
+ public ResourceProvider getResourceProvider(ResourceResolverContext ctx) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java
index 739ddcb..a47ed4e 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java
@@ -34,9 +34,7 @@ import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.resourceresolver.impl.tree.ProviderHandler;
-import org.apache.sling.resourceresolver.impl.tree.ResourceProviderEntry;
-import org.apache.sling.resourceresolver.impl.tree.ResourceProviderHandler;
+import org.apache.sling.api.resource.ValueMap;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.Constants;
@@ -301,6 +299,30 @@ public class ResourceProviderEntryTest {
public Iterator<String> getAttributeNames() {
return Collections.<String> emptyList().iterator();
}
+
+ public boolean delete(Resource resource) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Resource addChild(Resource parent, String name, ValueMap properties) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void update(Resource resource, ValueMap properties) {
+ // TODO Auto-generated method stub
+ }
+
+ public void revert() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void commit() {
+ // TODO Auto-generated method stub
+
+ }
}
private static class TestResource extends AbstractResource {
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.