Repository: syncope
Updated Branches:
  refs/heads/master d433501b9 -> e34a8e4f3


[SYNCOPE-119] Adding isAssignable support to dynamic group memberships


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e34a8e4f
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e34a8e4f
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e34a8e4f

Branch: refs/heads/master
Commit: e34a8e4f3330c1ce4bc9565f894bfe336b28cb7b
Parents: d433501
Author: Francesco Chicchiriccò <[email protected]>
Authored: Tue Dec 1 12:19:39 2015 +0100
Committer: Francesco Chicchiriccò <[email protected]>
Committed: Tue Dec 1 12:19:39 2015 +0100

----------------------------------------------------------------------
 .../api/dao/search/AssignableCond.java          | 15 ++++
 .../persistence/jpa/dao/JPAAnySearchDAO.java    | 73 ++++++++++----------
 .../core/persistence/jpa/dao/JPAGroupDAO.java   | 37 +++++++---
 .../core/persistence/jpa/dao/SearchSupport.java |  4 ++
 4 files changed, 83 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/e34a8e4f/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
index 0ece01b..54587f3 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
@@ -24,6 +24,13 @@ public class AssignableCond extends AbstractSearchCond {
 
     private String realmFullPath;
 
+    /**
+     * Whether this condition should be evaluated from the assignable group 
(default) - or instead the
+     * assignee - point of view.
+     * The converter from FIQL will ignore this setting, which is meant for 
internal usage.
+     */
+    private boolean fromGroup = true;
+
     public String getRealmFullPath() {
         return realmFullPath;
     }
@@ -32,6 +39,14 @@ public class AssignableCond extends AbstractSearchCond {
         this.realmFullPath = realmFullPath;
     }
 
+    public boolean isFromGroup() {
+        return fromGroup;
+    }
+
+    public void setFromGroup(final boolean fromGroup) {
+        this.fromGroup = fromGroup;
+    }
+
     @Override
     public final boolean isValid() {
         return realmFullPath != null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/e34a8e4f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index c0f57b0..942b950 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -137,7 +137,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
 
         // 1. get the query string from the search condition
         SearchSupport svs = new SearchSupport(typeKind);
-        StringBuilder queryString = getQuery(searchCondition, parameters, 
typeKind, svs);
+        StringBuilder queryString = getQuery(searchCondition, parameters, svs);
 
         // 2. take into account administrative realms
         queryString.insert(0, "SELECT u.any_id FROM (");
@@ -206,7 +206,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
 
         // 1. get the query string from the search condition
         SearchSupport svs = new SearchSupport(typeKind);
-        StringBuilder queryString = getQuery(searchCondition, parameters, 
typeKind, svs);
+        StringBuilder queryString = getQuery(searchCondition, parameters, svs);
 
         boolean matches;
         if (queryString.length() == 0) {
@@ -365,7 +365,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
 
         // 1. get the query string from the search condition
         SearchSupport svs = new SearchSupport(typeKind);
-        StringBuilder queryString = getQuery(nodeCond, parameters, typeKind, 
svs);
+        StringBuilder queryString = getQuery(nodeCond, parameters, svs);
 
         // 2. take into account administrative groups and ordering
         OrderBySupport orderBySupport = parseOrderBy(typeKind, svs, orderBy);
@@ -417,64 +417,59 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
         return result;
     }
 
-    private StringBuilder getQuery(final SearchCond nodeCond, final 
List<Object> parameters,
-            final AnyTypeKind anyTypeKind, final SearchSupport svs) {
-
+    private StringBuilder getQuery(final SearchCond nodeCond, final 
List<Object> parameters, final SearchSupport svs) {
         StringBuilder query = new StringBuilder();
 
         switch (nodeCond.getType()) {
 
             case LEAF:
             case NOT_LEAF:
-                if (nodeCond.getAnyTypeCond() != null && 
AnyTypeKind.ANY_OBJECT == anyTypeKind) {
+                if (nodeCond.getAnyTypeCond() != null && 
AnyTypeKind.ANY_OBJECT == svs.anyTypeKind()) {
                     query.append(getQuery(nodeCond.getAnyTypeCond(),
                             nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 } else if (nodeCond.getRelationshipTypeCond() != null
-                        && (AnyTypeKind.USER == anyTypeKind || 
AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
+                        && (AnyTypeKind.USER == svs.anyTypeKind() || 
AnyTypeKind.ANY_OBJECT == svs.anyTypeKind())) {
 
                     query.append(getQuery(nodeCond.getRelationshipTypeCond(),
                             nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 } else if (nodeCond.getRelationshipCond() != null
-                        && (AnyTypeKind.USER == anyTypeKind || 
AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
+                        && (AnyTypeKind.USER == svs.anyTypeKind() || 
AnyTypeKind.ANY_OBJECT == svs.anyTypeKind())) {
 
                     query.append(getQuery(nodeCond.getRelationshipCond(),
                             nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 } else if (nodeCond.getMembershipCond() != null
-                        && (AnyTypeKind.USER == anyTypeKind || 
AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
+                        && (AnyTypeKind.USER == svs.anyTypeKind() || 
AnyTypeKind.ANY_OBJECT == svs.anyTypeKind())) {
 
                     query.append(getQuery(nodeCond.getMembershipCond(),
                             nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
-                } else if (nodeCond.getAssignableCond() != null
-                        && (AnyTypeKind.GROUP == anyTypeKind || 
AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
-
-                    query.append(getQuery(nodeCond.getAssignableCond(), 
parameters, anyTypeKind, svs));
-                } else if (nodeCond.getRoleCond() != null && AnyTypeKind.USER 
== anyTypeKind) {
+                } else if (nodeCond.getAssignableCond() != null) {
+                    query.append(getQuery(nodeCond.getAssignableCond(), 
parameters, svs));
+                } else if (nodeCond.getRoleCond() != null && AnyTypeKind.USER 
== svs.anyTypeKind()) {
                     query.append(getQuery(nodeCond.getRoleCond(),
                             nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 } else if (nodeCond.getResourceCond() != null) {
                     query.append(getQuery(nodeCond.getResourceCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, anyTypeKind, svs));
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 } else if (nodeCond.getAttributeCond() != null) {
                     query.append(getQuery(nodeCond.getAttributeCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, anyTypeKind, svs));
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 } else if (nodeCond.getAnyCond() != null) {
                     query.append(getQuery(nodeCond.getAnyCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, anyTypeKind,
-                            svs));
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, 
parameters, svs));
                 }
                 break;
 
             case AND:
-                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, 
anyTypeKind, svs)).
+                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, 
svs)).
                         append(" AND any_id IN ( ").
-                        append(getQuery(nodeCond.getRightNodeCond(), 
parameters, anyTypeKind, svs)).
+                        append(getQuery(nodeCond.getRightNodeCond(), 
parameters, svs)).
                         append(")");
                 break;
 
             case OR:
-                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, 
anyTypeKind, svs)).
+                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, 
svs)).
                         append(" OR any_id IN ( ").
-                        append(getQuery(nodeCond.getRightNodeCond(), 
parameters, anyTypeKind, svs)).
+                        append(getQuery(nodeCond.getRightNodeCond(), 
parameters, svs)).
                         append(")");
                 break;
 
@@ -607,7 +602,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
     }
 
     private String getQuery(final ResourceCond cond, final boolean not, final 
List<Object> parameters,
-            final AnyTypeKind typeKind, final SearchSupport svs) {
+            final SearchSupport svs) {
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM 
").
                 append(svs.field().name).append(" WHERE ");
@@ -623,7 +618,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
                 append(" WHERE resource_name=?").
                 append(setParameter(parameters, cond.getResourceName()));
 
-        if (typeKind == AnyTypeKind.USER) {
+        if (svs.anyTypeKind() == AnyTypeKind.USER) {
             query.append(" UNION SELECT DISTINCT any_id FROM ").
                     append(svs.groupResource().name).
                     append(" WHERE resource_name=?").
@@ -635,9 +630,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
         return query.toString();
     }
 
-    private String getQuery(final AssignableCond cond, final List<Object> 
parameters, final AnyTypeKind typeKind,
-            final SearchSupport svs) {
-
+    private String getQuery(final AssignableCond cond, final List<Object> 
parameters, final SearchSupport svs) {
         Realm realm = realmDAO.find(cond.getRealmFullPath());
         if (realm == null) {
             return EMPTY_QUERY;
@@ -645,10 +638,18 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM 
").
                 append(svs.field().name).append(" WHERE (");
-        for (Realm current = realm; current.getParent() != null; current = 
current.getParent()) {
-            query.append("realm_id=?").append(setParameter(parameters, 
current.getKey())).append(" OR ");
+        if (cond.isFromGroup()) {
+            for (Realm current = realm; current.getParent() != null; current = 
current.getParent()) {
+                query.append("realm_id=?").append(setParameter(parameters, 
current.getKey())).append(" OR ");
+            }
+            query.append("realm_id=?").append(setParameter(parameters, 
realmDAO.getRoot().getKey()));
+        } else {
+            for (Realm current : realmDAO.findDescendants(realm)) {
+                query.append("realm_id=?").append(setParameter(parameters, 
current.getKey())).append(" OR ");
+            }
+            query.setLength(query.length() - 4);
         }
-        query.append("realm_id=?").append(setParameter(parameters, 
realmDAO.getRoot().getKey())).append(')');
+        query.append(')');
 
         return query.toString();
     }
@@ -746,9 +747,9 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
     }
 
     private String getQuery(final AttributeCond cond, final boolean not, final 
List<Object> parameters,
-            final AnyTypeKind typeKind, final SearchSupport svs) {
+            final SearchSupport svs) {
 
-        AnyUtils attrUtils = anyUtilsFactory.getInstance(typeKind);
+        AnyUtils attrUtils = anyUtilsFactory.getInstance(svs.anyTypeKind());
 
         PlainSchema schema = schemaDAO.find(cond.getSchema());
         if (schema == null) {
@@ -797,9 +798,9 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
 
     @SuppressWarnings("rawtypes")
     private String getQuery(final AnyCond cond, final boolean not, final 
List<Object> parameters,
-            final AnyTypeKind typeKind, final SearchSupport svs) {
+            final SearchSupport svs) {
 
-        AnyUtils attrUtils = anyUtilsFactory.getInstance(typeKind);
+        AnyUtils attrUtils = anyUtilsFactory.getInstance(svs.anyTypeKind());
 
         // Keeps track of difference between entity's getKey() and JPA @Id 
fields
         if ("key".equals(cond.getSchema())) {
@@ -840,7 +841,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, 
Long> implements AnySea
         if (anyField.getType().getAnnotation(Entity.class) != null) {
             Method relMethod = null;
             try {
-                relMethod = ClassUtils.getPublicMethod(anyField.getType(), 
"getKey", new Class[0]);
+                relMethod = ClassUtils.getPublicMethod(anyField.getType(), 
"getKey", new Class<?>[0]);
             } catch (Exception e) {
                 LOG.error("Could not find {}#getKey", anyField.getType(), e);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e34a8e4f/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
index d050d4c..671582c 100644
--- 
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
@@ -42,9 +42,12 @@ import 
org.apache.syncope.core.misc.search.SearchCondConverter;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
@@ -159,12 +162,21 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
         return query.getResultList();
     }
 
+    private SearchCond buildDynMembershipCond(final String baseCondFIQL, final 
Realm groupRealm) {
+        AssignableCond cond = new AssignableCond();
+        cond.setRealmFullPath(groupRealm.getFullPath());
+        cond.setFromGroup(false);
+
+        return SearchCond.getAndCond(SearchCond.getLeafCond(cond), 
SearchCondConverter.convert(baseCondFIQL));
+    }
+
     @Override
     public Group save(final Group group) {
         // refresh dynaminc memberships
         if (group.getADynMembership() != null) {
             List<AnyObject> matching = searchDAO.search(
-                    
SearchCondConverter.convert(group.getADynMembership().getFIQLCond()), 
AnyTypeKind.ANY_OBJECT);
+                    
buildDynMembershipCond(group.getADynMembership().getFIQLCond(), 
group.getRealm()),
+                    AnyTypeKind.ANY_OBJECT);
 
             group.getADynMembership().getMembers().clear();
             for (AnyObject anyObject : matching) {
@@ -173,7 +185,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
         }
         if (group.getUDynMembership() != null) {
             List<User> matching = searchDAO.search(
-                    
SearchCondConverter.convert(group.getUDynMembership().getFIQLCond()), 
AnyTypeKind.USER);
+                    
buildDynMembershipCond(group.getUDynMembership().getFIQLCond(), 
group.getRealm()),
+                    AnyTypeKind.USER);
 
             group.getUDynMembership().getMembers().clear();
             for (User user : matching) {
@@ -258,11 +271,13 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public void refreshDynMemberships(final AnyObject anyObject) {
-        for (Group role : findAll()) {
-            if (role.getADynMembership() != null && 
!searchDAO.matches(anyObject,
-                    
SearchCondConverter.convert(role.getADynMembership().getFIQLCond()), 
AnyTypeKind.ANY_OBJECT)) {
+        for (Group group : findAll()) {
+            if (group.getADynMembership() != null && !searchDAO.matches(
+                    anyObject,
+                    
buildDynMembershipCond(group.getADynMembership().getFIQLCond(), 
group.getRealm()),
+                    AnyTypeKind.ANY_OBJECT)) {
 
-                role.getADynMembership().remove(anyObject);
+                group.getADynMembership().remove(anyObject);
             }
         }
     }
@@ -270,11 +285,13 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public void refreshDynMemberships(final User user) {
-        for (Group role : findAll()) {
-            if (role.getUDynMembership() != null && !searchDAO.matches(user,
-                    
SearchCondConverter.convert(role.getUDynMembership().getFIQLCond()), 
AnyTypeKind.USER)) {
+        for (Group group : findAll()) {
+            if (group.getUDynMembership() != null && !searchDAO.matches(
+                    user,
+                    
buildDynMembershipCond(group.getUDynMembership().getFIQLCond(), 
group.getRealm()),
+                    AnyTypeKind.USER)) {
 
-                role.getUDynMembership().remove(user);
+                group.getUDynMembership().remove(user);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e34a8e4f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
index 4c8297a..06854df 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
@@ -53,6 +53,10 @@ class SearchSupport {
         this.anyTypeKind = anyTypeKind;
     }
 
+    public AnyTypeKind anyTypeKind() {
+        return anyTypeKind;
+    }
+
     public String fieldName(final AttrSchemaType attrSchemaType) {
         String result;
 

Reply via email to