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

com.day.cq.mailer.commons.AuthorizableGroupMailingList Maven / Gradle / Ivy

/*
 * ADOBE CONFIDENTIAL
 *   ___________________
 *
 *    Copyright 2012 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.day.cq.mailer.commons;

import com.day.cq.mailer.AuthorizableMailingList;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Predicate;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;

import javax.jcr.RepositoryException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;

/**
 * MailingList that takes a {@link org.apache.jackrabbit.api.security.user.Group Group's} members as
 * its members. The List unfolds the transitive dependencies of
 * {@link org.apache.jackrabbit.api.security.user.Group#getMembers()}  Group membership}
 * 
 * @see com.day.cq.mailer.AuthorizableMailingList
 *
 */
public class AuthorizableGroupMailingList implements AuthorizableMailingList {

    private final Group group;
    private Predicate filterPredicate;

    /**
     * @param group Group
     */
    public AuthorizableGroupMailingList(Group group) {
        this(group, null);
    }

    /**
     * Constructor to set an optional filter predicate.
     *
     * @param group
     *            group this list represents
     * @param filterPredicate
     *            an optional filter predicate to filter the group members when
     *            accessing the {@link #members()} method.
     */
    public AuthorizableGroupMailingList(Group group, Predicate filterPredicate) {
        this.group = group;
        this.filterPredicate = filterPredicate;
    }


    /**
     * @return all members of the Group including transitive members
     * @throws javax.jcr.RepositoryException if an error occurs.
     */
    public Iterator members() throws RepositoryException {
        if (filterPredicate == null) {
            return new GroupUnfoldingIterator(group.getDeclaredMembers());
        } else {
            return (Iterator) IteratorUtils.filteredIterator(new GroupUnfoldingIterator(group.getDeclaredMembers()),
                    filterPredicate);
        }
    }

    /**
     * This Iterator iterates includes all
     * {@link org.apache.jackrabbit.api.security.user.Authorizable Authorizables} of the backing
     * Iterator. It "unfolds" any transitive membership. This means, if the
     * backing iterator contains a Group A that has a Group B as member, this
     * iterator will have contain the members of Group B
     */
    private static final class GroupUnfoldingIterator implements Iterator {

        private final Stack> iterators = new Stack>();

        private final HashSet served = new HashSet();
        private Authorizable next;

        GroupUnfoldingIterator(Iterator base) throws RepositoryException {
            iterators.push(base);
            next = seek();
        }

        public boolean hasNext() {
            return next != null;
        }

        public Authorizable next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            Authorizable serve = next;
            try {
                next = seek();
            } catch (RepositoryException e) {
                throw new RuntimeException(e);
            }
            return serve;
        }

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

        private Authorizable seek() throws RepositoryException {
            while (!iterators.isEmpty()) {
                Iterator current = iterators.pop();
                while (current != null && current.hasNext()) {
                    Authorizable test = current.next();
                    if (!served.contains(test.getID())) {
                        served.add(test.getID());
                        if (current.hasNext()) {
                            iterators.push(current);
                        }
                        if (test.isGroup()) {
                            iterators.push(((Group) test).getDeclaredMembers());
                        }
                        return test;
                    }
                }
            }
            return null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy