syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmarte...@apache.org
Subject svn commit: r1607399 - in /syncope/trunk/core/src: main/java/org/apache/syncope/core/persistence/beans/ main/java/org/apache/syncope/core/propagation/ main/java/org/apache/syncope/core/propagation/impl/ main/java/org/apache/syncope/core/rest/data/ main...
Date Wed, 02 Jul 2014 15:30:14 GMT
Author: fmartelli
Date: Wed Jul  2 15:30:13 2014
New Revision: 1607399

URL: http://svn.apache.org/r1607399
Log:
[SYNCOPE-471] fixed providing some improvement and integration tests for matching/unmatching rules about sync tasks

Modified:
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/PushTask.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncTask.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/DefaultPushActions.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/RolePushResultHandler.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/UserPushResultHandler.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/SyncTaskTest.java
    syncope/trunk/core/src/test/resources/content.xml

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java Wed Jul  2 15:30:13 2014
@@ -29,6 +29,7 @@ import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.types.MatchingRule;
 import org.apache.syncope.common.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.validation.entity.AbstractSyncTaskCheck;
@@ -68,12 +69,14 @@ public abstract class AbstractSyncTask e
     /**
      * @see UnmatchingRule
      */
+    @NotNull
     @Enumerated(EnumType.STRING)
     protected UnmatchingRule unmatchingRule;
 
     /**
      * @see MatchingRule
      */
+    @NotNull
     @Enumerated(EnumType.STRING)
     protected MatchingRule matchingRule;
 
@@ -130,13 +133,17 @@ public abstract class AbstractSyncTask e
         this.syncStatus = getBooleanAsInteger(syncStatus);
     }
 
-    public abstract UnmatchingRule getUnmatchingRule();
+    public UnmatchingRule getUnmatchingRule() {
+        return this.unmatchingRule;
+    }
 
     public void setUnmatchingRule(final UnmatchingRule unmatchigRule) {
         this.unmatchingRule = unmatchigRule;
     }
 
-    public abstract MatchingRule getMatchingRule();
+    public MatchingRule getMatchingRule() {
+        return this.matchingRule;
+    }
 
     public void setMatchingRule(final MatchingRule matchigRule) {
         this.matchingRule = matchigRule;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/PushTask.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/PushTask.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/PushTask.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/PushTask.java Wed Jul  2 15:30:13 2014
@@ -19,8 +19,6 @@
 package org.apache.syncope.core.persistence.beans;
 
 import javax.persistence.Entity;
-import org.apache.syncope.common.types.MatchingRule;
-import org.apache.syncope.common.types.UnmatchingRule;
 import org.apache.syncope.core.sync.impl.PushJob;
 
 @Entity
@@ -28,10 +26,6 @@ public class PushTask extends AbstractSy
 
     private static final long serialVersionUID = -4141057723006682564L;
 
-    private static final UnmatchingRule DEF_UNMATCHIG_RULE = UnmatchingRule.ASSIGN;
-
-    private static final MatchingRule DEF_MATCHIG_RULE = MatchingRule.UPDATE;
-
     private String userFilter;
 
     private String roleFilter;
@@ -58,14 +52,4 @@ public class PushTask extends AbstractSy
     public void setRoleFilter(final String roleFilter) {
         this.roleFilter = roleFilter;
     }
-
-    @Override
-    public UnmatchingRule getUnmatchingRule() {
-        return this.unmatchingRule == null ? DEF_UNMATCHIG_RULE : unmatchingRule;
-    }
-
-    @Override
-    public MatchingRule getMatchingRule() {
-        return this.matchingRule == null ? DEF_MATCHIG_RULE : this.matchingRule;
-    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncTask.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncTask.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncTask.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/SyncTask.java Wed Jul  2 15:30:13 2014
@@ -25,8 +25,6 @@ import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.apache.syncope.common.to.RoleTO;
 import org.apache.syncope.common.to.UserTO;
-import org.apache.syncope.common.types.MatchingRule;
-import org.apache.syncope.common.types.UnmatchingRule;
 import org.apache.syncope.core.sync.impl.SyncJob;
 import org.apache.syncope.core.util.POJOHelper;
 
@@ -35,10 +33,6 @@ public class SyncTask extends AbstractSy
 
     private static final long serialVersionUID = -4141057723006682563L;
 
-    private static final UnmatchingRule DEF_UNMATCHIG_RULE = UnmatchingRule.PROVISION;
-
-    private static final MatchingRule DEF_MATCHIG_RULE = MatchingRule.UPDATE;
-
     @Lob
     private String userTemplate;
 
@@ -84,14 +78,4 @@ public class SyncTask extends AbstractSy
     public void setFullReconciliation(final boolean fullReconciliation) {
         this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
     }
-
-    @Override
-    public UnmatchingRule getUnmatchingRule() {
-        return this.unmatchingRule == null ? DEF_UNMATCHIG_RULE : unmatchingRule;
-    }
-
-    @Override
-    public MatchingRule getMatchingRule() {
-        return this.matchingRule == null ? DEF_MATCHIG_RULE : this.matchingRule;
-    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java Wed Jul  2 15:30:13 2014
@@ -129,9 +129,8 @@ public interface Connector {
      * @param options ConnId's OperationOptions
      * @return ConnId's connector object for given uid
      */
-    ConnectorObject getObject(PropagationMode propagationMode,
-            ResourceOperation operationType, ObjectClass objectClass, Uid uid,
-            OperationOptions options);
+    ConnectorObject getObject(PropagationMode propagationMode, ResourceOperation operationType, ObjectClass objectClass,
+            Uid uid, OperationOptions options);
 
     /**
      * Search for remote objects.

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java Wed Jul  2 15:30:13 2014
@@ -375,7 +375,7 @@ public class PropagationManager {
                 Collections.<MembershipMod>emptySet());
     }
 
-    protected List<PropagationTask> getUpdateTaskIds(final AbstractSubject subject,
+    public List<PropagationTask> getUpdateTaskIds(final AbstractSubject subject,
             final String password, final boolean changePwd, final Boolean enable,
             final Set<String> vAttrsToBeRemoved, final Set<AttributeMod> vAttrsToBeUpdated,
             final PropagationByResource propByRes, final Collection<String> noPropResourceNames,

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java Wed Jul  2 15:30:13 2014
@@ -35,6 +35,8 @@ import org.apache.syncope.common.util.Be
 import org.apache.syncope.common.SyncopeClientException;
 import org.apache.syncope.common.to.AbstractSyncTaskTO;
 import org.apache.syncope.common.to.PushTaskTO;
+import org.apache.syncope.common.types.MatchingRule;
+import org.apache.syncope.common.types.UnmatchingRule;
 import org.apache.syncope.core.init.JobInstanceLoader;
 import org.apache.syncope.core.persistence.beans.AbstractSyncTask;
 import org.apache.syncope.core.persistence.beans.ExternalResource;
@@ -68,7 +70,8 @@ public class TaskDataBinder {
      */
     private static final Logger LOG = LoggerFactory.getLogger(TaskDataBinder.class);
 
-    private static final String[] IGNORE_TASK_PROPERTIES = { "executions", "resource" };
+    private static final String[] IGNORE_TASK_PROPERTIES = {
+        "executions", "resource", "matchingRule", "unmatchingRule" };
 
     private static final String[] IGNORE_TASK_EXECUTION_PROPERTIES = { "id", "task" };
 
@@ -105,10 +108,22 @@ public class TaskDataBinder {
             pushTask.setUserFilter(pushTaskTO.getUserFilter());
             pushTask.setRoleFilter(pushTaskTO.getRoleFilter());
 
+            pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
+                    ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
+
+            pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
+                    ? UnmatchingRule.ASSIGN : pushTaskTO.getUnmatchingRule());
+
         } else if (task instanceof SyncTask && taskTO instanceof SyncTaskTO) {
             final SyncTask syncTask = (SyncTask) task;
             final SyncTaskTO syncTaskTO = (SyncTaskTO) taskTO;
 
+            syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
+                    ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
+
+            syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
+                    ? UnmatchingRule.PROVISION : syncTaskTO.getUnmatchingRule());
+
             // 1. validate JEXL expressions in user and role templates
             if (syncTaskTO.getUserTemplate() != null) {
                 UserTO template = syncTaskTO.getUserTemplate();
@@ -155,8 +170,6 @@ public class TaskDataBinder {
         task.setPerformUpdate(taskTO.isPerformUpdate());
         task.setPerformDelete(taskTO.isPerformDelete());
         task.setSyncStatus(taskTO.isSyncStatus());
-        task.setMatchingRule(taskTO.getMatchingRule());
-        task.setUnmatchingRule(taskTO.getUnmatchingRule());
         task.getActionsClassNames().clear();
         task.getActionsClassNames().addAll(taskTO.getActionsClassNames());
     }
@@ -254,17 +267,9 @@ public class TaskDataBinder {
         BeanUtils.copyProperties(task, taskTO, IGNORE_TASK_PROPERTIES);
 
         TaskExec latestExec = taskExecDAO.findLatestStarted(task);
-        taskTO.setLatestExecStatus(latestExec == null
-                ? ""
-                : latestExec.getStatus());
-
-        taskTO.setStartDate(latestExec == null
-                ? null
-                : latestExec.getStartDate());
-
-        taskTO.setEndDate(latestExec == null
-                ? null
-                : latestExec.getEndDate());
+        taskTO.setLatestExecStatus(latestExec == null ? "" : latestExec.getStatus());
+        taskTO.setStartDate(latestExec == null ? null : latestExec.getStartDate());
+        taskTO.setEndDate(latestExec == null ? null : latestExec.getEndDate());
 
         for (TaskExec execution : task.getExecs()) {
             taskTO.getExecutions().add(getTaskExecTO(execution));
@@ -298,6 +303,10 @@ public class TaskDataBinder {
                 ((SyncTaskTO) taskTO).setName(((SyncTask) task).getName());
                 ((SyncTaskTO) taskTO).setDescription(((SyncTask) task).getDescription());
                 ((SyncTaskTO) taskTO).setResource(((SyncTask) task).getResource().getName());
+                ((SyncTaskTO) taskTO).setMatchingRule(((SyncTask) task).getMatchingRule() == null
+                        ? MatchingRule.UPDATE : ((SyncTask) task).getMatchingRule());
+                ((SyncTaskTO) taskTO).setUnmatchingRule(((SyncTask) task).getUnmatchingRule() == null
+                        ? UnmatchingRule.PROVISION : ((SyncTask) task).getUnmatchingRule());
                 break;
 
             case PUSH:
@@ -309,6 +318,10 @@ public class TaskDataBinder {
                 ((PushTaskTO) taskTO).setName(((PushTask) task).getName());
                 ((PushTaskTO) taskTO).setDescription(((PushTask) task).getDescription());
                 ((PushTaskTO) taskTO).setResource(((PushTask) task).getResource().getName());
+                ((PushTaskTO) taskTO).setMatchingRule(((PushTask) task).getMatchingRule() == null
+                        ? MatchingRule.LINK : ((PushTask) task).getMatchingRule());
+                ((PushTaskTO) taskTO).setUnmatchingRule(((PushTask) task).getUnmatchingRule() == null
+                        ? UnmatchingRule.ASSIGN : ((PushTask) task).getUnmatchingRule());
                 break;
 
             case NOTIFICATION:

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/DefaultPushActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/DefaultPushActions.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/DefaultPushActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/DefaultPushActions.java Wed Jul  2 15:30:13 2014
@@ -19,11 +19,8 @@
 package org.apache.syncope.core.sync;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
-import org.identityconnectors.framework.common.objects.Attribute;
 import org.quartz.JobExecutionException;
 
 /**
@@ -36,76 +33,66 @@ public abstract class DefaultPushActions
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeAssign(
+    public <T extends AbstractAttributable> T beforeAssign(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUpdate(
+    public <T extends AbstractAttributable> T beforeUpdate(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> void after(
+    public <T extends AbstractAttributable> T beforeProvision(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
-            final T subject,
-            SyncResult result) throws JobExecutionException {
+            final T subject) throws JobExecutionException {
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeProvision(
+    public <T extends AbstractAttributable> T beforeLink(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeLink(
+    public <T extends AbstractAttributable> T beforeUnlink(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUnlink(
+    public <T extends AbstractAttributable> T beforeUnassign(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUnassign(
+    public <T extends AbstractAttributable> T beforeDeprovision(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeDeprovision(
+    public <T extends AbstractAttributable> T beforeDelete(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException {
-        return delta;
+        return subject;
     }
 
     @Override
-    public <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeDelete(
+    public <T extends AbstractAttributable> void after(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
-            final T subject) throws JobExecutionException {
-        return delta;
+            final T subject,
+            SyncResult result) throws JobExecutionException {
     }
 
     @Override

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java Wed Jul  2 15:30:13 2014
@@ -34,126 +34,108 @@ public interface PushActions extends Abs
      * Action to be executed before to assign (link & provision) a synchronized user / role to the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeAssign(
+    <T extends AbstractAttributable> T beforeAssign(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to provision a synchronized user / role to the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeProvision(
+    <T extends AbstractAttributable> T beforeProvision(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to update a synchronized user / role on the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be updated.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUpdate(
+    <T extends AbstractAttributable> T beforeUpdate(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to link a synchronized user / role to the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeLink(
+    <T extends AbstractAttributable> T beforeLink(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to unlink a synchronized user / role from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUnlink(
+    <T extends AbstractAttributable> T beforeUnlink(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to unassign a synchronized user / role from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeUnassign(
+    <T extends AbstractAttributable> T beforeUnassign(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to unassign a synchronized user / role from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeDeprovision(
+    <T extends AbstractAttributable> T beforeDeprovision(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before delete a synchronized user / role locally and from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info to be pushed out (accountId, attributes).
      * @param subject user / role to be created.
-     * @return info to be pushed out (accountId, attributes).
+     * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractAttributable> Map.Entry<String, Set<Attribute>> beforeDelete(
+    <T extends AbstractAttributable> T beforeDelete(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject) throws JobExecutionException;
 
     /**
      * Action to be executed after each local user / role synchronization.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta info pushed out (accountId, attributes)
      * @param subject synchronized user / role.
      * @param result operation result.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributable> void after(
             final SyncProfile<?, ?> profile,
-            final Map.Entry<String, Set<Attribute>> delta,
             final T subject,
             final SyncResult result) throws JobExecutionException;
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java Wed Jul  2 15:30:13 2014
@@ -18,25 +18,34 @@
  */
 package org.apache.syncope.core.sync.impl;
 
+import static org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler.LOG;
 import java.util.ArrayList;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.mod.AttributeMod;
+import org.apache.syncope.common.mod.MembershipMod;
 import org.apache.syncope.common.to.AbstractSubjectTO;
 import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.common.types.AuditElements;
 import org.apache.syncope.common.types.AuditElements.Result;
+import org.apache.syncope.common.types.IntMappingType;
 import org.apache.syncope.common.types.MatchingRule;
 import org.apache.syncope.common.types.ResourceOperation;
 import org.apache.syncope.common.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.beans.AbstractMapping;
+import org.apache.syncope.core.persistence.beans.AbstractMappingItem;
 import org.apache.syncope.core.persistence.beans.AbstractSubject;
+import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
 import org.apache.syncope.core.persistence.beans.PushTask;
+import org.apache.syncope.core.persistence.beans.membership.Membership;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.sync.PushActions;
 import org.apache.syncope.core.sync.SyncResult;
 import org.apache.syncope.core.util.AttributableUtil;
 import org.apache.syncope.core.util.MappingUtil;
-import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.quartz.JobExecutionException;
 import org.springframework.transaction.annotation.Transactional;
@@ -45,27 +54,21 @@ public abstract class AbstractSubjectPus
 
     protected abstract String getName(final AbstractSubject subject);
 
+    protected abstract AbstractMapping getMapping();
+
     protected abstract AbstractSubjectTO getSubjectTO(final long id);
 
     protected abstract AbstractSubject getSubject(final long id);
 
-    protected abstract AbstractSubject deprovision(final AbstractSubject sbj, final SyncResult result);
-
-    protected abstract AbstractSubject provision(
-            final AbstractSubject sbj, final Boolean enabled, final SyncResult result);
+    protected abstract AbstractSubject deprovision(final AbstractSubject sbj);
 
-    protected abstract AbstractSubject link(final AbstractSubject sbj, final Boolean unlink, final SyncResult result);
+    protected abstract AbstractSubject provision(final AbstractSubject sbj, final Boolean enabled);
 
-    protected abstract AbstractSubject unassign(final AbstractSubject sbj, final SyncResult result);
+    protected abstract AbstractSubject link(final AbstractSubject sbj, final Boolean unlink);
 
-    protected abstract AbstractSubject assign(final AbstractSubject sbj, Boolean enabled, final SyncResult result);
+    protected abstract AbstractSubject unassign(final AbstractSubject sbj);
 
-    protected abstract AbstractSubject update(
-            final AbstractSubject sbj,
-            final String accountId,
-            final Set<Attribute> attributes,
-            final ConnectorObject beforeObj,
-            final SyncResult result);
+    protected abstract AbstractSubject assign(final AbstractSubject sbj, Boolean enabled);
 
     protected abstract ConnectorObject getRemoteObject(final String accountId);
 
@@ -110,20 +113,14 @@ public abstract class AbstractSubjectPus
         ConnectorObject beforeObj = null;
         String operation = null;
 
-        Map.Entry<String, Set<Attribute>> values = MappingUtil.prepareAttributes(
-                attrUtil, // attributable util
-                toBeHandled, // attributable (user or role)
-                null, // current password if decode is possible; generate otherwise
-                true, // propagate password (if required)
-                null, // no vir attrs to be removed
-                null, // propagate current vir attr values
-                null, // no membership vir attrs to be removed
-                null, // propagate current membership vir attr values
-                enabled, // propagate status (suspended or not) if required
-                profile.getSyncTask().getResource()); // target external resource
-
         // Try to read remote object (user / group) BEFORE any actual operation
-        beforeObj = getRemoteObject(values.getKey());
+
+        final String accountId = MappingUtil.getAccountIdValue(
+                subject, profile.getSyncTask().getResource(), getMapping().getAccountIdItem());
+
+        beforeObj = getRemoteObject(accountId);
+
+        Boolean status = profile.getSyncTask().isSyncStatus() ? enabled : null;
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
@@ -141,21 +138,39 @@ public abstract class AbstractSubjectPus
                     switch (profile.getSyncTask().getUnmatchingRule()) {
                         case ASSIGN:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeAssign(this.getProfile(), values, toBeHandled);
+                                action.beforeAssign(this.getProfile(), toBeHandled);
                             }
-                            assign(toBeHandled, enabled, result);
+
+                            if (!profile.getSyncTask().isPerformCreate()) {
+                                LOG.debug("PushTask not configured for create");
+                            } else {
+                                assign(toBeHandled, status);
+                            }
+
                             break;
                         case PROVISION:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeProvision(this.getProfile(), values, toBeHandled);
+                                action.beforeProvision(this.getProfile(), toBeHandled);
+                            }
+
+                            if (!profile.getSyncTask().isPerformCreate()) {
+                                LOG.debug("PushTask not configured for create");
+                            } else {
+                                provision(toBeHandled, status);
                             }
-                            provision(toBeHandled, enabled, result);
+
                             break;
                         case UNLINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), values, toBeHandled);
+                                action.beforeUnlink(this.getProfile(), toBeHandled);
                             }
-                            link(toBeHandled, true, result);
+
+                            if (!profile.getSyncTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                link(toBeHandled, true);
+                            }
+
                             break;
                         default:
                         // do nothing
@@ -168,33 +183,62 @@ public abstract class AbstractSubjectPus
                     switch (profile.getSyncTask().getMatchingRule()) {
                         case UPDATE:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUpdate(this.getProfile(), values, toBeHandled);
+                                action.beforeUpdate(this.getProfile(), toBeHandled);
+                            }
+                            if (!profile.getSyncTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                update(toBeHandled, status);
                             }
-                            update(toBeHandled, values.getKey(), values.getValue(), beforeObj, result);
+
                             break;
                         case DEPROVISION:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeDeprovision(this.getProfile(), values, toBeHandled);
+                                action.beforeDeprovision(this.getProfile(), toBeHandled);
+                            }
+
+                            if (!profile.getSyncTask().isPerformDelete()) {
+                                LOG.debug("PushTask not configured for delete");
+                            } else {
+                                deprovision(toBeHandled);
                             }
-                            deprovision(toBeHandled, result);
+
                             break;
                         case UNASSIGN:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnassign(this.getProfile(), values, toBeHandled);
+                                action.beforeUnassign(this.getProfile(), toBeHandled);
+                            }
+
+                            if (!profile.getSyncTask().isPerformDelete()) {
+                                LOG.debug("PushTask not configured for delete");
+                            } else {
+                                unassign(toBeHandled);
                             }
-                            unassign(toBeHandled, result);
+
                             break;
                         case LINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeLink(this.getProfile(), values, toBeHandled);
+                                action.beforeLink(this.getProfile(), toBeHandled);
+                            }
+
+                            if (!profile.getSyncTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                link(toBeHandled, false);
                             }
-                            link(toBeHandled, false, result);
+
                             break;
                         case UNLINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), values, toBeHandled);
