Package org.jboss.seam.security.permission

Source Code of org.jboss.seam.security.permission.PermissionMetadata

package org.jboss.seam.security.permission;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.seam.security.annotations.permission.Permissions;

/**
* Permission actions can either be persisted as a comma-separated list of values, or as a
* bit-masked numerical value where certain bits represent specific actions for that class. This
* is a helper class that handles the conversion automatically and presents a unified API for
* dealing with these persistent actions.
*
* @author Shane Bryzak
*/
public class PermissionMetadata {
    private Map<Class<?>, Boolean> usesActionMask = new HashMap<Class<?>, Boolean>();
    private Map<Class<?>, Map<String, Long>> classActions = new HashMap<Class<?>, Map<String, Long>>();

    private synchronized void initClassActions(Class<?> cls) {
        if (!classActions.containsKey(cls)) {
            Map<String, Long> actions = new HashMap<String, Long>();

            boolean useMask = false;

            Permissions p = (Permissions) cls.getAnnotation(Permissions.class);
            if (p != null) {
                org.jboss.seam.security.annotations.permission.Permission[] permissions = p.value();
                if (permissions != null) {
                    for (org.jboss.seam.security.annotations.permission.Permission permission : permissions) {
                        actions.put(permission.action(), permission.mask());

                        if (permission.mask() != 0) {
                            useMask = true;
                        }
                    }
                }
            }

            // Validate that all actions have a proper mask
            if (useMask) {
                Set<Long> masks = new HashSet<Long>();

                for (String action : actions.keySet()) {
                    Long mask = actions.get(action);
                    if (masks.contains(mask)) {
                        throw new IllegalArgumentException("Class " + cls.getName() +
                                " defines a duplicate mask for permission action [" + action + "]");
                    }

                    if (mask == 0) {
                        throw new IllegalArgumentException("Class " + cls.getName() +
                                " must define a valid mask value for action [" + action + "]");
                    }

                    if ((mask & (mask - 1)) != 0) {
                        throw new IllegalArgumentException("Class " + cls.getName() +
                                " must define a mask value that is a power of 2 for action [" + action + "]");
                    }

                    masks.add(mask);
                }
            }

            usesActionMask.put(cls, useMask);
            classActions.put(cls, actions);
        }
    }

    protected class ActionSet {
        private Set<String> members = new HashSet<String>();
        private Class<?> targetClass;

        public ActionSet(Class<?> targetClass, String members) {
            this.targetClass = targetClass;
            addMembers(members);
        }

        public void addMembers(String members) {
            if (members == null) return;

            if (usesActionMask.get(targetClass)) {
                // bit mask-based actions
                long vals = Long.valueOf(members);

                Map<String, Long> actions = classActions.get(targetClass);
                for (String action : actions.keySet()) {
                    long mask = actions.get(action).longValue();
                    if ((vals & mask) != 0) {
                        this.members.add(action);
                    }
                }
            } else {
                // comma-separated string based actions
                String[] actions = members.split(",");
                for (String action : actions) {
                    this.members.add(action);
                }
            }
        }

        public boolean contains(String action) {
            return members.contains(action);
        }

        public ActionSet add(String action) {
            members.add(action);
            return this;
        }

        public ActionSet remove(String action) {
            members.remove(action);
            return this;
        }

        public Set<String> members() {
            return members;
        }

        public boolean isEmpty() {
            return members.isEmpty();
        }

        @Override
        public String toString() {
            if (usesActionMask.get(targetClass)) {
                Map<String, Long> actions = classActions.get(targetClass);
                long mask = 0;

                for (String member : members) {
                    mask |= actions.get(member).longValue();
                }

                return "" + mask;
            } else {
                StringBuilder sb = new StringBuilder();
                for (String member : members) {
                    if (sb.length() > 0) sb.append(',');
                    sb.append(member);
                }
                return sb.toString();
            }
        }
    }

    public ActionSet createActionSet(Class<?> targetClass, String members) {
        if (!classActions.containsKey(targetClass)) initClassActions(targetClass);

        return new ActionSet(targetClass, members);
    }

    public List<String> listAllowableActions(Class<?> targetClass) {
        if (!classActions.containsKey(targetClass)) initClassActions(targetClass);

        List<String> actions = new ArrayList<String>();
        for (String action : classActions.get(targetClass).keySet()) {
            actions.add(action);
        }

        return actions;
    }
}
TOP

Related Classes of org.jboss.seam.security.permission.PermissionMetadata

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.