syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [14/27] syncope git commit: [SYNCOPE-119] Renaming Role to Group
Date Mon, 06 Apr 2015 16:14:10 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
index bc74b30..18c0776 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
@@ -20,11 +20,11 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
-import org.apache.syncope.core.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
 import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.Entitlement;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.jpa.entity.JPAEntitlement;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -33,7 +33,7 @@ import org.springframework.stereotype.Repository;
 public class JPAEntitlementDAO extends AbstractDAO<Entitlement, String> implements EntitlementDAO {
 
     @Autowired
-    private RoleDAO roleDAO;
+    private GroupDAO groupDAO;
 
     @Override
     public Entitlement find(final String name) {
@@ -54,12 +54,12 @@ public class JPAEntitlementDAO extends AbstractDAO<Entitlement, String> implemen
     }
 
     @Override
-    public Entitlement saveRoleEntitlement(final Role role) {
-        Entitlement roleEnt = new JPAEntitlement();
-        roleEnt.setKey(RoleEntitlementUtil.getEntitlementNameFromRoleKey(role.getKey()));
-        roleEnt.setDescription("Entitlement for managing role " + role.getKey());
+    public Entitlement saveGroupEntitlement(final Group group) {
+        Entitlement groupEnt = new JPAEntitlement();
+        groupEnt.setKey(GroupEntitlementUtil.getEntitlementNameFromGroupKey(group.getKey()));
+        groupEnt.setDescription("Entitlement for managing group " + group.getKey());
 
-        return save(roleEnt);
+        return save(groupEnt);
     }
 
     @Override
@@ -78,9 +78,9 @@ public class JPAEntitlementDAO extends AbstractDAO<Entitlement, String> implemen
             return;
         }
 
-        for (Role role : roleDAO.findByEntitlement(entitlement)) {
-            role.removeEntitlement(entitlement);
-            roleDAO.save(role);
+        for (Group group : groupDAO.findByEntitlement(entitlement)) {
+            group.removeEntitlement(entitlement);
+            groupDAO.save(group);
         }
 
         entityManager.remove(entitlement);

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 9bc2a25..c79d1e8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
@@ -37,7 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Mapping;
 import org.apache.syncope.core.persistence.api.entity.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
@@ -45,7 +45,7 @@ import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
 import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMappingItem;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -62,7 +62,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
     private UserDAO userDAO;
 
     @Autowired
-    private RoleDAO roleDAO;
+    private GroupDAO groupDAO;
 
     @Autowired
     private PolicyDAO policyDAO;
@@ -173,7 +173,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
         Class<? extends AbstractMappingItem> jpaRef = reference.equals(UMappingItem.class)
                 ? JPAUMappingItem.class
-                : JPARMappingItem.class;
+                : JPAGMappingItem.class;
 
         TypedQuery<T> query = entityManager.createQuery("SELECT m FROM " + jpaRef.getSimpleName()
                 + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", reference);
@@ -218,8 +218,8 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         for (User user : userDAO.findByResource(resource)) {
             user.removeResource(resource);
         }
-        for (Role role : roleDAO.findByResource(resource)) {
-            role.removeResource(resource);
+        for (Group group : groupDAO.findByResource(resource)) {
+            group.removeResource(resource);
         }
         for (AccountPolicy policy : policyDAO.findByResource(resource)) {
             policy.removeResource(resource);
@@ -240,13 +240,13 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             resource.getUmapping().setResource(null);
             resource.setUmapping(null);
         }
-        if (resource.getRmapping() != null) {
-            for (MappingItem item : resource.getRmapping().getItems()) {
+        if (resource.getGmapping() != null) {
+            for (MappingItem item : resource.getGmapping().getItems()) {
                 item.setMapping(null);
             }
-            resource.getRmapping().getItems().clear();
-            resource.getRmapping().setResource(null);
-            resource.setRmapping(null);
+            resource.getGmapping().getItems().clear();
+            resource.getGmapping().setResource(null);
+            resource.setGmapping(null);
         }
 
         entityManager.remove(resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
new file mode 100644
index 0000000..63e9fc6
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -0,0 +1,579 @@
+/*
+ * 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.syncope.core.persistence.jpa.dao;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
+import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
+import org.apache.syncope.core.persistence.api.entity.DerAttr;
+import org.apache.syncope.core.persistence.api.entity.Entitlement;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.Policy;
+import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
+import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
+import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.misc.security.AuthContextUtil;
+import org.apache.syncope.core.misc.security.UnauthorizedGroupException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAttr> implements GroupDAO {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Autowired
+    private VirAttrDAO virAttrDAO;
+
+    @Autowired
+    private EntitlementDAO entitlementDAO;
+
+    @Autowired
+    private AttributableUtilFactory attrUtilFactory;
+
+    @Override
+    protected Subject<GPlainAttr, GDerAttr, GVirAttr> findInternal(final Long key) {
+        return find(key);
+    }
+
+    @Override
+    public Group find(final Long key) {
+        TypedQuery<Group> query = entityManager.createQuery("SELECT e FROM " + JPAGroup.class.getSimpleName() + " e WHERE e.id = :id", Group.class);
+        query.setParameter("id", key);
+
+        Group result = null;
+        try {
+            result = query.getSingleResult();
+        } catch (NoResultException e) {
+            LOG.debug("No group found with id {}", key, e);
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<Group> find(final String name) {
+        TypedQuery<Group> query = entityManager.createQuery("SELECT e FROM " + JPAGroup.class.getSimpleName() + " e WHERE e.name = :name", Group.class);
+        query.setParameter("name", name);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public Group find(final String name, final Long parentId) {
+        TypedQuery<Group> query;
+        if (parentId == null) {
+            query = entityManager.createQuery("SELECT r FROM " + JPAGroup.class.getSimpleName() + " r WHERE "
+                    + "r.name=:name AND r.parent IS NULL", Group.class);
+        } else {
+            query = entityManager.createQuery("SELECT r FROM " + JPAGroup.class.getSimpleName() + " r WHERE "
+                    + "r.name=:name AND r.parent.id=:parentId", Group.class);
+            query.setParameter("parentId", parentId);
+        }
+        query.setParameter("name", name);
+
+        List<Group> result = query.getResultList();
+        return result.isEmpty()
+                ? null
+                : result.get(0);
+    }
+
+    private void findSameOwnerDescendants(final List<Group> result, final Group group) {
+        List<Group> children = findChildren(group);
+        if (children != null) {
+            for (Group child : children) {
+                if ((child.getUserOwner() == null && child.getGroupOwner() == null && child.isInheritOwner())
+                        || (child.getUserOwner() != null && child.getUserOwner().equals(group.getUserOwner()))
+                        || (child.getGroupOwner() != null && child.getGroupOwner().equals(group.getGroupOwner()))) {
+
+                    findDescendants(result, child);
+                }
+            }
+        }
+        result.add(group);
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public List<Group> findOwnedByUser(final Long userKey) {
+        User owner = userDAO.find(userKey);
+        if (owner == null) {
+            return Collections.<Group>emptyList();
+        }
+
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPAGroup.class.getSimpleName()).
+                append(" e WHERE e.userOwner=:owner ");
+        for (Long groupKey : owner.getGroupKeys()) {
+            queryString.append("OR e.groupOwner.id=").append(groupKey).append(' ');
+        }
+
+        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        query.setParameter("owner", owner);
+
+        List<Group> result = new ArrayList<>();
+        for (Group group : query.getResultList()) {
+            findSameOwnerDescendants(result, group);
+        }
+
+        return result;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public List<Group> findOwnedByGroup(final Long groupId) {
+        Group owner = find(groupId);
+        if (owner == null) {
+            return Collections.<Group>emptyList();
+        }
+
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPAGroup.class.getSimpleName()).
+                append(" e WHERE e.groupOwner=:owner ");
+
+        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        query.setParameter("owner", owner);
+
+        List<Group> result = new ArrayList<Group>();
+        for (Group group : query.getResultList()) {
+            findSameOwnerDescendants(result, group);
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<Group> findByEntitlement(final Entitlement entitlement) {
+        TypedQuery<Group> query = entityManager.createQuery("SELECT e FROM " + JPAGroup.class.getSimpleName() + " e "
+                + "WHERE :entitlement MEMBER OF e.entitlements", Group.class);
+        query.setParameter("entitlement", entitlement);
+
+        return query.getResultList();
+    }
+
+    private Map.Entry<String, String> getPolicyFields(final PolicyType type) {
+        String policyField;
+        String inheritPolicyField;
+        if (type == PolicyType.GLOBAL_ACCOUNT || type == PolicyType.ACCOUNT) {
+            policyField = "accountPolicy";
+            inheritPolicyField = "inheritAccountPolicy";
+        } else {
+            policyField = "passwordPolicy";
+            inheritPolicyField = "inheritPasswordPolicy";
+        }
+
+        return new AbstractMap.SimpleEntry<>(policyField, inheritPolicyField);
+    }
+
+    private List<Group> findSamePolicyChildren(final Group group, final PolicyType type) {
+        List<Group> result = new ArrayList<>();
+
+        for (Group child : findChildren(group)) {
+            boolean inherit = type == PolicyType.GLOBAL_ACCOUNT || type == PolicyType.ACCOUNT
+                    ? child.isInheritAccountPolicy()
+                    : child.isInheritPasswordPolicy();
+            if (inherit) {
+                result.add(child);
+                result.addAll(findSamePolicyChildren(child, type));
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<Group> findByPolicy(final Policy policy) {
+        if (policy.getType() == PolicyType.GLOBAL_SYNC || policy.getType() == PolicyType.SYNC) {
+            return Collections.<Group>emptyList();
+        }
+
+        Map.Entry<String, String> policyFields = getPolicyFields(policy.getType());
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAGroup.class.getSimpleName()).append(" e WHERE e.").
+                append(policyFields.getKey()).append(" = :policy AND (e.").
+                append(policyFields.getValue()).append(" IS NULL OR e.").
+                append(policyFields.getValue()).append(" = 0)");
+
+        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        query.setParameter("policy", policy);
+
+        List<Group> result = new ArrayList<>();
+        for (Group group : query.getResultList()) {
+            result.add(group);
+            result.addAll(findSamePolicyChildren(group, policy.getType()));
+        }
+        return result;
+    }
+
+    @Override
+    public List<Group> findWithoutPolicy(final PolicyType type) {
+        if (type == PolicyType.GLOBAL_SYNC || type == PolicyType.SYNC) {
+            return Collections.<Group>emptyList();
+        }
+
+        Map.Entry<String, String> policyFields = getPolicyFields(type);
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAGroup.class.getSimpleName()).append(" e WHERE e.").
+                append(policyFields.getKey()).append(" IS NULL AND (e.").
+                append(policyFields.getValue()).append(" IS NULL OR e.").
+                append(policyFields.getValue()).append(" = 0)");
+
+        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        return query.getResultList();
+    }
+
+    private void findAncestors(final List<Group> result, final Group group) {
+        if (group.getParent() != null && !result.contains(group.getParent())) {
+            result.add(group.getParent());
+            findAncestors(result, group.getParent());
+        }
+    }
+
+    @Override
+    public List<Group> findAncestors(final Group group) {
+        List<Group> result = new ArrayList<>();
+        findAncestors(result, group);
+        return result;
+    }
+
+    @Override
+    public List<Group> findChildren(final Group group) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT g FROM " + JPAGroup.class.getSimpleName() + " g WHERE g.parent=:group", Group.class);
+        query.setParameter("group", group);
+
+        return query.getResultList();
+    }
+
+    private void findDescendants(final List<Group> result, final Group group) {
+        List<Group> children = findChildren(group);
+        if (children != null) {
+            for (Group child : children) {
+                findDescendants(result, child);
+            }
+        }
+        result.add(group);
+    }
+
+    @Override
+    public List<Group> findDescendants(final Group group) {
+        List<Group> result = new ArrayList<>();
+        findDescendants(result, group);
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<Group> findByAttrValue(final String schemaName, final GPlainAttrValue attrValue) {
+        return (List<Group>) findByAttrValue(
+                schemaName, attrValue, attrUtilFactory.getInstance(AttributableType.GROUP));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Group findByAttrUniqueValue(final String schemaName, final GPlainAttrValue attrUniqueValue) {
+        return (Group) findByAttrUniqueValue(schemaName, attrUniqueValue,
+                attrUtilFactory.getInstance(AttributableType.GROUP));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<Group> findByDerAttrValue(final String schemaName, final String value) {
+        return (List<Group>) findByDerAttrValue(
+                schemaName, value, attrUtilFactory.getInstance(AttributableType.GROUP));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<Group> findByResource(final ExternalResource resource) {
+        return (List<Group>) findByResource(resource, attrUtilFactory.getInstance(AttributableType.GROUP));
+    }
+
+    @Override
+    public List<Group> findAll() {
+        return findAll(-1, -1, Collections.<OrderByClause>emptyList());
+    }
+
+    @Override
+    public List<Group> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
+        TypedQuery<Group> query = entityManager.createQuery("SELECT e FROM " + JPAGroup.class.getSimpleName() + " e "
+                + toOrderByStatement(Group.class, "e", orderBy), Group.class);
+
+        query.setFirstResult(itemsPerPage * (page <= 0
+                ? 0
+                : page - 1));
+
+        if (itemsPerPage > 0) {
+            query.setMaxResults(itemsPerPage);
+        }
+
+        return query.getResultList();
+    }
+
+    @Override
+    public List<Membership> findMemberships(final Group group) {
+        TypedQuery<Membership> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e"
+                + " WHERE e.group=:group", Membership.class);
+        query.setParameter("group", group);
+
+        return query.getResultList();
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<Long> unmatched(final Long groupId,
+            final Class<?> attrClass, final Class<? extends AttrTemplate<?>> attrTemplateClass) {
+
+        final Query query = entityManager.createNativeQuery(new StringBuilder().
+                append("SELECT ma.id ").
+                append("FROM ").append(JPAMembership.TABLE).append(" m, ").
+                append(attrClass.getSimpleName()).append(" ma ").
+                append("WHERE m.group_id = ?1 ").
+                append("AND ma.owner_id = m.id ").
+                append("AND ma.template_id NOT IN (").
+                append("SELECT id ").
+                append("FROM ").append(attrTemplateClass.getSimpleName()).append(' ').
+                append("WHERE owner_id = ?1)").toString());
+        query.setParameter(1, groupId);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public final int count() {
+        Query countQuery = entityManager.createNativeQuery("SELECT COUNT(e.id) FROM " + JPAGroup.TABLE + " e");
+
+        return ((Number) countQuery.getSingleResult()).intValue();
+    }
+
+    @Override
+    public Group save(final Group group) {
+        // reset account policy in case of inheritance
+        if (group.isInheritAccountPolicy()) {
+            group.setAccountPolicy(null);
+        }
+
+        // reset password policy in case of inheritance
+        if (group.isInheritPasswordPolicy()) {
+            group.setPasswordPolicy(null);
+        }
+
+        // remove attributes without a valid template
+        List<GPlainAttr> rToBeDeleted = new ArrayList<>();
+        for (PlainAttr attr : group.getPlainAttrs()) {
+            boolean found = false;
+            for (GPlainAttrTemplate template : group.findInheritedTemplates(GPlainAttrTemplate.class)) {
+                if (template.getSchema().equals(attr.getSchema())) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                rToBeDeleted.add((GPlainAttr) attr);
+            }
+        }
+        for (GPlainAttr attr : rToBeDeleted) {
+            LOG.debug("Removing {} from {} because no template is available for it", attr, group);
+            group.removePlainAttr(attr);
+        }
+
+        // remove derived attributes without a valid template
+        List<GDerAttr> rDerToBeDeleted = new ArrayList<GDerAttr>();
+        for (DerAttr attr : group.getDerAttrs()) {
+            boolean found = false;
+            for (GDerAttrTemplate template : group.findInheritedTemplates(GDerAttrTemplate.class)) {
+                if (template.getSchema().equals(attr.getSchema())) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                rDerToBeDeleted.add((GDerAttr) attr);
+            }
+        }
+        for (GDerAttr attr : rDerToBeDeleted) {
+            LOG.debug("Removing {} from {} because no template is available for it", attr, group);
+            group.removeDerAttr(attr);
+        }
+
+        // remove virtual attributes without a valid template
+        List<GVirAttr> rVirToBeDeleted = new ArrayList<GVirAttr>();
+        for (VirAttr attr : group.getVirAttrs()) {
+            boolean found = false;
+            for (GVirAttrTemplate template : group.findInheritedTemplates(GVirAttrTemplate.class)) {
+                if (template.getSchema().equals(attr.getSchema())) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                LOG.debug("Removing {} from {} because no template is available for it", attr, group);
+                rVirToBeDeleted.add((GVirAttr) attr);
+            }
+        }
+        for (GVirAttr attr : rVirToBeDeleted) {
+            group.removeVirAttr(attr);
+        }
+
+        Group merged = entityManager.merge(group);
+
+        // Now the same process for any exising membership of the group being saved
+        if (group.getKey() != null) {
+            for (Long key : unmatched(group.getKey(), MPlainAttr.class, MPlainAttrTemplate.class)) {
+                LOG.debug("Removing MAttr[{}] because no template is available for it in {}", key, group);
+                plainAttrDAO.delete(key, MPlainAttr.class);
+            }
+            for (Long id : unmatched(group.getKey(), MDerAttr.class, MDerAttrTemplate.class)) {
+                LOG.debug("Removing MDerAttr[{}] because no template is available for it in {}", id, group);
+                derAttrDAO.delete(id, MDerAttr.class);
+            }
+            for (Long id : unmatched(group.getKey(), MVirAttr.class, MVirAttrTemplate.class)) {
+                LOG.debug("Removing MVirAttr[{}] because no template is available for it in {}", id, group);
+                virAttrDAO.delete(id, MVirAttr.class);
+            }
+        }
+
+        merged = entityManager.merge(merged);
+        for (VirAttr attr : merged.getVirAttrs()) {
+            attr.getValues().clear();
+            attr.getValues().addAll(group.getVirAttr(attr.getSchema().getKey()).getValues());
+        }
+
+        entitlementDAO.saveGroupEntitlement(merged);
+
+        return merged;
+    }
+
+    @Override
+    public void delete(final Group group) {
+        for (Group groupToBeDeleted : findDescendants(group)) {
+            for (Membership membership : findMemberships(groupToBeDeleted)) {
+                membership.getUser().removeMembership(membership);
+                userDAO.save(membership.getUser());
+
+                entityManager.remove(membership);
+            }
+
+            groupToBeDeleted.getEntitlements().clear();
+
+            groupToBeDeleted.setParent(null);
+            groupToBeDeleted.setUserOwner(null);
+            groupToBeDeleted.setGroupOwner(null);
+            entityManager.remove(groupToBeDeleted);
+
+            entitlementDAO.delete(GroupEntitlementUtil.getEntitlementNameFromGroupKey(groupToBeDeleted.getKey()));
+        }
+    }
+
+    @Override
+    public void delete(final Long key) {
+        Group group = (Group) findInternal(key);
+        if (group == null) {
+            return;
+        }
+
+        delete(group);
+    }
+
+    @Override
+    public Group authFetch(Long key) {
+        if (key == null) {
+            throw new NotFoundException("Null group id");
+        }
+
+        Group group = find(key);
+        if (group == null) {
+            throw new NotFoundException("Group " + key);
+        }
+
+        Set<Long> allowedGroupKeys = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
+        if (!allowedGroupKeys.contains(group.getKey())) {
+            throw new UnauthorizedGroupException(group.getKey());
+        }
+        return group;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public Map<Long, PropagationByResource> findUsersWithIndirectResources(final Long groupKey) {
+        Group group = authFetch(groupKey);
+
+        Map<Long, PropagationByResource> result = new HashMap<>();
+
+        for (Membership membership : findMemberships(group)) {
+            User user = membership.getUser();
+
+            PropagationByResource propByRes = new PropagationByResource();
+            for (ExternalResource resource : group.getResources()) {
+                if (!user.getOwnResources().contains(resource)) {
+                    propByRes.add(ResourceOperation.DELETE, resource.getKey());
+                }
+
+                if (!propByRes.isEmpty()) {
+                    result.put(user.getKey(), propByRes);
+                }
+            }
+        }
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
index 8be8c72..998f680 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
@@ -26,7 +26,7 @@ import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -44,18 +44,19 @@ public class JPAMembershipDAO extends AbstractDAO<Membership, Long> implements M
     }
 
     @Override
-    public Membership find(final User user, final Role role) {
+    public Membership find(final User user, final Group group) {
         Query query = entityManager.createQuery(
-                "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e WHERE e.user = :user AND e.role = :role");
+                "SELECT e FROM " + JPAMembership.class.getSimpleName()
+                + " e WHERE e.user = :user AND e.group = :group");
         query.setParameter("user", user);
-        query.setParameter("role", role);
+        query.setParameter("group", group);
 
         Membership result = null;
 
         try {
             result = (Membership) query.getSingleResult();
         } catch (NoResultException e) {
-            LOG.debug("No membership was found for user {} and role {}", user, role, e);
+            LOG.debug("No membership was found for user {} and group {}", user, group, e);
         }
 
         return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
index 9e2f757..b41066c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
@@ -23,12 +23,12 @@ import org.apache.syncope.core.persistence.api.entity.Attributable;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
 import org.springframework.stereotype.Repository;
 
@@ -40,8 +40,8 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements Pla
 
         return CPlainAttr.class.isAssignableFrom(reference)
                 ? JPACPlainAttr.class
-                : RPlainAttr.class.isAssignableFrom(reference)
-                        ? JPARPlainAttr.class
+                : GPlainAttr.class.isAssignableFrom(reference)
+                        ? JPAGPlainAttr.class
                         : MPlainAttr.class.isAssignableFrom(reference)
                                 ? JPAMPlainAttr.class
                                 : UPlainAttr.class.isAssignableFrom(reference)

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
index 17861d6..4b99051 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -26,8 +26,8 @@ import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
@@ -35,8 +35,8 @@ import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueVa
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
 import org.springframework.stereotype.Repository;
@@ -51,10 +51,10 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
                 ? JPACPlainAttrValue.class
                 : reference.equals(CPlainAttrUniqueValue.class)
                         ? JPACPlainAttrUniqueValue.class
-                        : reference.equals(RPlainAttrValue.class)
-                                ? JPARPlainAttrValue.class
-                                : reference.equals(RPlainAttrUniqueValue.class)
-                                        ? JPARPlainAttrUniqueValue.class
+                        : reference.equals(GPlainAttrValue.class)
+                                ? JPAGPlainAttrValue.class
+                                : reference.equals(GPlainAttrUniqueValue.class)
+                                        ? JPAGPlainAttrUniqueValue.class
                                         : reference.equals(MPlainAttrValue.class)
                                                 ? JPAMPlainAttrValue.class
                                                 : reference.equals(MPlainAttrUniqueValue.class)

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
index 2a354a5..b271868 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -34,15 +34,15 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.role.RMappingItem;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainSchema;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -64,8 +64,8 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
         return CPlainSchema.class.isAssignableFrom(reference)
                 ? JPACPlainSchema.class
-                : RPlainSchema.class.isAssignableFrom(reference)
-                        ? JPARPlainSchema.class
+                : GPlainSchema.class.isAssignableFrom(reference)
+                        ? JPAGPlainSchema.class
                         : MPlainSchema.class.isAssignableFrom(reference)
                                 ? JPAMPlainSchema.class
                                 : UPlainSchema.class.isAssignableFrom(reference)
@@ -90,7 +90,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
         final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPAPlainAttrDAO) attrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.");
-        if (RPlainAttr.class.isAssignableFrom(reference) || MPlainAttr.class.isAssignableFrom(reference)) {
+        if (GPlainAttr.class.isAssignableFrom(reference) || MPlainAttr.class.isAssignableFrom(reference)) {
             queryString.append("template.");
         }
         queryString.append("schema=:schema");
@@ -122,7 +122,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
             attrDAO.delete(attrId, attributableUtil.plainAttrClass());
         }
 
-        if (attributableUtil.getType() == AttributableType.ROLE
+        if (attributableUtil.getType() == AttributableType.GROUP
                 || attributableUtil.getType() == AttributableType.MEMBERSHIP) {
 
             for (Iterator<Number> it = attrTemplateDAO.
@@ -134,7 +134,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
         }
 
         resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), UMappingItem.class);
-        resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), RMappingItem.class);
+        resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), GMappingItem.class);
 
         entityManager.remove(schema);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
deleted file mode 100644
index 3003bb4..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * 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.syncope.core.persistence.jpa.dao;
-
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.persistence.NoResultException;
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.RoleEntitlementUtil;
-import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.role.RDerAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.role.RVirAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARole;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.misc.security.AuthContextUtil;
-import org.apache.syncope.core.misc.security.UnauthorizedRoleException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-
-@Repository
-public class JPARoleDAO extends AbstractSubjectDAO<RPlainAttr, RDerAttr, RVirAttr> implements RoleDAO {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private DerAttrDAO derAttrDAO;
-
-    @Autowired
-    private VirAttrDAO virAttrDAO;
-
-    @Autowired
-    private EntitlementDAO entitlementDAO;
-
-    @Autowired
-    private AttributableUtilFactory attrUtilFactory;
-
-    @Override
-    protected Subject<RPlainAttr, RDerAttr, RVirAttr> findInternal(final Long key) {
-        return find(key);
-    }
-
-    @Override
-    public Role find(final Long key) {
-        TypedQuery<Role> query = entityManager.createQuery(
-                "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.id = :id", Role.class);
-        query.setParameter("id", key);
-
-        Role result = null;
-        try {
-            result = query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No role found with id {}", key, e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Role> find(final String name) {
-        TypedQuery<Role> query = entityManager.createQuery(
-                "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.name = :name", Role.class);
-        query.setParameter("name", name);
-
-        return query.getResultList();
-    }
-
-    @Override
-    public Role find(final String name, final Long parentId) {
-        TypedQuery<Role> query;
-        if (parentId == null) {
-            query = entityManager.createQuery("SELECT r FROM " + JPARole.class.getSimpleName() + " r WHERE "
-                    + "r.name=:name AND r.parent IS NULL", Role.class);
-        } else {
-            query = entityManager.createQuery("SELECT r FROM " + JPARole.class.getSimpleName() + " r WHERE "
-                    + "r.name=:name AND r.parent.id=:parentId", Role.class);
-            query.setParameter("parentId", parentId);
-        }
-        query.setParameter("name", name);
-
-        List<Role> result = query.getResultList();
-        return result.isEmpty()
-                ? null
-                : result.get(0);
-    }
-
-    private void findSameOwnerDescendants(final List<Role> result, final Role role) {
-        List<Role> children = findChildren(role);
-        if (children != null) {
-            for (Role child : children) {
-                if ((child.getUserOwner() == null && child.getRoleOwner() == null && child.isInheritOwner())
-                        || (child.getUserOwner() != null && child.getUserOwner().equals(role.getUserOwner()))
-                        || (child.getRoleOwner() != null && child.getRoleOwner().equals(role.getRoleOwner()))) {
-
-                    findDescendants(result, child);
-                }
-            }
-        }
-        result.add(role);
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<Role> findOwnedByUser(final Long userKey) {
-        User owner = userDAO.find(userKey);
-        if (owner == null) {
-            return Collections.<Role>emptyList();
-        }
-
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPARole.class.getSimpleName()).
-                append(" e WHERE e.userOwner=:owner ");
-        for (Long roleKey : owner.getRoleKeys()) {
-            queryString.append("OR e.roleOwner.id=").append(roleKey).append(' ');
-        }
-
-        TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
-        query.setParameter("owner", owner);
-
-        List<Role> result = new ArrayList<>();
-        for (Role role : query.getResultList()) {
-            findSameOwnerDescendants(result, role);
-        }
-
-        return result;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<Role> findOwnedByRole(final Long roleId) {
-        Role owner = find(roleId);
-        if (owner == null) {
-            return Collections.<Role>emptyList();
-        }
-
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPARole.class.getSimpleName()).
-                append(" e WHERE e.roleOwner=:owner ");
-
-        TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
-        query.setParameter("owner", owner);
-
-        List<Role> result = new ArrayList<Role>();
-        for (Role role : query.getResultList()) {
-            findSameOwnerDescendants(result, role);
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Role> findByEntitlement(final Entitlement entitlement) {
-        TypedQuery<Role> query = entityManager.createQuery(
-                "SELECT e FROM " + JPARole.class.getSimpleName() + " e "
-                + "WHERE :entitlement MEMBER OF e.entitlements", Role.class);
-        query.setParameter("entitlement", entitlement);
-
-        return query.getResultList();
-    }
-
-    private Map.Entry<String, String> getPolicyFields(final PolicyType type) {
-        String policyField;
-        String inheritPolicyField;
-        if (type == PolicyType.GLOBAL_ACCOUNT || type == PolicyType.ACCOUNT) {
-            policyField = "accountPolicy";
-            inheritPolicyField = "inheritAccountPolicy";
-        } else {
-            policyField = "passwordPolicy";
-            inheritPolicyField = "inheritPasswordPolicy";
-        }
-
-        return new AbstractMap.SimpleEntry<>(policyField, inheritPolicyField);
-    }
-
-    private List<Role> findSamePolicyChildren(final Role role, final PolicyType type) {
-        List<Role> result = new ArrayList<Role>();
-
-        for (Role child : findChildren(role)) {
-            boolean inherit = type == PolicyType.GLOBAL_ACCOUNT || type == PolicyType.ACCOUNT
-                    ? child.isInheritAccountPolicy()
-                    : child.isInheritPasswordPolicy();
-            if (inherit) {
-                result.add(child);
-                result.addAll(findSamePolicyChildren(child, type));
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Role> findByPolicy(final Policy policy) {
-        if (policy.getType() == PolicyType.GLOBAL_SYNC || policy.getType() == PolicyType.SYNC) {
-            return Collections.<Role>emptyList();
-        }
-
-        Map.Entry<String, String> policyFields = getPolicyFields(policy.getType());
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
-                append(JPARole.class.getSimpleName()).append(" e WHERE e.").
-                append(policyFields.getKey()).append(" = :policy AND (e.").
-                append(policyFields.getValue()).append(" IS NULL OR e.").
-                append(policyFields.getValue()).append(" = 0)");
-
-        TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
-        query.setParameter("policy", policy);
-
-        List<Role> result = new ArrayList<Role>();
-        for (Role role : query.getResultList()) {
-            result.add(role);
-            result.addAll(findSamePolicyChildren(role, policy.getType()));
-        }
-        return result;
-    }
-
-    @Override
-    public List<Role> findWithoutPolicy(final PolicyType type) {
-        if (type == PolicyType.GLOBAL_SYNC || type == PolicyType.SYNC) {
-            return Collections.<Role>emptyList();
-        }
-
-        Map.Entry<String, String> policyFields = getPolicyFields(type);
-        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
-                append(JPARole.class.getSimpleName()).append(" e WHERE e.").
-                append(policyFields.getKey()).append(" IS NULL AND (e.").
-                append(policyFields.getValue()).append(" IS NULL OR e.").
-                append(policyFields.getValue()).append(" = 0)");
-
-        TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
-        return query.getResultList();
-    }
-
-    private void findAncestors(final List<Role> result, final Role role) {
-        if (role.getParent() != null && !result.contains(role.getParent())) {
-            result.add(role.getParent());
-            findAncestors(result, role.getParent());
-        }
-    }
-
-    @Override
-    public List<Role> findAncestors(final Role role) {
-        List<Role> result = new ArrayList<>();
-        findAncestors(result, role);
-        return result;
-    }
-
-    @Override
-    public List<Role> findChildren(final Role role) {
-        TypedQuery<Role> query = entityManager.createQuery(
-                "SELECT r FROM " + JPARole.class.getSimpleName() + " r WHERE r.parent=:role", Role.class);
-        query.setParameter("role", role);
-
-        return query.getResultList();
-    }
-
-    private void findDescendants(final List<Role> result, final Role role) {
-        List<Role> children = findChildren(role);
-        if (children != null) {
-            for (Role child : children) {
-                findDescendants(result, child);
-            }
-        }
-        result.add(role);
-    }
-
-    @Override
-    public List<Role> findDescendants(final Role role) {
-        List<Role> result = new ArrayList<>();
-        findDescendants(result, role);
-        return result;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<Role> findByAttrValue(final String schemaName, final RPlainAttrValue attrValue) {
-        return (List<Role>) findByAttrValue(
-                schemaName, attrValue, attrUtilFactory.getInstance(AttributableType.ROLE));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Role findByAttrUniqueValue(final String schemaName, final RPlainAttrValue attrUniqueValue) {
-        return (Role) findByAttrUniqueValue(schemaName, attrUniqueValue,
-                attrUtilFactory.getInstance(AttributableType.ROLE));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<Role> findByDerAttrValue(final String schemaName, final String value) {
-        return (List<Role>) findByDerAttrValue(
-                schemaName, value, attrUtilFactory.getInstance(AttributableType.ROLE));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<Role> findByResource(final ExternalResource resource) {
-        return (List<Role>) findByResource(resource, attrUtilFactory.getInstance(AttributableType.ROLE));
-    }
-
-    @Override
-    public List<Role> findAll() {
-        return findAll(-1, -1, Collections.<OrderByClause>emptyList());
-    }
-
-    @Override
-    public List<Role> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
-        TypedQuery<Role> query = entityManager.createQuery(
-                "SELECT e FROM " + JPARole.class.getSimpleName() + " e "
-                + toOrderByStatement(Role.class, "e", orderBy), Role.class);
-
-        query.setFirstResult(itemsPerPage * (page <= 0
-                ? 0
-                : page - 1));
-
-        if (itemsPerPage > 0) {
-            query.setMaxResults(itemsPerPage);
-        }
-
-        return query.getResultList();
-    }
-
-    @Override
-    public List<Membership> findMemberships(final Role role) {
-        TypedQuery<Membership> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e"
-                + " WHERE e.role=:role", Membership.class);
-        query.setParameter("role", role);
-
-        return query.getResultList();
-    }
-
-    @SuppressWarnings("unchecked")
-    private List<Long> unmatched(final Long roleId,
-            final Class<?> attrClass, final Class<? extends AttrTemplate<?>> attrTemplateClass) {
-
-        final Query query = entityManager.createNativeQuery(new StringBuilder().
-                append("SELECT ma.id ").
-                append("FROM ").append(JPAMembership.TABLE).append(" m, ").
-                append(attrClass.getSimpleName()).append(" ma ").
-                append("WHERE m.role_id = ?1 ").
-                append("AND ma.owner_id = m.id ").
-                append("AND ma.template_id NOT IN (").
-                append("SELECT id ").
-                append("FROM ").append(attrTemplateClass.getSimpleName()).append(' ').
-                append("WHERE owner_id = ?1)").toString());
-        query.setParameter(1, roleId);
-
-        return query.getResultList();
-    }
-
-    @Override
-    public final int count() {
-        Query countQuery = entityManager.createNativeQuery(
-                "SELECT COUNT(e.id) FROM " + JPARole.TABLE + " e");
-
-        return ((Number) countQuery.getSingleResult()).intValue();
-    }
-
-    @Override
-    public Role save(final Role role) {
-        // reset account policy in case of inheritance
-        if (role.isInheritAccountPolicy()) {
-            role.setAccountPolicy(null);
-        }
-
-        // reset password policy in case of inheritance
-        if (role.isInheritPasswordPolicy()) {
-            role.setPasswordPolicy(null);
-        }
-
-        // remove attributes without a valid template
-        List<RPlainAttr> rToBeDeleted = new ArrayList<>();
-        for (PlainAttr attr : role.getPlainAttrs()) {
-            boolean found = false;
-            for (RPlainAttrTemplate template : role.findInheritedTemplates(RPlainAttrTemplate.class)) {
-                if (template.getSchema().equals(attr.getSchema())) {
-                    found = true;
-                }
-            }
-            if (!found) {
-                rToBeDeleted.add((RPlainAttr) attr);
-            }
-        }
-        for (RPlainAttr attr : rToBeDeleted) {
-            LOG.debug("Removing {} from {} because no template is available for it", attr, role);
-            role.removePlainAttr(attr);
-        }
-
-        // remove derived attributes without a valid template
-        List<RDerAttr> rDerToBeDeleted = new ArrayList<RDerAttr>();
-        for (DerAttr attr : role.getDerAttrs()) {
-            boolean found = false;
-            for (RDerAttrTemplate template : role.findInheritedTemplates(RDerAttrTemplate.class)) {
-                if (template.getSchema().equals(attr.getSchema())) {
-                    found = true;
-                }
-            }
-            if (!found) {
-                rDerToBeDeleted.add((RDerAttr) attr);
-            }
-        }
-        for (RDerAttr attr : rDerToBeDeleted) {
-            LOG.debug("Removing {} from {} because no template is available for it", attr, role);
-            role.removeDerAttr(attr);
-        }
-
-        // remove virtual attributes without a valid template
-        List<RVirAttr> rVirToBeDeleted = new ArrayList<RVirAttr>();
-        for (VirAttr attr : role.getVirAttrs()) {
-            boolean found = false;
-            for (RVirAttrTemplate template : role.findInheritedTemplates(RVirAttrTemplate.class)) {
-                if (template.getSchema().equals(attr.getSchema())) {
-                    found = true;
-                }
-            }
-            if (!found) {
-                LOG.debug("Removing {} from {} because no template is available for it", attr, role);
-                rVirToBeDeleted.add((RVirAttr) attr);
-            }
-        }
-        for (RVirAttr attr : rVirToBeDeleted) {
-            role.removeVirAttr(attr);
-        }
-
-        Role merged = entityManager.merge(role);
-
-        // Now the same process for any exising membership of the role being saved
-        if (role.getKey() != null) {
-            for (Long key : unmatched(role.getKey(), MPlainAttr.class, MPlainAttrTemplate.class)) {
-                LOG.debug("Removing MAttr[{}] because no template is available for it in {}", key, role);
-                plainAttrDAO.delete(key, MPlainAttr.class);
-            }
-            for (Long id : unmatched(role.getKey(), MDerAttr.class, MDerAttrTemplate.class)) {
-                LOG.debug("Removing MDerAttr[{}] because no template is available for it in {}", id, role);
-                derAttrDAO.delete(id, MDerAttr.class);
-            }
-            for (Long id : unmatched(role.getKey(), MVirAttr.class, MVirAttrTemplate.class)) {
-                LOG.debug("Removing MVirAttr[{}] because no template is available for it in {}", id, role);
-                virAttrDAO.delete(id, MVirAttr.class);
-            }
-        }
-
-        merged = entityManager.merge(merged);
-        for (VirAttr attr : merged.getVirAttrs()) {
-            attr.getValues().clear();
-            attr.getValues().addAll(role.getVirAttr(attr.getSchema().getKey()).getValues());
-        }
-
-        entitlementDAO.saveRoleEntitlement(merged);
-
-        return merged;
-    }
-
-    @Override
-    public void delete(final Role role) {
-        for (Role roleToBeDeleted : findDescendants(role)) {
-            for (Membership membership : findMemberships(roleToBeDeleted)) {
-                membership.getUser().removeMembership(membership);
-                userDAO.save(membership.getUser());
-
-                entityManager.remove(membership);
-            }
-
-            roleToBeDeleted.getEntitlements().clear();
-
-            roleToBeDeleted.setParent(null);
-            roleToBeDeleted.setUserOwner(null);
-            roleToBeDeleted.setRoleOwner(null);
-            entityManager.remove(roleToBeDeleted);
-
-            entitlementDAO.delete(RoleEntitlementUtil.getEntitlementNameFromRoleKey(roleToBeDeleted.getKey()));
-        }
-    }
-
-    @Override
-    public void delete(final Long key) {
-        Role role = (Role) findInternal(key);
-        if (role == null) {
-            return;
-        }
-
-        delete(role);
-    }
-
-    @Override
-    public Role authFetch(Long key) {
-        if (key == null) {
-            throw new NotFoundException("Null role id");
-        }
-
-        Role role = find(key);
-        if (role == null) {
-            throw new NotFoundException("Role " + key);
-        }
-
-        Set<Long> allowedRoleKeys = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
-        if (!allowedRoleKeys.contains(role.getKey())) {
-            throw new UnauthorizedRoleException(role.getKey());
-        }
-        return role;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public Map<Long, PropagationByResource> findUsersWithIndirectResources(final Long roleKey) {
-        Role role = authFetch(roleKey);
-
-        Map<Long, PropagationByResource> result = new HashMap<>();
-
-        for (Membership membership : findMemberships(role)) {
-            User user = membership.getUser();
-
-            PropagationByResource propByRes = new PropagationByResource();
-            for (ExternalResource resource : role.getResources()) {
-                if (!user.getOwnResources().contains(resource)) {
-                    propByRes.add(ResourceOperation.DELETE, resource.getKey());
-                }
-
-                if (!propByRes.isEmpty()) {
-                    result.put(user.getKey(), propByRes);
-                }
-            }
-        }
-
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
index 0fec6de..3e30b7c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
@@ -37,7 +37,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
@@ -65,7 +65,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
     private UserDAO userDAO;
 
     @Autowired
-    private RoleDAO roleDAO;
+    private GroupDAO groupDAO;
 
     @Autowired
     private PlainSchemaDAO schemaDAO;
@@ -73,50 +73,50 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
     @Autowired
     private AttributableUtilFactory attrUtilFactory;
 
-    private String getAdminRolesFilter(final Set<Long> adminRoles, final SubjectType type) {
-        final StringBuilder adminRolesFilter = new StringBuilder();
+    private String getAdminGroupsFilter(final Set<Long> adminGroups, final SubjectType type) {
+        final StringBuilder adminGroupFilter = new StringBuilder();
 
         if (type == SubjectType.USER) {
-            adminRolesFilter.append("SELECT user_id AS subject_id FROM Membership M1 WHERE role_id IN (").
-                    append("SELECT role_id FROM Membership M2 WHERE M2.user_id=M1.user_id ").
-                    append("AND role_id NOT IN (");
+            adminGroupFilter.append("SELECT user_id AS subject_id FROM Membership M1 WHERE group_id IN (").
+                    append("SELECT group_id FROM Membership M2 WHERE M2.user_id=M1.user_id ").
+                    append("AND group_id NOT IN (");
         }
 
-        adminRolesFilter.append("SELECT id AS ").
-                append(type == SubjectType.USER ? "role" : "subject").
-                append("_id FROM SyncopeRole");
+        adminGroupFilter.append("SELECT id AS ").
+                append(type == SubjectType.USER ? "group" : "subject").
+                append("_id FROM SyncopeGroup");
 
-        boolean firstRole = true;
+        boolean firstGroup = true;
 
-        for (Long adminRoleId : adminRoles) {
-            if (firstRole) {
-                adminRolesFilter.append(" WHERE");
-                firstRole = false;
+        for (Long adminGroupId : adminGroups) {
+            if (firstGroup) {
+                adminGroupFilter.append(" WHERE");
+                firstGroup = false;
             } else {
-                adminRolesFilter.append(type == SubjectType.USER ? " OR" : " AND");
+                adminGroupFilter.append(type == SubjectType.USER ? " OR" : " AND");
             }
-            adminRolesFilter.append(type == SubjectType.USER ? " id = " : " id <> ").append(adminRoleId);
+            adminGroupFilter.append(type == SubjectType.USER ? " id = " : " id <> ").append(adminGroupId);
         }
 
         if (type == SubjectType.USER) {
-            adminRolesFilter.append("))");
+            adminGroupFilter.append("))");
         }
 
-        return adminRolesFilter.toString();
+        return adminGroupFilter.toString();
     }
 
     @Override
-    public int count(final Set<Long> adminRoles, final SearchCond searchCondition, final SubjectType type) {
+    public int count(final Set<Long> adminGroups, final SearchCond searchCondition, final SubjectType type) {
         List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
 
         // 1. get the query string from the search condition
         SearchSupport svs = new SearchSupport(type);
         StringBuilder queryString = getQuery(searchCondition, parameters, type, svs);
 
-        // 2. take into account administrative roles
+        // 2. take into account administrative groups
         queryString.insert(0, "SELECT u.subject_id FROM (");
         queryString.append(") u WHERE subject_id NOT IN (");
-        queryString.append(getAdminRolesFilter(adminRoles, type)).append(')');
+        queryString.append(getAdminGroupsFilter(adminGroups, type)).append(')');
 
         // 3. prepare the COUNT query
         queryString.insert(0, "SELECT COUNT(subject_id) FROM (");
@@ -135,32 +135,32 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
     @Override
     public <T extends Subject<?, ?, ?>> List<T> search(
-            final Set<Long> adminRoles, final SearchCond searchCondition, final SubjectType type) {
+            final Set<Long> adminGroups, final SearchCond searchCondition, final SubjectType type) {
 
-        return search(adminRoles, searchCondition, Collections.<OrderByClause>emptyList(), type);
+        return search(adminGroups, searchCondition, Collections.<OrderByClause>emptyList(), type);
     }
 
     @Override
     public <T extends Subject<?, ?, ?>> List<T> search(
-            final Set<Long> adminRoles, final SearchCond searchCondition, final List<OrderByClause> orderBy,
+            final Set<Long> adminGroups, final SearchCond searchCondition, final List<OrderByClause> orderBy,
             final SubjectType type) {
 
-        return search(adminRoles, searchCondition, -1, -1, orderBy, type);
+        return search(adminGroups, searchCondition, -1, -1, orderBy, type);
     }
 
     @Override
     public <T extends Subject<?, ?, ?>> List<T> search(
-            final Set<Long> adminRoles, final SearchCond searchCondition, final int page, final int itemsPerPage,
+            final Set<Long> adminGroups, final SearchCond searchCondition, final int page, final int itemsPerPage,
             final List<OrderByClause> orderBy, final SubjectType type) {
 
         List<T> result = Collections.<T>emptyList();
 
-        if (adminRoles != null && (!adminRoles.isEmpty() || roleDAO.findAll().isEmpty())) {
+        if (adminGroups != null && (!adminGroups.isEmpty() || groupDAO.findAll().isEmpty())) {
             LOG.debug("Search condition:\n{}", searchCondition);
 
             if (searchCondition != null && searchCondition.isValid()) {
                 try {
-                    result = doSearch(adminRoles, searchCondition, page, itemsPerPage, orderBy, type);
+                    result = doSearch(adminGroups, searchCondition, page, itemsPerPage, orderBy, type);
                 } catch (Exception e) {
                     LOG.error("While searching for {}", type, e);
                 }
@@ -184,7 +184,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
         boolean matches;
         if (queryString.length() == 0) {
-            // Could be empty: got into a role search with a single membership condition ...
+            // Could be empty: got into a group search with a single membership condition ...
             matches = false;
         } else {
             // 2. take into account the passed user
@@ -331,7 +331,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
     }
 
     @SuppressWarnings("unchecked")
-    private <T extends Subject<?, ?, ?>> List<T> doSearch(final Set<Long> adminRoles,
+    private <T extends Subject<?, ?, ?>> List<T> doSearch(final Set<Long> adminGroups,
             final SearchCond nodeCond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy,
             final SubjectType type) {
 
@@ -341,7 +341,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
         SearchSupport svs = new SearchSupport(type);
         StringBuilder queryString = getQuery(nodeCond, parameters, type, svs);
 
-        // 2. take into account administrative roles and ordering
+        // 2. take into account administrative groups and ordering
         OrderBySupport orderBySupport = parseOrderBy(type, svs, orderBy);
         if (queryString.charAt(0) == '(') {
             queryString.insert(0, buildSelect(orderBySupport));
@@ -351,7 +351,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
             queryString.append(')').append(buildWhere(orderBySupport, type));
         }
         queryString.
-                append(getAdminRolesFilter(adminRoles, type)).append(')').
+                append(getAdminGroupsFilter(adminGroups, type)).append(')').
                 append(buildOrderBy(orderBySupport));
 
         // 3. prepare the search query
@@ -382,7 +382,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
             T subject = type == SubjectType.USER
                     ? (T) userDAO.find(actualId)
-                    : (T) roleDAO.find(actualId);
+                    : (T) groupDAO.find(actualId);
             if (subject == null) {
                 LOG.error("Could not find {} with id {}, even though returned by the native query",
                         type, actualId);
@@ -461,7 +461,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
         query.append("SELECT DISTINCT subject_id ").append("FROM ").
                 append(svs.membership().name).append(" WHERE ").
-                append("role_id=?").append(setParameter(parameters, cond.getRoleId())).
+                append("group_id=?").append(setParameter(parameters, cond.getGroupId())).
                 append(')');
 
         return query.toString();
@@ -486,7 +486,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
         if (type == SubjectType.USER) {
             query.append(" UNION SELECT DISTINCT subject_id FROM ").
-                    append(svs.roleResource().name).
+                    append(svs.groupResource().name).
                     append(" WHERE resource_name=?").
                     append(setParameter(parameters, cond.getResourceName()));
         }
@@ -676,7 +676,7 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
         }
 
         // Deal with subject Integer fields logically mapping to boolean values
-        // (JPARole.inheritPlainAttrs, for example)
+        // (JPAGroup.inheritPlainAttrs, for example)
         boolean foundBooleanMin = false;
         boolean foundBooleanMax = false;
         if (Integer.class.equals(subjectField.getType())) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index c08e1a2..5e48aac 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -26,9 +26,9 @@ import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
@@ -48,7 +48,7 @@ import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.misc.security.AuthContextUtil;
-import org.apache.syncope.core.misc.security.UnauthorizedRoleException;
+import org.apache.syncope.core.misc.security.UnauthorizedGroupException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
@@ -60,7 +60,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     private SubjectSearchDAO searchDAO;
 
     @Autowired
-    private RoleDAO roleDAO;
+    private GroupDAO groupDAO;
 
     @Resource(name = "anonymousUser")
     private String anonymousUser;
@@ -69,7 +69,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     private AttributableUtilFactory attrUtilFactory;
 
     @Override
-    protected Subject<UPlainAttr, UDerAttr, UVirAttr> findInternal(Long key) {
+    protected Subject<UPlainAttr, UDerAttr, UVirAttr> findInternal(final Long key) {
         return find(key);
     }
 
@@ -174,8 +174,8 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     }
 
     @Override
-    public final List<User> findAll(final Set<Long> adminRoles, final int page, final int itemsPerPage) {
-        return findAll(adminRoles, page, itemsPerPage, Collections.<OrderByClause>emptyList());
+    public final List<User> findAll(final Set<Long> adminGroups, final int page, final int itemsPerPage) {
+        return findAll(adminGroups, page, itemsPerPage, Collections.<OrderByClause>emptyList());
     }
 
     private SearchCond getAllMatchingCond() {
@@ -185,16 +185,16 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     }
 
     @Override
-    public List<User> findAll(final Set<Long> adminRoles,
+    public List<User> findAll(final Set<Long> adminGroups,
             final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
 
         return searchDAO.search(
-                adminRoles, getAllMatchingCond(), page, itemsPerPage, orderBy, SubjectType.USER);
+                adminGroups, getAllMatchingCond(), page, itemsPerPage, orderBy, SubjectType.USER);
     }
 
     @Override
-    public final int count(final Set<Long> adminRoles) {
-        return searchDAO.count(adminRoles, getAllMatchingCond(), SubjectType.USER);
+    public final int count(final Set<Long> adminGroups) {
+        return searchDAO.count(adminGroups, getAllMatchingCond(), SubjectType.USER);
     }
 
     @Override
@@ -225,8 +225,8 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
         for (Membership membership : user.getMemberships()) {
             membership.setUser(null);
 
-            roleDAO.save(membership.getRole());
-            membership.setRole(null);
+            groupDAO.save(membership.getGroup());
+            membership.setGroup(null);
 
             entityManager.remove(membership);
         }
@@ -237,15 +237,15 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
 
     private void securityChecks(final User user) {
         // Allows anonymous (during self-registration) and self (during self-update) to read own user,
-        // otherwise goes thorugh security checks to see if needed role entitlements are owned
+        // otherwise goes thorugh security checks to see if needed group entitlements are owned
         if (!AuthContextUtil.getAuthenticatedUsername().equals(anonymousUser)
                 && !AuthContextUtil.getAuthenticatedUsername().equals(user.getUsername())) {
 
-            Set<Long> roleKeys = user.getRoleKeys();
-            Set<Long> adminRoleKeys = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
-            roleKeys.removeAll(adminRoleKeys);
-            if (!roleKeys.isEmpty()) {
-                throw new UnauthorizedRoleException(roleKeys);
+            Set<Long> groupKeys = user.getGroupKeys();
+            Set<Long> adminGroupKeys = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
+            groupKeys.removeAll(adminGroupKeys);
+            if (!groupKeys.isEmpty()) {
+                throw new UnauthorizedGroupException(groupKeys);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
index 2235295..48a645a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
@@ -24,11 +24,11 @@ import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.entity.Attributable;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RVirAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.role.JPARVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
 import org.springframework.stereotype.Repository;
 
@@ -38,8 +38,8 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr, Long> implements VirAttr
     public <T extends VirAttr> Class<? extends AbstractVirAttr> getJPAEntityReference(
             final Class<T> reference) {
 
-        return RVirAttr.class.isAssignableFrom(reference)
-                ? JPARVirAttr.class
+        return GVirAttr.class.isAssignableFrom(reference)
+                ? JPAGVirAttr.class
                 : MVirAttr.class.isAssignableFrom(reference)
                         ? JPAMVirAttr.class
                         : UVirAttr.class.isAssignableFrom(reference)


Mime
View raw message