org.opentestsystem.shared.permissions.dao.xml.XmlPermissionsPersister.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.shared.permissions.dao.xml.XmlPermissionsPersister.java

Source

/*******************************************************************************
 * Educational Online Test Delivery System Copyright (c) 2013 American
 * Institutes for Research
 * 
 * Distributed under the AIR Open Source License, Version 1.0 See accompanying
 * file AIR-License-1_0.txt or at
 * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf
 ******************************************************************************/
package org.opentestsystem.shared.permissions.dao.xml;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.opentestsystem.shared.permissions.abstractions.IPermissionsPersister;
import org.opentestsystem.shared.permissions.data.AllowableEntityType;
import org.opentestsystem.shared.permissions.data.Component;
import org.opentestsystem.shared.permissions.data.Permission;
import org.opentestsystem.shared.permissions.data.PermissionMapping;
import org.opentestsystem.shared.permissions.data.Permissions;
import org.opentestsystem.shared.permissions.data.Role;
import org.opentestsystem.shared.permissions.exceptions.PermissionsPersistException;
import org.opentestsystem.shared.permissions.exceptions.PermissionsRetrievalException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;

import AIR.Common.Configuration.ConfigurationManager;

@ComponentScan
public class XmlPermissionsPersister extends IPermissionsPersister {
    private URL _diskFile = null;
    private JAXBContext _jaxbContext = null;
    private static final String LOCK = "_lock";
    private static List<AllowableEntityType> allowableEntities = null;

    @Autowired
    private static ConfigurationManager configurationManager;

    public XmlPermissionsPersister() {

    }

    public XmlPermissionsPersister(URL xmlFilePath) throws JAXBException {
        _diskFile = xmlFilePath;
        _jaxbContext = JAXBContext.newInstance(Permissions.class);
    }

    public static IPermissionsPersister getXmlPermissionsPersisterInstance() throws PermissionsRetrievalException {
        try {
            String permissionsXmlFilePath = configurationManager.getAppSettings().get("permissions.xml.resource");
            URL permissionsXmlFileUrl = new File(permissionsXmlFilePath).toURL();

            IPermissionsPersister persister = new org.opentestsystem.shared.permissions.dao.xml.XmlPermissionsPersister(
                    permissionsXmlFileUrl);
            persister.retrieve();
            return persister;
        } catch (JAXBException exp) {
            throw new PermissionsRetrievalException("Error loading dummy data", exp);
        } catch (MalformedURLException exp) {
            throw new PermissionsRetrievalException("URL is not well formed", exp);
        }
    }

    @Override
    public void persist() throws PermissionsPersistException {
        synchronized (LOCK) {
            try {
                Marshaller jaxbMarshaller = _jaxbContext.createMarshaller();
                jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                final OutputStream os = new FileOutputStream(_diskFile.getFile());
                jaxbMarshaller.marshal(getPermissions(), os);
                os.close();

            } catch (Exception exp) {
                throw new PermissionsPersistException("Error saving permissions", exp);
            }
        }
    }

    @Override
    public List<Permission> getAllPermissions() throws PermissionsRetrievalException {
        List<Permission> permissions = new ArrayList<Permission>();
        for (Component component : this.getPermissions().getComponents()) {
            for (Permission p : component.getPermissions()) {
                if (!permissions.contains(p) && p != null) {
                    permissions.add(p);
                }
            }
        }
        return permissions;
    }

    @Override
    public Collection<Role> getAllRoles() throws PermissionsRetrievalException {
        return getPermissions().getRoles();
    }

    @Override
    public Role getRoleByRoleName(final String name) throws PermissionsRetrievalException {
        return (Role) CollectionUtils.find(getPermissions().getRoles(), new Predicate() {
            @Override
            public boolean evaluate(Object arg) {
                if (StringUtils.equals(name, ((Role) arg).getRole()))
                    return true;
                return false;
            }
        });
    }

    @Override
    public Collection<org.opentestsystem.shared.permissions.data.Component> getAllComponents()
            throws PermissionsRetrievalException {
        return getPermissions().getComponents();
    }

