All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.granite.rest.utils.Resources Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2014 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.granite.rest.utils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

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.ValueMap;

import com.adobe.granite.rest.filter.Filter;

/**
 * {@code Resources} provides helper methods to deal with modifying a
 * {@link org.apache.sling.api.resource.Resource}.
 */
public final class Resources {

    private Resources() {
        
    }

    /**
     * Returns the number of child resources for the specified {@link org.apache.sling.api.resource.Resource}.
     * 
     * @param children Iterator to get size from
     * @param filter A {@link Filter} implementation or {@code null}
     * @return Number of elements in provided {@code children}
     */
    public static int getSize(Iterator children, Filter filter) {
        List filteredChildren = new LinkedList();
        
        for (Iterator it = children; it.hasNext();) {
            Resource child = it.next();
            ValueMap vm = child.adaptTo(ValueMap.class);
            if (vm != null && Boolean.TRUE.equals(vm.get("hidden", Boolean.class))) {
                continue;
            }
            if ((filter == null || filter.matches(child))) {
                filteredChildren.add(child);
            }
        }
        return filteredChildren.size();
    }

    /**
     * Copies the {@code resource} into the {@code destinationParent}. The
     * name of the newly created item is set to {@code name}.
     *
     * @param src The resource to copy to the new location
     * @param dstParent The resource into which the {@code resource} is to be
     *            copied.
     * @param name The name of the newly created item. If this is
     *            {@code null} the new item gets the same name as the
     *            {@code src} item.
     * @param depth Traversal depth of copy. 0 indicates that only the source
     *            and its properties are copied. A value > 0 indicates the depth
     *            of childs to be copied.
     * @return The copied {@link org.apache.sling.api.resource.Resource}
     * @throws PersistenceException May be thrown in case of any problem copying
     *             the content.
     */
    public static Resource copy(Resource src, Resource dstParent, String name, int depth) throws PersistenceException {
        HashSet ignoreProperties = new HashSet();
        ignoreProperties.add("jcr:uuid");
        return copy(src, dstParent, name, depth, ignoreProperties);
    }
    
    /**
     * Copies the {@code resource} into the {@code destinationParent}. The
     * name of the newly created item is set to {@code name}.
     *
     * @param src The resource to copy to the new location
     * @param dstParent The resource into which the {@code resource} is to be
     *            copied.
     * @param name The name of the newly created item. If this is
     *            {@code null} the new item gets the same name as the
     *            {@code src} item.
     * @param depth Traversal depth of copy. 0 indicates that only the source
     *            and its properties are copied. A value > 0 indicates the depth
     *            of childs to be copied.
     * @param ignoreProperties A set of all properties that will be excluded from the copy.
     * @return The copied {@link org.apache.sling.api.resource.Resource}
     * @throws PersistenceException May be thrown in case of any problem copying
     *             the content.
     */
    public static Resource copy(Resource src, Resource dstParent, String name, int depth, Set ignoreProperties) throws PersistenceException {
        
        if(isAncestorOrSameNode(src, dstParent)) {
            throw new PersistenceException("Cannot copy ancestor " + src.getPath() + " to descendant " + dstParent.getPath());
        }
        
        ResourceResolver resolver = src.getResourceResolver();
        
        // ensure destination name
        if (name == null) {
            name = src.getName();
        }
        
        // ensure new node creation
        if (dstParent.getChild(name) != null) {
            Resource child = dstParent.getChild(name);
            resolver.delete(child);
        }
        
        // get properties (except protected)
        Map properties = new HashMap();
        for (Entry entry : src.adaptTo(ValueMap.class).entrySet()) {
            if (ignoreProperties.contains(entry.getKey())) {
                continue;
            }
            properties.put(entry.getKey(), entry.getValue());
        }
        
        // create new node
        Resource dst = resolver.create(dstParent, name, properties);
        
        if (depth == 0) {
            return dst;
        }
        
        // copy the child nodes
        for (Iterator it = src.listChildren(); it.hasNext(); ) {
            Resource child = it.next();
            copy(child, dst, null, --depth, ignoreProperties);
        }
        return dst;
    }

    /**
     * Checks if {@code src} is an ancestor of {@code dest} or the same as
     * {@code dest}.
     * 
     * @param src Source resource
     * @param dest Destination resource
     * @return true if {@code src} is an ancestor resource of {@code dest}, or if both are the same
     *         resource
     */
    private static boolean isAncestorOrSameNode(Resource src, Resource dest) {
        if("/".equals(src.getPath())) {
            return true;
        } else if(src.getPath().equals(dest.getPath())) {
            return true;
        } else if(dest.getPath().startsWith(src.getPath() + "/")) {
            return true;
        }
        return false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy