Repository: syncope
Updated Branches:
  refs/heads/master bf2dcae39 -> 175c5b22a


[SYNCOPE-666] Missing TypeExtension management


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

Branch: refs/heads/master
Commit: 175c5b22af3674bacb3f640a1270d04ad5fbbfda
Parents: bf2dcae
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Mon Nov 23 09:58:42 2015 +0100
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Mon Nov 23 09:58:42 2015 +0100

----------------------------------------------------------------------
 .../cli/commands/group/GroupResultManager.java  |  1 -
 .../client/cli/util/JasyptUtilsTest.java        |  7 --
 .../console/wizards/any/GroupDetails.java       | 10 +-
 .../client/console/wizards/any/StatusPanel.java | 33 ++++---
 .../syncope/common/lib/patch/GroupPatch.java    | 18 +++-
 .../common/lib/policy/PushPolicySpec.java       |  3 +-
 .../common/lib/policy/SyncPolicySpec.java       |  3 +-
 .../apache/syncope/common/lib/to/GroupTO.java   | 16 +++-
 .../core/persistence/api/dao/GroupDAO.java      |  4 +
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java | 14 +++
 .../core/persistence/jpa/dao/JPAGroupDAO.java   | 13 +++
 .../persistence/jpa/entity/AbstractEntity.java  | 18 +---
 .../jpa/entity/JPAEntityFactory.java            |  4 +
 .../jpa/entity/group/JPATypeExtension.java      |  4 +-
 .../jpa/entity/policy/JPAAccountPolicy.java     |  2 +-
 .../resources/META-INF/spring-orm-oracle.xml    |  8 ++
 .../resources/META-INF/spring-orm-sqlserver.xml |  8 ++
 .../src/main/resources/META-INF/spring-orm.xml  |  8 ++
 .../core/persistence/jpa/inner/GroupTest.java   | 11 ++-
 .../core/persistence/jpa/outer/GroupTest.java   | 25 +++++
 .../test/resources/domains/MasterContent.xml    |  7 ++
 .../java/data/GroupDataBinderImpl.java          | 97 ++++++++++++++++++++
 .../syncope/fit/core/reference/GroupITCase.java | 70 +++++++++-----
 .../fit/core/reference/VirSchemaITCase.java     |  1 -
 24 files changed, 311 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/client/cli/src/main/java/org/apache/syncope/client/cli/commands/group/GroupResultManager.java
----------------------------------------------------------------------
diff --git 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/group/GroupResultManager.java
 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/group/GroupResultManager.java
