/*
 * 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.resource;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import org.apache.sling.api.wrappers.ValueMapDecorator;

/**
 * The <code>ResourceUtil</code> class provides helper methods dealing with
 * resources.
 * <p>
 * This class is not intended to be extended or instantiated because it just
 * provides static utility methods not intended to be overwritten.
 */
public class ResourceUtil {

    /**
     * Resolves relative path segments '.' and '..' in the absolute path.
     * Returns {@code null} if not possible (.. points above root) or if path is not
     * absolute.
     *
     * @param path The path to normalize
     * @return The normalized path or {@code null}.
     */
    public static @CheckForNull String normalize(@Nonnull String path) {

        // don't care for empty paths
        if (path.length() == 0) {
            return path;
        }

        // prepare the path buffer with trailing slash (simplifies impl)
        int absOffset = (path.charAt(0) == '/') ? 0 : 1;
        char[] buf = new char[path.length() + 1 + absOffset];
        if (absOffset == 1) {
            buf[0] = '/';
        }
        path.getChars(0, path.length(), buf, absOffset);
        buf[buf.length - 1] = '/';

        int lastSlash = 0; // last slash in path
        int numDots = 0; // number of consecutive dots after last slash

        int bufPos = 0;
        for (int bufIdx = lastSlash; bufIdx < buf.length; bufIdx++) {
            char c = buf[bufIdx];
            if (c == '/') {
                if (numDots == 2) {
                    if (bufPos == 0) {
                        return null;
                    }

                    do {
                        bufPos--;
                    } while (bufPos > 0 && buf[bufPos] != '/');
                }

                lastSlash = bufIdx;
                numDots = 0;
            } else if (c == '.' && useDot(buf, bufIdx) && numDots < 2) {
                numDots++;
            } else {
                // find the next slash
                int nextSlash = bufIdx + 1;
                while (nextSlash < buf.length && buf[nextSlash] != '/') {
                    nextSlash++;
                }

                // append up to the next slash (or end of path)
                if (bufPos < lastSlash) {
                    int segLen = nextSlash - bufIdx + 1;
                    System.arraycopy(buf, lastSlash, buf, bufPos, segLen);
                    bufPos += segLen;
                } else {
                    bufPos = nextSlash;
                }

                numDots = 0;
                lastSlash = nextSlash;
                bufIdx = nextSlash;
            }
        }

        String resolved;
        if (bufPos == 0 && numDots == 0) {
            resolved = (absOffset == 0) ? "/" : "";
        } else if ((bufPos - absOffset) == path.length()) {
            resolved = path;
        } else {
            resolved = new String(buf, absOffset, bufPos - absOffset);
        }

        return resolved;
    }

    // use this dot only if followed by /
    // don't use if followed by neither . nor /
    // keep checking till a non-dot is found
    private static boolean useDot(char[] buf, int bufIdx) {
        while(bufIdx < buf.length -1) {
            if(buf[bufIdx] == '/') {
                return true;
            }
            else if(buf[bufIdx] != '.') {
                return false;
            }
            bufIdx++;
        }
        return true;
    }
    /**
     * Utility method returns the parent path of the given <code>path</code>,
     * which is normalized by {@link #normalize(String)} before resolving the
     * parent.
     *
     * @param path The path whose parent is to be returned.
     * @return <code>null</code> if <code>path</code> is the root path (
     *         <code>/</code>) or if <code>path</code> is a single name
     *         containing no slash (<code>/</code>) characters.
     * @throws IllegalArgumentException If the path cannot be normalized by the
     *             {@link #normalize(String)} method.
     * @throws NullPointerException If <code>path</code> is <code>null</code>.
     */
    public static @CheckForNull String getParent(@Nonnull String path) {
        if ("/".equals(path)) {
            return null;
        }

        // normalize path (remove . and ..)
        path = normalize(path);

        // if normalized to root, there is no parent
        if (path == null || "/".equals(path)) {
            return null;
        }

        String workspaceName = null;

        final int wsSepPos = path.indexOf(":/");
        if (wsSepPos != -1) {
            workspaceName = path.substring(0, wsSepPos);
            path = path.substring(wsSepPos + 1);
        }

        // find the last slash, after which to cut off
        int lastSlash = path.lastIndexOf('/');
        if (lastSlash < 0) {
            // no slash in the path
            return null;
        } else if (lastSlash == 0) {
            // parent is root
            if (workspaceName != null) {
                return workspaceName + ":/";
            }
            return "/";
        }

        String parentPath = path.substring(0, lastSlash);
        if (workspaceName != null) {
            return workspaceName + ":" + parentPath;
        }
        return parentPath;
    }

