You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/03/09 12:52:45 UTC

[09/17] syncope git commit: Further refactoring as per SYNCOPE-620

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
new file mode 100644
index 0000000..7c6c38a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -0,0 +1,241 @@
+/*
+ * 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.jexl;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.JexlException;
+import org.apache.commons.jexl3.JexlExpression;
+import org.apache.commons.jexl3.JxltEngine;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JEXL <a href="http://commons.apache.org/jexl/reference/index.html">reference</a> is available.
+ */
+public final class JexlUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JexlUtils.class);
+
+    private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
+
+    private static JexlEngine JEXL_ENGINE;
+
+    private static JexlEngine getEngine() {
+        synchronized (LOG) {
+            if (JEXL_ENGINE == null) {
+                JEXL_ENGINE = new JexlBuilder().
+                        uberspect(new ClassFreeUberspect()).
+                        loader(new EmptyClassLoader()).
+                        cache(512).
+                        silent(false).
+                        strict(false).
+                        create();
+            }
+        }
+
+        return JEXL_ENGINE;
+    }
+
+    public static JxltEngine newJxltEngine() {
+        return getEngine().createJxltEngine(false);
+    }
+
+    public static boolean isExpressionValid(final String expression) {
+        boolean result;
+        try {
+            getEngine().createExpression(expression);
+            result = true;
+        } catch (JexlException e) {
+            LOG.error("Invalid jexl expression: " + expression, e);
+            result = false;
+        }
+
+        return result;
+    }
+
+    public static String evaluate(final String expression, final JexlContext jexlContext) {
+        String result = StringUtils.EMPTY;
+
+        if (StringUtils.isNotBlank(expression) && jexlContext != null) {
+            try {
+                JexlExpression jexlExpression = getEngine().createExpression(expression);
+                Object evaluated = jexlExpression.evaluate(jexlContext);
+                if (evaluated != null) {
+                    result = evaluated.toString();
+                }
+            } catch (Exception e) {
+                LOG.error("Error while evaluating JEXL expression: " + expression, e);
+            }
+        } else {
+            LOG.debug("Expression not provided or invalid context");
+        }
+
+        return result;
+    }
+
+    public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
+        JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
+
+        try {
+            for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
+                Class<?> type = desc.getPropertyType();
+                String fieldName = desc.getName();
+
+                if ((!fieldName.startsWith("pc"))
+                        && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
+                        && (!Iterable.class.isAssignableFrom(type))
+                        && (!type.isArray())) {
+
+                    try {
+                        Object fieldValue;
+                        if (desc.getReadMethod() == null) {
+                            final Field field = object.getClass().getDeclaredField(fieldName);
+                            field.setAccessible(true);
+                            fieldValue = field.get(object);
+                        } else {
+                            fieldValue = desc.getReadMethod().invoke(object);
+                        }
+
+                        context.set(fieldName, fieldValue == null
+                                ? StringUtils.EMPTY
+                                : (type.equals(Date.class)
+                                ? FormatUtils.format((Date) fieldValue, false)
+                                : fieldValue));
+
+                        LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+                    } catch (Exception iae) {
+                        LOG.error("Reading '{}' value error", fieldName, iae);
+                    }
+                }
+            }
+        } catch (IntrospectionException ie) {
+            LOG.error("Reading class attributes error", ie);
+        }
+
+        if (object instanceof Any) {
+            Any<?> any = (Any<?>) object;
+            if (any.getRealm() != null) {
+                context.set("realm", any.getRealm().getName());
+            }
+        }
+
+        return context;
+    }
+
+    public static void addPlainAttrsToContext(
+            final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
+
+        for (PlainAttr<?> attr : attrs) {
+            if (attr.getSchema() != null) {
+                List<String> attrValues = attr.getValuesAsStrings();
+                String expressionValue = attrValues.isEmpty()
+                        ? StringUtils.EMPTY
+                        : attrValues.get(0);
+
+                LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
+
+                jexlContext.set(attr.getSchema().getKey(), expressionValue);
+            }
+        }
+    }
+
+    public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
+        Map<DerSchema, String> derAttrs =
+                ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
+
+        for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
+            jexlContext.set(entry.getKey().getKey(), entry.getValue());
+        }
+    }
+
+    public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
+        JexlContext jexlContext = new MapContext();
+        addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
+        addDerAttrsToContext(any, jexlContext);
+
+        return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
+    }
+
+    public static String evaluate(final String expression, final AnyTO anyTO) {
+        final JexlContext context = new MapContext();
+
+        addFieldsToContext(anyTO, context);
+
+        for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
+            List<String> values = plainAttr.getValues();
+            String expressionValue = values.isEmpty()
+                    ? StringUtils.EMPTY
+                    : values.get(0);
+
+            LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
+
+            context.set(plainAttr.getSchema(), expressionValue);
+        }
+        for (AttrTO derAttr : anyTO.getDerAttrs()) {
+            List<String> values = derAttr.getValues();
+            String expressionValue = values.isEmpty()
+                    ? StringUtils.EMPTY
+                    : values.get(0);
+
+            LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
+
+            context.set(derAttr.getSchema(), expressionValue);
+        }
+        for (AttrTO virAttr : anyTO.getVirAttrs()) {
+            List<String> values = virAttr.getValues();
+            String expressionValue = values.isEmpty()
+                    ? StringUtils.EMPTY
+                    : values.get(0);
+
+            LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
+
+            context.set(virAttr.getSchema(), expressionValue);
+        }
+
+        // Evaluate expression using the context prepared before
+        return evaluate(expression, context);
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private JexlUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
index bd550b5..3b22728 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.provisioning.java.job;
 
 import java.util.Date;
 import java.util.concurrent.atomic.AtomicReference;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.InterruptableJob;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