+                                action.beforeUnlink(this.getProfile(), toBeHandled);
+                            }
+
+                            if (!profile.getSyncTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                link(toBeHandled, true);
                             }
-                            link(toBeHandled, true, result);
+
                             break;
                         default:
                         // do nothing
@@ -202,12 +246,12 @@ public abstract class AbstractSubjectPus
                 }
 
                 for (PushActions action : profile.getActions()) {
-                    action.after(this.getProfile(), values, toBeHandled, result);
+                    action.after(this.getProfile(), toBeHandled, result);
                 }
 
                 result.setStatus(SyncResult.Status.SUCCESS);
                 resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(values.getKey());
+                output = getRemoteObject(accountId);
             } catch (Exception e) {
                 result.setStatus(SyncResult.Status.FAILURE);
                 result.setMessage(ExceptionUtils.getRootCauseMessage(e));
@@ -260,4 +304,74 @@ public abstract class AbstractSubjectPus
                 return ResourceOperation.NONE;
         }
     }
+
+    protected AbstractSubject update(final AbstractSubject sbj, final Boolean enabled) {
+
+        final Set<MembershipMod> membsToAdd = new HashSet<MembershipMod>();
+        final Set<String> vattrToBeRemoved = new HashSet<String>();
+        final Set<String> membVattrToBeRemoved = new HashSet<String>();
+        final Set<AttributeMod> vattrToBeUpdated = new HashSet<AttributeMod>();
+
+        // Search for all mapped vattrs
+        final AbstractMapping umapping = getMapping();
+        for (AbstractMappingItem mappingItem : umapping.getItems()) {
+            if (mappingItem.getIntMappingType() == IntMappingType.UserVirtualSchema) {
+                vattrToBeRemoved.add(mappingItem.getIntAttrName());
+            } else if (mappingItem.getIntMappingType() == IntMappingType.MembershipVirtualSchema) {
+                membVattrToBeRemoved.add(mappingItem.getIntAttrName());
+            }
+        }
+
+        // Search for all user's vattrs and:
+        // 1. add mapped vattrs not owned by the user to the set of vattrs to be removed
+        // 2. add all vattrs owned by the user to the set of vattrs to be update
+        for (AbstractVirAttr vattr : sbj.getVirAttrs()) {
+            vattrToBeRemoved.remove(vattr.getSchema().getName());
+            final AttributeMod mod = new AttributeMod();
+            mod.setSchema(vattr.getSchema().getName());
+            mod.getValuesToBeAdded().addAll(vattr.getValues());
+            vattrToBeUpdated.add(mod);
+        }
+
+        final boolean changepwd;
+
+        if (sbj instanceof SyncopeUser) {
+            changepwd = true;
+
+            // Search for memberships
+            for (Membership membership : SyncopeUser.class.cast(sbj).getMemberships()) {
+                final MembershipMod membershipMod = new MembershipMod();
+                membershipMod.setId(membership.getId());
+                membershipMod.setRole(membership.getSyncopeRole().getId());
+
+                for (AbstractVirAttr vattr : membership.getVirAttrs()) {
+                    membVattrToBeRemoved.remove(vattr.getSchema().getName());
+                    final AttributeMod mod = new AttributeMod();
+                    mod.setSchema(vattr.getSchema().getName());
+                    mod.getValuesToBeAdded().addAll(vattr.getValues());
+                    membershipMod.getVirAttrsToUpdate().add(mod);
+                }
+
+                membsToAdd.add(membershipMod);
+            }
+
+            if (!membsToAdd.isEmpty()) {
+                membsToAdd.iterator().next().getVirAttrsToRemove().addAll(membVattrToBeRemoved);
+            }
+        } else {
+            changepwd = false;
+        }
+
+        final List<String> noPropResources = new ArrayList<String>(sbj.getResourceNames());
+        noPropResources.remove(profile.getSyncTask().getResource().getName());
+
+        final PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.CREATE, profile.getSyncTask().getResource().getName());
+
+        taskExecutor.execute(propagationManager.getUpdateTaskIds(
+                sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources,
+                membsToAdd));
+
+        return userDataBinder.getUserFromId(sbj.getId());
+    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java Wed Jul  2 15:30:13 2014
@@ -97,17 +97,16 @@ public abstract class AbstractSubjectSyn
 
     protected List<SyncResult> assign(final SyncDelta delta, final AttributableUtil attrUtil)
             throws JobExecutionException {
+        if (!profile.getSyncTask().isPerformCreate()) {
+            LOG.debug("SyncTask not configured for create");
+            return Collections.<SyncResult>emptyList();
+        }
 
         final AbstractSubjectTO subjectTO =
                 connObjectUtil.getSubjectTO(delta.getObject(), profile.getSyncTask(), attrUtil);
 
         subjectTO.getResources().add(profile.getSyncTask().getResource().getName());
 
-        if (!profile.getSyncTask().isPerformCreate()) {
-            LOG.debug("SyncTask not configured for create");
-            return Collections.<SyncResult>emptyList();
-        }
-
         final SyncResult result = new SyncResult();
         result.setOperation(ResourceOperation.CREATE);
         result.setSubjectType(attrUtil.getType());
@@ -135,7 +134,6 @@ public abstract class AbstractSubjectSyn
 
     protected List<SyncResult> create(final SyncDelta delta, final AttributableUtil attrUtil)
             throws JobExecutionException {
-
         if (!profile.getSyncTask().isPerformCreate()) {
             LOG.debug("SyncTask not configured for create");
             return Collections.<SyncResult>emptyList();

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java Wed Jul  2 15:30:13 2014
@@ -40,7 +40,7 @@ public abstract class AbstractSyncopeRes
      * Logger.
      */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
-
+    
     /**
      * User data binder.
      */

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java Wed Jul  2 15:30:13 2014
@@ -124,16 +124,14 @@ public class PushJob extends AbstractSyn
                         uhandler.handle(localUser);
                     } catch (Exception e) {
                         LOG.warn("Failure pushing user '{}' on '{}'", localUser, pushTask.getResource(), e);
-                        if (!continueOnError()) {
-                            throw new JobExecutionException("While pushing users on connector", e);
-                        }
+                        throw new JobExecutionException("While pushing users on connector", e);
                     }
                 }
             }
         }
 
         if (rMapping != null) {
-            final List<SyncopeRole> localRoles = getRoles(authorizations, pushTask, PAGE_SIZE);
+            final List<SyncopeRole> localRoles = getRoles(authorizations, pushTask);
 
             for (SyncopeRole localRole : localRoles) {
                 try {
@@ -141,9 +139,7 @@ public class PushJob extends AbstractSyn
                     rhandler.handle(localRole);
                 } catch (Exception e) {
                     LOG.warn("Failure pushing role '{}' on '{}'", localRole, pushTask.getResource(), e);
-                    if (!continueOnError()) {
-                        throw new JobExecutionException("While pushing roles on connector", e);
-                    }
+                    throw new JobExecutionException("While pushing roles on connector", e);
                 }
             }
         }