index 6a8cf69..ecda625 100644
--- 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/group/GroupResultManager.java
+++ 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/group/GroupResultManager.java
@@ -37,7 +37,6 @@ public class GroupResultManager extends CommonsResultManager {
     public void printGroup(final GroupTO groupTO) {
         System.out.println(" > GROUP ID: " + groupTO.getKey());
         System.out.println("    name: " + groupTO.getName());
-        System.out.println("    display name: " + groupTO.getDisplayName());
         System.out.println("    type: " + groupTO.getType());
         System.out.println("    realm: " + groupTO.getRealm());
         System.out.println("    status: " + groupTO.getStatus());

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/client/cli/src/test/java/org/apache/syncope/client/cli/util/JasyptUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/client/cli/src/test/java/org/apache/syncope/client/cli/util/JasyptUtilsTest.java
 
b/client/cli/src/test/java/org/apache/syncope/client/cli/util/JasyptUtilsTest.java
index 2c4b963..fce9ae1 100644
--- 
a/client/cli/src/test/java/org/apache/syncope/client/cli/util/JasyptUtilsTest.java
+++ 
b/client/cli/src/test/java/org/apache/syncope/client/cli/util/JasyptUtilsTest.java
@@ -25,13 +25,6 @@ import org.junit.Test;
 public class JasyptUtilsTest {
 
     @Test
-    public void singleton() {
-        final JasyptUtils jasyptUtils = JasyptUtils.getJasyptUtils();
-        final JasyptUtils jasyptUtils2 = JasyptUtils.getJasyptUtils();
-        assertEquals(jasyptUtils, jasyptUtils2);
-    }
-
-    @Test
     public void encryption() {
         final String password = "password";
         final JasyptUtils jasyptUtils = JasyptUtils.getJasyptUtils();

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
index 9e95f73..8c789ae 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupDetails.java
@@ -80,8 +80,8 @@ public class GroupDetails extends Details<GroupTO> {
         groupOwnerSelectWin.setCookieName("create-groupOwnerSelect-modal");
         this.add(groupOwnerSelectWin);
 
-        final AjaxTextFieldPanel name
-                = new AjaxTextFieldPanel("name", "name", new 
PropertyModel<String>(groupTO, "name"), false);
+        final AjaxTextFieldPanel name =
+                new AjaxTextFieldPanel("name", "name", new 
PropertyModel<String>(groupTO, "name"), false);
 
         final WebMarkupContainer jexlHelp = 
JexlHelpUtils.getJexlHelpWebContainer("jexlHelp");
 
@@ -135,8 +135,8 @@ public class GroupDetails extends Details<GroupTO> {
 
         groupOwnerModel = new OwnerModel(groupTO, AnyTypeKind.GROUP);
         @SuppressWarnings("unchecked")
-        final AjaxTextFieldPanel groupOwner
-                = new AjaxTextFieldPanel("groupOwner", "groupOwner", 
groupOwnerModel, false);
+        final AjaxTextFieldPanel groupOwner =
+                new AjaxTextFieldPanel("groupOwner", "groupOwner", 
groupOwnerModel, false);
         groupOwner.setReadOnly(true);
         groupOwner.setOutputMarkupId(true);
         ownerContainer.add(groupOwner);
@@ -243,7 +243,7 @@ public class GroupDetails extends Details<GroupTO> {
                         if (group == null) {
                             groupTO.setGroupOwner(null);
                         } else {
-                            object = group.getDisplayName();
+                            object = group.getName();
                         }
                     }
                     break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index 2b03146..98a3b35 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -112,7 +112,7 @@ public class StatusPanel extends Panel implements 
IHeaderContributor {
             }
             syncope.setStatus(syncopeStatus);
         } else if (any instanceof GroupTO) {
-            syncope.setConnObjectLink(((GroupTO) any).getDisplayName());
+            syncope.setConnObjectLink(((GroupTO) any).getName());
             syncope.setStatus(Status.ACTIVE);
         }
 
@@ -138,21 +138,30 @@ public class StatusPanel extends Panel implements 
IHeaderContributor {
                 if ("status".equalsIgnoreCase(key)) {
                     return new Label("field", StringUtils.EMPTY) {
 
-                        private static final long serialVersionUID = 1L;
+                        private static final long serialVersionUID = 
4755868673082976208L;
 
                         @Override
                         protected void onComponentTag(final ComponentTag tag) {
                             super.onComponentTag(tag);
-                            if (bean.getStatus() == Status.OBJECT_NOT_FOUND) {
-                                tag.put("class", "glyphicon 
glyphicon-remove-circle");
-                            } else if (bean.getStatus() == Status.UNDEFINED
-                                    || bean.getStatus() == Status.CREATED
-                                    || bean.getStatus() == 
Status.NOT_YET_SUBMITTED) {
-                                tag.put("class", "glyphicon 
glyphicon-question-sign");
-                            } else if (bean.getStatus() == Status.SUSPENDED) {
-                                tag.put("class", "glyphicon 
glyphicon-ban-circle");
-                            } else if (bean.getStatus() == Status.ACTIVE) {
-                                tag.put("class", "glyphicon 
glyphicon-ok-circle");
+                            if (null != bean.getStatus()) {
+                                switch (bean.getStatus()) {
+                                    case OBJECT_NOT_FOUND:
+                                        tag.put("class", "glyphicon 
glyphicon-remove-circle");
+                                        break;
+                                    case UNDEFINED:
+                                    case CREATED:
+                                    case NOT_YET_SUBMITTED:
+                                        tag.put("class", "glyphicon 
glyphicon-question-sign");
+                                        break;
+                                    case SUSPENDED:
+                                        tag.put("class", "glyphicon 
glyphicon-ban-circle");
+                                        break;
+                                    case ACTIVE:
+                                        tag.put("class", "glyphicon 
glyphicon-ok-circle");
+                                        break;
+                                    default:
+                                        break;
+                                }
                             }
 
                             tag.put("alt", "status icon");

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
index 310c3d1..c6347c1 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
@@ -18,8 +18,15 @@
  */
 package org.apache.syncope.common.lib.patch;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 
 @XmlRootElement(name = "groupPatch")
 @XmlType
@@ -37,6 +44,10 @@ public class GroupPatch extends AnyPatch {
 
     private StringReplacePatchItem udynMembershipCond;
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
+    private final Map<String, Set<String>> typeExtensions = new HashMap<>();
+
     public StringReplacePatchItem getName() {
         return name;
     }
@@ -77,11 +88,16 @@ public class GroupPatch extends AnyPatch {
         this.udynMembershipCond = udynMembershipCond;
     }
 
+    @JsonProperty
+    public Map<String, Set<String>> getTypeExtensions() {
+        return typeExtensions;
+    }
+
     @Override
     public boolean isEmpty() {
         return super.isEmpty()
                 && name == null && userOwner == null && groupOwner == null
-                && adynMembershipCond == null && udynMembershipCond == null;
+                && adynMembershipCond == null && udynMembershipCond == null && 
typeExtensions.isEmpty();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PushPolicySpec.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PushPolicySpec.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PushPolicySpec.java
index 4b61374..7cfe621 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PushPolicySpec.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PushPolicySpec.java
@@ -19,9 +19,10 @@
 package org.apache.syncope.common.lib.policy;
 
 import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlType
-public class PushPolicySpec {
+public class PushPolicySpec extends AbstractBaseBean {
 
     private static final long serialVersionUID = 3641030189482617497L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
index 1eb578e..2a31d64 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
@@ -24,11 +24,12 @@ import java.util.HashMap;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.AbstractBaseBean;
 import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 import org.apache.syncope.common.lib.types.ConflictResolutionAction;
 
 @XmlType
-public class SyncPolicySpec {
+public class SyncPolicySpec extends AbstractBaseBean {
 
     private static final long serialVersionUID = -3144027171719498127L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
index a5a33ca..9c375c8 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
@@ -19,8 +19,14 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @XmlRootElement(name = "group")
@@ -39,6 +45,10 @@ public class GroupTO extends AnyTO {
 
     private String udynMembershipCond;
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
+    private final Map<String, Set<String>> typeExtensions = new HashMap<>();
+
     @Override
     public String getType() {
         return AnyTypeKind.GROUP.name();
@@ -89,9 +99,9 @@ public class GroupTO extends AnyTO {
         this.udynMembershipCond = uDynMembershipCond;
     }
 
-    @JsonIgnore
-    public String getDisplayName() {
-        return getKey() + " " + getName();
+    @JsonProperty
+    public Map<String, Set<String>> getTypeExtensions() {
+        return typeExtensions;
     }
 
     public static long fromDisplayName(final String displayName) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
index f77d9b5..65555c2 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
@@ -21,9 +21,11 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 import java.util.Map;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 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.Group;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 
@@ -57,6 +59,8 @@ public interface GroupDAO extends AnyDAO<Group> {
      */
     Map<Long, PropagationByResource> findUsersWithTransitiveResources(Long 
groupKey);
 
+    List<TypeExtension> findTypeExtensionByAnyTypeClass(AnyTypeClass 
anyTypeClass);
+
     void refreshDynMemberships(AnyObject anyObject);
 
     void refreshDynMemberships(User user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index a999e14..7a32a18 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -24,6 +24,7 @@ import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -31,6 +32,7 @@ import 
org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -50,6 +52,9 @@ public class JPAAnyTypeClassDAO extends 
AbstractDAO<AnyTypeClass, String> implem
     @Autowired
     private VirSchemaDAO virSchemaDAO;
 
+    @Autowired
+    private GroupDAO groupDAO;
+
     @Override
     public AnyTypeClass find(final String key) {
         return entityManager().find(JPAAnyTypeClass.class, key);
@@ -100,6 +105,15 @@ public class JPAAnyTypeClassDAO extends 
AbstractDAO<AnyTypeClass, String> implem
             type.remove(anyTypeClass);
         }
 
+        for (TypeExtension typeExt : 
groupDAO.findTypeExtensionByAnyTypeClass(anyTypeClass)) {
+            typeExt.remove(anyTypeClass);
+
+            if (typeExt.getAuxClasses().isEmpty()) {
+                typeExt.getGroup().remove(typeExt);
+                typeExt.setGroup(null);
+            }
+        }
+
         entityManager().remove(anyTypeClass);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/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 e421863..af77371 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
@@ -44,12 +44,15 @@ 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.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.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -245,6 +248,16 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
         return result;
     }
 
+    @Override
+    public List<TypeExtension> findTypeExtensionByAnyTypeClass(final 
AnyTypeClass anyTypeClass) {
+        TypedQuery<TypeExtension> query = entityManager().createQuery(
+                "SELECT e FROM " + JPATypeExtension.class.getSimpleName()
+                + " e WHERE :anyTypeClass MEMBER OF e.auxClasses", 
TypeExtension.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public void refreshDynMemberships(final AnyObject anyObject) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
index 1b8ab54..d66e9d2 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -89,20 +88,7 @@ public abstract class AbstractEntity<KEY> implements 
Entity<KEY> {
 
     @Override
     public String toString() {
-        Method method = BeanUtils.findMethod(getClass(), "getKey");
-
-        StringBuilder result = new 
StringBuilder().append(getClass().getSimpleName()).append('[');
-        if (method != null) {
-            try {
-                result.append(method.invoke(this));
-            } catch (Exception e) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.error("While serializing to string", e);
-                }
-            }
-        }
-        result.append(']');
-
-        return result.toString();
+        return new StringBuilder().append(getClass().getSimpleName()).
+                append('[').append(getKey()).append(']').toString();
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index a31392f..90b5290 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -64,6 +64,7 @@ import 
org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 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.group.Group;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
@@ -98,6 +99,7 @@ import 
org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
 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.group.JPAGroup;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
@@ -152,6 +154,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAUser();
         } else if (reference.equals(Group.class)) {
             result = (T) new JPAGroup();
+        } else if (reference.equals(TypeExtension.class)) {
+            result = (T) new JPATypeExtension();
         } else if (reference.equals(RelationshipType.class)) {
             result = (T) new JPARelationshipType();
         } else if (reference.equals(ARelationship.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
index 69fe3be..7d244da 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
@@ -92,13 +92,13 @@ public class JPATypeExtension extends AbstractEntity<Long> 
implements TypeExtens
     @Override
     public boolean add(final AnyTypeClass auxClass) {
         checkType(auxClass, JPAAnyTypeClass.class);
-        return this.auxClasses.add((JPAAnyTypeClass) auxClass);
+        return auxClasses.contains((JPAAnyTypeClass) auxClass) || 
auxClasses.add((JPAAnyTypeClass) auxClass);
     }
 
     @Override
     public boolean remove(final AnyTypeClass auxClass) {
         checkType(auxClass, JPAAnyTypeClass.class);
-        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
+        return auxClasses.remove((JPAAnyTypeClass) auxClass);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
index e9b38c3..7f87029 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
@@ -126,7 +126,7 @@ public class JPAAccountPolicy extends AbstractPolicy 
implements AccountPolicy {
     @Override
     public boolean add(final ExternalResource resource) {
         checkType(resource, JPAExternalResource.class);
-        return resources.add((JPAExternalResource) resource);
+        return resources.contains((JPAExternalResource) resource) || 
resources.add((JPAExternalResource) resource);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml 
b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
index a2eb846..d1379c9 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
@@ -119,6 +119,14 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity 
class="org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_TypeExtension" strategy="TABLE"/>
+        <table-generator name="SEQ_TypeExtension" 
pk-column-value="SEQ_TypeExtension" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
 
   <entity 
class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
     <attributes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml 
b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
index a2eb846..d1379c9 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
@@ -119,6 +119,14 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity 
class="org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_TypeExtension" strategy="TABLE"/>
+        <table-generator name="SEQ_TypeExtension" 
pk-column-value="SEQ_TypeExtension" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
 
   <entity 
class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
     <attributes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml 
b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
index 5b820ff..584d8ec 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
@@ -119,6 +119,14 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity 
class="org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_TypeExtension" strategy="TABLE"/>
+        <table-generator name="SEQ_TypeExtension" 
pk-column-value="SEQ_TypeExtension" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
 
   <entity 
class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
     <attributes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
index 0b24a25..4d37425 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
 
 import java.util.List;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -41,16 +42,24 @@ public class GroupTest extends AbstractTest {
     @Autowired
     private RealmDAO realmDAO;
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Test
     public void findAll() {
         List<Group> list = 
groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertEquals("did not get expected number of groups ", 14, 
list.size());
+        assertEquals("did not get expected number of groups ", 15, 
list.size());
     }
 
     @Test
     public void find() {
         Group group = groupDAO.find("root");
         assertNotNull("did not find expected group", group);
+
+        group = groupDAO.find("additional");
+        assertNotNull(group);
+        assertEquals(1, group.getTypeExtensions().size());
+        assertEquals(2, 
group.getTypeExtension(anyTypeDAO.findUser()).getAuxClasses().size());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index 57e3d1f..e3db14f 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -48,6 +48,7 @@ import 
org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -122,6 +123,30 @@ public class GroupTest extends AbstractTest {
     }
 
     @Test
+    public void create() {
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("new");
+
+        TypeExtension typeExt = entityFactory.newEntity(TypeExtension.class);
+        typeExt.setAnyType(anyTypeDAO.findUser());
+        typeExt.add(anyTypeClassDAO.find("csv"));
+        typeExt.add(anyTypeClassDAO.find("other"));
+
+        group.add(typeExt);
+        typeExt.setGroup(group);
+
+        groupDAO.save(group);
+
+        groupDAO.flush();
+
+        group = groupDAO.find("new");
+        assertNotNull(group);
+        assertEquals(1, group.getTypeExtensions().size());
+        assertEquals(2, 
group.getTypeExtension(anyTypeDAO.findUser()).getAuxClasses().size());
+    }
+
+    @Test
     public void delete() {
         groupDAO.delete(2L);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml 
b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index b0a1a1a..c7bdb08 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -278,7 +278,14 @@ under the License.
   <SyncopeGroup id="14" name="artDirector"
                 realm_id="1"
                 creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 
11:00:00"/>  
+  <SyncopeGroup id="15" name="additional"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
                 creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 
11:00:00"/>
+  <TypeExtension id="1" group_id="15" anyType_name="USER"/>
+  <TypeExtension_AnyTypeClass typeExtension_id="1" anyTypeClass_name="csv"/>
+  <TypeExtension_AnyTypeClass typeExtension_id="1" anyTypeClass_name="other"/>
   
   <URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index 680cf4a..1f8655f 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -19,8 +19,13 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -34,12 +39,17 @@ import 
org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import 
org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -47,6 +57,9 @@ import 
org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public class GroupDataBinderImpl extends AbstractAnyDataBinder implements 
GroupDataBinder {
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     private void setDynMembership(final Group group, final AnyTypeKind 
anyTypeKind, final String dynMembershipFIQL) {
         SearchCond dynMembershipCond = 
SearchCondConverter.convert(dynMembershipFIQL);
         if (!dynMembershipCond.isValid()) {
@@ -114,6 +127,33 @@ public class GroupDataBinderImpl extends 
AbstractAnyDataBinder implements GroupD
             setDynMembership(group, AnyTypeKind.USER, 
groupTO.getUDynMembershipCond());
         }
 
+        // type extensions
+        for (Map.Entry<String, Set<String>> entry : 
groupTO.getTypeExtensions().entrySet()) {
+            AnyType anyType = anyTypeDAO.find(entry.getKey());
+            if (anyType == null) {
+                LOG.warn("Ignoring invalid {}: {}", 
AnyType.class.getSimpleName(), entry.getKey());
+            } else {
+                TypeExtension typeExt = 
entityFactory.newEntity(TypeExtension.class);
+                typeExt.setAnyType(anyType);
+                typeExt.setGroup(group);
+                group.add(typeExt);
+
+                for (String name : entry.getValue()) {
+                    AnyTypeClass anyTypeClass = anyTypeClassDAO.find(name);
+                    if (anyTypeClass == null) {
+                        LOG.warn("Ignoring invalid {}: {}", 
AnyTypeClass.class.getSimpleName(), name);
+                    } else {
+                        typeExt.add(anyTypeClass);
+                    }
+                }
+
+                if (typeExt.getAuxClasses().isEmpty()) {
+                    group.remove(typeExt);
+                    typeExt.setGroup(null);
+                }
+            }
+        }
+
         return group;
     }
 
@@ -183,6 +223,52 @@ public class GroupDataBinderImpl extends 
AbstractAnyDataBinder implements GroupD
             }
         }
 
+        // type extensions
+        for (Map.Entry<String, Set<String>> entry : 
groupPatch.getTypeExtensions().entrySet()) {
+            AnyType anyType = anyTypeDAO.find(entry.getKey());
+            if (anyType == null) {
+                LOG.warn("Ignoring invalid {}: {}", 
AnyType.class.getSimpleName(), entry.getKey());
+            } else {
+                TypeExtension typeExt = group.getTypeExtension(anyType);
+                if (typeExt == null) {
+                    typeExt = entityFactory.newEntity(TypeExtension.class);
+                    typeExt.setAnyType(anyType);
+                    typeExt.setGroup(group);
+                    group.add(typeExt);
+                }
+
+                // add all classes contained in the TO
+                for (String name : entry.getValue()) {
+                    AnyTypeClass anyTypeClass = anyTypeClassDAO.find(name);
+                    if (anyTypeClass == null) {
+                        LOG.warn("Ignoring invalid {}: {}", 
AnyTypeClass.class.getSimpleName(), name);
+                    } else {
+                        typeExt.add(anyTypeClass);
+                    }
+                }
+                // remove all classes not contained in the TO
+                for (Iterator<? extends AnyTypeClass> itor = 
typeExt.getAuxClasses().iterator(); itor.hasNext();) {
+                    AnyTypeClass anyTypeClass = itor.next();
+                    if (!entry.getValue().contains(anyTypeClass.getKey())) {
+                        itor.remove();
+                    }
+                }
+
+                // only consider non-empty type extensions
+                if (typeExt.getAuxClasses().isEmpty()) {
+                    group.remove(typeExt);
+                    typeExt.setGroup(null);
+                }
+            }
+        }
+        // remove all type extensions not contained in the TO
+        for (Iterator<? extends TypeExtension> itor = 
group.getTypeExtensions().iterator(); itor.hasNext();) {
+            TypeExtension typeExt = itor.next();
+            if 
(!groupPatch.getTypeExtensions().containsKey(typeExt.getAnyType().getKey())) {
+                itor.remove();
+            }
+        }
+
         return propByRes;
     }
 
@@ -221,6 +307,17 @@ public class GroupDataBinderImpl extends 
AbstractAnyDataBinder implements GroupD
             
groupTO.setUDynMembershipCond(group.getUDynMembership().getFIQLCond());
         }
 
+        for (TypeExtension typeExt : group.getTypeExtensions()) {
+            groupTO.getTypeExtensions().put(typeExt.getAnyType().getKey(),
+                    CollectionUtils.collect(typeExt.getAuxClasses(), new 
Transformer<AnyTypeClass, String>() {
+
+                        @Override
+                        public String transform(final AnyTypeClass clazz) {
+                            return clazz.getKey();
+                        }
+                    }, new HashSet<String>()));
+        }
+
         return groupTO;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index f5a503b..502b832 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@ -28,6 +28,9 @@ import static org.junit.Assert.fail;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
@@ -276,28 +279,6 @@ public class GroupITCase extends AbstractITCase {
     }
 
     @Test
-    public void issue178() {
-        GroupTO groupTO = new GroupTO();
-        String groupName = "torename" + getUUIDString();
-        groupTO.setName(groupName);
-        groupTO.setRealm("/");
-
-        GroupTO actual = createGroup(groupTO).getAny();
-
-        assertNotNull(actual);
-        assertEquals(groupName, actual.getName());
-
-        GroupPatch groupPatch = new GroupPatch();
-        groupPatch.setKey(actual.getKey());
-        String renamedGroup = "renamed" + getUUIDString();
-        groupPatch.setName(new 
StringReplacePatchItem.Builder().value(renamedGroup).build());
-
-        actual = updateGroup(groupPatch).getAny();
-        assertNotNull(actual);
-        assertEquals(renamedGroup, actual.getName());
-    }
-
-    @Test
     public void unlink() {
         GroupTO actual = createGroup(getSampleTO("unlink")).getAny();
         assertNotNull(actual);
@@ -710,6 +691,51 @@ public class GroupITCase extends AbstractITCase {
     }
 
     @Test
+    public void typeExtensions() {
+        GroupTO groupTO = getBasicSampleTO("typeExtensions");
+        groupTO.getTypeExtensions().put(AnyTypeKind.USER.name(), 
Collections.singleton("csv"));
+
+        groupTO = createGroup(groupTO).getAny();
+        assertNotNull(groupTO);
+        assertEquals(1, groupTO.getTypeExtensions().size());
+        assertEquals(1, 
groupTO.getTypeExtensions().get(AnyTypeKind.USER.name()).size());
+        assertEquals(Collections.singleton("csv"), 
groupTO.getTypeExtensions().get(AnyTypeKind.USER.name()));
+
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(groupTO.getKey());
+        groupPatch.getTypeExtensions().put(AnyTypeKind.USER.name(), new 
HashSet<>(Arrays.asList("csv", "other")));
+
+        groupTO = updateGroup(groupPatch).getAny();
+        assertNotNull(groupTO);
+        assertEquals(1, groupTO.getTypeExtensions().size());
+        assertEquals(2, 
groupTO.getTypeExtensions().get(AnyTypeKind.USER.name()).size());
+        
assertTrue(groupTO.getTypeExtensions().get(AnyTypeKind.USER.name()).contains("csv"));
+        
assertTrue(groupTO.getTypeExtensions().get(AnyTypeKind.USER.name()).contains("other"));
+    }
+
+    @Test
+    public void issue178() {
+        GroupTO groupTO = new GroupTO();
+        String groupName = "torename" + getUUIDString();
+        groupTO.setName(groupName);
+        groupTO.setRealm("/");
+
+        GroupTO actual = createGroup(groupTO).getAny();
+
+        assertNotNull(actual);
+        assertEquals(groupName, actual.getName());
+
+        GroupPatch groupPatch = new GroupPatch();
+        groupPatch.setKey(actual.getKey());
+        String renamedGroup = "renamed" + getUUIDString();
+        groupPatch.setName(new 
StringReplacePatchItem.Builder().value(renamedGroup).build());
+
+        actual = updateGroup(groupPatch).getAny();
+        assertNotNull(actual);
+        assertEquals(renamedGroup, actual.getName());
+    }
+
+    @Test
     public void issueSYNCOPE632() {
         GroupTO groupTO = null;
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/175c5b22/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
index f251525..56d8186 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static 
org.apache.syncope.fit.core.reference.AbstractITCase.clientFactory;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;

Reply via email to