index ea6a525..aec8853 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -20,13 +20,13 @@ package org.apache.syncope.core.provisioning.java.job;
 
 import java.util.Date;
 import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.quartz.JobExecutionException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
index 4692e88..50067dc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.provisioning.java.job;
 
 import org.apache.commons.lang3.ClassUtils;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 74dc39f..b119bd1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -54,8 +54,8 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 7d7edc1..2c2e9ea 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -44,11 +44,10 @@ import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
@@ -59,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 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.user.User;
+import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
@@ -574,11 +574,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
         ConnectorObject obj = null;
         try {
-            obj = connector.getObject(
-                    new ObjectClass(task.getObjectClassName()),
+            obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
                     new Uid(connObjectKey),
-                    MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
-                            MappingUtils.getPropagationMappingItems(provision).iterator(),
+                    MappingManagerImpl.buildOperationOptions(IteratorUtils.chainedIterator(MappingManagerImpl.
+                            getPropagationMappingItems(provision).iterator(),
                             linkingMappingItems.iterator())));
 
             for (MappingItem item : linkingMappingItems) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
index 55c4a0b..635c015 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 9a7214c..6aa076e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -30,7 +30,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 5ea6616..15ddb30 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -36,7 +36,7 @@ import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index f816228..5f66a2f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -43,9 +43,9 @@ import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
@@ -58,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 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.user.User;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -108,7 +109,7 @@ public class PropagationManagerImpl implements PropagationManager {
     protected ConnObjectUtils connObjectUtils;
 
     @Autowired
-    protected MappingUtils mappingUtils;
+    protected MappingManager mappingManager;
 
     @Autowired
     protected AnyUtilsFactory anyUtilsFactory;
@@ -367,7 +368,7 @@ public class PropagationManagerImpl implements PropagationManager {
             Provision provision = resource == null ? null : resource.getProvision(any.getType());
             List<MappingItem> mappingItems = provision == null
                     ? Collections.<MappingItem>emptyList()
-                    : MappingUtils.getPropagationMappingItems(provision);
+                    : MappingManagerImpl.getPropagationMappingItems(provision);
 
             if (resource == null) {
                 LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey());
@@ -391,7 +392,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
 
                 Pair<String, Set<Attribute>> preparedAttrs =
-                        mappingUtils.prepareAttrs(any, password, changePwd, enable, provision);
+                        mappingManager.prepareAttrs(any, password, changePwd, enable, provision);
                 task.setConnObjectKey(preparedAttrs.getKey());
 
                 // Check if any of mandatory attributes (in the mapping) is missing or not received any value: 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
index 4e6b875..1c0aa9b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.provisioning.java.propagation;
 
 import java.util.Collection;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
deleted file mode 100644
index d6f4c15..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
+++ /dev/null
@@ -1,434 +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.sync;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Resource;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
-import org.apache.syncope.core.provisioning.java.job.TaskJob;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask>
-        extends AbstractSchedTaskJobDelegate {
-
-    @Resource(name = "adminUser")
-    protected String adminUser;
-
-    /**
-     * ConnInstance loader.
-     */
-    @Autowired
-    protected ConnectorFactory connFactory;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
-
-    /**
-     * Resource DAO.
-     */
-    @Autowired
-    protected ExternalResourceDAO resourceDAO;
-
-    /**
-     * Policy DAO.
-     */
-    @Autowired
-    protected PolicyDAO policyDAO;
-
-    /**
-     * Create a textual report of the synchronization, based on the trace level.
-     *
-     * @param provResults Sync results
-     * @param syncTraceLevel Sync trace level
-     * @param dryRun dry run?
-     * @return report as string
-     */
-    protected String createReport(final Collection<ProvisioningReport> provResults, final TraceLevel syncTraceLevel,
-            final boolean dryRun) {
-
-        if (syncTraceLevel == TraceLevel.NONE) {
-            return null;
-        }
-
-        StringBuilder report = new StringBuilder();
-
-        if (dryRun) {
-            report.append("==>Dry run only, no modifications were made<==\n\n");
-        }
-
-        List<ProvisioningReport> uSuccCreate = new ArrayList<>();
-        List<ProvisioningReport> uFailCreate = new ArrayList<>();
-        List<ProvisioningReport> uSuccUpdate = new ArrayList<>();
-        List<ProvisioningReport> uFailUpdate = new ArrayList<>();
-        List<ProvisioningReport> uSuccDelete = new ArrayList<>();
-        List<ProvisioningReport> uFailDelete = new ArrayList<>();
-        List<ProvisioningReport> uSuccNone = new ArrayList<>();
-        List<ProvisioningReport> uIgnore = new ArrayList<>();
-        List<ProvisioningReport> gSuccCreate = new ArrayList<>();
-        List<ProvisioningReport> gFailCreate = new ArrayList<>();
-        List<ProvisioningReport> gSuccUpdate = new ArrayList<>();
-        List<ProvisioningReport> gFailUpdate = new ArrayList<>();
-        List<ProvisioningReport> gSuccDelete = new ArrayList<>();
-        List<ProvisioningReport> gFailDelete = new ArrayList<>();
-        List<ProvisioningReport> gSuccNone = new ArrayList<>();
-        List<ProvisioningReport> gIgnore = new ArrayList<>();
-        List<ProvisioningReport> aSuccCreate = new ArrayList<>();
-        List<ProvisioningReport> aFailCreate = new ArrayList<>();
-        List<ProvisioningReport> aSuccUpdate = new ArrayList<>();
-        List<ProvisioningReport> aFailUpdate = new ArrayList<>();
-        List<ProvisioningReport> aSuccDelete = new ArrayList<>();
-        List<ProvisioningReport> aFailDelete = new ArrayList<>();
-        List<ProvisioningReport> aSuccNone = new ArrayList<>();
-        List<ProvisioningReport> aIgnore = new ArrayList<>();
-
-        for (ProvisioningReport provResult : provResults) {
-            AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
-
-            switch (provResult.getStatus()) {
-                case SUCCESS:
-                    switch (provResult.getOperation()) {
-                        case CREATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccCreate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccCreate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccCreate.add(provResult);
-                            }
-                            break;
-
-                        case UPDATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccUpdate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccUpdate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccUpdate.add(provResult);
-                            }
-                            break;
-
-                        case DELETE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccDelete.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccDelete.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccDelete.add(provResult);
-                            }
-                            break;
-
-                        case NONE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccNone.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccNone.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccNone.add(provResult);
-                            }
-                            break;
-
-                        default:
-                    }
-                    break;
-
-                case FAILURE:
-                    switch (provResult.getOperation()) {
-                        case CREATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailCreate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailCreate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailCreate.add(provResult);
-                            }
-                            break;
-
-                        case UPDATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailUpdate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailUpdate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailUpdate.add(provResult);
-                            }
-                            break;
-
-                        case DELETE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailDelete.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailDelete.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailDelete.add(provResult);
-                            }
-                            break;
-
-                        default:
-                    }
-                    break;
-
-                case IGNORE:
-                    switch (anyType.getKind()) {
-                        case USER:
-                            uIgnore.add(provResult);
-                            break;
-
-                        case GROUP:
-                            gIgnore.add(provResult);
-                            break;
-
-                        case ANY_OBJECT:
-                        default:
-                            aIgnore.add(provResult);
-                    }
-                    break;
-
-                default:
-            }
-        }
-
-        // Summary, also to be included for FAILURE and ALL, so create it anyway.
-        report.append("Users ").
-                append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
-                append('\n');
-        report.append("Groups ").
-                append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
-                append('\n');
-        report.append("Any objects ").
-                append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
-
-        // Failures
-        if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
-            if (!uFailCreate.isEmpty()) {
-                report.append("\n\nUsers failed to create: ");
-                report.append(ProvisioningReport.produceReport(uFailCreate, syncTraceLevel));
-            }
-            if (!uFailUpdate.isEmpty()) {
-                report.append("\nUsers failed to update: ");
-                report.append(ProvisioningReport.produceReport(uFailUpdate, syncTraceLevel));
-            }
-            if (!uFailDelete.isEmpty()) {
-                report.append("\nUsers failed to delete: ");
-                report.append(ProvisioningReport.produceReport(uFailDelete, syncTraceLevel));
-            }
-
-            if (!gFailCreate.isEmpty()) {
-                report.append("\n\nGroups failed to create: ");
-                report.append(ProvisioningReport.produceReport(gFailCreate, syncTraceLevel));
-            }
-            if (!gFailUpdate.isEmpty()) {
-                report.append("\nGroups failed to update: ");
-                report.append(ProvisioningReport.produceReport(gFailUpdate, syncTraceLevel));
-            }
-            if (!gFailDelete.isEmpty()) {
-                report.append("\nGroups failed to delete: ");
-                report.append(ProvisioningReport.produceReport(gFailDelete, syncTraceLevel));
-            }
-
-            if (!aFailCreate.isEmpty()) {
-                report.append("\nAny objects failed to create: ");
-                report.append(ProvisioningReport.produceReport(aFailCreate, syncTraceLevel));
-            }
-            if (!aFailUpdate.isEmpty()) {
-                report.append("\nAny objects failed to update: ");
-                report.append(ProvisioningReport.produceReport(aFailUpdate, syncTraceLevel));
-            }
-            if (!aFailDelete.isEmpty()) {
-                report.append("\nAny objects failed to delete: ");
-                report.append(ProvisioningReport.produceReport(aFailDelete, syncTraceLevel));
-            }
-        }
-
-        // Succeeded, only if on 'ALL' level
-        if (syncTraceLevel == TraceLevel.ALL) {
-            report.append("\n\nUsers created:\n").
-                    append(ProvisioningReport.produceReport(uSuccCreate, syncTraceLevel)).
-                    append("\nUsers updated:\n").
-                    append(ProvisioningReport.produceReport(uSuccUpdate, syncTraceLevel)).
-                    append("\nUsers deleted:\n").
-                    append(ProvisioningReport.produceReport(uSuccDelete, syncTraceLevel)).
-                    append("\nUsers no operation:\n").
-                    append(ProvisioningReport.produceReport(uSuccNone, syncTraceLevel)).
-                    append("\nUsers ignored:\n").
-                    append(ProvisioningReport.produceReport(uIgnore, syncTraceLevel));
-            report.append("\n\nGroups created:\n").
-                    append(ProvisioningReport.produceReport(gSuccCreate, syncTraceLevel)).
-                    append("\nGroups updated:\n").
-                    append(ProvisioningReport.produceReport(gSuccUpdate, syncTraceLevel)).
-                    append("\nGroups deleted:\n").
-                    append(ProvisioningReport.produceReport(gSuccDelete, syncTraceLevel)).
-                    append("\nGroups no operation:\n").
-                    append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel)).
-                    append("\nGroups ignored:\n").
-                    append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel));
-            report.append("\n\nAny objects created:\n").
-                    append(ProvisioningReport.produceReport(aSuccCreate, syncTraceLevel)).
-                    append("\nAny objects updated:\n").
-                    append(ProvisioningReport.produceReport(aSuccUpdate, syncTraceLevel)).
-                    append("\nAny objects deleted:\n").
-                    append(ProvisioningReport.produceReport(aSuccDelete, syncTraceLevel)).
-                    append("\nAny objects no operation:\n").
-                    append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel)).
-                    append("\nAny objects ignored:\n").
-                    append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel));
-        }
-
-        return report.toString();
-    }
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        try {
-            Class<T> clazz = getTaskClassReference();
-            if (!clazz.isAssignableFrom(task.getClass())) {
-                throw new JobExecutionException("Task " + task.getKey() + " isn't a ProvisioningTask");
-            }
-
-            T provisioningTask = clazz.cast(task);
-
-            Connector connector;
-            try {
-                connector = connFactory.getConnector(provisioningTask.getResource());
-            } catch (Exception e) {
-                String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
-                        provisioningTask.getResource(), provisioningTask.getResource().getConnector());
-                throw new JobExecutionException(msg, e);
-            }
-
-            boolean noMapping = true;
-            for (Provision provision : provisioningTask.getResource().getProvisions()) {
-                Mapping mapping = provision.getMapping();
-                if (mapping != null) {
-                    noMapping = false;
-                    if (mapping.getConnObjectKeyItem() == null) {
-                        throw new JobExecutionException(
-                                "Invalid ConnObjectKey mapping for provision " + provision);
-                    }
-                }
-            }
-            if (noMapping) {
-                return "No mapping configured for both users and groups: aborting...";
-            }
-
-            return doExecuteProvisioning(
-                    provisioningTask,
-                    connector,
-                    dryRun);
-        } catch (Throwable t) {
-            LOG.error("While executing provisioning job {}", getClass().getName(), t);
-            throw t;
-        }
-    }
-
-    protected abstract String doExecuteProvisioning(
-            final T task,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException;
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        final ProvisioningTask provTask = (ProvisioningTask) task;
-
-        // True if either failed and failures have to be registered, or if ALL has to be registered.
-        return (TaskJob.Status.valueOf(execution.getStatus()) == TaskJob.Status.FAILURE
-                && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
-                || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class<T> getTaskClassReference() {
-        return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
deleted file mode 100644
index f88982f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ /dev/null
@@ -1,434 +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.sync;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
-        implements SyncopePushResultHandler {
-
-    @Autowired
-    protected MappingUtils mappingUtils;
-
-    protected abstract String getName(Any<?> any);
-
-    protected void deprovision(final Any<?> any) {
-        AnyTO before = getAnyTO(any.getKey());
-
-        List<String> noPropResources = new ArrayList<>(before.getResources());
-        noPropResources.remove(profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getDeleteTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                null,
-                noPropResources));
-    }
-
-    protected void provision(final Any<?> any, final Boolean enabled) {
-        AnyTO before = getAnyTO(any.getKey());
-
-        List<String> noPropResources = new ArrayList<>(before.getResources());
-        noPropResources.remove(profile.getTask().getResource().getKey());
-
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getCreateTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                propByRes,
-                before.getVirAttrs(),
-                noPropResources));
-    }
-
-    @SuppressWarnings("unchecked")
-    protected void link(final Any<?> any, final Boolean unlink) {
-        AnyPatch patch = newPatch(any.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        update(patch);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected void unassign(final Any<?> any) {
-        AnyPatch patch = newPatch(any.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.DELETE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        update(patch);
-
-        deprovision(any);
-    }
-
-    protected void assign(final Any<?> any, final Boolean enabled) {
-        AnyPatch patch = newPatch(any.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        update(patch);
-
-        provision(any, enabled);
-    }
-
-    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
-        ConnectorObject obj = null;
-        try {
-            Uid uid = new Uid(connObjectKey);
-
-            obj = profile.getConnector().getObject(
-                    objectClass,
-                    uid,
-                    MappingUtils.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
-        } catch (TimeoutException toe) {
-            LOG.debug("Request timeout", toe);
-            throw toe;
-        } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", connObjectKey, ignore);
-        }
-
-        return obj;
-    }
-
-    @Transactional(propagation = Propagation.REQUIRES_NEW)
-    @Override
-    public boolean handle(final long anyKey) {
-        Any<?> any = null;
-        try {
-            any = getAny(anyKey);
-            doHandle(any);
-            return true;
-        } catch (IgnoreProvisionException e) {
-            ProvisioningReport result = new ProvisioningReport();
-            result.setOperation(ResourceOperation.NONE);
-            result.setAnyType(any == null ? null : any.getType().getKey());
-            result.setStatus(ProvisioningReport.Status.IGNORE);
-            result.setKey(anyKey);
-            profile.getResults().add(result);
-
-            LOG.warn("Ignoring during push", e);
-            return true;
-        } catch (JobExecutionException e) {
-            LOG.error("Push failed", e);
-            return false;
-        }
-    }
-
-    protected final void doHandle(final Any<?> any) throws JobExecutionException {
-        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-
-        ProvisioningReport result = new ProvisioningReport();
-        profile.getResults().add(result);
-
-        result.setKey(any.getKey());
-        result.setAnyType(any.getType().getKey());
-        result.setName(getName(any));
-
-        Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
-                ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
-                : null;
-
-        LOG.debug("Propagating {} with key {} towards {}",
-                anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
-
-        Object output = null;
-        Result resultStatus = null;
-        String operation = null;
-
-        // Try to read remote object BEFORE any actual operation
-        Provision provision = profile.getTask().getResource().getProvision(any.getType());
-        String connObjecKey = mappingUtils.getConnObjectKeyValue(any, provision);
-
-        ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
-
-        Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
-
-        if (profile.isDryRun()) {
-            if (beforeObj == null) {
-                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-            } else {
-                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-            }
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
-        } else {
-            try {
-                if (beforeObj == null) {
-                    operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule());
-                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-
-                    switch (profile.getTask().getUnmatchingRule()) {
-                        case ASSIGN:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeAssign(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformCreate()) {
-                                LOG.debug("PushTask not configured for create");
-                            } else {
-                                assign(any, status);
-                            }
-
-                            break;
-
-                        case PROVISION:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeProvision(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformCreate()) {
-                                LOG.debug("PushTask not configured for create");
-                            } else {
-                                provision(any, status);
-                            }
-
-                            break;
-
-                        case UNLINK:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                link(any, true);
-                            }
-
-                            break;
-
-                        case IGNORE:
-                            LOG.debug("Ignored any: {}", any);
-                            break;
-                        default:
-                        // do nothing
-                    }
-                } else {
-                    operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
-                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-
-                    switch (profile.getTask().getMatchingRule()) {
-                        case UPDATE:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUpdate(this.getProfile(), any);
-                            }
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                update(any, status);
-                            }
-
-                            break;
-
-                        case DEPROVISION:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeDeprovision(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformDelete()) {
-                                LOG.debug("PushTask not configured for delete");
-                            } else {
-                                deprovision(any);
-                            }
-
-                            break;
-
-                        case UNASSIGN:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUnassign(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformDelete()) {
-                                LOG.debug("PushTask not configured for delete");
-                            } else {
-                                unassign(any);
-                            }
-
-                            break;
-
-                        case LINK:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeLink(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                link(any, false);
-                            }
-
-                            break;
-
-                        case UNLINK:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                link(any, true);
-                            }
-
-                            break;
-
-                        case IGNORE:
-                            LOG.debug("Ignored any: {}", any);
-                            break;
-                        default:
-                        // do nothing
-                    }
-                }
-
-                for (PushActions action : profile.getActions()) {
-                    action.after(this.getProfile(), any, result);
-                }
-
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-                resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(connObjecKey, provision.getObjectClass());
-            } catch (IgnoreProvisionException e) {
-                throw e;
-            } catch (Exception e) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                resultStatus = AuditElements.Result.FAILURE;
-                output = e;
-
-                LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
-
-                for (PushActions action : profile.getActions()) {
-                    action.onError(this.getProfile(), any, result, e);
-                }
-
-                throw new JobExecutionException(e);
-            } finally {
-                notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
-                        any.getType().getKind().name().toLowerCase(),
-                        profile.getTask().getResource().getKey(),
-                        operation,
-                        resultStatus,
-                        beforeObj,
-                        output,
-                        any);
-                auditManager.audit(AuditElements.EventCategoryType.PUSH,
-                        any.getType().getKind().name().toLowerCase(),
-                        profile.getTask().getResource().getKey(),
-                        operation,
-                        resultStatus,
-                        connObjectUtils.getConnObjectTO(beforeObj),
-                        output instanceof ConnectorObject
-                                ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output,
-                        any);
-            }
-        }
-    }
-
-    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
-        switch (rule) {
-            case ASSIGN:
-            case PROVISION:
-                return ResourceOperation.CREATE;
-            default:
-                return ResourceOperation.NONE;
-        }
-    }
-
-    private ResourceOperation getResourceOperation(final MatchingRule rule) {
-        switch (rule) {
-            case UPDATE:
-                return ResourceOperation.UPDATE;
-            case DEPROVISION:
-            case UNASSIGN:
-                return ResourceOperation.DELETE;
-            default:
-                return ResourceOperation.NONE;
-        }
-    }
-
-    protected Any<?> update(final Any<?> any, final Boolean enabled) {
-        boolean changepwd;
-        Collection<String> resourceNames;
-        if (any instanceof User) {
-            changepwd = true;
-            resourceNames = userDAO.findAllResourceNames((User) any);
-        } else if (any instanceof AnyObject) {
-            changepwd = false;
-            resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any);
-        } else {
-            changepwd = false;
-            resourceNames = ((Group) any).getResourceNames();
-        }
-
-        List<String> noPropResources = new ArrayList<>(resourceNames);
-        noPropResources.remove(profile.getTask().getResource().getKey());
-
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getUpdateTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                changepwd,
-                null,
-                propByRes,
-                null,
-                noPropResources));
-
-        return getAny(any.getKey());
-    }
-}