    /**
     * Utility method returns the ancestor's path at the given <code>level</code>
     * relative to <code>path</code>, which is normalized by {@link #normalize(String)}
     * before resolving the ancestor.
     *
     * <ul>
     * <li><code>level</code> = 0 returns the <code>path</code>.</li>
     * <li><code>level</code> = 1 returns the parent of <code>path</code>, if it exists, <code>null</code> otherwise.</li>
     * <li><code>level</code> = 2 returns the grandparent of <code>path</code>, if it exists, <code>null</code> otherwise.</li>
     * </ul>
     *
     * @param path The path whose ancestor is to be returned.
     * @param level The relative level of the ancestor, relative to <code>path</code>.
     * @return <code>null</code> if <code>path</code> doesn't have an ancestor at the
     *            specified <code>level</code>.
     * @throws IllegalArgumentException If the path cannot be normalized by the
     *             {@link #normalize(String)} method or if <code>level</code> &lt; 0.
     * @throws NullPointerException If <code>path</code> is <code>null</code>.
     * @since 2.2 (Sling API Bundle 2.2.0)
     */
    public static String getParent(final String path, final int level) {
        if ( level < 0 ) {
            throw new IllegalArgumentException("level must be non-negative");
        }
        String result = path;
        for(int i=0; i<level; i++) {
            result = getParent(result);
            if ( result == null ) {
                break;
            }
        }
        return result;
    }

    /**
     * Utility method returns the parent resource of the resource.
     *
     * @param rsrc The resource to get the parent of.
     * @return The parent resource or null if the rsrc is the root.
     * @throws NullPointerException If <code>rsrc</code> is <code>null</code>.
     * @throws org.apache.sling.api.SlingException If an error occurs trying to
     *             get the resource object from the path.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @deprecated since 2.1.0, use {@link Resource#getParent()} instead
     */
    @Deprecated
    public static @CheckForNull Resource getParent(@Nonnull Resource rsrc) {
        return rsrc.getParent();
    }

    /**
     * Utility method returns the name of the resource.
     *
     * @param rsrc The resource to get the name from.
     * @return The name of the resource
     * @throws NullPointerException If <code>rsrc</code> is <code>null</code>.
     * @deprecated since 2.1.0, use {@link Resource#getName()} instead
     */
    @Deprecated
    public static @Nonnull String getName(@Nonnull Resource rsrc) {
        /*
         * Same as AbstractResource.getName() implementation to prevent problems
         * if there are implementations of the pre-2.1.0 Resource interface in
         * the framework.
         */
        return getName(rsrc.getPath());
    }

    /**
     * Utility method returns the name of the given <code>path</code>, which is
     * normalized by {@link #normalize(String)} before resolving the name.
     *
     * @param path The path whose name (the last path element) is to be
     *            returned.
     * @return The empty string if <code>path</code> is the root path (
     *         <code>/</code>) or if <code>path</code> is a single name
     *         containing no slash (<code>/</code>) characters.
     * @throws IllegalArgumentException If the path cannot be normalized by the
     *             {@link #normalize(String)} method.
     * @throws NullPointerException If <code>path</code> is <code>null</code>.
     */
    public static @Nonnull String getName(@Nonnull String path) {
        if ("/".equals(path)) {
            return "";
        }

        // normalize path (remove . and ..)
        path = normalize(path);
        if ("/".equals(path)) {
            return "";
        }

        // find the last slash
        return path.substring(path.lastIndexOf('/') + 1);
    }

