| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| ******************************************************************************/ |
| package org.apache.sling.api.wrappers; |
| |
| import java.util.Iterator; |
| import java.util.Map; |
| import org.jetbrains.annotations.NotNull; |
| import javax.servlet.http.HttpServletRequest; |
| |
| 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.ResourceWrapper; |
| import org.osgi.annotation.versioning.ConsumerType; |
| |
| /** |
| * The {@code ResourceResolverWrapper} is a wrapper for any {@code ResourceResolver}, delegating all method calls to the wrapped resource |
| * resolver by default. Extensions of this class may overwrite any method to return different values as appropriate. |
| */ |
| @ConsumerType |
| public class ResourceResolverWrapper implements ResourceResolver { |
| |
| private ResourceResolver wrapped; |
| |
| /** |
| * Creates a new wrapper instance, delegating all calls to the given {@code resolver}. |
| * |
| * @param resolver the wrapped resource resolver |
| */ |
| public ResourceResolverWrapper(ResourceResolver resolver) { |
| wrapped = resolver; |
| } |
| |
| /** |
| * Wraps and returns the {@code Resource} obtained by calling {@code resolve} on the wrapped resource resolver. |
| * |
| * @param request The http servlet request object providing more hints at |
| * how to resolve the <code>absPath</code>. This parameter may be |
| * <code>null</code> in which case the implementation should use |
| * reasonable defaults. |
| * @param absPath The absolute path to be resolved to a resource. If this |
| * parameter is <code>null</code>, it is assumed to address the |
| * root of the resource tree. If the path is relative it is |
| * assumed relative to the root, that is a slash is prepended to |
| * the path before resolving it. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public Resource resolve(@NotNull HttpServletRequest request, @NotNull String absPath) { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.resolve(request, absPath)); |
| } |
| |
| /** |
| * Wraps and returns the {@code Resource} obtained by calling {@code resolve} on the wrapped resource resolver. |
| * |
| * @param absPath The absolute path to be resolved to a resource. If this |
| * parameter is <code>null</code>, it is assumed to address the |
| * root of the resource tree. If the path is relative it is |
| * assumed relative to the root, that is a slash is prepended to |
| * the path before resolving it. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public Resource resolve(@NotNull String absPath) { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.resolve(absPath)); |
| } |
| |
| /** |
| * Wraps and returns the {@code Resource} obtained by calling {@code resolve} on the wrapped resource resolver. |
| * |
| * @param request The http servlet request object used to resolve the |
| * resource for. This must not be <code>null</code>. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @SuppressWarnings("deprecation") |
| @NotNull |
| @Override |
| public Resource resolve(@NotNull HttpServletRequest request) { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.resolve(request)); |
| } |
| |
| @NotNull |
| @Override |
| public String map(@NotNull String resourcePath) { |
| return wrapped.map(resourcePath); |
| } |
| |
| @Override |
| public String map(@NotNull HttpServletRequest request, @NotNull String resourcePath) { |
| return wrapped.map(request, resourcePath); |
| } |
| |
| /** |
| * Wraps and returns the {@code Resource} obtained by calling {@code getResource} on the wrapped resource resolver. |
| * |
| * @param path The absolute path to the resource object to be loaded. The |
| * path may contain relative path specifiers like <code>.</code> |
| * (current location) and <code>..</code> (parent location), |
| * which are resolved by this method. If the path is relative, |
| * that is the first character is not a slash, implementations |
| * are expected to apply a search path algorithm to resolve the |
| * relative path to a resource. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @Override |
| public Resource getResource(@NotNull String path) { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.getResource(path)); |
| } |
| |
| /** |
| * Wraps and returns the {@code Resource} obtained by calling {@code getResource} on the wrapped resource resolver. |
| * |
| * @param base The base {@link Resource} against which a relative path |
| * argument given by <code>path</code> is resolved. This |
| * parameter may be <code>null</code> if the <code>path</code> is |
| * known to be absolute. |
| * @param path The path to the resource object to be loaded. If the path is |
| * relative, i.e. does not start with a slash (<code>/</code>), |
| * the resource relative to the given <code>base</code> resource |
| * is returned. The path may contain relative path specifiers |
| * like <code>.</code> (current location) and <code>..</code> |
| * (parent location), which are resolved by this method. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @Override |
| public Resource getResource(Resource base, @NotNull String path) { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.getResource(base, path)); |
| } |
| |
| @NotNull |
| @Override |
| public String[] getSearchPath() { |
| return wrapped.getSearchPath(); |
| } |
| |
| /** |
| * Wraps and returns the {@code Iterator} obtained by calling {@code listChildren} on the wrapped resource resolver. |
| * |
| * @param parent The {@link Resource Resource} whose children are requested. |
| * @return a wrapped iterator obtained through the wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public Iterator<Resource> listChildren(@NotNull Resource parent) { |
| return new ResourceIteratorWrapper(this, wrapped.listChildren(parent)); |
| } |
| |
| /** |
| * Wraps and returns the {@code Resource} obtained by calling {@code getParent} on the wrapped resource resolver. |
| * |
| * @param child The {@link Resource Resource} whose parent is requested. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @Override |
| public Resource getParent(@NotNull Resource child) { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.getParent(child)); |
| } |
| |
| /** |
| * Wraps and returns the {@code Iterable} obtained by calling {@code getChildren} on the wrapped resource resolver. |
| * |
| * @param parent The {@link Resource Resource} whose children are requested. |
| * @return a wrapped iterable obtained through the wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public Iterable<Resource> getChildren(@NotNull final Resource parent) { |
| final ResourceResolverWrapper resourceResolverWrapper = this; |
| return new Iterable<Resource>() { |
| @Override |
| public Iterator<Resource> iterator() { |
| return new ResourceIteratorWrapper(resourceResolverWrapper, wrapped.getChildren(parent).iterator()); |
| } |
| }; |
| } |
| |
| /** |
| * Wraps and returns the {@code Iterator} obtained by calling {@code findResources} on the wrapped resource resolver. |
| * |
| * @param query The query string to use to find the resources. |
| * @param language The language in which the query is formulated. The |
| * language should always be specified. However for |
| * compatibility with older version, if no language |
| * is specified, "xpath" is used. |
| * @return a wrapped iterator obtained through the wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public Iterator<Resource> findResources(@NotNull String query, String language) { |
| return new ResourceIteratorWrapper(this, wrapped.findResources(query, language)); |
| } |
| |
| @NotNull |
| @Override |
| public Iterator<Map<String, Object>> queryResources(@NotNull String query, String language) { |
| return wrapped.queryResources(query, language); |
| } |
| |
| @Override |
| public boolean hasChildren(@NotNull Resource resource) { |
| return wrapped.hasChildren(resource); |
| } |
| |
| /** |
| * Wraps and returns the {@code ResourceResolver} obtained by calling {@code clone} on the wrapped resource resolver. |
| * |
| * @param authenticationInfo The map or credential data to overlay the |
| * original credential data with for the creation of a new |
| * resource resolver. This may be <code>null</code> in which case |
| * the same credential data is used as was used to create this |
| * instance. |
| * @return a wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public ResourceResolver clone(Map<String, Object> authenticationInfo) throws LoginException { |
| ResourceResolver toWrap = wrapped.clone(authenticationInfo); |
| return new ResourceResolverWrapper(toWrap); |
| } |
| |
| @Override |
| public boolean isLive() { |
| return wrapped.isLive(); |
| } |
| |
| @Override |
| public void close() { |
| wrapped.close(); |
| } |
| |
| @Override |
| public String getUserID() { |
| return wrapped.getUserID(); |
| } |
| |
| @NotNull |
| @Override |
| public Iterator<String> getAttributeNames() { |
| return wrapped.getAttributeNames(); |
| } |
| |
| @Override |
| public Object getAttribute(@NotNull String name) { |
| return wrapped.getAttribute(name); |
| } |
| |
| @Override |
| public void delete(@NotNull Resource resource) throws PersistenceException { |
| wrapped.delete(resource); |
| } |
| |
| /** |
| * Wraps the {@code Resource} obtained by calling {@code create} on the wrapped resource resolver. |
| * |
| * @param parent The parent resource |
| * @param name The name of the child resource - this is a plain name, not a path! |
| * @param properties Optional properties for the resource |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @NotNull |
| @Override |
| public Resource create(@NotNull Resource parent, @NotNull String name, Map<String, Object> properties) throws PersistenceException { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.create(parent, name, properties)); |
| } |
| |
| @Override |
| public void revert() { |
| wrapped.revert(); |
| } |
| |
| @Override |
| public void commit() throws PersistenceException { |
| wrapped.commit(); |
| } |
| |
| @Override |
| public boolean hasChanges() { |
| return wrapped.hasChanges(); |
| } |
| |
| @Override |
| public String getParentResourceType(Resource resource) { |
| return wrapped.getParentResourceType(resource); |
| } |
| |
| @Override |
| public String getParentResourceType(String resourceType) { |
| return wrapped.getParentResourceType(resourceType); |
| } |
| |
| @Override |
| public boolean isResourceType(Resource resource, String resourceType) { |
| return wrapped.isResourceType(resource, resourceType); |
| } |
| |
| @Override |
| public void refresh() { |
| wrapped.refresh(); |
| } |
| |
| /** |
| * Wraps the {@code Resource} obtained by calling {@code copy} on the wrapped resource resolver. |
| * |
| * @param srcAbsPath the path of the resource to be copied. |
| * @param destAbsPath the location to which the resource at |
| * <code>srcAbsPath</code> is to be copied. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @Override |
| public Resource copy(String srcAbsPath, String destAbsPath) throws PersistenceException { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.copy(srcAbsPath, destAbsPath)); |
| } |
| |
| /** |
| * Wraps the {@code Resource} obtained by calling {@code move} on the wrapped resource resolver. |
| * |
| * @param srcAbsPath the path of the resource to be moved. |
| * @param destAbsPath the location to which the resource at |
| * <code>srcAbsPath</code> is to be moved. |
| * @return a wrapped resource obtained through the wrapped resource resolver |
| */ |
| @Override |
| public Resource move(String srcAbsPath, String destAbsPath) throws PersistenceException { |
| return ResourceResolverResourceWrapper.wrap(this, wrapped.move(srcAbsPath, destAbsPath)); |
| } |
| |
| @Override |
| public <AdapterType> AdapterType adaptTo(@NotNull Class<AdapterType> type) { |
| return wrapped.adaptTo(type); |
| } |
| |
| /** |
| * {@code ResourceWrapper} that overwrites the {@link #getResourceResolver()} to return the {@link ResourceResolverWrapper}. |
| */ |
| private static class ResourceResolverResourceWrapper extends ResourceWrapper { |
| |
| private final ResourceResolverWrapper resolver; |
| |
| /** |
| * Creates a new wrapper instance delegating all method calls to the given {@code resource}. |
| * |
| * @param resolver the wrapping resource resolver |
| * @param resource the wrapped resource |
| */ |
| ResourceResolverResourceWrapper(ResourceResolverWrapper resolver, Resource resource) { |
| super(resource); |
| this.resolver = resolver; |
| } |
| |
| /** |
| * Returns the wrapping resource resolver from which this resource was obtained. |
| * |
| * @return the wrapping resource resolver |
| */ |
| @Override |
| public ResourceResolver getResourceResolver() { |
| return resolver; |
| } |
| |
| private static Resource wrap(ResourceResolverWrapper resolver, Resource resource) { |
| if (resource != null) { |
| return new ResourceResolverResourceWrapper(resolver, resource); |
| } |
| return null; |
| } |
| } |
| |
| /** |
| * {@code IteratorWrapper} that wraps every returned {@code Resource} with the {@code ResourceResolverResourceWrapper}. |
| * |
| * @see ResourceResolverResourceWrapper |
| */ |
| private static class ResourceIteratorWrapper extends IteratorWrapper<Resource> { |
| |
| private final ResourceResolverWrapper resolver; |
| |
| public ResourceIteratorWrapper(ResourceResolverWrapper resolver, Iterator<Resource> wrappedIterator) { |
| super(wrappedIterator); |
| this.resolver = resolver; |
| } |
| |
| @Override |
| public Resource next() { |
| return ResourceResolverResourceWrapper.wrap(resolver, super.next()); |
| } |
| } |
| } |