@@ -161,10 +157,6 @@ public class PushJob extends AbstractSyn
         return result;
     }
 
-    protected boolean continueOnError() {
-        return true;
-    }
-
     private List<SyncopeUser> getUsers(final Set<Long> authorizations, final PushTask pushTask, final int page) {
         final String filter = pushTask.getUserFilter();
         if (StringUtils.isBlank(filter)) {
@@ -176,7 +168,7 @@ public class PushJob extends AbstractSyn
         }
     }
 
-    private List<SyncopeRole> getRoles(final Set<Long> authorizations, final PushTask pushTask, final int page) {
+    private List<SyncopeRole> getRoles(final Set<Long> authorizations, final PushTask pushTask) {
         final String filter = pushTask.getRoleFilter();
         if (StringUtils.isBlank(filter)) {
             return roleDAO.findAll();

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/RolePushResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/RolePushResultHandler.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/RolePushResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/RolePushResultHandler.java Wed Jul  2 15:30:13 2014
@@ -20,21 +20,17 @@ package org.apache.syncope.core.sync.imp
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import org.apache.syncope.common.mod.RoleMod;
 import org.apache.syncope.common.to.AbstractSubjectTO;
 import org.apache.syncope.common.to.RoleTO;
 import org.apache.syncope.common.types.ResourceOperation;
+import org.apache.syncope.core.persistence.beans.AbstractMapping;
 import org.apache.syncope.core.persistence.beans.AbstractMappingItem;
 import org.apache.syncope.core.persistence.beans.AbstractSubject;
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.propagation.TimeoutException;
-import org.apache.syncope.core.propagation.impl.AbstractPropagationTaskExecutor;
-import org.apache.syncope.core.sync.SyncResult;
-import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.Uid;
@@ -42,7 +38,7 @@ import org.identityconnectors.framework.
 public class RolePushResultHandler extends AbstractSubjectPushResultHandler {
 
     @Override
-    protected AbstractSubject deprovision(final AbstractSubject sbj, final SyncResult result) {
+    protected AbstractSubject deprovision(final AbstractSubject sbj) {
         final RoleTO before = roleDataBinder.getRoleTO(SyncopeRole.class.cast(sbj));
 
         final List<String> noPropResources = new ArrayList<String>(before.getResources());
@@ -54,7 +50,7 @@ public class RolePushResultHandler exten
     }
 
     @Override
-    protected AbstractSubject provision(final AbstractSubject sbj, final Boolean enabled, final SyncResult result) {
+    protected AbstractSubject provision(final AbstractSubject sbj, final Boolean enabled) {
         final RoleTO before = roleDataBinder.getRoleTO(SyncopeRole.class.cast(sbj));
 
         final List<String> noPropResources = new ArrayList<String>(before.getResources());
@@ -73,8 +69,7 @@ public class RolePushResultHandler exten
     }
 
     @Override
-    protected AbstractSubject link(
-            final AbstractSubject sbj, final Boolean unlink, final SyncResult result) {
+    protected AbstractSubject link(final AbstractSubject sbj, final Boolean unlink) {
 
         final RoleMod roleMod = new RoleMod();
         roleMod.setId(sbj.getId());
@@ -91,43 +86,21 @@ public class RolePushResultHandler exten
     }
 
     @Override
-    protected AbstractSubject unassign(final AbstractSubject sbj, final SyncResult result) {
+    protected AbstractSubject unassign(final AbstractSubject sbj) {
         final RoleMod roleMod = new RoleMod();
         roleMod.setId(sbj.getId());
         roleMod.getResourcesToRemove().add(profile.getSyncTask().getResource().getName());
         rwfAdapter.update(roleMod);
-        return deprovision(sbj, result);
+        return deprovision(sbj);
     }
 
     @Override
-    protected AbstractSubject assign(final AbstractSubject sbj, final Boolean enabled, final SyncResult result) {
+    protected AbstractSubject assign(final AbstractSubject sbj, final Boolean enabled) {
         final RoleMod roleMod = new RoleMod();
         roleMod.setId(sbj.getId());
         roleMod.getResourcesToAdd().add(profile.getSyncTask().getResource().getName());
         rwfAdapter.update(roleMod);
-        return provision(sbj, enabled, result);
-    }
-
-    @Override
-    protected AbstractSubject update(
-            final AbstractSubject sbj,
-            final String accountId,
-            final Set<Attribute> attributes,
-            final ConnectorObject beforeObj,
-            final SyncResult result) {
-
-        AbstractPropagationTaskExecutor.createOrUpdate(
-                ObjectClass.GROUP,
-                accountId,
-                attributes,
-                profile.getSyncTask().getResource().getName(),
-                profile.getSyncTask().getResource().getPropagationMode(),
-                beforeObj,
-                profile.getConnector(),
-                new HashSet<String>(),
-                connObjectUtil);
-
-        return userDataBinder.getUserFromId(sbj.getId());
+        return provision(sbj, enabled);
     }
 
     @Override
@@ -176,4 +149,9 @@ public class RolePushResultHandler exten
         }
         return obj;
     }
+
+    @Override
+    protected AbstractMapping getMapping() {
+        return profile.getSyncTask().getResource().getRmapping();
+    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/UserPushResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/UserPushResultHandler.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/UserPushResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/UserPushResultHandler.java Wed Jul  2 15:30:13 2014
@@ -20,21 +20,17 @@ package org.apache.syncope.core.sync.imp
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import org.apache.syncope.common.mod.UserMod;
 import org.apache.syncope.common.to.AbstractSubjectTO;
 import org.apache.syncope.common.to.UserTO;
 import org.apache.syncope.common.types.ResourceOperation;
+import org.apache.syncope.core.persistence.beans.AbstractMapping;
 import org.apache.syncope.core.persistence.beans.AbstractMappingItem;
 import org.apache.syncope.core.persistence.beans.AbstractSubject;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.propagation.TimeoutException;
-import org.apache.syncope.core.propagation.impl.AbstractPropagationTaskExecutor;
-import org.apache.syncope.core.sync.SyncResult;
-import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.Uid;
@@ -42,7 +38,7 @@ import org.identityconnectors.framework.
 public class UserPushResultHandler extends AbstractSubjectPushResultHandler {
 
     @Override
-    protected AbstractSubject deprovision(final AbstractSubject sbj, final SyncResult result) {
+    protected AbstractSubject deprovision(final AbstractSubject sbj) {
         final UserTO before = userDataBinder.getUserTO(sbj.getId());
 
         final List<String> noPropResources = new ArrayList<String>(before.getResources());
@@ -55,7 +51,7 @@ public class UserPushResultHandler exten
     }
 
     @Override
-    protected AbstractSubject provision(final AbstractSubject sbj, final Boolean enabled, final SyncResult result) {
+    protected AbstractSubject provision(final AbstractSubject sbj, final Boolean enabled) {
         final UserTO before = userDataBinder.getUserTO(sbj.getId());
 
         final List<String> noPropResources = new ArrayList<String>(before.getResources());
@@ -77,8 +73,7 @@ public class UserPushResultHandler exten
     }
 
     @Override
-    protected AbstractSubject link(
-            final AbstractSubject sbj, final Boolean unlink, final SyncResult result) {
+    protected AbstractSubject link(final AbstractSubject sbj, final Boolean unlink) {
 
         final UserMod userMod = new UserMod();
         userMod.setId(sbj.getId());
@@ -95,43 +90,21 @@ public class UserPushResultHandler exten
     }
 
     @Override
-    protected AbstractSubject unassign(final AbstractSubject sbj, final SyncResult result) {
+    protected AbstractSubject unassign(final AbstractSubject sbj) {
         final UserMod userMod = new UserMod();
         userMod.setId(sbj.getId());
         userMod.getResourcesToRemove().add(profile.getSyncTask().getResource().getName());
         uwfAdapter.update(userMod);
-        return deprovision(sbj, result);
+        return deprovision(sbj);
     }
 
     @Override
-    protected AbstractSubject assign(final AbstractSubject sbj, final Boolean enabled, final SyncResult result) {
+    protected AbstractSubject assign(final AbstractSubject sbj, final Boolean enabled) {
         final UserMod userMod = new UserMod();
         userMod.setId(sbj.getId());
         userMod.getResourcesToAdd().add(profile.getSyncTask().getResource().getName());
         uwfAdapter.update(userMod);
-        return provision(sbj, enabled, result);
-    }
-
-    @Override
-    protected AbstractSubject update(
-            final AbstractSubject sbj,
-            final String accountId,
-            final Set<Attribute> attributes,
-            final ConnectorObject beforeObj,
-            final SyncResult result) {
-
-        AbstractPropagationTaskExecutor.createOrUpdate(
-                ObjectClass.ACCOUNT,
-                accountId,
-                attributes,
-                profile.getSyncTask().getResource().getName(),
-                profile.getSyncTask().getResource().getPropagationMode(),
-                beforeObj,
-                profile.getConnector(),
-                new HashSet<String>(),
-                connObjectUtil);
-
-        return userDataBinder.getUserFromId(sbj.getId());
+        return provision(sbj, enabled);
     }
 
     @Override
@@ -179,4 +152,9 @@ public class UserPushResultHandler exten
         }
         return obj;
     }
+
+    @Override
+    protected AbstractMapping getMapping() {
+        return profile.getSyncTask().getResource().getUmapping();
+    }
 }

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java Wed Jul  2 15:30:13 2014
@@ -67,7 +67,7 @@ public class TaskTest extends AbstractDA
         assertEquals(4, taskDAO.findAll(PropagationTask.class).size());
         assertEquals(1, taskDAO.findAll(NotificationTask.class).size());
         assertEquals(1, taskDAO.findAll(SchedTask.class).size());
-        assertEquals(7, taskDAO.findAll(SyncTask.class).size());
+        assertEquals(9, taskDAO.findAll(SyncTask.class).size());
         assertEquals(11, taskDAO.findAll(PushTask.class).size());
     }
 

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java Wed Jul  2 15:30:13 2014
@@ -298,7 +298,7 @@ public class TaskTestITCase extends Abst
     }
 
     @Test
-    public void sync() {
+    public void sync() throws Exception {
         removeTestUsers();
 
         // -----------------------------
@@ -318,6 +318,7 @@ public class TaskTestITCase extends Abst
 
         inUserTO = createUser(inUserTO);
         assertNotNull(inUserTO);
+        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
 
         // -----------------------------
         try {
@@ -335,17 +336,25 @@ public class TaskTestITCase extends Abst
             assertEquals("test9@syncope.apache.org", userTO.getAttrMap().get("email").getValues().get(0));
             assertEquals("test9@syncope.apache.org", userTO.getAttrMap().get("userId").getValues().get(0));
             assertTrue(Integer.valueOf(userTO.getAttrMap().get("fullname").getValues().get(0)) <= 10);
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+            
+            // Matching --> Update (no link)
+            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
 
             // check for user template
             userTO = readUser("test7");
             assertNotNull(userTO);
             assertEquals("TYPE_OTHER", userTO.getAttrMap().get("type").getValues().get(0));
-            assertEquals(2, userTO.getResources().size());
+            assertEquals(3, userTO.getResources().size());
             assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
             assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
             assertEquals(1, userTO.getMemberships().size());
             assertTrue(userTO.getMemberships().get(0).getAttrMap().containsKey("subscriptionDate"));
 
+            // Unmatching --> Assign (link)
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
             userTO = readUser("test8");
             assertNotNull(userTO);
             assertEquals("TYPE_8", userTO.getAttrMap().get("type").getValues().get(0));
@@ -368,6 +377,15 @@ public class TaskTestITCase extends Abst
 
             // SYNCOPE-317
             execSyncTask(SYNC_TASK_ID, 50, false);
+
+            final Set<Long> pushTaskIds = new HashSet<Long>();
+            pushTaskIds.add(25L);
+            pushTaskIds.add(26L);
+            
+            execSyncTasks(pushTaskIds, 50, false);
+            // Matching --> UNLINK
+            assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
+            assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
         } finally {
             removeTestUsers();
         }

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/SyncTaskTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/SyncTaskTest.java?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/SyncTaskTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/SyncTaskTest.java Wed Jul  2 15:30:13 2014
@@ -22,6 +22,8 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertNotNull;
 
 import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.common.types.MatchingRule;
+import org.apache.syncope.common.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.SyncTask;
 import org.apache.syncope.core.persistence.dao.AbstractDAOTest;
@@ -51,6 +53,8 @@ public class SyncTaskTest extends Abstra
         task.setDescription("SyncTask description");
         task.setUserTemplate(new UserTO());
         task.setCronExpression("BLA BLA");
+        task.setMatchingRule(MatchingRule.UPDATE);
+        task.setUnmatchingRule(UnmatchingRule.PROVISION);
 
         // this save() fails because of an invalid Cron Expression
         InvalidEntityException exception = null;
@@ -105,6 +109,8 @@ public class SyncTaskTest extends Abstra
         task.setName("issueSYNCOPE144");
         task.setDescription("issueSYNCOPE144 Description");
         task.getActionsClassNames().add(TestSyncActions.class.getName());
+        task.setMatchingRule(MatchingRule.UPDATE);
+        task.setUnmatchingRule(UnmatchingRule.PROVISION);
 
         task = taskDAO.save(task);
         assertNotNull(task);

Modified: syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1607399&r1=1607398&r2=1607399&view=diff
==============================================================================
--- syncope/trunk/core/src/test/resources/content.xml (original)
+++ syncope/trunk/core/src/test/resources/content.xml Wed Jul  2 15:30:13 2014
@@ -879,9 +879,9 @@ under the License.
   <Task DTYPE="PropagationTask" id="3" propagationMode="TWO_PHASES" propagationOperation="DELETE"
         objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" subjectType="USER" subjectId="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"type","value":["type"]}]'/>
-  <Task DTYPE="SyncTask" id="4" name="CSV Task" resource_name="resource-csv"
+  <Task DTYPE="SyncTask" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="ASSIGN" matchingRule="UPDATE"
         userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"attributes":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}],"derivedAttributes":[{"schema":"cn","readonly":false,"values":[null]}],"virtualAttributes":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"roleId":8,"roleName":null,"attributes":[{"schema":"subscriptionDate","readonly":false,"values":["&apos;2009-08-18T16:33:12.203+0200&apos;"]}],"derivedAttributes":[],"virtualAttributes":[]}]}'
         roleTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"name":null,"parent":0,"userOwner":null,"roleOwner":null,"inheritOwner":false,"inheritTemplates":false,"inheritAttrs":false,"inheritDerAttrs":false,"inheritVirAttrs":false,"inheritPasswordPolicy":false,"inheritAccountPolicy":false,"passwordPolicy":null,"accountPolicy":null,"attributes":[],"derivedAttributes":[],"virtualAttributes":[],"resources":[],"propagationStatuses":[],"entitlements":[],"rAttrTemplates":[],"rDerAttrTemplates":[],"rVirAttrTemplates":[],"mAttrTemplates":[],"mDerAttrTemplates":[],"mVirAttrTemplates":[]}'/>
   <SyncTask_actionsClassNames SyncTask_id="4" element="org.apache.syncope.core.sync.TestSyncActions"/>
@@ -892,26 +892,26 @@ under the License.
   <TaskExec id="6" task_id="6" status="SUCCESS"/>
   <Task DTYPE="SyncTask" id="7" name="TestDB Task" resource_name="resource-testdb"
         performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"
         userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"attributes":[{"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;"]}],"derivedAttributes":[],"virtualAttributes":[],"resources":[],"propagationStatuses":[],"memberships":[]}'
         roleTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"name":null,"parent":0,"userOwner":null,"roleOwner":null,"inheritOwner":false,"inheritTemplates":false,"inheritAttrs":false,"inheritDerAttrs":false,"inheritVirAttrs":false,"inheritPasswordPolicy":false,"inheritAccountPolicy":false,"passwordPolicy":null,"accountPolicy":null,"attributes":[],"derivedAttributes":[],"virtualAttributes":[],"resources":[],"propagationStatuses":[],"entitlements":[],"rAttrTemplates":[],"rDerAttrTemplates":[],"rVirAttrTemplates":[],"mAttrTemplates":[],"mDerAttrTemplates":[],"mVirAttrTemplates":[]}'/>
   <Task DTYPE="NotificationTask" id="8" sender="admin@prova.org" subject="Notification for SYNCOPE-81" 
         textBody="NOTIFICATION-81" htmlBody="NOTIFICATION-81" traceLevel="ALL"/>
   <Task DTYPE="SyncTask" id="9" name="TestDB2 Task" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"/>
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="SyncTask" id="10" name="TestDB Sync Task" resource_name="resource-db-sync"
         fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"/>
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="SyncTask" id="11" name="LDAP Sync Task" resource_name="resource-ldap"
         fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"
         userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"attributes":[],"derivedAttributes":[],"virtualAttributes":[{"schema":"virtualReadOnly","readonly":false,"values":[""]}],"resources":["resource-ldap"],"propagationStatuses":[],"memberships":[]}'
         roleTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"name":null,"parent":8,"userOwner":null,"roleOwner":null,"inheritOwner":false,"inheritTemplates":false,"inheritAttrs":false,"inheritDerAttrs":false,"inheritVirAttrs":false,"inheritPasswordPolicy":false,"inheritAccountPolicy":false,"passwordPolicy":null,"accountPolicy":null,"attributes":[{"schema":"show","readonly":false,"values":["&apos;true&apos;"]}],"derivedAttributes":[],"virtualAttributes":[],"resources":[],"propagationStatuses":[],"entitlements":[],"rAttrTemplates":["show"],"rDerAttrTemplates":[],"rVirAttrTemplates":[],"mAttrTemplates":[],"mDerAttrTemplates":[],"mVirAttrTemplates":[]}'/>
   <SyncTask_actionsClassNames SyncTask_id="11" element="org.apache.syncope.core.sync.impl.LDAPMembershipSyncActions"/>
   <Task DTYPE="SyncTask" id="12" name="VirAttrCache test" resource_name="resource-csv"
         performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" fullReconciliation="1"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"/>
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="PushTask" id="13" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
         jobClassName="org.apache.syncope.core.sync.impl.PushJob" unmatchingRule="ASSIGN" matchingRule="IGNORE" 