    /**
     * Returns <code>true</code> if the resource <code>res</code> is a synthetic
     * resource.
     * <p>
     * This method checks whether the resource is an instance of the
     * <code>org.apache.sling.resource.SyntheticResource</code> class.
     *
     * @param res The <code>Resource</code> to check whether it is a synthetic
     *            resource.
     * @return <code>true</code> if <code>res</code> is a synthetic resource.
     *         <code>false</code> is returned if <code>res</code> is
     *         <code>null</code> or not an instance of the
     *         <code>org.apache.sling.resource.SyntheticResource</code> class.
     */
    public static boolean isSyntheticResource(@Nonnull Resource res) {
        if (res instanceof SyntheticResource) {
            return true;
        }

        if (!(res instanceof ResourceWrapper)) {
            return false;
        }

        do {
            res = ((ResourceWrapper) res).getResource();
        } while (res instanceof ResourceWrapper);

        return res instanceof SyntheticResource;
    }

    /**
     * Returns <code>true</code> if the resource <code>res</code> is a "star
     * resource". A <i>star resource</i> is a resource returned from the
     * <code>ResourceResolver.resolve(HttpServletRequest)</code> whose path
     * terminates in a <code>/*</code>. Generally such resource result from
     * requests to something like <code>/some/path/*</code> or
     * <code>/some/path/*.html</code> which may be used web applications to
     * uniformly handle resources to be created.
     * <p>
     * This method checks whether the resource path ends with a <code>/*</code>
     * indicating such a star resource.
     *
     * @param res The <code>Resource</code> to check whether it is a star
     *            resource.
     * @return <code>true</code> if <code>res</code> is to be considered a star
     *         resource.
     * @throws NullPointerException if <code>res</code> is <code>null</code>.
     */
    public static boolean isStarResource(@Nonnull Resource res) {
        return res.getPath().endsWith("/*");
    }

    /**
     * Returns <code>true</code> if the resource <code>res</code> is a
     * non-existing resource.
     * <p>
     * This method checks the resource type of the resource to match the
     * well-known resource type <code>sling:nonexisting</code> of the
     * <code>NonExistingResource</code> class defined in the Sling API.
     *
     * @param res The <code>Resource</code> to check whether it is a
     *            non-existing resource.
     * @return <code>true</code> if <code>res</code> is to be considered a
     *         non-existing resource.
     * @throws NullPointerException if <code>res</code> is <code>null</code>.
     */
    public static boolean isNonExistingResource(@Nonnull Resource res) {
        return Resource.RESOURCE_TYPE_NON_EXISTING.equals(res.getResourceType());
    }

    /**
     * Returns an <code>Iterator</code> of {@link Resource} objects loaded from
     * the children of the given <code>Resource</code>.
     * <p>
     * This is a convenience method for
     * {@link ResourceResolver#listChildren(Resource)}.
     *
     * @param parent The {@link Resource Resource} whose children are requested.
     * @return An <code>Iterator</code> of {@link Resource} objects.
     * @throws NullPointerException If <code>parent</code> is <code>null</code>.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @throws org.apache.sling.api.SlingException If any error occurs acquiring
     *             the child resource iterator.
     * @see ResourceResolver#listChildren(Resource)
     * @deprecated since 2.1.0, use {@link Resource#listChildren()} instead
     */
    @Deprecated
    public static @Nonnull Iterator<Resource> listChildren(@Nonnull Resource parent) {
        return parent.listChildren();
    }

    /**
     * Returns an <code>ValueMap</code> object for the given
     * <code>Resource</code>. This method calls {@link Resource#getValueMap()}.
     * If <code>null</code> is provided as the resource an empty map is returned as
     * well.
     * <p>For backward compatibility reasons the map returned is not immutable,
     * but it is not recommend to rely on this behavior.</p>
     *
     * @param res The <code>Resource</code> to adapt to the value map.
     * @return A value map.
     */
    public static @Nonnull ValueMap getValueMap(final Resource res) {
        if ( res == null ) {
            // use empty map
            return new ValueMapDecorator(new HashMap<String, Object>());
        }
        return res.getValueMap();
    }

    /**
     * Helper method, which returns the given resource type as returned from the
     * {@link org.apache.sling.api.resource.Resource#getResourceType()} as a
     * relative path.
     *
     * @param type The resource type to be converted into a path
     * @return The resource type as a path.
     * @since 2.0.6 (Sling API Bundle 2.0.6)
     */
    public static @Nonnull String resourceTypeToPath(@Nonnull final String type) {
        return type.replace(':', '/');
    }