    @Override
    public Component getComponentByComponentName(final String name) throws PermissionsRetrievalException {
        Component cx = (Component) CollectionUtils.find(getPermissions().getComponents(), new Predicate() {
            @Override
            public boolean evaluate(Object arg) {
                if (StringUtils.equals(name, ((Component) arg).getComponent()))
                    return true;
                return false;
            }
        });
        return cx;
    }

    @Override
    public List<Role> getRoleByComponent(final String componentName) throws PermissionsRetrievalException {

        Component component = getComponentByComponentName(componentName);
        List<Role> roles = new ArrayList<Role>();

        // TODO mskhan: should we throw an exception instead if we did not find
        // the
        // componentName?
        if (component == null)
            // return roles;
            throw new PermissionsRetrievalException("Component does not exist.");

        for (PermissionMapping mapping : getPermissions().getPermissionMapping()) {
            /*
             * if (component.containsPermission (mapping.getPermission ())) {
             * Role role = getRoleByRoleName (mapping.getRole ()); if (role !=
             * null) roles.add (role); }
             */
            if (StringUtils.equals(componentName, mapping.getComponent())) {
                Role role = this.getRoleByRoleName(mapping.getRole());
                if (!roles.contains(role))
                    roles.add(role);
            }
        }
        return roles;
    }

    @Override
    public List<Role> getRoleByComponentandPermission(String componentName, String permission)
            throws PermissionsRetrievalException {
        Component component = getComponentByComponentName(componentName);
        List<Role> roles = new ArrayList<Role>();

        if (component == null || !component.containsPermission(permission))
            return roles;

        for (PermissionMapping mapping : getPermissions().getPermissionMapping()) {
            /*
             * String permissionName = mapping.getPermission (); if
             * (permissionName.equals (permission)) { Role role =
             * getRoleByRoleName (mapping.getRole ()); if (role != null)
             * roles.add (role); }
             */
            if (StringUtils.equals(componentName, mapping.getComponent())
                    && StringUtils.equals(permission, mapping.getPermission())) {
                Role role = this.getRoleByRoleName(mapping.getRole());
                if (role != null && !roles.contains(role))
                    roles.add(role);
            }
        }
        return roles;
    }

    @Override
    public List<Component> getComponentByRole(String roleName) throws PermissionsRetrievalException {
        List<Component> components = new ArrayList<Component>();

        for (PermissionMapping mapping : getPermissions().getPermissionMapping()) {
            /*
             * if (mapping.getRole ().equals (roleName)) { for (Component
             * component : getAllComponents ()) { if
             * (component.containsPermission (mapping.getPermission ())) {
             * Component comp = getComponentByComponentName
             * (component.getComponent ()); if (comp != null) components.add
             * (comp); } } }
             */
            if (StringUtils.equals(roleName, mapping.getRole())) {
                Component component = this.getComponentByComponentName(mapping.getComponent());
                if (!components.contains(component))
                    components.add(component);
            }
        }
        return components;
    }

    @Override
    public List<Permission> getPermissionByRoleAndComponent(String roleName, String componentName)
            throws PermissionsRetrievalException {
        Component component = getComponentByComponentName(componentName);
        List<Permission> permissions = new ArrayList<Permission>();
        if (component == null)
            return permissions;

        for (PermissionMapping mapping : getPermissions().getPermissionMapping()) {
            /*
             * final String permission = mapping.getPermission (); if
             * (mapping.getRole ().equals (roleName) &&
             * component.containsPermission (permission)) { Permission p =
             * (Permission) CollectionUtils.find (component.getPermissions (),
             * new Predicate () {
             * 
             * @Override public boolean evaluate (Object arg) { if
             * (((Permission) arg).containsPermission (permission)) return true;
             * return false; } }); if (!permissions.contains (p) && p != null)
             * permissions.add (p); }
             */
            Component comp = this.getComponentByComponentName(mapping.getComponent());
            if (StringUtils.equals(roleName, mapping.getRole())
                    && StringUtils.equals(componentName, comp.getComponent())) {
                Permission permission = this.getPermissionByName(comp.getPermissions(), mapping.getPermission());
                if (!permissions.contains(permission))
                    permissions.add(permission);
            }
        }
        return permissions;
    }

