org.apache.sling.resource.collection.impl.ResourceCollectionImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sling.resource.collection.impl.ResourceCollectionImpl.java

Source

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

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.sling.resource.collection.ResourceCollection;

/**
 * Implements <code>ResourceCollection</code>
 *
 */
public class ResourceCollectionImpl implements ResourceCollection {

    private static final Logger log = LoggerFactory.getLogger(ResourceCollectionImpl.class);

    /**
     * Defines the resource type property
     */
    private static final String RESOURCE_TYPE = JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY;

    /**
     * underlying resource
     */
    private final Resource resource;

    /**
     * The resource resolver in use by the resource.
     */
    private final ResourceResolver resolver;

    private final Resource membersResource;

    /**
     * Creates a new collection from the given resource
     * 
     * @param resource the resource
     */
    public ResourceCollectionImpl(Resource resource) {
        this.resource = resource;
        resolver = resource.getResourceResolver();
        membersResource = resource.getChild(ResourceCollectionConstants.MEMBERS_NODE_NAME);
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return resource.getName();
    }

    /**
     * {@inheritDoc}
     */
    public String getPath() {
        return resource.getPath();
    }

    /**
     * {@inheritDoc}
     */
    public boolean add(Resource res, Map<String, Object> properties) throws PersistenceException {
        if (res != null && !contains(res)) {
            ModifiableValueMap vm = membersResource.adaptTo(ModifiableValueMap.class);
            String[] order = vm.get(ResourceCollectionConstants.REFERENCES_PROP, new String[] {});

            order = (String[]) ArrayUtils.add(order, res.getPath());
            vm.put(ResourceCollectionConstants.REFERENCES_PROP, order);

            if (properties == null) {
                properties = new HashMap<String, Object>();
            }
            properties.put(ResourceCollectionConstants.REF_PROPERTY, res.getPath());
            resolver.create(membersResource, ResourceUtil.createUniqueChildName(membersResource, res.getName()),
                    properties);
            log.debug("added member to resource {} to collection {}",
                    new String[] { res.getPath(), resource.getPath() });
            return true;
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public boolean add(Resource res) throws PersistenceException {
        if (res != null && !contains(res)) {
            ModifiableValueMap vm = membersResource.adaptTo(ModifiableValueMap.class);
            String[] order = vm.get(ResourceCollectionConstants.REFERENCES_PROP, new String[] {});

            order = (String[]) ArrayUtils.add(order, res.getPath());
            vm.put(ResourceCollectionConstants.REFERENCES_PROP, order);

            Map<String, Object> properties = new HashMap<String, Object>();
            properties.put(ResourceCollectionConstants.REF_PROPERTY, res.getPath());
            resolver.create(membersResource, ResourceUtil.createUniqueChildName(membersResource, res.getName()),
                    properties);
            log.debug("added member to resource {} to collection {}",
                    new String[] { res.getPath(), resource.getPath() });
            return true;
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public Iterator<Resource> getResources() {

        ValueMap vm = membersResource.adaptTo(ValueMap.class);
        String[] references = vm.get(ResourceCollectionConstants.REFERENCES_PROP, new String[] {});
        List<Resource> resources = new ArrayList<Resource>();

        for (String path : references) {
            Resource resource = resolver.getResource(path);
            if (resource != null) {
                resources.add(resource);
            }
        }

        return resources.iterator();
    }

    /**
     * Returns the sling resource type on content node of collection
     * 
     * @param
     * @return <code>sling:resourceType</code> for the collection resource
     */
    public String getType() {
        return resource.getResourceType();
    }

    /**
     * {@inheritDoc}
     */
    public boolean contains(Resource res) {
        if (res != null) {
            ValueMap vm = membersResource.adaptTo(ValueMap.class);
            String[] order = vm.get(ResourceCollectionConstants.REFERENCES_PROP, new String[] {});

            int index = ArrayUtils.indexOf(order, res.getPath(), 0);

            return index >= 0 ? true : false;
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public boolean remove(Resource res) throws PersistenceException {
        //remove the resource
        Resource tobeRemovedRes = findRes(res);
        if (tobeRemovedRes == null) {
            return false;
        }
        resolver.delete(tobeRemovedRes);
        //remove from order array
        ModifiableValueMap vm = membersResource.adaptTo(ModifiableValueMap.class);
        String[] order = vm.get(ResourceCollectionConstants.REFERENCES_PROP, new String[] {});

        int index = ArrayUtils.indexOf(order, res.getPath(), 0);

        order = (String[]) ArrayUtils.remove(order, index);
        vm.put(ResourceCollectionConstants.REFERENCES_PROP, order);

        return true;
    }

    /**
     * Sets the sling resource type on content node of collection
     * 
     * @param type <code>sling:resourceType</code> to be set on the content node
     * @return
     */
    public void setType(String type) throws PersistenceException {
        ModifiableValueMap mvp = resource.adaptTo(ModifiableValueMap.class);
        mvp.put(RESOURCE_TYPE, type);
    }

    private Resource findRes(Resource res) {
        if (res != null) {
            String resName = res.getName();
            if (membersResource.getChild(resName) != null
                    && (res.getPath()).equals(ResourceUtil.getValueMap(membersResource.getChild(resName))
                            .get(ResourceCollectionConstants.REF_PROPERTY, "")))
                return membersResource.getChild(resName);
            // handle multiple res with same name but different paths
            Iterator<Resource> children = membersResource.listChildren();
            while (children.hasNext()) {
                Resource r = children.next();
                if (ResourceUtil.getValueMap(r).get(ResourceCollectionConstants.REF_PROPERTY, "")
                        .equals(res.getPath()))
                    return r;
            }
        }
        return null;
    }

    public void orderBefore(Resource srcResource, Resource destResource) {
        if (srcResource == null) {
            throw new IllegalArgumentException("Source Resource can not be null");
        }
        ModifiableValueMap vm = membersResource.adaptTo(ModifiableValueMap.class);
        String[] order = vm.get(ResourceCollectionConstants.REFERENCES_PROP, new String[] {});
        String srcPath = srcResource.getPath();
        int srcIndex = ArrayUtils.indexOf(order, srcPath);
        if (srcIndex < 0) {
            log.warn("Collection ordering failed, as there is no resource {} in collection {} for destResource",
                    srcPath, getPath());
            return;
        }
        if (destResource == null) {
            //add it to the end.
            order = (String[]) ArrayUtils.remove(order, srcIndex);
            order = (String[]) ArrayUtils.add(order, srcPath);
        } else {
            String destPath = destResource.getPath();

            if (destPath.equals(srcPath)) {
                String message = MessageFormat.format(
                        "Collection ordering failed, as source {0} and destination {1} can not be same", srcPath,
                        destPath);
                log.error(message);
                throw new IllegalArgumentException(message);
            }

            int destIndex = ArrayUtils.indexOf(order, destPath);

            if (destIndex < 0) {
                log.warn("Collection ordering failed, as there is no resource {} in collection {} for destResource",
                        destPath, getPath());
                return;
            }

            order = (String[]) ArrayUtils.remove(order, srcIndex);
            if (srcIndex < destIndex) { //recalculate dest index
                destIndex = ArrayUtils.indexOf(order, destPath);
            }
            order = (String[]) ArrayUtils.add(order, destIndex, srcPath);
        }

        vm.put(ResourceCollectionConstants.REFERENCES_PROP, order);
    }

    public ModifiableValueMap getProperties(Resource resource) {
        Iterator<Resource> entries = membersResource.listChildren();
        while (entries.hasNext()) {
            Resource entry = entries.next();
            String path = ResourceUtil.getValueMap(entry).get(ResourceCollectionConstants.REF_PROPERTY, "");

            if (resource.getPath().equals(path)) {
                return entry.adaptTo(ModifiableValueMap.class);
            }
        }

        return null;
    }
}