    /**
     * Returns the super type of the given resource type. This method converts
     * the resource type to a resource path by calling
     * {@link #resourceTypeToPath(String)} and uses the
     * <code>resourceResolver</code> to get the corresponding resource. If the
     * resource exists, the {@link Resource#getResourceSuperType()} method is
     * called.
     *
     * @param resourceResolver The <code>ResourceResolver</code> used to access
     *            the resource whose path (relative or absolute) is given by the
     *            <code>resourceType</code> parameter.
     * @param resourceType The resource type whose super type is to be returned.
     *            This type is turned into a path by calling the
     *            {@link #resourceTypeToPath(String)} method before trying to
     *            get the resource through the <code>resourceResolver</code>.
     * @return the super type of the <code>resourceType</code> or
     *         <code>null</code> if the resource type does not exists or returns
     *         <code>null</code> for its super type.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @since 2.0.6 (Sling API Bundle 2.0.6)
     * @deprecated Use {@link ResourceResolver#getParentResourceType(String)}
     */
    @Deprecated
    public static @CheckForNull String getResourceSuperType(
            final @Nonnull ResourceResolver resourceResolver, final String resourceType) {
        return resourceResolver.getParentResourceType(resourceType);
    }

    /**
     * Returns the super type of the given resource. This method checks first if
     * the resource itself knows its super type by calling
     * {@link Resource#getResourceSuperType()}. If that returns
     * <code>null</code> {@link #getResourceSuperType(ResourceResolver, String)}
     * is invoked with the resource type of the resource.
     *
     * @param resource The resource to return the resource super type for.
     * @return the super type of the <code>resource</code> or <code>null</code>
     *         if no super type could be computed.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @since 2.0.6 (Sling API Bundle 2.0.6)
     * @deprecated Use {@link ResourceResolver#getParentResourceType(Resource)}
     */
    @Deprecated
    public static @CheckForNull String findResourceSuperType(@Nonnull final Resource resource) {
        if ( resource == null ) {
            return null;
        }
        return resource.getResourceResolver().getParentResourceType(resource);
    }

    /**
     * Check if the resource is of the given type. This method first checks the
     * resource type of the resource, then its super resource type and continues
     * to go up the resource super type hierarchy.
     *
     * In case the type of the given resource or the given resource type starts with one of the resource resolver's search paths
     * it is converted to a relative resource type by stripping off the resource resolver's search path
     * before doing the comparison.
     *
     * @param resource the resource to check
     * @param resourceType the resource type to check the resource against
     * @return <code>false</code> if <code>resource</code> is <code>null</code>.
     *         Otherwise returns the result of calling
     *         {@link Resource#isResourceType(String)} with the given
     *         <code>resourceType</code>.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @since 2.0.6 (Sling API Bundle 2.0.6)
     * @deprecated Use {@link ResourceResolver#isResourceType(Resource, String)}
     */
    @Deprecated
    public static boolean isA(@Nonnull final Resource resource, final String resourceType) {
        if ( resource == null ) {
            return false;
        }
        return resource.getResourceResolver().isResourceType(resource, resourceType);
    }

