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 2016/02/05 11:19:25 UTC
svn commit: r1728626 - in /sling/trunk/bundles/resourceresolver/src:
main/java/org/apache/sling/resourceresolver/impl/
main/java/org/apache/sling/resourceresolver/impl/helper/
main/java/org/apache/sling/resourceresolver/impl/providers/
main/java/org/ap...
Author: cziegeler
Date: Fri Feb 5 10:19:24 2016
New Revision: 1728626
URL: http://svn.apache.org/viewvc?rev=1728626&view=rev
Log:
SLING-5470 : Resource providers might not be closed
Removed:
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResourceProviderAuthenticator.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/StatefulResourceProvider.java
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/helper/ResourceResolverContext.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.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/BasicResolveContext.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecorator.java
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.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=1728626&r1=1728625&r2=1728626&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 Fri Feb 5 10:19:24 2016
@@ -61,7 +61,6 @@ import org.apache.sling.resourceresolver
import org.apache.sling.resourceresolver.impl.mapping.MapEntry;
import org.apache.sling.resourceresolver.impl.params.ParsedParameters;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.stateful.ResourceProviderAuthenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -112,9 +111,9 @@ public class ResourceResolverImpl extend
ResourceResolverImpl(final CommonResourceResolverFactoryImpl factory, final boolean isAdmin, final Map<String, Object> authenticationInfo, final ResourceProviderStorage storage) throws LoginException {
this.factory = factory;
+ this.context = new ResourceResolverContext(this);
this.control = createControl(storage, authenticationInfo, isAdmin);
this.factory.register(this, control);
- this.context = new ResourceResolverContext(this);
}
/**
@@ -132,17 +131,28 @@ public class ResourceResolverImpl extend
if (authenticationInfo != null) {
authInfo.putAll(authenticationInfo);
}
+ this.context = new ResourceResolverContext(this);
this.control = createControl(factory.getResourceProviderTracker().getResourceProviderStorage(), authInfo, resolver.control.isAdmin());
this.factory.register(this, control);
- this.context = new ResourceResolverContext(this);
}
- private ResourceResolverControl createControl(ResourceProviderStorage storage, Map<String, Object> authenticationInfo, final boolean isAdmin)
+ /**
+ * Create the resource resolver control
+ * @param storage The provider storage
+ * @param authenticationInfo Current auth info
+ * @param isAdmin Is this admin?
+ * @return A control
+ * @throws LoginException If auth to the required providers fails.
+ */
+ private ResourceResolverControl createControl(final ResourceProviderStorage storage,
+ final Map<String, Object> authenticationInfo,
+ final boolean isAdmin)
throws LoginException {
- final ResourceProviderAuthenticator authenticator = new ResourceProviderAuthenticator(this, authenticationInfo, this.factory.getResourceAccessSecurityTracker());
- final ResourceResolverControl provider = new ResourceResolverControl(isAdmin, authenticationInfo, storage, authenticator);
- authenticator.authenticateAll(storage.getAuthRequiredHandlers(), provider);
- return provider;
+ final ResourceResolverControl control = new ResourceResolverControl(isAdmin, authenticationInfo, storage);
+
+ this.context.getResolveContextManager().authenticateAll(storage.getAuthRequiredHandlers(), control);
+
+ return control;
}
/**
@@ -163,7 +173,7 @@ public class ResourceResolverImpl extend
*/
@Override
public boolean isLive() {
- return !this.control.isClosed() && this.control.isLive() && this.factory.isLive();
+ return !this.control.isClosed() && this.control.isLive(this.context) && this.factory.isLive();
}
/**
@@ -203,7 +213,7 @@ public class ResourceResolverImpl extend
@Override
public Iterator<String> getAttributeNames() {
checkClosed();
- return this.control.getAttributeNames().iterator();
+ return this.control.getAttributeNames(this.context).iterator();
}
/**
@@ -216,7 +226,7 @@ public class ResourceResolverImpl extend
throw new NullPointerException("name");
}
- return this.control.getAttribute(name);
+ return this.control.getAttribute(this.context, name);
}
// ---------- resolving resources
@@ -737,7 +747,7 @@ public class ResourceResolverImpl extend
checkClosed();
return new ResourceIteratorDecorator(this.factory.getResourceDecoratorTracker(),
- control.findResources(query, defaultString(language, DEFAULT_QUERY_LANGUAGE)));
+ control.findResources(this.context, query, defaultString(language, DEFAULT_QUERY_LANGUAGE)));
}
/**
@@ -749,7 +759,7 @@ public class ResourceResolverImpl extend
throws SlingException {
checkClosed();
- return control.queryResources(query, defaultString(language, DEFAULT_QUERY_LANGUAGE));
+ return control.queryResources(this.context, query, defaultString(language, DEFAULT_QUERY_LANGUAGE));
}
/**
@@ -799,7 +809,7 @@ public class ResourceResolverImpl extend
private Session getSession() {
if ( !this.searchedSession ) {
this.searchedSession = true;
- this.cachedSession = this.control.adaptTo(Session.class);
+ this.cachedSession = this.control.adaptTo(this.context, Session.class);
}
return this.cachedSession;
}
@@ -817,7 +827,7 @@ public class ResourceResolverImpl extend
if (type == Session.class) {
return (AdapterType) getSession();
}
- final AdapterType result = this.control.adaptTo(type);
+ final AdapterType result = this.control.adaptTo(this.context, type);
if ( result != null ) {
return result;
}
@@ -1155,7 +1165,7 @@ public class ResourceResolverImpl extend
return;
}
// if resource is null, we get an NPE as stated in the API
- this.control.delete(resource);
+ this.control.delete(this.context, resource);
}
/**
@@ -1196,7 +1206,7 @@ public class ResourceResolverImpl extend
*/
@Override
public void revert() {
- this.control.revert();
+ this.control.revert(this.context);
}
/**
@@ -1204,7 +1214,7 @@ public class ResourceResolverImpl extend
*/
@Override
public void commit() throws PersistenceException {
- this.control.commit();
+ this.control.commit(this.context);
}
/**
@@ -1212,7 +1222,7 @@ public class ResourceResolverImpl extend
*/
@Override
public boolean hasChanges() {
- return this.control.hasChanges();
+ return this.control.hasChanges(this.context);
}
/**
@@ -1283,7 +1293,7 @@ public class ResourceResolverImpl extend
*/
@Override
public void refresh() {
- this.control.refresh();
+ this.control.refresh(this.context);
}
@Override
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java Fri Feb 5 10:19:24 2016
@@ -22,6 +22,8 @@ import org.apache.sling.resourceresolver
/**
* The resource resolver context.
+ *
+ * This class is not thread safe (same as the resource resolver).
*/
public class ResourceResolverContext {
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java Fri Feb 5 10:19:24 2016
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@@ -47,8 +48,7 @@ import org.apache.sling.resource.path.Pa
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.stateful.ResourceProviderAuthenticator;
-import org.apache.sling.resourceresolver.impl.providers.stateful.StatefulResourceProvider;
+import org.apache.sling.resourceresolver.impl.providers.stateful.AuthenticatedResourceProvider;
import org.apache.sling.resourceresolver.impl.providers.tree.Node;
import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.slf4j.Logger;
@@ -69,6 +69,9 @@ public class ResourceResolverControl {
/** Is this a resource resolver for an admin? */
private final boolean isAdmin;
+ /** The authentication info. */
+ private final Map<String, Object> authenticationInfo;
+
/** Resource type resource resolver (admin resolver) */
private volatile ResourceResolver resourceTypeResourceResolver;
@@ -77,48 +80,59 @@ public class ResourceResolverControl {
private final ResourceProviderStorage storage;
- private final ResourceProviderAuthenticator authenticator;
-
- private final Map<String, Object> authenticationInfo;
+ private final Map<ResourceProviderHandler, Object> authenticatedProviders;
/**
* Create a new resource resolver context.
*/
public ResourceResolverControl(final boolean isAdmin,
final Map<String, Object> authenticationInfo,
- ResourceProviderStorage storage,
- ResourceProviderAuthenticator authenticator) {
+ final ResourceProviderStorage storage) {
+ this.authenticatedProviders = new IdentityHashMap<ResourceProviderHandler, Object>();
this.authenticationInfo = authenticationInfo;
this.isAdmin = isAdmin;
this.storage = storage;
- this.authenticator = authenticator;
}
+ /**
+ * Is this an admin resource resolver?
+ * @return{@code true} if it is an admin resource resolver
+ */
public boolean isAdmin() {
return isAdmin;
}
+ /**
+ * The authentication info
+ * @return The map with the auth info
+ */
public Map<String, Object> getAuthenticationInfo() {
return this.authenticationInfo;
}
+ /**
+ * Is this already closed?
+ * @return {@code true} if it is closed.
+ */
public boolean isClosed() {
return this.isClosed.get();
}
+
/**
* Logs out from all providers.
*/
private void logout() {
- for (StatefulResourceProvider p : authenticator.getAllUsedAuthenticated()) {
- p.logout();
+ for(final Map.Entry<ResourceProviderHandler, Object> entry : this.authenticatedProviders.entrySet()) {
+ entry.getKey().getResourceProvider().logout(entry.getValue());
}
+ this.authenticatedProviders.clear();
}
/**
* Refreshes all refreshable providers.
*/
- public void refresh() {
- for (StatefulResourceProvider p : authenticator.getAllUsedRefreshable()) {
+ public void refresh(@Nonnull final ResourceResolverContext context) {
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedRefreshable()) {
p.refresh();
}
}
@@ -126,8 +140,8 @@ public class ResourceResolverControl {
/**
* Returns {@code true} if all providers are live.
*/
- public boolean isLive() {
- for (StatefulResourceProvider p : authenticator.getAllUsedAuthenticated()) {
+ public boolean isLive(@Nonnull final ResourceResolverContext context) {
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllAuthenticated()) {
if (!p.isLive()) {
return false;
}
@@ -145,21 +159,19 @@ public class ResourceResolverControl {
*/
public Resource getParent(final ResourceResolverContext context, final Resource child) {
final String path = child.getPath();
- try {
- final StatefulResourceProvider provider = getBestMatchingProvider(path);
- if ( provider != null ) {
- final Resource parentCandidate = provider.getParent(child);
- if (parentCandidate != null) {
- return parentCandidate;
- }
+ final AuthenticatedResourceProvider provider = getBestMatchingProvider(context, path);
+ if ( provider != null ) {
+ final Resource parentCandidate = provider.getParent(child);
+ if (parentCandidate != null) {
+ return parentCandidate;
}
- } catch ( final LoginException le ) {
- // ignore
}
+
final String parentPath = ResourceUtil.getParent(path);
if (parentPath != null && isIntermediatePath(parentPath)) {
return new SyntheticResource(context.getResourceResolver(), parentPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
}
+
return null;
}
@@ -185,17 +197,14 @@ public class ResourceResolverControl {
return null; // path must be absolute
}
- try {
- final StatefulResourceProvider provider = this.getBestMatchingProvider(path);
- if ( provider != null ) {
- final Resource resourceCandidate = provider.getResource(path, parent, parameters, isResolve);
- if (resourceCandidate != null) {
- return resourceCandidate;
- }
+ final AuthenticatedResourceProvider provider = this.getBestMatchingProvider(context, path);
+ if ( provider != null ) {
+ final Resource resourceCandidate = provider.getResource(path, parent, parameters, isResolve);
+ if (resourceCandidate != null) {
+ return resourceCandidate;
}
- } catch ( LoginException le ) {
- // ignore
}
+
// query: /libs/sling/servlet/default
// resource Provider: libs/sling/servlet/default/GET.servlet
// list will match libs, sling, servlet, default
@@ -233,13 +242,9 @@ public class ResourceResolverControl {
// children of the 'parent' provider
Iterator<Resource> realChildren = null;
- try {
- final StatefulResourceProvider provider = this.getBestMatchingProvider(parentPath);
- if ( provider != null ) {
- realChildren = provider.listChildren(parent);
- }
- } catch ( final LoginException le ) {
- // ignore, realChildren will be null
+ final AuthenticatedResourceProvider provider = this.getBestMatchingProvider(context, parentPath);
+ if ( provider != null ) {
+ realChildren = provider.listChildren(parent);
}
final Set<String> visitedNames = new HashSet<String>();
@@ -266,7 +271,8 @@ public class ResourceResolverControl {
} else {
Resource rsrc = null;
try {
- rsrc = authenticator.getStateful(handler, this).getResource(childPath, parent, null, false);
+ final AuthenticatedResourceProvider rp = context.getResolveContextManager().getOrCreateProvider(handler, this);
+ rsrc = rp == null ? null : rp.getResource(childPath, parent, null, false);
} catch ( final LoginException ignore) {
// ignore
}
@@ -299,10 +305,10 @@ public class ResourceResolverControl {
/**
* Returns the union of all attribute names.
*/
- public Collection<String> getAttributeNames() {
+ public Collection<String> getAttributeNames(final ResourceResolverContext context) {
final Set<String> names = new LinkedHashSet<String>();
- for (StatefulResourceProvider p : authenticator.getAllBestEffort(storage.getAttributableHandlers(), this)) {
- final Collection<String> newNames = p.getAttributeNames();
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getAttributableHandlers(), this)) {
+ final Collection<String> newNames = p.getAttributeNames(this.authenticationInfo);
if (newNames != null) {
names.addAll(newNames);
}
@@ -315,9 +321,9 @@ public class ResourceResolverControl {
* {@link StatefulResourceProvider#getAttribute(String)} invocation on
* the providers.
*/
- public Object getAttribute(String name) {
- for (StatefulResourceProvider p : authenticator.getAllBestEffort(storage.getAttributableHandlers(), this)) {
- Object attribute = p.getAttribute(name);
+ public Object getAttribute(final ResourceResolverContext context, final String name) {
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getAttributableHandlers(), this)) {
+ Object attribute = p.getAttribute(name, this.authenticationInfo);
if (attribute != null) {
return attribute;
}
@@ -337,16 +343,12 @@ public class ResourceResolverControl {
public Resource create(final ResourceResolverContext context,
final String path, final Map<String, Object> properties)
throws PersistenceException {
- try {
- final StatefulResourceProvider provider = getBestMatchingModifiableProvider(path);
- if ( provider != null ) {
- final Resource creationResultResource = provider.create(context.getResourceResolver(), path, properties);
- if (creationResultResource != null) {
- return creationResultResource;
- }
+ final AuthenticatedResourceProvider provider = getBestMatchingModifiableProvider(context, path);
+ if ( provider != null ) {
+ final Resource creationResultResource = provider.create(context.getResourceResolver(), path, properties);
+ if (creationResultResource != null) {
+ return creationResultResource;
}
- } catch (LoginException le) {
- // ignore and throw (see below)
}
throw new UnsupportedOperationException("create '" + ResourceUtil.getName(path) + "' at " + ResourceUtil.getParent(path));
}
@@ -362,16 +364,12 @@ public class ResourceResolverControl {
* @throws PersistenceException
* If deletion fails
*/
- public void delete(final Resource resource) throws PersistenceException {
+ public void delete(final ResourceResolverContext context, final Resource resource) throws PersistenceException {
final String path = resource.getPath();
- try {
- final StatefulResourceProvider provider = getBestMatchingModifiableProvider(path);
- if ( provider != null ) {
- provider.delete(resource);
- return;
- }
- } catch (LoginException le) {
- // ignore and throw (see below)
+ final AuthenticatedResourceProvider provider = getBestMatchingModifiableProvider(context, path);
+ if ( provider != null ) {
+ provider.delete(resource);
+ return;
}
throw new UnsupportedOperationException("delete at '" + path + "'");
}
@@ -379,8 +377,8 @@ public class ResourceResolverControl {
/**
* Revert changes on all modifiable ResourceProviders.
*/
- public void revert() {
- for (StatefulResourceProvider p : authenticator.getAllUsedModifiable()) {
+ public void revert(final ResourceResolverContext context) {
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedModifiable()) {
p.revert();
}
}
@@ -388,8 +386,8 @@ public class ResourceResolverControl {
/**
* Commit changes on all modifiable ResourceProviders.
*/
- public void commit() throws PersistenceException {
- for (StatefulResourceProvider p : authenticator.getAllUsedModifiable()) {
+ public void commit(final ResourceResolverContext context) throws PersistenceException {
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedModifiable()) {
p.commit();
}
}
@@ -397,8 +395,8 @@ public class ResourceResolverControl {
/**
* Check if any modifiable ResourceProvider has uncommited changes.
*/
- public boolean hasChanges() {
- for (StatefulResourceProvider p : authenticator.getAllUsedModifiable()) {
+ public boolean hasChanges(final ResourceResolverContext context) {
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedModifiable()) {
if (p.hasChanges()) {
return true;
}
@@ -409,9 +407,9 @@ public class ResourceResolverControl {
/**
* Return the union of query languages supported by the providers.
*/
- public String[] getSupportedLanguages() {
- Set<String> supportedLanguages = new LinkedHashSet<String>();
- for (StatefulResourceProvider p : authenticator.getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
+ public String[] getSupportedLanguages(final ResourceResolverContext context) {
+ final Set<String> supportedLanguages = new LinkedHashSet<String>();
+ for (AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
supportedLanguages.addAll(Arrays.asList(p.getSupportedLanguages()));
}
return supportedLanguages.toArray(new String[supportedLanguages.size()]);
@@ -420,18 +418,21 @@ public class ResourceResolverControl {
/**
* Queries all resource providers and combines the results.
*/
- public Iterator<Resource> findResources(final String query, final String language) {
- List<StatefulResourceProvider> queryableRP = getQueryableProviders(language);
- List<Iterator<Resource>> iterators = new ArrayList<Iterator<Resource>>(queryableRP.size());
- for (StatefulResourceProvider p : queryableRP) {
+ public Iterator<Resource> findResources(final ResourceResolverContext context,
+ final String query, final String language) {
+ final List<AuthenticatedResourceProvider> queryableRP = getQueryableProviders(context, language);
+ final List<Iterator<Resource>> iterators = new ArrayList<Iterator<Resource>>(queryableRP.size());
+ for (AuthenticatedResourceProvider p : queryableRP) {
iterators.add(p.findResources(query, language));
}
return new ChainedIterator<Resource>(iterators.iterator());
}
- private List<StatefulResourceProvider> getQueryableProviders(String language) {
- List<StatefulResourceProvider> queryableProviders = new ArrayList<StatefulResourceProvider>();
- for (StatefulResourceProvider p : authenticator.getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
+ private List<AuthenticatedResourceProvider> getQueryableProviders(
+ final ResourceResolverContext context,
+ final String language) {
+ final List<AuthenticatedResourceProvider> queryableProviders = new ArrayList<AuthenticatedResourceProvider>();
+ for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
if (ArrayUtils.contains(p.getSupportedLanguages(), language)) {
queryableProviders.add(p);
}
@@ -442,10 +443,11 @@ public class ResourceResolverControl {
/**
* Queries all resource providers and combines the results.
*/
- public Iterator<Map<String, Object>> queryResources(final String query, final String language) {
- List<StatefulResourceProvider> queryableRP = getQueryableProviders(language);
- List<Iterator<Map<String, Object>>> iterators = new ArrayList<Iterator<Map<String, Object>>>(queryableRP.size());
- for (StatefulResourceProvider p : queryableRP) {
+ public Iterator<Map<String, Object>> queryResources(final ResourceResolverContext context,
+ final String query, final String language) {
+ final List<AuthenticatedResourceProvider> queryableRP = getQueryableProviders(context, language);
+ final List<Iterator<Map<String, Object>>> iterators = new ArrayList<Iterator<Map<String, Object>>>(queryableRP.size());
+ for (AuthenticatedResourceProvider p : queryableRP) {
iterators.add(p.queryResources(query, language));
}
return new ChainedIterator<Map<String, Object>>(iterators.iterator());
@@ -456,8 +458,9 @@ public class ResourceResolverControl {
* providers.
*/
@SuppressWarnings("unchecked")
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- for (StatefulResourceProvider p : authenticator.getAllBestEffort(storage.getAdaptableHandlers(), this)) {
+ public <AdapterType> AdapterType adaptTo(final ResourceResolverContext context, Class<AdapterType> type) {
+ // TODO - improve by providing an iterator instead of a list (getAllBestEffort)
+ for (AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getAdaptableHandlers(), this)) {
final Object adaptee = p.adaptTo(type);
if (adaptee != null) {
return (AdapterType) adaptee;
@@ -466,15 +469,16 @@ public class ResourceResolverControl {
return null;
}
- private StatefulResourceProvider checkSourceAndDest(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
+ private AuthenticatedResourceProvider checkSourceAndDest(final ResourceResolverContext context,
+ final String srcAbsPath, final String destAbsPath) throws PersistenceException {
// check source
final Node<ResourceProviderHandler> srcNode = storage.getTree().getBestMatchingNode(srcAbsPath);
if ( srcNode == null ) {
throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
}
- StatefulResourceProvider srcProvider = null;
+ AuthenticatedResourceProvider srcProvider = null;
try {
- srcProvider = authenticator.getStateful(srcNode.getValue(), this);
+ srcProvider = context.getResolveContextManager().getOrCreateProvider(srcNode.getValue(), this);
} catch (LoginException e) {
// ignore
}
@@ -491,9 +495,9 @@ public class ResourceResolverControl {
if ( destNode == null ) {
throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
}
- StatefulResourceProvider destProvider = null;
+ AuthenticatedResourceProvider destProvider = null;
try {
- destProvider = authenticator.getStateful(destNode.getValue(), this);
+ destProvider = context.getResolveContextManager().getOrCreateProvider(destNode.getValue(), this);
} catch (LoginException e) {
// ignore
}
@@ -506,24 +510,25 @@ public class ResourceResolverControl {
}
// check for sub providers of src and dest
- if ( srcProvider == destProvider && !collectProviders(srcNode) && !collectProviders(destNode) ) {
+ if ( srcProvider == destProvider && !collectProviders(context, srcNode) && !collectProviders(context, destNode) ) {
return srcProvider;
}
return null;
}
- private boolean collectProviders(final Node<ResourceProviderHandler> parent) {
+ private boolean collectProviders(final ResourceResolverContext context,
+ 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);
+ context.getResolveContextManager().getOrCreateProvider(entry.getValue().getValue(), this);
hasMoreProviders = true;
} catch ( final LoginException ignore) {
// ignore
}
}
- if ( collectProviders(entry.getValue())) {
+ if ( collectProviders(context, entry.getValue())) {
hasMoreProviders = true;
}
}
@@ -547,7 +552,7 @@ public class ResourceResolverControl {
*/
public Resource copy(final ResourceResolverContext context,
final String srcAbsPath, final String destAbsPath) throws PersistenceException {
- final StatefulResourceProvider optimizedSourceProvider = checkSourceAndDest(srcAbsPath, destAbsPath);
+ final AuthenticatedResourceProvider optimizedSourceProvider = checkSourceAndDest(context, srcAbsPath, destAbsPath);
if ( optimizedSourceProvider != null && optimizedSourceProvider.copy(srcAbsPath, destAbsPath) ) {
return this.getResource(context, destAbsPath + '/' + ResourceUtil.getName(srcAbsPath), null, null, false);
}
@@ -562,7 +567,7 @@ public class ResourceResolverControl {
} finally {
if ( rollback ) {
for(final Resource rsrc : newResources) {
- this.delete(rsrc);
+ this.delete(context, rsrc);
}
}
}
@@ -575,7 +580,7 @@ public class ResourceResolverControl {
*/
public Resource move(final ResourceResolverContext context,
String srcAbsPath, String destAbsPath) throws PersistenceException {
- final StatefulResourceProvider optimizedSourceProvider = checkSourceAndDest(srcAbsPath, destAbsPath);
+ final AuthenticatedResourceProvider optimizedSourceProvider = checkSourceAndDest(context, srcAbsPath, destAbsPath);
if ( optimizedSourceProvider != null && optimizedSourceProvider.move(srcAbsPath, destAbsPath) ) {
return this.getResource(context, destAbsPath + '/' + ResourceUtil.getName(srcAbsPath), null, null, false);
}
@@ -584,13 +589,13 @@ public class ResourceResolverControl {
boolean rollback = true;
try {
this.copy(context, srcResource, destAbsPath, newResources);
- this.delete(srcResource);
+ this.delete(context, srcResource);
rollback = false;
return newResources.get(0);
} finally {
if ( rollback ) {
for(final Resource rsrc : newResources) {
- this.delete(rsrc);
+ this.delete(context, rsrc);
}
}
}
@@ -600,33 +605,36 @@ public class ResourceResolverControl {
return this.storage;
}
- public @CheckForNull StatefulResourceProvider getStatefulResourceProvider(@Nonnull final ResourceProviderHandler handler)
- throws LoginException {
- if ( handler != null ) {
- return authenticator.getStateful(handler, this);
- }
- return null;
- }
-
/**
* @param path
* @return
- * @throws LoginException
*/
- private @CheckForNull StatefulResourceProvider getBestMatchingProvider(final String path) throws LoginException {
- final Node<ResourceProviderHandler> node = storage.getTree().getBestMatchingNode(path);
- return node == null ? null : authenticator.getStateful(node.getValue(), this);
+ private @CheckForNull AuthenticatedResourceProvider getBestMatchingProvider(final ResourceResolverContext context,
+ final String path) {
+ try {
+ final Node<ResourceProviderHandler> node = storage.getTree().getBestMatchingNode(path);
+ return node == null ? null : context.getResolveContextManager().getOrCreateProvider(node.getValue(), this);
+ } catch ( final LoginException le ) {
+ // ignore
+ return null;
+ }
}
/**
* @param path
* @return The modifiable provider or {@code null}
- * @throws LoginException
*/
- private @CheckForNull StatefulResourceProvider getBestMatchingModifiableProvider(final String path) throws LoginException {
+ private @CheckForNull AuthenticatedResourceProvider getBestMatchingModifiableProvider(
+ final ResourceResolverContext context,
+ final String path) {
final Node<ResourceProviderHandler> node = storage.getTree().getBestMatchingNode(path);
if ( node != null && node.getValue().getInfo().isModifiable() ) {
- return authenticator.getStateful(node.getValue(), this);
+ try {
+ return context.getResolveContextManager().getOrCreateProvider(node.getValue(), this);
+ } catch ( final LoginException le ) {
+ // ignore
+ return null;
+ }
}
return null;
}
@@ -747,4 +755,13 @@ public class ResourceResolverControl {
return null;
}
+
+ public void registerAuthenticatedProvider(@Nonnull ResourceProviderHandler handler,
+ @CheckForNull Object providerState) {
+ this.authenticatedProviders.put(handler, providerState);
+ }
+
+ public void clearAuthenticatedProviders() {
+ this.authenticatedProviders.clear();
+ }
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java Fri Feb 5 10:19:24 2016
@@ -39,8 +39,6 @@ public class ResourceProviderStorage {
private final List<ResourceProviderHandler> attributableHandlers;
- private final List<ResourceProviderHandler> refreshableHandlers;
-
private final List<ResourceProviderHandler> languageQueryableHandlers;
private final PathTree<ResourceProviderHandler> handlersTree;
@@ -50,7 +48,6 @@ public class ResourceProviderStorage {
this.authRequiredHandlers = new ArrayList<ResourceProviderHandler>();
this.adaptableHandlers = new ArrayList<ResourceProviderHandler>();
this.attributableHandlers = new ArrayList<ResourceProviderHandler>();
- this.refreshableHandlers = new ArrayList<ResourceProviderHandler>();
this.languageQueryableHandlers = new ArrayList<ResourceProviderHandler>();
for (ResourceProviderHandler h : allHandlers) {
ResourceProviderInfo info = h.getInfo();
@@ -63,9 +60,6 @@ public class ResourceProviderStorage {
if (info.isAttributable()) {
this.attributableHandlers.add(h);
}
- if (info.isRefreshable()) {
- this.refreshableHandlers.add(h);
- }
if (h.getResourceProvider().getQueryLanguageProvider() != null) {
this.languageQueryableHandlers.add(h);
}
@@ -89,10 +83,6 @@ public class ResourceProviderStorage {
return attributableHandlers;
}
- public List<ResourceProviderHandler> getRefreshableHandlers() {
- return refreshableHandlers;
- }
-
public List<ResourceProviderHandler> getLanguageQueryableHandlers() {
return languageQueryableHandlers;
}
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=1728626&r1=1728625&r2=1728626&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 Fri Feb 5 10:19:24 2016
@@ -24,22 +24,15 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
-import org.apache.commons.lang.ArrayUtils;
-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.ResourceResolverFactory;
-import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* This {@link StatefulResourceProvider} implementation authenticates the
@@ -47,105 +40,41 @@ import org.slf4j.LoggerFactory;
* creation of the object (for {@link AuthType#required}) or before invoking the
* first method (for {@link AuthType#lazy}).
*/
-public class AuthenticatedResourceProvider implements StatefulResourceProvider {
-
- private static final Logger logger = LoggerFactory.getLogger(AuthenticatedResourceProvider.class);
+public class AuthenticatedResourceProvider {
private static final String FORBIDDEN_ATTRIBUTE = ResourceResolverFactory.PASSWORD;
- private final ResourceProviderHandler handler;
-
- private final Map<String, Object> authInfo;
+ public static final AuthenticatedResourceProvider UNAUTHENTICATED_PROVIDER = new AuthenticatedResourceProvider(null, null);
- private final ResourceResolver resolver;
+ private final ResourceProvider<Object> provider;
- private final ResourceResolverControl resolverContext;
-
- private volatile ResolveContext<Object> cachedContext;
+ private final ResolveContext<Object> cachedContext;
private volatile boolean authenticated;
- public AuthenticatedResourceProvider(final ResourceProviderHandler handler,
- ResourceResolver resolver,
- Map<String, Object> authInfo,
- ResourceResolverControl resolverContext) throws LoginException {
- this.handler = handler;
- this.authInfo = authInfo;
- this.resolver = resolver;
- this.resolverContext = resolverContext;
- if (handler.getInfo().getAuthType() == AuthType.required) {
- authenticate();
- }
- }
-
- private ResolveContext<Object> authenticate() throws LoginException {
- if ( cachedContext == null ) {
- Object contextData = null;
- if ( (handler.getInfo().getAuthType() == AuthType.required || handler.getInfo().getAuthType() == AuthType.lazy) ) {
- try {
- contextData = handler.getResourceProvider().authenticate(authInfo);
- } catch ( final LoginException le ) {
- logger.debug("Unable to login into resource provider " + handler.getResourceProvider(), le);
- throw le;
- }
- authenticated = true;
- }
-
- cachedContext = new BasicResolveContext<Object>(resolver, contextData, ResourceUtil.getParent(handler.getInfo().getPath()), this.resolverContext);
- }
-
- return cachedContext;
- }
-
- @Override
- public ResolveContext<Object> getContext() throws LoginException {
- return authenticate();
+ public AuthenticatedResourceProvider(final ResourceProvider<Object> provider,
+ final ResolveContext<Object> resolveContext) {
+ this.provider = provider;
+ this.cachedContext = resolveContext;
}
- @Override
- public void logout() {
- if (authenticated) {
- try {
- handler.getResourceProvider().logout(getContext().getProviderState());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
- authenticated = false;
- }
- cachedContext = null;
+ public ResolveContext<Object> getResolveContext() {
+ return this.cachedContext;
}
- @Override
public void refresh() {
- try {
- handler.getResourceProvider().refresh(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
+ this.provider.refresh(this.cachedContext);
}
- @Override
public boolean isLive() {
- try {
- return handler.getResourceProvider().isLive(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return false;
- }
+ return this.provider.isLive(this.cachedContext);
}
- @Override
- public Resource getParent(Resource child) {
- try {
- return handler.getResourceProvider().getParent(getContext(), child);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
+ public Resource getParent(final Resource child) {
+ return this.provider.getParent(this.cachedContext, child);
}
- @Override
public Resource getResource(String path, Resource parent, final Map<String, String> parameters, boolean isResolve) {
ResourceContext resourceContext = ResourceContext.EMPTY_CONTEXT;
if ( parameters != null ) {
@@ -157,34 +86,16 @@ public class AuthenticatedResourceProvid
}
};
}
- try {
- return handler.getResourceProvider().getResource(getContext(), path, resourceContext, parent);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
-
+ return this.provider.getResource(this.cachedContext, path, resourceContext, parent);
}
- @Override
public Iterator<Resource> listChildren(Resource parent) {
- try {
- return handler.getResourceProvider().listChildren(getContext(), parent);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
+ return this.provider.listChildren(this.cachedContext, parent);
}
- @Override
- public Collection<String> getAttributeNames() {
+ public Collection<String> getAttributeNames(final Map<String, Object> authInfo) {
Set<String> attributeNames = new LinkedHashSet<String>();
- Collection<String> rpAttributeNames = null;
- try {
- rpAttributeNames = handler.getResourceProvider().getAttributeNames(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
+ Collection<String> rpAttributeNames = this.provider.getAttributeNames(this.cachedContext);
if (rpAttributeNames != null) {
attributeNames.addAll(rpAttributeNames);
}
@@ -195,152 +106,80 @@ public class AuthenticatedResourceProvid
return attributeNames;
}
- @Override
- public Object getAttribute(String name) {
+ public Object getAttribute(final String name, final Map<String, Object> authInfo) {
if (FORBIDDEN_ATTRIBUTE.equals(name)) {
return null;
}
- Object attribute = null;
- try {
- attribute = handler.getResourceProvider().getAttribute(getContext(), name);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
+ Object attribute = this.provider.getAttribute(this.cachedContext, name);
if (attribute == null) {
attribute = authInfo.get(name);
}
return attribute;
}
- @Override
public Resource create(final ResourceResolver resolver, String path, Map<String, Object> properties) throws PersistenceException {
- try {
- return handler.getResourceProvider().create(getContext(), path, properties);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
+ return this.provider.create(this.cachedContext, path, properties);
}
- @Override
public void delete(Resource resource) throws PersistenceException {
- try {
- handler.getResourceProvider().delete(getContext(), resource);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
+ this.provider.delete(this.cachedContext, resource);
}
- @Override
public void revert() {
- try {
- handler.getResourceProvider().revert(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
+ this.provider.revert(this.cachedContext);
}
- @Override
public void commit() throws PersistenceException {
- try {
- handler.getResourceProvider().commit(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- }
+ this.provider.commit(this.cachedContext);
}
- @Override
public boolean hasChanges() {
- try {
- return handler.getResourceProvider().hasChanges(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return false;
- }
+ return this.provider.hasChanges(this.cachedContext);
}
private QueryLanguageProvider<Object> getQueryLanguageProvider() {
- return handler.getResourceProvider().getQueryLanguageProvider();
+ return this.provider.getQueryLanguageProvider();
}
- @Override
public String[] getSupportedLanguages() {
final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
if (jcrQueryProvider == null) {
return null;
}
- try {
- return jcrQueryProvider.getSupportedLanguages(getContext());
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return ArrayUtils.EMPTY_STRING_ARRAY;
- }
+ return jcrQueryProvider.getSupportedLanguages(this.cachedContext);
}
- @Override
public Iterator<Resource> findResources(String query, String language) {
final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
if (jcrQueryProvider == null) {
return null;
}
- try {
- return jcrQueryProvider.findResources(getContext(), query, language);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
+ return jcrQueryProvider.findResources(this.cachedContext, query, language);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
public Iterator<Map<String, Object>> queryResources(String query, String language) {
final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
if (jcrQueryProvider == null) {
return null;
}
- try {
- return (Iterator) jcrQueryProvider.queryResources(getContext(), query, language);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
+ return (Iterator) jcrQueryProvider.queryResources(this.cachedContext, query, language);
}
- @Override
public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- try {
- return handler.getResourceProvider().adaptTo(getContext(), type);
- } catch (LoginException e) {
- logger.error("Can't create context", e);
- return null;
- }
+ return this.provider.adaptTo(this.cachedContext, type);
}
- @Override
public boolean copy(String srcAbsPath, String destAbsPath) throws PersistenceException {
- try {
- return handler.getResourceProvider().copy(getContext(), srcAbsPath, destAbsPath);
- } catch (LoginException e) {
- throw new PersistenceException("Unable to create context.", e);
- }
+ return this.provider.copy(this.cachedContext, srcAbsPath, destAbsPath);
}
- @Override
public boolean move(String srcAbsPath, String destAbsPath) throws PersistenceException {
- try {
- return handler.getResourceProvider().move(getContext(), srcAbsPath, destAbsPath);
- } catch (LoginException e) {
- throw new PersistenceException("Unable to create context.", e);
- }
- }
-
- @Override
- public ResourceProvider<Object> getResourceProvider() {
- return handler.getResourceProvider();
+ return this.provider.move(this.cachedContext, srcAbsPath, destAbsPath);
}
@Override
public String toString() {
- return "[" + getClass().getSimpleName() + "# rp: " + getResourceProvider() + ", authenticated: " + authenticated + "]";
+ return "[" + getClass().getSimpleName() + "# rp: " + this.provider + ", authenticated: " + authenticated + "]";
}
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java Fri Feb 5 10:19:24 2016
@@ -18,25 +18,34 @@
*/
package org.apache.sling.resourceresolver.impl.providers.stateful;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
import org.apache.sling.resourceresolver.impl.providers.tree.Node;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;
+/**
+ * Resolve context implementation for a resource provider.
+ *
+ * This class is not thread safe (same as the resource resolver).
+ */
public class BasicResolveContext<T> implements ResolveContext<T> {
- private final String parentPath;
+ private final ResourceResolver resolver;
+
+ private final ResolveContextManager resolveContextManager;
- private final ResourceResolver resourceResolver;
+ private final ResourceResolverControl control;
private final T providerState;
- private final ResourceResolverControl combinedProvider;
+ private final String parentPath;
private volatile boolean parentLookupDone = false;
@@ -44,24 +53,21 @@ public class BasicResolveContext<T> impl
private volatile ResolveContext<Object> parentResolveContext;
- public BasicResolveContext(ResourceResolver resourceResolver,
- T providerState,
- String parentPath,
- ResourceResolverControl combinedProvider) {
- this.resourceResolver = resourceResolver;
+ public BasicResolveContext(@Nonnull final ResourceResolver resolver,
+ @Nonnull final ResolveContextManager resolveContextManager,
+ @Nonnull final ResourceResolverControl control,
+ @CheckForNull final T providerState,
+ @Nonnull final String parentPath) {
+ this.resolver = resolver;
+ this.resolveContextManager = resolveContextManager;
this.parentPath = parentPath;
this.providerState = providerState;
- this.combinedProvider = combinedProvider;
- }
-
- public BasicResolveContext(ResourceResolver resourceResolver,
- T providerState, String parentPath) {
- this(resourceResolver, providerState, parentPath, null);
+ this.control = control;
}
@Override
public ResourceResolver getResourceResolver() {
- return resourceResolver;
+ return this.resolver;
}
@Override
@@ -80,20 +86,18 @@ public class BasicResolveContext<T> impl
if ( ! parentLookupDone ) {
synchronized ( this ) {
if ( this.parentPath != null ) {
- final ResourceProviderStorage storage = this.combinedProvider.getResourceProviderStorage();
String path = this.parentPath;
while ( path != null && this.parentProvider != null ) {
- final Node<ResourceProviderHandler> node = storage.getTree().getBestMatchingNode(this.parentPath);
+ final Node<ResourceProviderHandler> node = this.control.getResourceProviderStorage().getTree().getBestMatchingNode(this.parentPath);
if ( node != null ) {
+ final ResourceProviderHandler handler = node.getValue();
try {
- final StatefulResourceProvider srp = this.combinedProvider.getStatefulResourceProvider(node.getValue());
- if ( srp != null ) {
- this.parentProvider = srp.getResourceProvider();
- this.parentResolveContext = srp.getContext();
+ this.parentResolveContext = this.resolveContextManager.getOrCreateResolveContext(handler, this.control);
+ if ( this.parentResolveContext != null ) {
+ this.parentProvider = handler.getResourceProvider();
}
} catch ( final LoginException se) {
// skip this, try next
- this.parentProvider = null;
}
if ( this.parentProvider == null ) {
path = ResourceUtil.getParent(path);
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java Fri Feb 5 10:19:24 2016
@@ -17,22 +17,185 @@
*/
package org.apache.sling.resourceresolver.impl.providers.stateful;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.runtime.dto.AuthType;
+import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.spi.resource.provider.ResolveContext;
-
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manages resolve contexts for each resource provider including
+ * authentication.
+ *
+ * This class is not thread safe (same as the resource resolver).
+ */
public class ResolveContextManager {
- private final Map<ResourceProviderHandler, ResolveContext<Object>> contextMap;
+ private static final Logger logger = LoggerFactory.getLogger(ResolveContextManager.class);
+
+ private final ResourceResolver resolver;
+
+ private final Map<ResourceProviderHandler, AuthenticatedResourceProvider> contextMap;
+
+ /** Set of authenticated resource providers. */
+ private final List<AuthenticatedResourceProvider> authenticated = new ArrayList<AuthenticatedResourceProvider>();
+
+ /** Set of modifiable resource providers. */
+ private final List<AuthenticatedResourceProvider> modifiable = new ArrayList<AuthenticatedResourceProvider>();
+
+ /** Set of refreshable resource providers. */
+ private final List<AuthenticatedResourceProvider> refreshable = new ArrayList<AuthenticatedResourceProvider>();
+
+ public ResolveContextManager(@Nonnull final ResourceResolver resolver) {
+ this.contextMap = new IdentityHashMap<ResourceProviderHandler, AuthenticatedResourceProvider>();
+ this.resolver = resolver;
+ }
+
+ /**
+ * Get the context
+ * @param handler The resource handler
+ * @return The resource context or {@code null} if authentication failed previously.
+ */
+ public @CheckForNull AuthenticatedResourceProvider getOrCreateProvider(@Nonnull final ResourceProviderHandler handler,
+ @Nonnull final ResourceResolverControl control)
+ throws LoginException {
+ AuthenticatedResourceProvider provider = this.contextMap.get(handler);
+ if (provider == null) {
+ try {
+ provider = authenticate(handler, control);
+ this.contextMap.put(handler, provider);
+ if ( handler.getInfo().getAuthType() == AuthType.lazy || handler.getInfo().getAuthType() == AuthType.required ) {
+ control.registerAuthenticatedProvider(handler, provider.getResolveContext().getProviderState());
+ }
+ } catch ( final LoginException le) {
+ logger.debug("Authentication to resource provider " + handler.getResourceProvider() + " failed: " + le.getMessage(), le);
+ this.contextMap.put(handler, AuthenticatedResourceProvider.UNAUTHENTICATED_PROVIDER);
+
+ throw le;
+ }
+ }
+
+ return provider == AuthenticatedResourceProvider.UNAUTHENTICATED_PROVIDER ? null : provider;
+ }
+
+ /**
+ * Get the context
+ * @param handler The resource handler
+ * @return The resource context or {@code null}.
+ */
+ public @CheckForNull ResolveContext<Object> getOrCreateResolveContext(@Nonnull final ResourceProviderHandler handler,
+ @Nonnull final ResourceResolverControl control)
+ throws LoginException {
+ AuthenticatedResourceProvider provider = this.getOrCreateProvider(handler, control);
+ return provider == null ? null : provider.getResolveContext();
+ }
+
+ /**
+ * Authenticate all handlers
+ * @param handlers List of handlers
+ * @param control the resource resolver control
+ * @throws LoginException If authentication fails to one provider
+ */
+ public void authenticateAll(@Nonnull final List<ResourceProviderHandler> handlers,
+ @Nonnull final ResourceResolverControl control)
+ throws LoginException {
+ for (final ResourceProviderHandler h : handlers) {
+ try {
+ this.getOrCreateProvider(h, control);
+ } catch ( final LoginException le ) {
+ // authentication failed, logout from all successful handlers
+ for(final Map.Entry<ResourceProviderHandler, AuthenticatedResourceProvider> entry : this.contextMap.entrySet()) {
+ if ( entry.getValue() != null ) {
+ entry.getKey().getResourceProvider().logout(entry.getValue().getResolveContext().getProviderState());
+ }
+ }
+ this.contextMap.clear();
+ control.clearAuthenticatedProviders();
+ throw le;
+ }
+ }
+ }
+
+ /**
+ * Authenticate a single resource provider (handler)
+ * @param handler The resource provider handler
+ * @param control The resource control
+ * @return The resolve context
+ * @throws LoginException If authentication fails
+ */
+ private @Nonnull AuthenticatedResourceProvider authenticate(@Nonnull final ResourceProviderHandler handler,
+ @Nonnull final ResourceResolverControl control) throws LoginException {
+ final ResourceProvider<Object> provider = handler.getResourceProvider();
+ boolean isAuthenticated = false;
+ Object contextData = null;
+ if ( (handler.getInfo().getAuthType() == AuthType.required || handler.getInfo().getAuthType() == AuthType.lazy) ) {
+ try {
+ contextData = provider.authenticate(control.getAuthenticationInfo());
+ isAuthenticated = true;
+ } catch ( final LoginException le ) {
+ logger.debug("Unable to login into resource provider " + provider, le);
+ throw le;
+ }
+ }
+
+ final ResolveContext<Object> context = new BasicResolveContext<Object>(this.resolver,
+ this,
+ control,
+ contextData,
+ ResourceUtil.getParent(handler.getInfo().getPath()));
+ final AuthenticatedResourceProvider rp = new AuthenticatedResourceProvider(provider, context);
+ if ( isAuthenticated ) {
+ this.authenticated.add(rp);
+ }
+ if ( handler.getInfo().isModifiable() ) {
+ this.modifiable.add(rp);
+ }
+ if ( handler.getInfo().isRefreshable() ) {
+ this.refreshable.add(rp);
+ }
+
+ return rp;
+ }
+
+ public Collection<AuthenticatedResourceProvider> getAllAuthenticated() {
+ return authenticated;
+ }
+
+ public Collection<AuthenticatedResourceProvider> getAllUsedModifiable() {
+ return modifiable;
+ }
- public ResolveContextManager(final ResourceResolver resolver) {
- this.contextMap = new IdentityHashMap<ResourceProviderHandler, ResolveContext<Object>>();
+ public Collection<AuthenticatedResourceProvider> getAllUsedRefreshable() {
+ return refreshable;
}
- public ResolveContext<Object> getResolveContext(final ResourceProviderHandler handler) {
- return this.contextMap.get(handler);
+ public Collection<AuthenticatedResourceProvider> getAllBestEffort(@Nonnull final List<ResourceProviderHandler> handlers,
+ @Nonnull final ResourceResolverControl control) {
+ final List<AuthenticatedResourceProvider> result = new ArrayList<AuthenticatedResourceProvider>(handlers.size());
+ for (final ResourceProviderHandler h : handlers) {
+ try {
+ final AuthenticatedResourceProvider rp = this.getOrCreateProvider(h, control);
+ if ( rp != null ) {
+ result.add(rp);
+ }
+ } catch ( final LoginException le) {
+ // ignore
+ }
+ }
+ return result;
}
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecorator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecorator.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecorator.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecorator.java Fri Feb 5 10:19:24 2016
@@ -18,11 +18,9 @@
*/
package org.apache.sling.resourceresolver.impl.providers.stateful;
-import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
-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;
@@ -39,121 +37,58 @@ import org.slf4j.LoggerFactory;
* This wrapper adds the Sling security layer (see
* {@link ResourceAccessSecurity}) to the underlying {@link ResourceProvider}.
*/
-public class SecureResourceProviderDecorator implements StatefulResourceProvider {
+public class SecureResourceProviderDecorator extends AuthenticatedResourceProvider {
private static final Logger logger = LoggerFactory.getLogger(ResourceResolverImpl.class);
- private final StatefulResourceProvider rp;
-
private final ResourceAccessSecurityTracker tracker;
- public SecureResourceProviderDecorator(final StatefulResourceProvider rp, final ResourceAccessSecurityTracker tracker) {
- this.rp = rp;
+ public SecureResourceProviderDecorator(final ResourceProvider<Object> provider,
+ final ResolveContext<Object> resolveContext,
+ final ResourceAccessSecurityTracker tracker) {
+ super(provider, resolveContext);
if (tracker == null) {
logger.warn("ResourceAccessSecurityTracker is null. Resource-level security will be disabled.");
}
this.tracker = tracker;
}
- @Override
- public void logout() {
- rp.logout();
- }
-
- @Override
- public void refresh() {
- rp.refresh();
- }
-
- @Override
- public boolean isLive() {
- return rp.isLive();
- }
-
- @Override
- public Resource getParent(Resource child) {
- return rp.getParent(child);
- }
-
- @Override
- public Resource getResource(String path, Resource parent, Map<String, String> parameters, boolean isResolve) {
- return rp.getResource(path, parent, parameters, isResolve);
- }
-
- @Override
- public Iterator<Resource> listChildren(Resource parent) {
- return rp.listChildren(parent);
- }
-
- @Override
- public Collection<String> getAttributeNames() {
- return rp.getAttributeNames();
- }
-
- @Override
- public Object getAttribute(String name) {
- return rp.getAttribute(name);
- }
-
- @Override
- public void revert() {
- rp.revert();
- }
-
- @Override
- public void commit() throws PersistenceException {
- rp.commit();
- }
-
- @Override
- public boolean hasChanges() {
- return rp.hasChanges();
- }
-
- @Override
- public String[] getSupportedLanguages() {
- return rp.getSupportedLanguages();
- }
-
- @Override
- public Iterator<Map<String, Object>> queryResources(String query, String language) {
- return rp.queryResources(query, language);
- }
-
- @Override
- public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- return rp.adaptTo(type);
+ private Resource wrapResource(Resource rsrc) {
+ if ( rsrc != null && tracker != null ) {
+ if (tracker.getProviderResourceAccessSecurity() != null) {
+ rsrc = tracker.getProviderResourceAccessSecurity().getReadableResource(rsrc);
+ }
+ if (rsrc != null && tracker.getApplicationResourceAccessSecurity() != null) {
+ rsrc = tracker.getApplicationResourceAccessSecurity().getReadableResource(rsrc);
+ }
+ }
+ return rsrc;
}
@Override
- public boolean copy(String srcAbsPath, String destAbsPath) throws PersistenceException {
- return rp.copy(srcAbsPath, destAbsPath);
+ public Resource getParent(final Resource child) {
+ return wrapResource(super.getParent(child));
}
@Override
- public boolean move(String srcAbsPath, String destAbsPath) throws PersistenceException {
- return rp.move(srcAbsPath, destAbsPath);
- }
-
- @Override
- public ResourceProvider<Object> getResourceProvider() {
- return rp.getResourceProvider();
+ public Resource getResource(final String path, final Resource parent, final Map<String, String> parameters, final boolean isResolve) {
+ return wrapResource(super.getResource(path, parent, parameters, isResolve));
}
@Override
- public ResolveContext<Object> getContext() throws LoginException {
- return rp.getContext();
+ public Iterator<Resource> listChildren(final Resource parent) {
+ return wrapIterator(super.listChildren(parent));
}
@Override
public Resource create(final ResourceResolver resolver, final String path, Map<String, Object> properties) throws PersistenceException {
if (isAllowed(new SecurityTest() {
- @Override
- public boolean isAllowed(ResourceAccessSecurity security) {
- return security.canCreate(path, resolver);
- }
- })) {
- return rp.create(resolver, path, properties);
+ @Override
+ public boolean isAllowed(ResourceAccessSecurity security) {
+ return security.canCreate(path, resolver);
+ }
+ })) {
+ return super.create(resolver, path, properties);
} else {
return null;
}
@@ -162,22 +97,24 @@ public class SecureResourceProviderDecor
@Override
public void delete(final Resource resource) throws PersistenceException {
if (isAllowed(new SecurityTest() {
- @Override
- public boolean isAllowed(ResourceAccessSecurity security) {
- return security.canDelete(resource);
- }
- })) {
- rp.delete(resource);
+ @Override
+ public boolean isAllowed(ResourceAccessSecurity security) {
+ return security.canDelete(resource);
+ }
+ })) {
+ super.delete(resource);
+ } else {
+ throw new PersistenceException("Unable to delete resource " + resource.getPath());
}
}
@Override
public Iterator<Resource> findResources(String query, String language) {
- return wrapIterator(rp.findResources(query, language));
+ return wrapIterator(super.findResources(query, language));
}
private Iterator<Resource> wrapIterator(Iterator<Resource> iterator) {
- if (tracker == null) {
+ if (tracker == null || iterator == null) {
return iterator;
} else {
return new SecureIterator(iterator);
Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java Fri Feb 5 10:19:24 2016
@@ -51,7 +51,6 @@ import org.apache.sling.resourceresolver
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.stateful.ResourceProviderAuthenticator;
import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
@@ -74,7 +73,6 @@ public class ResourceResolverControlTest
// query definitions
private static final String QUERY_MOCK_FIND_ALL = "FIND ALL";
- private ResourceProviderAuthenticator authenticator;
private ResourceResolverControl crp;
private List<ResourceProviderHandler> handlers;
private ResourceProvider<Object> subProvider;
@@ -140,9 +138,8 @@ public class ResourceResolverControlTest
handlers = Arrays.asList(rootHandler, handler);
ResourceProviderStorage storage = new ResourceProviderStorage(handlers);
- authenticator = new ResourceProviderAuthenticator(rr, authInfo, securityTracker);
- crp = new ResourceResolverControl(false, authInfo, storage, authenticator);
+ crp = new ResourceResolverControl(false, authInfo, storage);
context = new ResourceResolverContext(rr);
}
@@ -178,7 +175,7 @@ public class ResourceResolverControlTest
@Test
public void loginLogout() throws LoginException {
- authenticator.authenticateAll(handlers, crp);
+ context.getResolveContextManager().authenticateAll(handlers, crp);
verify(subProvider).authenticate(authInfo);
@@ -360,7 +357,7 @@ public class ResourceResolverControlTest
@Test
public void queryLanguages() throws PersistenceException {
- assertThat(crp.getSupportedLanguages(), arrayContainingInAnyOrder(QL_NOOP, QL_MOCK, QL_ANOTHER_MOCK));
+ assertThat(crp.getSupportedLanguages(context), arrayContainingInAnyOrder(QL_NOOP, QL_MOCK, QL_ANOTHER_MOCK));
}
/**
@@ -369,7 +366,7 @@ public class ResourceResolverControlTest
@Test
public void queryResources() throws PersistenceException {
- Iterator<Map<String, Object>> queryResources = crp.queryResources(QUERY_MOCK_FIND_ALL, QL_MOCK);
+ Iterator<Map<String, Object>> queryResources = crp.queryResources(context, QUERY_MOCK_FIND_ALL, QL_MOCK);
int count = 0;
@@ -387,7 +384,7 @@ public class ResourceResolverControlTest
@Test
public void findResource() throws PersistenceException {
- Iterator<Resource> resources = crp.findResources(QUERY_MOCK_FIND_ALL, QL_MOCK);
+ Iterator<Resource> resources = crp.findResources(context, QUERY_MOCK_FIND_ALL, QL_MOCK);
int count = 0;
Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java?rev=1728626&r1=1728625&r2=1728626&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java Fri Feb 5 10:19:24 2016
@@ -22,6 +22,7 @@ import static org.hamcrest.MatcherAssert
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -36,7 +37,9 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.security.ResourceAccessSecurity;
import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
import org.apache.sling.resourceresolver.impl.providers.stateful.SecureResourceProviderDecorator;
-import org.apache.sling.resourceresolver.impl.providers.stateful.StatefulResourceProvider;
+import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@ -45,8 +48,9 @@ public class SecureResourceProviderDecor
private ResourceAccessSecurity security;
private ResourceResolver rr;
+ private ResolveContext resolveContext;
private SecureResourceProviderDecorator src;
- private StatefulResourceProvider rp;
+ private ResourceProvider rp;
private Resource first;
private Resource second;
@@ -54,6 +58,8 @@ public class SecureResourceProviderDecor
public void prepare() throws PersistenceException {
rr = mock(ResourceResolver.class);
+ resolveContext = mock(ResolveContext.class);
+ when(resolveContext.getResourceResolver()).thenReturn(rr);
security = mock(ResourceAccessSecurity.class);
first = mock(Resource.class);
@@ -62,9 +68,13 @@ public class SecureResourceProviderDecor
when(security.getReadableResource(first)).thenReturn(first);
when(security.getReadableResource(second)).thenReturn(null);
- rp = mock(StatefulResourceProvider.class);
- when(rp.create(rr, "/some/path", Collections.<String, Object> emptyMap())).thenReturn(mock(Resource.class));
- when(rp.findResources("FIND ALL", "MockQueryLanguage")).thenReturn(Arrays.asList(first, second).iterator());
+ QueryLanguageProvider qlp = mock(QueryLanguageProvider.class);
+
+ rp = mock(ResourceProvider.class);
+ when(rp.getQueryLanguageProvider()).thenReturn(qlp);
+
+ when(rp.create(resolveContext, "/some/path", Collections.<String, Object> emptyMap())).thenReturn(mock(Resource.class));
+ when(qlp.findResources(resolveContext, "FIND ALL", "MockQueryLanguage")).thenReturn(Arrays.asList(first, second).iterator());
ResourceAccessSecurityTracker securityTracker = new ResourceAccessSecurityTracker() {
@Override
@@ -73,7 +83,7 @@ public class SecureResourceProviderDecor
}
};
- src = new SecureResourceProviderDecorator(rp, securityTracker);
+ src = new SecureResourceProviderDecorator(rp, resolveContext, securityTracker);
}
@@ -102,7 +112,7 @@ public class SecureResourceProviderDecor
src.delete(toDelete);
- verify(rp).delete(toDelete);
+ verify(rp).delete(resolveContext, toDelete);
}
@Test
@@ -112,7 +122,12 @@ public class SecureResourceProviderDecor
when(security.canDelete(toDelete)).thenReturn(false);
- src.delete(toDelete);
+ try {
+ src.delete(toDelete);
+ fail();
+ } catch ( PersistenceException pe ) {
+ // correct
+ }
Mockito.verifyZeroInteractions(rp);
}