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 2015/10/29 15:30:41 UTC
svn commit: r1711277 - in
/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl:
ResourceResolverImpl.java
providers/stateful/AuthenticatedResourceProvider.java
providers/stateful/CombinedResourceProvider.java
Author: cziegeler
Date: Thu Oct 29 14:30:40 2015
New Revision: 1711277
URL: http://svn.apache.org/viewvc?rev=1711277&view=rev
Log:
SLING-5186 : Implement Copy/move
Modified:
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/CombinedResourceProvider.java
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java?rev=1711277&r1=1711276&r2=1711277&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java Thu Oct 29 14:30:40 2015
@@ -1302,15 +1302,11 @@ public class ResourceResolverImpl extend
@Override
public void copy(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
- if (!this.provider.copy(srcAbsPath, destAbsPath)) {
- throw new UnsupportedOperationException();
- }
+ this.provider.copy(srcAbsPath, destAbsPath);
}
@Override
public void move(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
- if (!this.provider.move(srcAbsPath, destAbsPath)) {
- throw new UnsupportedOperationException();
- }
+ this.provider.move(srcAbsPath, destAbsPath);
}
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java?rev=1711277&r1=1711276&r2=1711277&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java Thu Oct 29 14:30:40 2015
@@ -356,8 +356,7 @@ public class AuthenticatedResourceProvid
try {
return rp.copy(getContext(), srcAbsPath, destAbsPath);
} catch (LoginException e) {
- logger.error("Can't create context", e);
- return false;
+ throw new PersistenceException("Unable to create context.", e);
}
}
@@ -366,8 +365,7 @@ public class AuthenticatedResourceProvid
try {
return rp.move(getContext(), srcAbsPath, destAbsPath);
} catch (LoginException e) {
- logger.error("Can't create context", e);
- return false;
+ throw new PersistenceException("Unable to create context.", e);
}
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/CombinedResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/CombinedResourceProvider.java?rev=1711277&r1=1711276&r2=1711277&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/CombinedResourceProvider.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/CombinedResourceProvider.java Thu Oct 29 14:30:40 2015
@@ -37,17 +37,16 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.apache.commons.collections.IteratorUtils;
-import org.apache.commons.collections.ListUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.iterators.IteratorChain;
import org.apache.commons.lang.ArrayUtils;
-import org.apache.sling.api.SlingException;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.query.Query;
import org.apache.sling.api.resource.query.QueryInstructions;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
@@ -439,21 +438,103 @@ public class CombinedResourceProvider {
return null;
}
+ private StatefulResourceProvider checkSourceAndDest(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
+ // check source
+ final Node<ResourceProviderHandler> srcNode = storage.getTree().getNode(srcAbsPath);
+ if ( srcNode == null ) {
+ throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
+ }
+ StatefulResourceProvider srcProvider = null;
+ try {
+ srcProvider = authenticator.getStateful(srcNode.getValue(), this);
+ } catch (LoginException e) {
+ // ignore
+ }
+ if ( srcProvider == null ) {
+ throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
+ }
+ final Resource srcResource = srcProvider.getResource(srcAbsPath, null, null, false);
+ if ( srcResource == null ) {
+ throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
+ }
+
+ // check destination
+ final Node<ResourceProviderHandler> destNode = storage.getTree().getNode(destAbsPath);
+ if ( destNode == null ) {
+ throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
+ }
+ StatefulResourceProvider destProvider = null;
+ try {
+ destProvider = authenticator.getStateful(destNode.getValue(), this);
+ } catch (LoginException e) {
+ // ignore
+ }
+ if ( destProvider == null ) {
+ throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
+ }
+ final Resource destResource = destProvider.getResource(destAbsPath, null, null, false);
+ if ( destResource == null ) {
+ throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
+ }
+
+ // check for sub providers of src and dest
+ if ( srcProvider == destProvider && !collectProviders(srcNode) && !collectProviders(destNode) ) {
+ return srcProvider;
+ }
+ return null;
+ }
+
+ private boolean collectProviders(final Node<ResourceProviderHandler> parent) {
+ boolean hasMoreProviders = false;
+ for (final Entry<String, Node<ResourceProviderHandler>> entry : parent.getChildren().entrySet()) {
+ if ( entry.getValue().getValue() != null ) {
+ try {
+ authenticator.getStateful(entry.getValue().getValue(), this);
+ hasMoreProviders = true;
+ } catch ( final LoginException ignore) {
+ // ignore
+ }
+ }
+ if ( collectProviders(entry.getValue())) {
+ hasMoreProviders = true;
+ }
+ }
+
+ return hasMoreProviders;
+ }
+
+ private void copy(final Resource src, final String dstPath, final List<Resource> newNodes) throws PersistenceException {
+ final ValueMap vm = src.getValueMap();
+ final String createPath = dstPath + '/' + src.getName();
+ newNodes.add(this.create(createPath, vm));
+ for(final Resource c : src.getChildren()) {
+ copy(c, createPath, newNodes);
+ }
+ }
+
/**
* Tries to find a resource provider accepting both paths and invokes
* {@link StatefulResourceProvider#copy(String, String)} method on it.
* Returns false if there's no such provider.
*/
- public boolean copy(String srcAbsPath, String destAbsPath) throws PersistenceException {
+ public void copy(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
+ final StatefulResourceProvider optimizedSourceProvider = checkSourceAndDest(srcAbsPath, destAbsPath);
+ if ( optimizedSourceProvider != null && optimizedSourceProvider.copy(srcAbsPath, destAbsPath) ) {
+ return;
+ }
+
+ final Resource srcResource = this.getResource(srcAbsPath, null, null, false);
+ final List<Resource> newResources = new ArrayList<Resource>();
+ boolean rollback = true;
try {
- List<StatefulResourceProvider> srcProviders = getMatchingProviders(srcAbsPath);
- List<StatefulResourceProvider> dstProviders = getMatchingModifiableProviders(destAbsPath);
- @SuppressWarnings("unchecked")
- List<StatefulResourceProvider> intersection = ListUtils.intersection(srcProviders, dstProviders);
- return head(intersection).copy(srcAbsPath, destAbsPath);
- } catch (LoginException le) {
- // TODO - ignore for a single handler
- throw new SlingException("Unable to authenticate", le);
+ this.copy(srcResource, destAbsPath, newResources);
+ rollback = false;
+ } finally {
+ if ( rollback ) {
+ for(final Resource rsrc : newResources) {
+ this.delete(rsrc);
+ }
+ }
}
}
@@ -462,16 +543,24 @@ public class CombinedResourceProvider {
* {@link StatefulResourceProvider#move(String, String)} method on it.
* Returns false if there's no such provider.
*/
- public boolean move(String srcAbsPath, String destAbsPath) throws PersistenceException {
+ public void move(String srcAbsPath, String destAbsPath) throws PersistenceException {
+ final StatefulResourceProvider optimizedSourceProvider = checkSourceAndDest(srcAbsPath, destAbsPath);
+ if ( optimizedSourceProvider != null && optimizedSourceProvider.move(srcAbsPath, destAbsPath) ) {
+ return;
+ }
+ final Resource srcResource = this.getResource(srcAbsPath, null, null, false);
+ final List<Resource> newResources = new ArrayList<Resource>();
+ boolean rollback = true;
try {
- List<StatefulResourceProvider> srcProviders = getMatchingModifiableProviders(srcAbsPath);
- List<StatefulResourceProvider> dstProviders = getMatchingModifiableProviders(destAbsPath);
- @SuppressWarnings("unchecked")
- List<StatefulResourceProvider> intersection = ListUtils.intersection(srcProviders, dstProviders);
- return head(intersection).move(srcAbsPath, destAbsPath);
- } catch (LoginException le) {
- // TODO - ignore for a single handler
- throw new SlingException("Unable to authenticate", le);
+ this.copy(srcResource, destAbsPath, newResources);
+ this.delete(srcResource);
+ rollback = false;
+ } finally {
+ if ( rollback ) {
+ for(final Resource rsrc : newResources) {
+ this.delete(rsrc);
+ }
+ }
}
}
@@ -510,36 +599,6 @@ public class CombinedResourceProvider {
return null;
}
- private List<StatefulResourceProvider> getMatchingProviders(String path) throws LoginException {
- List<ResourceProviderHandler> handlers = storage.getTree().getMatchingNodes(path);
- StatefulResourceProvider[] matching = new StatefulResourceProvider[handlers.size()];
- int i = matching.length - 1;
- for (ResourceProviderHandler h : handlers) {
- matching[i--] = authenticator.getStateful(h, this);
- }
- return Arrays.asList(matching);
- }
-
- private List<StatefulResourceProvider> getMatchingModifiableProviders(String path) throws LoginException {
- List<ResourceProviderHandler> handlers = storage.getTree().getMatchingNodes(path);
- List<StatefulResourceProvider> matching = new ArrayList<StatefulResourceProvider>(handlers.size());
- for (ResourceProviderHandler h : handlers) {
- if (h.getInfo().isModifiable()) {
- matching.add(authenticator.getStateful(h, this));
- }
- }
- Collections.reverse(matching);
- return matching;
- }
-
- private static StatefulResourceProvider head(List<StatefulResourceProvider> list) {
- if (list.isEmpty()) {
- return EmptyResourceProvider.SINGLETON;
- } else {
- return list.get(0);
- }
- }
-
private class CombinedQueryResult extends QueryResult implements Iterable<Resource> {
private final Query q;