    public List<AllowableEntityType> getAllAllowableEntities() throws PermissionsRetrievalException {
        return allowableEntities;
    }

    public void deleteRole(final String roleId) throws PermissionsPersistException {
        Permissions permissions = getPermissions();
        // step 1: delete the role
        Role role = (Role) CollectionUtils.find(permissions.getRoles(), new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                if (StringUtils.equals(roleId, ((Role) object).getRole()))
                    return true;
                return false;
            }
        });
        List<Role> roles = permissions.getRoles();
        roles.remove(role);
        // step 2: persist this modified permissions object back to disk.
        persist();
    }

    public void deleteComponent(final String componentId) throws PermissionsPersistException {
        Permissions permissions = getPermissions();
        // step 1: delete the component.
        Component component = (Component) CollectionUtils.find(permissions.getComponents(), new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                if (StringUtils.equals(componentId, ((Component) object).getComponent()))
                    return true;
                return false;
            }
        });
        List<Component> components = permissions.getComponents();
        components.remove(component);

        Iterator<PermissionMapping> it = this.getPermissions().getPermissionMapping().iterator();
        for (; it.hasNext();) {
            PermissionMapping mapping = it.next();
            if (StringUtils.equals(componentId, mapping.getComponent()))
                it.remove();
        }
        // step 2: persist this modified permissions object back to disk.
        persist();
    }

    @Override
    public void addPermission(String componentId, final String permissionId)
            throws PermissionsPersistException, PermissionsRetrievalException {
        Component component = getComponentByComponentName(componentId);
        if (component == null)
            throw new PermissionsPersistException("Component does not exist.");
        Permission permission = (Permission) CollectionUtils.find(component.getPermissions(), new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                if (StringUtils.equals(permissionId, ((Permission) object).getName()))
                    return true;
                return false;
            }
        });

        if (permission == null) {
            permission = new Permission();
            permission.setName(permissionId);
            if (component.getPermissions() == null)
                component.setPermissions(new ArrayList<Permission>());
            component.getPermissions().add(permission);
            persist();
        } else
            throw new PermissionsPersistException("Permission already exists.");
    }

    @Override
    public void deletePermission(final String componentId, final String permissionId)
            throws PermissionsPersistException, PermissionsRetrievalException {
        Component component = getComponentByComponentName(componentId);

        Permission permission = (Permission) CollectionUtils.find(component.getPermissions(), new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                if (StringUtils.equals(permissionId, ((Permission) object).getName()))
                    return true;
                return false;
            }
        });
        List<Permission> permissionList = component.getPermissions();
        permissionList.remove(permission);
        // delete from permissionMapping
        List<PermissionMapping> mappings = this.getPermissions().getPermissionMapping();
        Iterator<PermissionMapping> it = mappings.iterator();
        for (; it.hasNext();) {
            PermissionMapping mapping = it.next();
            if (StringUtils.equals(componentId, mapping.getComponent())
                    && StringUtils.equals(permissionId, mapping.getPermission()))
                it.remove();
        }
        // step 2: persist this modified permissions object back to disk.
        persist();
    }

    public void deleteEntity(final String roleId, final String entity)
            throws PermissionsPersistException, PermissionsRetrievalException {
        Role role = getRoleByRoleName(roleId);
        final String entityKey = this.getEntityByDescription(getAllAllowableEntities(), entity).getEntity();
        AllowableEntityType allowableEntity = (AllowableEntityType) CollectionUtils
                .find(role.getAllowableEntities(), new Predicate() {

                    @Override
                    public boolean evaluate(Object object) {
                        if (StringUtils.equals(entityKey.toLowerCase(),
                                ((AllowableEntityType) object).getEntity().toLowerCase()))
                            return true;
                        return false;
                    }

                });

        if (allowableEntity != null)
            role.getAllowableEntities().remove(allowableEntity);

        persist();
    }

    public AllowableEntityType getEntityByDescription(List<AllowableEntityType> entities,
            final String description) {
        AllowableEntityType allowableEntity = (AllowableEntityType) CollectionUtils.find(entities, new Predicate() {

            @Override
            public boolean evaluate(Object object) {
                if (StringUtils.equals(description.toLowerCase(),
                        ((AllowableEntityType) object).getDescription().toLowerCase()))
                    return true;
                return false;
            }
        });
        return allowableEntity;
    }

    @Override
    public void addEntity(String roleId, final String entity)
            throws PermissionsPersistException, PermissionsRetrievalException {
        Role role = getRoleByRoleName(roleId);
        if (role.getAllowableEntities() == null)
            role.setAllowableEntities(new ArrayList<AllowableEntityType>());
        AllowableEntityType allowableEntity = this.getEntityByDescription(getAllAllowableEntities(), entity);
        role.getAllowableEntities().add(allowableEntity);
        persist();
    }

    @Override
    public void addRole(String roleId) throws PermissionsPersistException, PermissionsRetrievalException {
        Role role = this.getRoleByRoleName(roleId);
        if (role == null) {
            role = new Role();
            role.setRole(roleId);
            if (this.getPermissions().getRoles() == null)
                this.getPermissions().setRoles(new ArrayList<Role>());
            this.getPermissions().getRoles().add(role);
            persist();
        } else
            throw new PermissionsPersistException("Role already exists.");
    }

    @Override
    public void editRole(String roleId, String newRole)
            throws PermissionsRetrievalException, PermissionsPersistException {
        if (this.getRoleByRoleName(newRole) == null) {
            this.getRoleByRoleName(roleId).setRole(newRole);
            Iterator<PermissionMapping> it = this.getPermissions().getPermissionMapping().iterator();
            for (; it.hasNext();) {
                PermissionMapping mapping = it.next();
                if (StringUtils.equals(roleId, mapping.getRole()))
                    mapping.setRole(newRole);
            }
            persist();
        } else
            throw new PermissionsPersistException("Role already exists.");
    }

    public Permission getPermissionByName(List<Permission> list, final String permissionName) {
        Permission permission = (Permission) CollectionUtils.find(list, new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                if (StringUtils.equals(permissionName.toLowerCase(), ((Permission) object).getName().toLowerCase()))
                    return true;
                return false;
            }
        });
        return permission;
    }

    @Override
    public void editPermission(String componentId, String permissionId, String newPermission)
            throws PermissionsRetrievalException, PermissionsPersistException {
        Component component = this.getComponentByComponentName(componentId);
        Permission permission = this.getPermissionByName(component.getPermissions(), newPermission);
        if (permission == null) {
            permission = this.getPermissionByName(component.getPermissions(), permissionId);
            permission.setName(newPermission);

            // update mappings with new permission name
            List<PermissionMapping> mappings = this.getPermissions().getPermissionMapping();
            for (PermissionMapping mapping : mappings) {
                if (StringUtils.equals(componentId, mapping.getComponent())
                        && StringUtils.equals(permissionId, mapping.getPermission()))
                    mapping.setPermission(newPermission);
            }

            persist();
        } else
            throw new PermissionsPersistException("Permission already exists.");
    }

    @Override
    public void addComponent(String componentId) throws PermissionsPersistException, PermissionsRetrievalException {

        Component component = this.getComponentByComponentName(componentId);
        if (component == null) {
            component = new Component();
            component.setComponent(componentId);
            if (this.getPermissions().getComponents() == null)
                this.getPermissions().setComponents(new ArrayList<Component>());
            this.getPermissions().getComponents().add(component);
            persist();
        } else
            throw new PermissionsPersistException("Component already exists.");
    }

    @Override
    public void editComponent(String componentId, String newComponent)
            throws PermissionsPersistException, PermissionsRetrievalException {
        if (this.getComponentByComponentName(newComponent) == null) {
            this.getComponentByComponentName(componentId).setComponent(newComponent);
            Iterator<PermissionMapping> it = this.getPermissions().getPermissionMapping().iterator();
            for (; it.hasNext();) {
                PermissionMapping mapping = it.next();
                if (StringUtils.equals(componentId, mapping.getComponent()))
                    mapping.setComponent(newComponent);
            }

            persist();
        } else
            throw new PermissionsPersistException("Component already exists.");
    }

    @Override
    public void addMapping(String componentId, String permissionId, String roleId)
            throws PermissionsPersistException {
        PermissionMapping mapping = new PermissionMapping();
        mapping.setComponent(componentId);
        mapping.setPermission(permissionId);
        mapping.setRole(roleId);
        List<PermissionMapping> mappings = this.getPermissions().getPermissionMapping();
        if (mappings == null) {
            mappings = new ArrayList<PermissionMapping>();
            this.getPermissions().setPermissionMapping(mappings);
        }
        mappings.add(mapping);

        persist();
    }

    @Override
    public void deleteMapping(String componentId, String permissionId, String roleId)
            throws PermissionsPersistException {
        Iterator<PermissionMapping> it = this.getPermissions().getPermissionMapping().iterator();

        for (; it.hasNext();) {
            PermissionMapping mapping = it.next();
            if (StringUtils.equals(componentId, mapping.getComponent())
                    && StringUtils.equals(permissionId, mapping.getPermission())
                    && StringUtils.equals(roleId, mapping.getRole()))
                it.remove();
        }
        persist();
    }

    @Override
    public List<Permission> getPermissionsByComponent(String componentId) throws PermissionsRetrievalException {
        List<Permission> permissions = new ArrayList<Permission>();
        if (StringUtils.equals(componentId, "") || StringUtils.equals(componentId, null))
            return permissions;
        Component component = this.getComponentByComponentName(componentId);
        if (component != null)
            permissions = component.getPermissions();
        return permissions;
    }

    @Override
    public Map<String, Object> getAllComponentsAndRoles() throws PermissionsRetrievalException {
        Map<String, Object> returnValue = new HashMap<String, Object>();
        returnValue.put("roles", getAllRoles());

        List<HashMap<String, Object>> listOfMappings = new ArrayList<HashMap<String, Object>>();
        returnValue.put("mappings", listOfMappings);

        for (Component c : getAllComponents()) {
            for (Permission p : c.getPermissions()) {
                HashMap<String, Object> v = new HashMap<String, Object>();
                listOfMappings.add(v);
                v.put("Component", c.getComponent());
                v.put("Permission", p.getName());

                for (Role r : getAllRoles()) {
                    // TODO Sajib: This is really inefficient especially if we
                    // move to DB.
                    v.put(r.getRole(), r.exists(getRoleByComponentandPermission(c.getComponent(), p.getName())));
                }
            }
        }
        return returnValue;
    }

    @Override
    protected Permissions customRetrieve() throws PermissionsRetrievalException {
        synchronized (LOCK) {
            try {

                Unmarshaller jaxbUnmarshaller = _jaxbContext.createUnmarshaller();
                return (Permissions) jaxbUnmarshaller.unmarshal(_diskFile);

            } catch (Exception exp) {
                throw new PermissionsRetrievalException("Error retrieving permissions.", exp);
            }
        }
    }

    /*public static void main(String[] args) {
       try {
     URL path = ClassLoader
           .getSystemResource("permissions-resource.xml");
     XmlPermissionsPersister persister = new XmlPermissionsPersister(
           path);
        
     Permissions xmlP = persister.retrieve();
     persister.deleteRole(xmlP.getRoles().get(0).getRole());
        
     Role r = persister.getRoleByRoleName("Test Kingpin");
     Component c = persister
           .getComponentByComponentName("TestAuthoring");
     System.err.println(persister.getAllAllowableEntities());
        
       } catch (Exception exp) {
     exp.printStackTrace();
       }
    }*/

    static {
        allowableEntities = new ArrayList<AllowableEntityType>();

        allowableEntities.add(new AllowableEntityType("client", "Client"));
        allowableEntities.add(new AllowableEntityType("GoS", "Group Of States"));
        allowableEntities.add(new AllowableEntityType("state", "State"));
        allowableEntities.add(new AllowableEntityType("God", "Group of Districts"));
        allowableEntities.add(new AllowableEntityType("dist", "District"));
        allowableEntities.add(new AllowableEntityType("GoI", "Group of Institutions"));
        allowableEntities.add(new AllowableEntityType("institutions", "Institutions"));
    }

}