syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmarte...@apache.org
Subject [22/26] syncope git commit: [SYNCOPE-665] Implementation completed
Date Thu, 10 Sep 2015 12:37:52 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
index cf87a3b..c4837ae 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
@@ -26,20 +26,24 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
 import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
 
 @Repository
 public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTypeDAO {
 
+    @Transactional(readOnly = true)
     @Override
     public AnyType find(final String key) {
         return entityManager().find(JPAAnyType.class, key);
     }
 
+    @Transactional(readOnly = true)
     @Override
     public AnyType findUser() {
         return find(AnyTypeKind.USER.name());
     }
 
+    @Transactional(readOnly = true)
     @Override
     public AnyType findGroup() {
         return find(AnyTypeKind.GROUP.name());

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index eee37f1..2733388 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -39,6 +39,7 @@ import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
 
 @Repository
 public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
@@ -68,6 +69,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
         return entityManager().find(JPARealm.class, key);
     }
 
+    @Transactional(readOnly = true)
     @Override
     public Realm find(final String fullPath) {
         if (SyncopeConstants.ROOT_REALM.equals(fullPath)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
new file mode 100644
index 0000000..cdb4b5e
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
@@ -0,0 +1,61 @@
+/*
+ * 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.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+
+@Entity
+@Table(name = JPAAnyTemplateRealm.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "realm_id", "anyType_name" }))
+public class JPAAnyTemplateRealm extends AbstractAnyTemplate implements AnyTemplateRealm {
+
+    public static final String TABLE = "AnyTemplateRealm";
+
+    private static final long serialVersionUID = 1863029633568957907L;
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPARealm realm;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Realm getRealm() {
+        return realm;
+    }
+
+    @Override
+    public void setRealm(final Realm realm) {
+        checkType(realm, JPARealm.class);
+        this.realm = (JPARealm) realm;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/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 586f6cd..4c3b816 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
@@ -26,6 +26,7 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
 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.ConnInstance;
@@ -69,7 +70,7 @@ 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;
 import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
@@ -107,7 +108,7 @@ 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;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyFilter;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
@@ -137,6 +138,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPADomain();
         } else if (reference.equals(Realm.class)) {
             result = (T) new JPARealm();
+        } else if (reference.equals(AnyTemplateRealm.class)) {
+            result = (T) new JPAAnyTemplateRealm();
         } else if (reference.equals(AccountPolicy.class)) {
             result = (T) new JPAAccountPolicy();
         } else if (reference.equals(PasswordPolicy.class)) {
@@ -239,8 +242,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPATaskExec();
         } else if (reference.equals(AnyFilter.class)) {
             result = (T) new JPAAnyFilter();
-        } else if (reference.equals(AnyTemplate.class)) {
-            result = (T) new JPAAnyTemplate();
+        } else if (reference.equals(AnyTemplateSyncTask.class)) {
+            result = (T) new JPAAnyTemplateSyncTask();
         } else if (reference.equals(SecurityQuestion.class)) {
             result = (T) new JPASecurityQuestion();
         } else if (reference.equals(Logger.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
index d458178..8186ede 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
@@ -18,18 +18,33 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
 import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import javax.validation.constraints.Size;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
@@ -61,6 +76,16 @@ public class JPARealm extends AbstractEntity<Long> implements Realm {
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAAccountPolicy accountPolicy;
 
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "actionClassName")
+    @CollectionTable(name = "Realm_actionsClassNames",
+            joinColumns =
+            @JoinColumn(name = "realm_id", referencedColumnName = "id"))
+    private Set<String> actionsClassNames = new HashSet<>();
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "realm")
+    private List<JPAAnyTemplateRealm> templates = new ArrayList<>();
+
     @Override
     public Long getKey() {
         return id;
@@ -116,4 +141,36 @@ public class JPARealm extends AbstractEntity<Long> implements Realm {
         this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
     }
 
+    @Override
+    public Set<String> getActionsClassNames() {
+        return actionsClassNames;
+    }
+
+    @Override
+    public boolean add(final AnyTemplateRealm template) {
+        checkType(template, JPAAnyTemplateRealm.class);
+        return this.templates.add((JPAAnyTemplateRealm) template);
+    }
+
+    @Override
+    public boolean remove(final AnyTemplateRealm template) {
+        checkType(template, JPAAnyTemplateRealm.class);
+        return this.templates.remove((JPAAnyTemplateRealm) template);
+    }
+
+    @Override
+    public AnyTemplateRealm getTemplate(final AnyType anyType) {
+        return CollectionUtils.find(templates, new Predicate<AnyTemplate>() {
+
+            @Override
+            public boolean evaluate(final AnyTemplate template) {
+                return anyType != null && anyType.equals(template.getAnyType());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends AnyTemplateRealm> getTemplates() {
+        return templates;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
new file mode 100644
index 0000000..28febea
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
@@ -0,0 +1,74 @@
+/*
+ * 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.entity.resource;
+
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+
+@MappedSuperclass
+public abstract class AbstractAnyTemplate extends AbstractEntity<Long> implements AnyTemplate {
+
+    private static final long serialVersionUID = -5280310945358790780L;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @Lob
+    private String template;
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public AnyTO get() {
+        return template == null
+                ? anyType == null
+                        ? null
+                        : new JPAAnyUtilsFactory().getInstance(anyType.getKind()).newAnyTO()
+                : anyType == null
+                        ? null
+                        : POJOHelper.deserialize(template, anyType.getKind().getToClass());
+    }
+
+    @Override
+    public void set(final AnyTO template) {
+        if (template == null) {
+            this.template = null;
+        } else {
+            this.template = POJOHelper.serialize(template);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
deleted file mode 100644
index 7af8491..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
+++ /dev/null
@@ -1,104 +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.entity.task;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
-
-@Entity
-@Table(name = JPAAnyTemplate.TABLE, uniqueConstraints =
-        @UniqueConstraint(columnNames = { "syncTask_id", "anyType_name" }))
-public class JPAAnyTemplate extends AbstractEntity<Long> implements AnyTemplate {
-
-    private static final long serialVersionUID = 3517381731849788407L;
-
-    public static final String TABLE = "AnyTemplate";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPASyncTask syncTask;
-
-    @ManyToOne
-    private JPAAnyType anyType;
-
-    @Lob
-    private String template;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public SyncTask getSyncTask() {
-        return syncTask;
-    }
-
-    @Override
-    public void setSyncTask(final SyncTask syncTask) {
-        checkType(syncTask, JPASyncTask.class);
-        this.syncTask = (JPASyncTask) syncTask;
-    }
-
-    @Override
-    public AnyType getAnyType() {
-        return anyType;
-    }
-
-    @Override
-    public void setAnyType(final AnyType anyType) {
-        checkType(anyType, JPAAnyType.class);
-        this.anyType = (JPAAnyType) anyType;
-    }
-
-    @Override
-    public AnyTO get() {
-        return template == null
-                ? anyType == null
-                        ? null
-                        : new JPAAnyUtilsFactory().getInstance(anyType.getKind()).newAnyTO()
-                : anyType == null
-                        ? null
-                        : POJOHelper.deserialize(template, anyType.getKind().getToClass());
-    }
-
-    @Override
-    public void set(final AnyTO template) {
-        if (template == null) {
-            this.template = null;
-        } else {
-            this.template = POJOHelper.serialize(template);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java
new file mode 100644
index 0000000..3b23342
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java
@@ -0,0 +1,61 @@
+/*
+ * 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.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+
+@Entity
+@Table(name = JPAAnyTemplateSyncTask.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "syncTask_id", "anyType_name" }))
+public class JPAAnyTemplateSyncTask extends AbstractAnyTemplate implements AnyTemplateSyncTask {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyTemplateSyncTask";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPASyncTask syncTask;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public SyncTask getSyncTask() {
+        return syncTask;
+    }
+
+    @Override
+    public void setSyncTask(final SyncTask syncTask) {
+        checkType(syncTask, JPASyncTask.class);
+        this.syncTask = (JPASyncTask) syncTask;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index f2da581..8cc8b05 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -41,7 +41,8 @@ import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
 
 @Entity
@@ -61,7 +62,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     private Set<String> actionsClassNames = new HashSet<>();
 
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask")
-    private List<JPAAnyTemplate> templates = new ArrayList<>();
+    private List<JPAAnyTemplateSyncTask> templates = new ArrayList<>();
 
     @Basic
     @Min(0)
@@ -102,19 +103,19 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public boolean add(final AnyTemplate template) {
-        checkType(template, JPAAnyTemplate.class);
-        return this.templates.add((JPAAnyTemplate) template);
+    public boolean add(final AnyTemplateSyncTask template) {
+        checkType(template, JPAAnyTemplateSyncTask.class);
+        return this.templates.add((JPAAnyTemplateSyncTask) template);
     }
 
     @Override
-    public boolean remove(final AnyTemplate template) {
-        checkType(template, JPAAnyTemplate.class);
-        return this.templates.remove((JPAAnyTemplate) template);
+    public boolean remove(final AnyTemplateSyncTask template) {
+        checkType(template, JPAAnyTemplateSyncTask.class);
+        return this.templates.remove((JPAAnyTemplateSyncTask) template);
     }
 
     @Override
-    public AnyTemplate getTemplate(final AnyType anyType) {
+    public AnyTemplateSyncTask getTemplate(final AnyType anyType) {
         return CollectionUtils.find(templates, new Predicate<AnyTemplate>() {
 
             @Override
@@ -125,7 +126,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public List<? extends AnyTemplate> getTemplates() {
+    public List<? extends AnyTemplateSyncTask> getTemplates() {
         return templates;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
index 3c64499..e397bce 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -47,7 +47,7 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
 
                 context.disableDefaultConstraintViolation();
                 context.buildConstraintViolationWithTemplate(
-                        getTemplate(EntityViolationType.InvalidSyncTask, "Resource cannot be null")).
+                        getTemplate(EntityViolationType.InvalidProvisioningTask, "Resource cannot be null")).
                         addPropertyNode("resource").addConstraintViolation();
             }
 
@@ -63,7 +63,8 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
                                         ? PushActions.class.isAssignableFrom(actionsClass)
                                         : false;
                     } catch (Exception e) {
-                        LOG.error("Invalid SyncActions specified", e);
+                        LOG.error("Invalid {} / {} specified",
+                                PushActions.class.getName(), SyncActions.class.getName(), e);
                         isValid = false;
                     }
 
@@ -72,7 +73,7 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
 
                         context.disableDefaultConstraintViolation();
                         context.buildConstraintViolationWithTemplate(
-                                getTemplate(EntityViolationType.InvalidSyncTask, "Invalid class name")).
+                                getTemplate(EntityViolationType.InvalidProvisioningTask, "Invalid class name")).
                                 addPropertyNode("actionsClassName").addConstraintViolation();
                     }
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RealmValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RealmValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RealmValidator.java
index 76bdb2b..1f27cd8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RealmValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RealmValidator.java
@@ -23,19 +23,20 @@ import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.provisioning.api.LogicActions;
 
 public class RealmValidator extends AbstractValidator<RealmCheck, Realm> {
 
-    private static final Pattern NAME_PATTERN = Pattern.compile("^[A-Za-z0-9]+");
+    private static final Pattern REALM_NAME_PATTERN = Pattern.compile("^[A-Za-z0-9]+");
 
     @Override
-    public boolean isValid(final Realm object, final ConstraintValidatorContext context) {
+    public boolean isValid(final Realm realm, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
 
         boolean isValid = true;
 
-        if (SyncopeConstants.ROOT_REALM.equals(object.getName())) {
-            if (object.getParent() != null) {
+        if (SyncopeConstants.ROOT_REALM.equals(realm.getName())) {
+            if (realm.getParent() != null) {
                 isValid = false;
 
                 context.buildConstraintViolationWithTemplate(
@@ -44,7 +45,7 @@ public class RealmValidator extends AbstractValidator<RealmCheck, Realm> {
                         addPropertyNode("parent").addConstraintViolation();
             }
         } else {
-            if (object.getParent() == null) {
+            if (realm.getParent() == null) {
                 isValid = false;
 
                 context.buildConstraintViolationWithTemplate(
@@ -53,7 +54,7 @@ public class RealmValidator extends AbstractValidator<RealmCheck, Realm> {
                         addPropertyNode("parent").addConstraintViolation();
             }
 
-            if (!NAME_PATTERN.matcher(object.getName()).matches()) {
+            if (!REALM_NAME_PATTERN.matcher(realm.getName()).matches()) {
                 isValid = false;
 
                 context.buildConstraintViolationWithTemplate(
@@ -63,6 +64,29 @@ public class RealmValidator extends AbstractValidator<RealmCheck, Realm> {
             }
         }
 
+        if (!realm.getActionsClassNames().isEmpty()) {
+            for (String className : realm.getActionsClassNames()) {
+                Class<?> actionsClass = null;
+                boolean isAssignable = false;
+                try {
+                    actionsClass = Class.forName(className);
+                    isAssignable = LogicActions.class.isAssignableFrom(actionsClass);
+                } catch (Exception e) {
+                    LOG.error("Invalid {} specified", LogicActions.class.getName(), e);
+                    isValid = false;
+                }
+
+                if (actionsClass == null || !isAssignable) {
+                    isValid = false;
+
+                    context.disableDefaultConstraintViolation();
+                    context.buildConstraintViolationWithTemplate(
+                            getTemplate(EntityViolationType.InvalidRealm, "Invalid class name")).
+                            addPropertyNode("actionsClassName").addConstraintViolation();
+                }
+            }
+        }
+
         return isValid;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/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 7e08ced..02c8c8b 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
@@ -362,11 +362,20 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.JPAAnyTemplateRealm">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_AnyTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_AnyTemplate" pk-column-value="SEQ_AnyTemplate" initial-value="1000"/>
+        <generated-value generator="SEQ_AnyTemplateRealm" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplateRealm" pk-column-value="SEQ_AnyTemplateRealm" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyTemplateSyncTask" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplateSyncTask" pk-column-value="SEQ_AnyTemplateSyncTask" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/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 7e08ced..02c8c8b 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
@@ -362,11 +362,20 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.JPAAnyTemplateRealm">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_AnyTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_AnyTemplate" pk-column-value="SEQ_AnyTemplate" initial-value="1000"/>
+        <generated-value generator="SEQ_AnyTemplateRealm" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplateRealm" pk-column-value="SEQ_AnyTemplateRealm" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyTemplateSyncTask" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplateSyncTask" pk-column-value="SEQ_AnyTemplateSyncTask" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/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 7be0d48..b5c54b6 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
@@ -410,11 +410,20 @@ under the License.
     </attributes>
   </entity>
   
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.JPAAnyTemplateRealm">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_AnyTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_AnyTemplate" pk-column-value="SEQ_AnyTemplate" initial-value="1000"/>
+        <generated-value generator="SEQ_AnyTemplateRealm" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplateRealm" pk-column-value="SEQ_AnyTemplateRealm" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyTemplateSyncTask" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplateSyncTask" pk-column-value="SEQ_AnyTemplateSyncTask" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
index 03ff4c6..e2b1c9e 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -45,7 +45,8 @@ 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;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
@@ -208,7 +209,7 @@ public class TaskTest extends AbstractTest {
         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
         assertNotNull(resource);
 
-        AnyTemplate template = entityFactory.newEntity(AnyTemplate.class);
+        AnyTemplateSyncTask template = entityFactory.newEntity(AnyTemplateSyncTask.class);
         template.set(new UserTO());
 
         SyncTask task = entityFactory.newEntity(SyncTask.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/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 3401bb7..a17002b 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -997,10 +997,10 @@ under the License.
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
         unmatchingRule="ASSIGN" matchingRule="UPDATE"/>
-  <AnyTemplate id="41" syncTask_id="4" anyType_name="USER"
-               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"relationships":[],"memberships":[{"leftType":null,"leftKey":0,"rightType":"GROUP","rightKey":8,"groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}]}'/>
-  <AnyTemplate id="42" syncTask_id="4" anyType_name="GROUP"
-               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
+  <AnyTemplateSyncTask id="41" syncTask_id="4" anyType_name="USER"
+                       template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"relationships":[],"memberships":[{"leftType":null,"leftKey":0,"rightType":"GROUP","rightKey":8,"groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}]}'/>
+  <AnyTemplateSyncTask id="42" syncTask_id="4" anyType_name="GROUP"
+                       template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
   <Task DTYPE="SchedTask" type="SCHEDULED" id="5" name="SampleJob Task" 
         jobDelegateClassName="org.apache.syncope.fit.core.reference.TestSampleJobDelegate" cronExpression="0 0 0 1 * ?"/>
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="6" propagationMode="TWO_PHASES" propagationOperation="UPDATE"
@@ -1010,10 +1010,10 @@ under the License.
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="7" name="TestDB Task" resource_name="resource-testdb"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
-  <AnyTemplate id="71" syncTask_id="7" anyType_name="USER"
-               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"relationships":[],"memberships":[],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["&apos;type a&apos;"]},{"schema":"userId","readonly":false,"values":["&apos;reconciled@syncope.apache.org&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;reconciled fullname&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;surname&apos;"]}]}'/>
-  <AnyTemplate id="72" syncTask_id="7" anyType_name="GROUP"
-               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
+  <AnyTemplateSyncTask id="71" syncTask_id="7" anyType_name="USER"
+                       template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"relationships":[],"memberships":[],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["&apos;type a&apos;"]},{"schema":"userId","readonly":false,"values":["&apos;reconciled@syncope.apache.org&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;reconciled fullname&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;surname&apos;"]}]}'/>
+  <AnyTemplateSyncTask id="72" syncTask_id="7" anyType_name="GROUP"
+                       template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
   <Task DTYPE="NotificationTask" type="NOTIFICATION" id="8" sender="admin@prova.org" subject="Notification for SYNCOPE-81" 
         textBody="NOTIFICATION-81" htmlBody="NOTIFICATION-81" traceLevel="ALL"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="9" name="TestDB2 Task" resource_name="resource-testdb2"
@@ -1025,10 +1025,10 @@ under the License.
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="11" name="LDAP Sync Task" resource_name="resource-ldap"
         destinationRealm_id="1" fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
-  <AnyTemplate id="1" syncTask_id="11" anyType_name="USER"
-               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":true,"values":[""]}],"resources":["resource-ldap"],"propagationStatuses":[],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[]}'/>
-  <AnyTemplate id="2" syncTask_id="11" anyType_name="GROUP"
-               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/>
+  <AnyTemplateSyncTask id="1" syncTask_id="11" anyType_name="USER"
+                       template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":true,"values":[""]}],"resources":["resource-ldap"],"propagationStatuses":[],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[]}'/>
+  <AnyTemplateSyncTask id="2" syncTask_id="11" anyType_name="GROUP"
+                       template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/>
   <SyncTask_actionsClassNames SyncTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="12" name="VirAttrCache test" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" fullReconciliation="1"
@@ -1092,10 +1092,10 @@ under the License.
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="24" name="CSV Task (update matching; provision unmatching)" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
-  <AnyTemplate id="3" syncTask_id="24" anyType_name="USER"
-               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[{"schema":"firstname","readonly":false,"values":[""]},{"schema":"userId","readonly":false,"values":["&apos;test&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;test&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;test&apos;"]}]}'/>
-  <AnyTemplate id="4" syncTask_id="24" anyType_name="GROUP"
-               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
+  <AnyTemplateSyncTask id="3" syncTask_id="24" anyType_name="USER"
+                       template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[{"schema":"firstname","readonly":false,"values":[""]},{"schema":"userId","readonly":false,"values":["&apos;test&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;test&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;test&apos;"]}]}'/>
+  <AnyTemplateSyncTask id="4" syncTask_id="24" anyType_name="GROUP"
+                       template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="25" name="CSV (unlink matching; ignore unmatching)" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
         unmatchingRule="IGNORE" matchingRule="UNLINK"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java
deleted file mode 100644
index d6ff876..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java
+++ /dev/null
@@ -1,33 +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.provisioning.api;
-
-import org.apache.syncope.common.lib.mod.AnyMod;
-import org.apache.syncope.common.lib.to.AnyTO;
-
-/**
- * Provides logic for transforming any object, received as input by RESTful methods, before any internal
- * processing logic takes place.
- */
-public interface AnyTransformer {
-
-    <T extends AnyTO> T transform(T input);
-
-    <T extends AnyMod> T transform(T input);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java
new file mode 100644
index 0000000..01464a7
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java
@@ -0,0 +1,40 @@
+/*
+ * 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.provisioning.api;
+
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+
+/**
+ * Interface for actions to be performed during business logic execution.
+ */
+public interface LogicActions {
+
+    <A extends AnyTO> A beforeCreate(A input);
+
+    <A extends AnyTO> A afterCreate(A input);
+
+    <M extends AnyMod> M beforeUpdate(M input);
+
+    <A extends AnyTO> A afterUpdate(A input);
+
+    <A extends AnyTO> A beforeDelete(A input);
+
+    <A extends AnyTO> A afterDelete(A input);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
index e5ce13b..8f34331 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
@@ -22,7 +22,7 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.quartz.JobExecutionException;
 
 /**
- * Interface for actions to be performed during PushJob execution.
+ * Interface for actions to be performed during push.
  * <br/>
  * All methods can throw {@link IgnoreProvisionException} to make the current any ignored by the push process.
  */
@@ -31,124 +31,134 @@ public interface PushActions extends ProvisioningActions {
     /**
      * Action to be executed before to assign (link & provision) a synchronized any object to the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeAssign(
+    <A extends Any<?, ?, ?>> A beforeAssign(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to provision a synchronized any object to the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeProvision(
+    <A extends Any<?, ?, ?>> A beforeProvision(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to update a synchronized any object on the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be updated.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeUpdate(
+    <A extends Any<?, ?, ?>> A beforeUpdate(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to link a synchronized any object to the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeLink(
+    <A extends Any<?, ?, ?>> A beforeLink(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to unlink a synchronized any object from the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeUnlink(
+    <A extends Any<?, ?, ?>> A beforeUnlink(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to unassign a synchronized any object from the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeUnassign(
+    <A extends Any<?, ?, ?>> A beforeUnassign(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to unassign a synchronized any object from the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeDeprovision(
+    <A extends Any<?, ?, ?>> A beforeDeprovision(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before delete a synchronized any object locally and from the resource.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any any object to be created.
      * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> T beforeDelete(
+    <A extends Any<?, ?, ?>> A beforeDelete(
             ProvisioningProfile<?, ?> profile,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed after any object push goes on error.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any synchronized any object.
      * @param result operation result.
      * @param error error being reported
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> void onError(
+    <A extends Any<?, ?, ?>> void onError(
             ProvisioningProfile<?, ?> profile,
-            T any,
+            A any,
             ProvisioningResult result,
             Exception error) throws JobExecutionException;
 
     /**
      * Action to be executed after each local any object push.
      *
+     * @param <A> concrete any object
      * @param profile profile of the push being executed.
      * @param any synchronized any object.
      * @param result operation result.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Any<?, ?, ?>> void after(
+    <A extends Any<?, ?, ?>> void after(
             ProvisioningProfile<?, ?> profile,
-            T any,
+            A any,
             ProvisioningResult result) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
index 82dd9d4..6638c42 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
@@ -24,7 +24,7 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.quartz.JobExecutionException;
 
 /**
- * Interface for actions to be performed during SyncJob execution.
+ * Interface for actions to be performed during synchronization.
  * <br/>
  * All methods can throw {@link IgnoreProvisionException} to make the current any object ignored by the synchronization
  * process.
@@ -36,102 +36,110 @@ public interface SyncActions extends ProvisioningActions {
      * User/group is created locally upon synchronization in case of the un-matching rule
      * {@link org.apache.syncope.common.types.UnmatchingRule#PROVISION} (default un-matching rule) is applied.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeProvision(
+    <A extends AnyTO> SyncDelta beforeProvision(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before creating (and linking to the resource) a synchronized user / group locally.
      * User/group is created locally and linked to the synchronized resource upon synchronization in case of the
      * un-matching rule {@link org.apache.syncope.common.types.UnmatchingRule#ASSIGN} is applied.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeAssign(
+    <A extends AnyTO> SyncDelta beforeAssign(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before unlinking resource from the synchronized user / group and de-provisioning.
      * User/group is unlinked and de-provisioned from the synchronized resource upon synchronization in case of the
      * matching rule {@link org.apache.syncope.common.types.MatchingRule#UNASSIGN} is applied.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeUnassign(
+    <A extends AnyTO> SyncDelta beforeUnassign(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before de-provisioning action only.
      * User/group is de-provisioned (without unlinking) from the synchronized resource upon synchronization in case of
      * the matching rule {@link org.apache.syncope.common.types.MatchingRule#DEPROVISION} is applied.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeDeprovision(
+    <A extends AnyTO> SyncDelta beforeDeprovision(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before unlinking resource from the synchronized user / group.
      * User/group is unlinked (without de-provisioning) from the synchronized resource upon synchronization in case of
      * the matching rule {@link org.apache.syncope.common.types.MatchingRule#UNLINK} is applied.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeUnlink(
+    <A extends AnyTO> SyncDelta beforeUnlink(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before linking resource to the synchronized user / group.
      * User/group is linked (without updating) to the synchronized resource upon synchronization in case of
      * the matching rule {@link org.apache.syncope.common.types.MatchingRule#LINK} is applied.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeLink(
+    <A extends AnyTO> SyncDelta beforeLink(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed before to update a synchronized user / group locally.
      * User/group is updated upon synchronization in case of the matching rule
      * {@link org.apache.syncope.common.types.MatchingRule#UPDATE} (default matching rule) is applied.
      *
+     * @param <M> concrete any object
+     * @param <A> any object modifications
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object
@@ -139,26 +147,27 @@ public interface SyncActions extends ProvisioningActions {
      * @return synchronization information used for logging and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure.
      */
-    <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
+    <M extends AnyTO, A extends AnyMod> SyncDelta beforeUpdate(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any,
-            K anyMod)
+            M any,
+            A anyMod)
             throws JobExecutionException;
 
     /**
      * Action to be executed before to delete a synchronized user / group locally.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
      * @param any any object to be deleted
      * @return synchronization information used for logging and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> SyncDelta beforeDelete(
+    <A extends AnyTO> SyncDelta beforeDelete(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any) throws JobExecutionException;
+            A any) throws JobExecutionException;
 
     /**
      * Action to be executed when user / group synchronization goes on error.
@@ -179,16 +188,17 @@ public interface SyncActions extends ProvisioningActions {
     /**
      * Action to be executed after each local user / group synchronization.
      *
+     * @param <A> concrete any object
      * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information (may be modified by
-     * 'beforeProvision/beforeUpdate/beforeDelete')
+     * @param delta retrieved synchronization information (may be modified by beforeProvision / beforeUpdate /
+     * beforeDelete)
      * @param any any object
      * @param result global synchronization results at the current synchronization step
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AnyTO> void after(
+    <A extends AnyTO> void after(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T any,
+            A any,
             ProvisioningResult result) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java
deleted file mode 100644
index f7f6bfb..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java
+++ /dev/null
@@ -1,40 +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.provisioning.java;
-
-import org.apache.syncope.common.lib.mod.AnyMod;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.provisioning.api.AnyTransformer;
-
-/**
- * Default empty implementation returning received input as result.
- */
-public class DefaultAnyTransformer implements AnyTransformer {
-
-    @Override
-    public <T extends AnyTO> T transform(final T input) {
-        return input;
-    }
-
-    @Override
-    public <T extends AnyMod> T transform(final T input) {
-        return input;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultLogicActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultLogicActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultLogicActions.java
new file mode 100644
index 0000000..a7ddf71
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultLogicActions.java
@@ -0,0 +1,57 @@
+/*
+ * 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.provisioning.java;
+
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.provisioning.api.LogicActions;
+
+public class DefaultLogicActions implements LogicActions {
+
+    @Override
+    public <A extends AnyTO> A beforeCreate(final A input) {
+        return input;
+    }
+
+    @Override
+    public <A extends AnyTO> A afterCreate(final A input) {
+        return input;
+    }
+
+    @Override
+    public <M extends AnyMod> M beforeUpdate(final M input) {
+        return input;
+    }
+
+    @Override
+    public <A extends AnyTO> A afterUpdate(final A input) {
+        return input;
+    }
+
+    @Override
+    public <A extends AnyTO> A beforeDelete(final A input) {
+        return input;
+    }
+
+    @Override
+    public <A extends AnyTO> A afterDelete(final A input) {
+        return input;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 08c7e1d..433b909 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -129,9 +129,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
             AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
 
             if (otherEnd == null) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
-                }
+                LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
             } else {
                 ARelationship relationship = null;
                 if (anyObject.getKey() != null) {
@@ -152,9 +150,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
             Group group = groupDAO.find(membershipTO.getRightKey());
 
             if (group == null) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
-                }
+                LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
             } else {
                 AMembership membership = null;
                 if (anyObject.getKey() != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/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 b40cc88..909b05d 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
@@ -81,7 +81,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
             group.setName(groupTO.getName());
         }
 
-        // attributes, derived attributes, virtual attributes and resources
+        // realm, attributes, derived attributes, virtual attributes and resources
         fill(group, groupTO, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce);
 
         // owner

http://git-wip-us.apache.org/repos/asf/syncope/blob/00988759/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
index d9a2838..af7f0a0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
@@ -18,20 +18,37 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.misc.TemplateUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.provisioning.api.data.RealmDataBinder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class RealmDataBinderImpl implements RealmDataBinder {
 
+    private static final Logger LOG = LoggerFactory.getLogger(RealmDataBinder.class);
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Autowired
     private RealmDAO realmDAO;
 
@@ -41,6 +58,38 @@ public class RealmDataBinderImpl implements RealmDataBinder {
     @Autowired
     private EntityFactory entityFactory;
 
+    @Autowired
+    private TemplateUtils templateUtils;
+
+    private void setTemplates(final RealmTO realmTO, final Realm realm) {
+        // validate JEXL expressions from templates and proceed if fine
+        templateUtils.check(realmTO.getTemplates(), ClientExceptionType.InvalidSyncTask);
+        for (Map.Entry<String, AnyTO> entry : realmTO.getTemplates().entrySet()) {
+            AnyType type = anyTypeDAO.find(entry.getKey());
+            if (type == null) {
+                LOG.debug("Invalid AnyType {} specified, ignoring...", entry.getKey());
+            } else {
+                AnyTemplateRealm anyTemplate = realm.getTemplate(type);
+                if (anyTemplate == null) {
+                    anyTemplate = entityFactory.newEntity(AnyTemplateRealm.class);
+                    anyTemplate.setAnyType(type);
+                    anyTemplate.setRealm(realm);
+
+                    realm.add(anyTemplate);
+                }
+                anyTemplate.set(entry.getValue());
+            }
+        }
+        // remove all templates not contained in the TO
+        CollectionUtils.filter(realm.getTemplates(), new Predicate<AnyTemplate>() {
+
+            @Override
+            public boolean evaluate(final AnyTemplate anyTemplate) {
+                return realmTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey());
+            }
+        });
+    }
+
     @Override
     public Realm create(final String parentPath, final RealmTO realmTO) {
         Realm realm = entityFactory.newEntity(Realm.class);
@@ -55,6 +104,10 @@ public class RealmDataBinderImpl implements RealmDataBinder {
             realm.setAccountPolicy((AccountPolicy) policyDAO.find(realmTO.getAccountPolicy()));
         }
 
+        realm.getActionsClassNames().addAll(realmTO.getActionsClassNames());
+
+        setTemplates(realmTO, realm);
+
         return realm;
     }
 
@@ -69,6 +122,11 @@ public class RealmDataBinderImpl implements RealmDataBinder {
         if (realmTO.getAccountPolicy() != null) {
             realm.setAccountPolicy((AccountPolicy) policyDAO.find(realmTO.getAccountPolicy()));
         }
+
+        realm.getActionsClassNames().clear();
+        realm.getActionsClassNames().addAll(realmTO.getActionsClassNames());
+
+        setTemplates(realmTO, realm);
     }
 
     @Override
@@ -81,6 +139,11 @@ public class RealmDataBinderImpl implements RealmDataBinder {
         realmTO.setFullPath(realm.getFullPath());
         realmTO.setAccountPolicy(realm.getAccountPolicy() == null ? null : realm.getAccountPolicy().getKey());
         realmTO.setPasswordPolicy(realm.getPasswordPolicy() == null ? null : realm.getPasswordPolicy().getKey());
+        realmTO.getActionsClassNames().addAll(realm.getActionsClassNames());
+
+        for (AnyTemplate template : realm.getTemplates()) {
+            realmTO.getTemplates().put(template.getAnyType().getKey(), template.get());
+        }
 
         return realmTO;
     }


Mime
View raw message