@@ -958,9 +958,15 @@ under the License.
         userFilter="username==_NO_ONE_" roleFilter="name==citizen"/>
   <Task DTYPE="SyncTask" id="24" name="CSV Task 2" resource_name="resource-csv"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
-        jobClassName="org.apache.syncope.core.sync.impl.SyncJob"
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"
         userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"attributes":[{"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;"]}],"derivedAttributes":[],"virtualAttributes":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[]}'
         roleTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"name":null,"parent":0,"userOwner":null,"roleOwner":null,"inheritOwner":false,"inheritTemplates":false,"inheritAttrs":false,"inheritDerAttrs":false,"inheritVirAttrs":false,"inheritPasswordPolicy":false,"inheritAccountPolicy":false,"passwordPolicy":null,"accountPolicy":null,"attributes":[],"derivedAttributes":[],"virtualAttributes":[],"resources":[],"propagationStatuses":[],"entitlements":[],"rAttrTemplates":[],"rDerAttrTemplates":[],"rVirAttrTemplates":[],"mAttrTemplates":[],"mDerAttrTemplates":[],"mVirAttrTemplates":[]}'/>
+  <Task DTYPE="SyncTask" id="25" name="CSV (unlink matching; ignore unmatching)" resource_name="resource-csv"
+        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="IGNORE" matchingRule="UNLINK"/>
+  <Task DTYPE="SyncTask" id="26" name="CSV (ignore matching; assign unmatching)" resource_name="resource-csv"
+        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
+        jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="ASSIGN" matchingRule="IGNORE"/>
       
   <Notification id="1" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" traceLevel="ALL"
                 userAbout="fullname==*o*;fullname==*i*"



Mime
View raw message