Package org.gatein.api.navigation

Source Code of org.gatein.api.navigation.ApiFilteredNode$VisibleFilter

/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.gatein.api.navigation;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.WeakHashMap;

import org.exoplatform.portal.mop.navigation.NodeContext;
import org.gatein.api.Portal;
import org.gatein.api.PortalRequest;
import org.gatein.api.common.Filter;
import org.gatein.api.internal.Parameters;
import org.gatein.api.page.Page;
import org.gatein.api.security.Permission;
import org.gatein.api.security.User;

/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ApiFilteredNode extends ApiNode implements FilteredNode {
    private final FilteredNodeMap map;

    @SuppressWarnings("unchecked")
    public ApiFilteredNode(NavigationImpl navigation, NodeContext<ApiNode> context) {
        this(navigation, context, new FilteredNodeMap(Collections.EMPTY_LIST));
    }

    private ApiFilteredNode(NavigationImpl navigation, NodeContext<ApiNode> context, FilteredNodeMap map) {
        super(navigation, context);
        this.map = map;
    }

    @Override
    public Node addChild(int index, String childName) {
        return map.getFiltered(super.addChild(realIndex(index), childName));
    }

    @Override
    public Node addChild(String childName) {
        return map.getFiltered(super.addChild(childName));
    }

    @Override
    public Node getChild(int index) {
        int i = 0;
        for (Iterator<Node> itr = iterator(); itr.hasNext();) {
            if (i == index) {
                return map.getFiltered(itr.next());
            }

            i++;
            itr.next();
        }

        throw new IndexOutOfBoundsException();
    }

    @Override
    public Node getChild(String childName) {
        Node n = super.getChild(childName);
        return map.isAccepted(n) ? map.getFiltered(n) : null;
    }

    @Override
    public int getChildCount() {
        int i = 0;
        for (Iterator<Node> itr = iterator(); itr.hasNext(); itr.next()) {
            i++;
        }
        return i;
    }

    @Override
    public Node getNode(NodePath nodePath) {
        Node n = this;
        for (String e : nodePath) {
            n = n.getChild(e);
            if (n == null) {
                return null;
            }
        }
        return n;
    }

    @Override
    public Node getParent() {
        return super.getParent() != null ? map.getFiltered(super.getParent()) : null;
    }

    @Override
    public boolean hasChild(String childName) {
        Node n = super.getChild(childName);
        return n != null ? map.isAccepted(n) : false;
    }

    @Override
    public int indexOf(String childName) {
        int i = 0;
        for (Iterator<Node> itr = iterator(); itr.hasNext();) {
            if (itr.next().getName().equals(childName)) {
                return i;
            }

            i++;
        }
        return -1;
    }

    @Override
    public Iterator<Node> iterator() {
        return new FilteredNodeIterator();
    }

    @Override
    public void moveTo(int index) {
        super.moveTo(map.getFiltered(super.getParent()).realIndex(index));
    }

    @Override
    public void moveTo(int index, Node parent) {
        super.moveTo(map.getFiltered(parent).realIndex(index), parent);
    }

    @Override
    @SuppressWarnings("unchecked")
    public FilteredNode showAll() {
        return new ApiFilteredNode(navigation, context, new FilteredNodeMap(Collections.EMPTY_LIST));
    }

    @Override
    public FilteredNode showDefault() {
        return showVisible().showHasAccess(PortalRequest.getInstance().getUser());
    }

    @Override
    public FilteredNode showHasAccess(User user) {
        return show(new PermissionFilter(user, PortalRequest.getInstance().getPortal(), true));
    }

    public FilteredNode showHasEdit(User user) {
        return show(new PermissionFilter(user, PortalRequest.getInstance().getPortal(), false));
    }

    @Override
    public FilteredNode showVisible() {
        return show(new VisibleFilter());
    }

    @Override
    public FilteredNode show(Filter<Node> filter) {
        List<Filter<Node>> filters = new LinkedList<Filter<Node>>(map.filters);
        filters.add(Parameters.requireNonNull(filter, "filter"));
        return new ApiFilteredNode(navigation, context, new FilteredNodeMap(filters));
    }

    private int realIndex(int index) {
        int i = 0;
        int j = 0;
        Iterator<Node> itr = super.iterator();

        while (itr.hasNext() && j <= index) {
            if (map.isAccepted(itr.next())) {
                j++;
            }
            i++;
        }

        if (j < index) {
            throw new IndexOutOfBoundsException();
        }

        return j > index ? i - 1 : i;
    }

    private class FilteredNodeIterator implements Iterator<Node> {
        private Iterator<ApiNode> itr = context.iterator();
        private ApiNode last;
        private ApiNode next = findNext();

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

        @Override
        public Node next() {
            if (next == null) {
                throw new NoSuchElementException();
            }

            last = next;
            next = findNext();

            return last;
        }

        @Override
        public void remove() {
            if (last == null) {
                throw new IllegalStateException();
            }

            last.context.remove();
        }

        private ApiNode findNext() {
            while (itr.hasNext()) {
                ApiNode n = itr.next();
                if (map.isAccepted(n)) {
                    return map.getFiltered(n);
                }
            }

            return null;
        }
    }

    private static class FilteredNodeMap {
        private Map<ApiNode, Boolean> acceptedMap = new WeakHashMap<ApiNode, Boolean>();

        private List<Filter<Node>> filters;

        private Map<ApiNode, ApiFilteredNode> filteredMap = new WeakHashMap<ApiNode, ApiFilteredNode>();

        private FilteredNodeMap(List<Filter<Node>> filters) {
            this.filters = filters;
        }

        private ApiFilteredNode getFiltered(Node node) {
            ApiNode apiNode = (ApiNode) node;
            ApiFilteredNode filteredNode = filteredMap.get(apiNode);
            if (filteredNode == null) {
                filteredNode = new ApiFilteredNode(apiNode.navigation, apiNode.context, this);
                filteredMap.put(apiNode, filteredNode);
            }
            return filteredNode;
        }

        private boolean isAccepted(Node node) {
            ApiNode apiNode = (ApiNode) node;
            Boolean accepted = acceptedMap.get(apiNode);
            if (accepted == null) {
                accepted = true;

                for (Filter<Node> f : filters) {
                    accepted = f.accept(node);

                    if (!accepted) {
                        break;
                    }
                }

                acceptedMap.put(apiNode, accepted);
            }
            return accepted;
        }
    }

    private static class VisibleFilter implements Filter<Node> {
        @Override
        public boolean accept(Node element) {
            return element.isVisible();
        }
    }

    private static class PermissionFilter implements Filter<Node> {
        private User user;
        private Portal portal;
        private boolean access;

        public PermissionFilter(User user, Portal portal, boolean access) {
            this.user = user;
            this.portal = portal;
            this.access = access;
        }

        @Override
        public boolean accept(Node element) {
            if (element.getPageId() == null) {
                return true;
            }

            Page page = portal.getPage(element.getPageId());
            Permission permission = access ? page.getAccessPermission() : page.getEditPermission();
            return portal.hasPermission(user, permission);
        }
    }
}
TOP

Related Classes of org.gatein.api.navigation.ApiFilteredNode$VisibleFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.