    /**
     * Return an iterator for objects of the specified type. A new iterator is
     * returned which tries to adapt the provided resources to the given type
     * (using {@link Resource#adaptTo(Class)}. If a resource in the original
     * iterator is not adaptable to the given class, this object is skipped.
     * This implies that the number of objects returned by the new iterator
     * might be less than the number of resource objects.
     *
     * @param iterator A resource iterator.
     * @param <T> The adapted type
     * @param type The adapted type
     * @return An iterator of the adapted objects
     * @since 2.0.6 (Sling API Bundle 2.0.6)
     */
    public static @Nonnull <T> Iterator<T> adaptTo(final @Nonnull Iterator<Resource> iterator,
            final Class<T> type) {
        return new Iterator<T>() {

            private T nextObject = seek();

            @Override
            public boolean hasNext() {
                return nextObject != null;
            }

            @Override
            public T next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                final T object = nextObject;
                nextObject = seek();
                return object;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }

            private T seek() {
                T result = null;
                while (result == null && iterator.hasNext()) {
                    final Resource r = iterator.next();
                    result = r.adaptTo(type);
                }
                return result;
            }
        };
    }

    /**
     * Creates or gets the resource at the given path.
     *
     * @param resolver The resource resolver to use for creation
     * @param path     The full path to be created
     * @param resourceType The optional resource type of the final resource to create
     * @param intermediateResourceType THe optional resource type of all intermediate resources
     * @param autoCommit If set to true, a commit is performed after each resource creation.
     * @return The resource for the path.
     * @throws org.apache.sling.api.SlingException If an error occurs trying to
     *             get/create the resource object from the path.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @throws PersistenceException If a persistence error occurs.
     * @since 2.3.0  (Sling API Bundle 2.4.0)
     */
    public static @Nonnull Resource getOrCreateResource(
                            final @Nonnull ResourceResolver resolver,
                            final @Nonnull String path,
                            final String resourceType,
                            final String intermediateResourceType,
                            final boolean autoCommit)
    throws PersistenceException {
        final Map<String, Object> props;
        if ( resourceType == null ) {
            props = null;
        } else {
            props = Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)resourceType);
        }
        return getOrCreateResource(resolver, path, props, intermediateResourceType, autoCommit);
    }

    /**
     * Creates or gets the resource at the given path.
     * If an exception occurs, it retries the operation up to five times if autoCommit is enabled.
     * In this case, {@link ResourceResolver#revert()} is called on the resolver before the
     * creation is retried.
     *
     * @param resolver The resource resolver to use for creation
     * @param path     The full path to be created
     * @param resourceProperties The optional resource properties of the final resource to create
     * @param intermediateResourceType THe optional resource type of all intermediate resources
     * @param autoCommit If set to true, a commit is performed after each resource creation.
     * @return The resource for the path.
     * @throws org.apache.sling.api.SlingException If an error occurs trying to
     *             get/create the resource object from the path.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @throws PersistenceException If a persistence error occurs.
     * @since 2.3.0  (Sling API Bundle 2.4.0)
     */
    public static @Nonnull Resource getOrCreateResource(
            final @Nonnull ResourceResolver resolver,
            final @Nonnull String path,
            final Map<String, Object> resourceProperties,
            final String intermediateResourceType,
            final boolean autoCommit)
    throws PersistenceException {
        PersistenceException mostRecentPE = null;
        for(int i=0;i<5;i++) {
            try {
                return ResourceUtil.getOrCreateResourceInternal(resolver,
                        path,
                        resourceProperties,
                        intermediateResourceType,
                        autoCommit);
            } catch ( final PersistenceException pe ) {
                if ( autoCommit ) {
                    // in case of exception, revert to last clean state and retry
                    resolver.revert();
                    resolver.refresh();
                    mostRecentPE = pe;
                } else {
                    throw pe;
                }
            }
        }
        throw mostRecentPE;
    }

    /**
     * Creates or gets the resource at the given path.
     *
     * @param resolver The resource resolver to use for creation
     * @param path     The full path to be created
     * @param resourceProperties The optional resource properties of the final resource to create
     * @param intermediateResourceType THe optional resource type of all intermediate resources
     * @param autoCommit If set to true, a commit is performed after each resource creation.
     * @return The resource for the path.
     * @throws org.apache.sling.api.SlingException If an error occurs trying to
     *             get/create the resource object from the path.
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @throws PersistenceException If a persistence error occurs.
     */
    private static Resource getOrCreateResourceInternal(
            final ResourceResolver resolver,
            final String path,
            final Map<String, Object> resourceProperties,
            final String intermediateResourceType,
            final boolean autoCommit)
    throws PersistenceException {
        Resource rsrc = resolver.getResource(path);
        if ( rsrc == null ) {
            final int lastPos = path.lastIndexOf('/');
            final String name = path.substring(lastPos + 1);

            final Resource parentResource;
            if ( lastPos == 0 ) {
                parentResource = resolver.getResource("/");
            } else {
                final String parentPath = path.substring(0, lastPos);
                parentResource = getOrCreateResource(resolver,
                        parentPath,
                        intermediateResourceType,
                        intermediateResourceType,
                        autoCommit);
            }
            if ( autoCommit ) {
                resolver.refresh();
            }
            try {
                int retry = 5;
                while ( retry > 0 && rsrc == null ) {
                    rsrc = resolver.create(parentResource, name, resourceProperties);
                    // check for SNS
                    if ( !name.equals(rsrc.getName()) ) {
                        resolver.refresh();
                        resolver.delete(rsrc);
                        rsrc = resolver.getResource(parentResource, name);
                    }
                    retry--;
                }
                if ( rsrc == null ) {
                    throw new PersistenceException("Unable to create resource.");
                }
            } catch ( final PersistenceException pe ) {
                // this could be thrown because someone else tried to create this
                // node concurrently
                resolver.refresh();
                rsrc = resolver.getResource(parentResource, name);
                if ( rsrc == null ) {
                    throw pe;
                }
            }
            if ( autoCommit ) {
                try {
                    resolver.commit();
                    resolver.refresh();
                    rsrc = resolver.getResource(parentResource, name);
                } catch ( final PersistenceException pe ) {
                    // try again - maybe someone else did create the resource in the meantime
                    // or we ran into Jackrabbit's stale item exception in a clustered environment
                    resolver.revert();
                    resolver.refresh();
                    rsrc = resolver.getResource(parentResource, name);
                    if ( rsrc == null ) {
                        rsrc = resolver.create(parentResource, name, resourceProperties);
                        resolver.commit();
                    }
                }
            }
        }
        return rsrc;
    }

    /**
     * Create a unique name for a child of the <code>parent</code>.
     * Creates a unique name and test if child already exists.
     * If child resource with the same name exists, iterate until a unique one is found.
     *
     * @param parent The parent resource
     * @param name   The name of the child resource
     * @return a unique non-existing name for child resource for a given <code>parent</code>
     *
     * @throws PersistenceException if it can not find unique name for child resource.
     * @throws NullPointerException if <code>parent</code> is null
     * @throws IllegalStateException if the resource resolver has already been
     *             closed}.
     * @since 2.5 (Sling API Bundle 2.7.0)
     */
    public static String createUniqueChildName(final Resource parent, final String name)
    throws PersistenceException {
        if (parent.getChild(name) != null) {
            // leaf node already exists, create new unique name
            String childNodeName = null;
            int i = 0;
            do {
                childNodeName = name + String.valueOf(i);
                //just so that it does not run into an infinite loop
                // this should not happen though :)
                if (i == Integer.MAX_VALUE) {
                    String message = MessageFormat.format("can not find a unique name {0} for {1}", name, parent.getPath());
                    throw new PersistenceException(message);
                }
                i++;
            } while (parent.getChild(childNodeName) != null);

            return childNodeName;
        }
        return name;
    }

    /**
     * Unwrap the resource and return the wrapped implementation.
     * @param rsrc The resource to unwrap
     * @return The unwrapped resource
     * @since 2.5  (Sling API Bundle 2.7.0)
     */
    public static @Nonnull Resource unwrap(final @Nonnull Resource rsrc) {
        Resource result = rsrc;
        while ( result instanceof ResourceWrapper ) {
            result = ((ResourceWrapper)result).getResource();
        }
        return result;
    }

    /**
     * A batch resource remover deletes resources in batches. Once the batch
     * size (threshold) is reached, an intermediate commit is performed. Resource
     * trees are deleted resource by resource starting with the deepest children first.
     * Once all resources have been passed to the batch resource remover, a final
     * commit needs to be called on the resource resolver.
     * @since 2.6  (Sling API Bundle 2.8.0)
     */
    public static class BatchResourceRemover {

        private final int max;

        private int count;

        public BatchResourceRemover(final int batchSize) {
            this.max = (batchSize < 1 ? 50 : batchSize);
        }

        public void delete(@Nonnull final Resource rsrc)
        throws PersistenceException {
            final ResourceResolver resolver = rsrc.getResourceResolver();
            for(final Resource child : rsrc.getChildren()) {
                delete(child);
            }
            resolver.delete(rsrc);
            count++;
            if ( count >= max ) {
                resolver.commit();
                count = 0;
            }
        }
    }

    /**
     * Create a batch resource remover.
     * A batch resource remove can be used to delete resources in batches.
     * Once the passed in threshold of deleted resources is reached, an intermediate
     * commit is called on the resource resolver. In addition the batch remover
     * deletes a resource recursively.
     * Once all resources to delete are passed to the remover, a final commit needs
     * to be call on the resource resolver.
     * @param threshold The threshold for the intermediate saves.
     * @return A new batch resource remover.
     * Since 2.6
     */
    public static @Nonnull BatchResourceRemover getBatchResourceRemover(final int threshold) {
        return new BatchResourceRemover(threshold);
    }
}
