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 2015/01/26 15:48:07 UTC

[01/12] syncope git commit: Fixed #SYNCOPE-581

Repository: syncope
Updated Branches:
  refs/heads/2_0_X 702810d8b -> 59bd58ce6


Fixed #SYNCOPE-581


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

Branch: refs/heads/2_0_X
Commit: c60066731b034948b0ea96fb50458cc90d41c2fd
Parents: e36a4a2
Author: massi <ma...@tirasa.net>
Authored: Fri Jan 23 16:37:13 2015 +0100
Committer: massi <ma...@tirasa.net>
Committed: Fri Jan 23 16:37:13 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/syncope/cli/SyncopeAdm.java |  19 +-
 .../syncope/cli/commands/AbstractCommand.java   |  11 +
 .../cli/commands/ConfigurationCommand.java      | 225 +++++++++++++++++++
 .../syncope/cli/commands/LoggerCommand.java     | 108 ++++++---
 4 files changed, 324 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/c6006673/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java b/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
index 4e8966e..296614f 100644
--- a/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
+++ b/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
@@ -20,6 +20,7 @@ package org.apache.syncope.cli;
 
 import com.beust.jcommander.JCommander;
 import com.beust.jcommander.ParameterException;
+import org.apache.syncope.cli.commands.ConfigurationCommand;
 import org.apache.syncope.cli.commands.LoggerCommand;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,11 +31,14 @@ public class SyncopeAdm {
 
     private static final String helpMessage = "Usage: Main [options]\n"
             + "  Options:\n"
-            + "    logger --help \n";
+            + "    logger --help \n"
+            + "    config --help \n";
+
+    private static final JCommander jcommander = new JCommander();
 
     private static LoggerCommand loggerCommand;
 
-    private static final JCommander jc = new JCommander();
+    private static ConfigurationCommand configurationCommand;
 
     public static void main(final String[] args) {
         LOG.debug("Starting with args \n");
@@ -49,7 +53,7 @@ public class SyncopeAdm {
             System.out.println(helpMessage);
         } else {
             try {
-                jc.parse(args);
+                jcommander.parse(args);
             } catch (final ParameterException ioe) {
                 System.out.println(helpMessage);
                 LOG.error("Parameter exception", ioe);
@@ -62,17 +66,22 @@ public class SyncopeAdm {
     private static void instantiateCommands() {
         LOG.debug("Init JCommander");
         loggerCommand = new LoggerCommand();
-        jc.addCommand(loggerCommand);
+        jcommander.addCommand(loggerCommand);
         LOG.debug("Added LoggerCommand");
+        configurationCommand = new ConfigurationCommand();
+        jcommander.addCommand(configurationCommand);
+        LOG.debug("Added ConfigurationCommand");
     }
 
     private static void executeCommand() {
-        final String command = jc.getParsedCommand();
+        final String command = jcommander.getParsedCommand();
 
         LOG.debug("Called command {}", command);
 
         if ("logger".equalsIgnoreCase(command)) {
             loggerCommand.execute();
+        } else if ("config".equalsIgnoreCase(command)) {
+            configurationCommand.execute();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c6006673/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
new file mode 100644
index 0000000..5dd3d38
--- /dev/null
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
@@ -0,0 +1,11 @@
+package org.apache.syncope.cli.commands;
+
+import com.beust.jcommander.Parameter;
+
+public abstract class AbstractCommand {
+
+    @Parameter(names = {"-h", "--help"})
+    protected boolean help = false;
+    
+    public abstract void execute();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/c6006673/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
new file mode 100644
index 0000000..f0f54ee
--- /dev/null
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
@@ -0,0 +1,225 @@
+/*
+ * 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.cli.commands;
+
+import com.beust.jcommander.DynamicParameter;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import java.io.File;
+import java.io.IOException;
+import java.io.SequenceInputStream;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.cli.SyncopeServices;
+import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.services.ConfigurationService;
+import org.apache.syncope.common.to.AttributeTO;
+import org.apache.syncope.common.to.ConfTO;
+import org.apache.syncope.common.wrap.MailTemplate;
+import org.apache.syncope.common.wrap.Validator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+@Parameters(
+        commandNames = "config",
+        optionPrefixes = "-",
+        separators = "=",
+        commandDescription = "Apache Syncope configuration service")
+public class ConfigurationCommand extends AbstractCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationCommand.class);
+
+    private static final Class SYNCOPE_CONFIGURATION_CLASS = ConfigurationService.class;
+
+    private static final String EXPORT_FILE_NAME = "/content.xml";
+
+    private final String helpMessage = "Usage: config [options]\n"
+            + "  Options:\n"
+            + "    -h, --help \n"
+            + "    -l, --list \n"
+            + "    -r, --read \n"
+            + "       Syntax: -r={CONF-NAME} \n"
+            + "    -u, --update \n"
+            + "       Syntax: {CONF-NAME}={CONF-VALUE} \n"
+            + "    -c, --create \n"
+            + "       Syntax: {CONF-NAME}={CONF-VALUE} \n"
+            + "    -d, --delete \n"
+            + "       Syntax: -d={CONF-NAME}"
+            + "    -v, --validators \n"
+            + "    -mt, --mail-templates \n"
+            + "    -e, --export \n"
+            + "       Syntax: -e={WHERE-DIR} \n";
+
+    @Parameter(names = {"-l", "--list"})
+    public boolean list = false;
+
+    @Parameter(names = {"-r", "--read"})
+    public String confNameToRead;
+
+    @DynamicParameter(names = {"-u", "--update"})
+    private final Map<String, String> updateConf = new HashMap<String, String>();
+
+    @DynamicParameter(names = {"-c", "--create"})
+    private final Map<String, String> createConf = new HashMap<String, String>();
+
+    @Parameter(names = {"-d", "--delete"})
+    public String confNameToDelete;
+
+    @Parameter(names = {"-v", "--validators"})
+    public boolean validators = false;
+
+    @Parameter(names = {"-mt", "--mail-templates"})
+    public boolean mailTemplates = false;
+
+    @Parameter(names = {"-e", "--export"})
+    public String export;
+
+    @Override
+    public void execute() {
+        final ConfigurationService configurationService = ((ConfigurationService) SyncopeServices.
+                get(SYNCOPE_CONFIGURATION_CLASS));
+
+        LOG.debug("Logger service successfully created");
+
+        if (help) {
+            LOG.debug("- configuration help command");
+            System.out.println(helpMessage);
+        } else if (list) {
+            LOG.debug("- configuration list command");
+            try {
+                final ConfTO confTO = configurationService.list();
+                for (final AttributeTO attrTO : confTO.getAttrMap().values()) {
+                    System.out.println(" - Conf " + attrTO.getSchema() + " has value(s) " + attrTO.getValues()
+                            + " - readonly: " + attrTO.isReadonly());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (StringUtils.isNotBlank(confNameToRead)) {
+            LOG.debug("- configuration read {} command", confNameToRead);
+            try {
+                final AttributeTO attrTO = configurationService.read(confNameToRead);
+                System.out.println(" - Conf " + attrTO.getSchema() + " has value(s) " + attrTO.getValues()
+                        + " - readonly: " + attrTO.isReadonly());
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (!updateConf.isEmpty()) {
+            LOG.debug("- configuration update command with params {}", updateConf);
+            try {
+                for (final Map.Entry<String, String> entrySet : updateConf.entrySet()) {
+                    final AttributeTO attrTO = configurationService.read(entrySet.getKey());
+                    attrTO.getValues().clear();
+                    attrTO.getValues().add(entrySet.getValue());
+                    configurationService.set(entrySet.getKey(), attrTO);
+                    System.out.println(" - Conf " + attrTO.getSchema() + " has value(s) " + attrTO.getValues()
+                            + " - readonly: " + attrTO.isReadonly());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (!createConf.isEmpty()) {
+            LOG.debug("- configuration create command with params {}", createConf);
+            try {
+                for (final Map.Entry<String, String> entrySet : createConf.entrySet()) {
+                    final AttributeTO attrTO = new AttributeTO();
+                    attrTO.setSchema(entrySet.getKey());
+                    attrTO.getValues().add(entrySet.getValue());
+                    configurationService.set(entrySet.getKey(), attrTO);
+                    System.out.println(" - Conf " + attrTO.getSchema() + " created with value(s) " + attrTO.getValues()
+                            + " - readonly: " + attrTO.isReadonly());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (StringUtils.isNotBlank(confNameToDelete)) {
+            try {
+                LOG.debug("- configuration delete {} command", confNameToDelete);
+                configurationService.delete(confNameToDelete);
+                System.out.println(" - Conf " + confNameToDelete + " deleted!");
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (validators) {
+            LOG.debug("- configuration validators command");
+            try {
+                for (final Validator validator : configurationService.getValidators()) {
+                    System.out.println(" - Conf validator class: " + validator.getElement());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (mailTemplates) {
+            LOG.debug("- configuration mailTemplates command");
+            try {
+                System.out.println(" - Conf mail template for:");
+                for (final MailTemplate mailTemplate : configurationService.getMailTemplates()) {
+                    System.out.println("    *** " + mailTemplate.getElement());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (StringUtils.isNotBlank(export)) {
+            LOG.debug("- configuration export command, directory where xml will be export: {}", export);
+
+            try {
+                TransformerFactory.newInstance().newTransformer()
+                        .transform(new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+                                                new InputSource(new StringReader(IOUtils.toString(
+                                                                        (SequenceInputStream) configurationService.
+                                                                        export().getEntity()))))),
+                                new StreamResult(new File(export + EXPORT_FILE_NAME)));
+                System.out.println(" - " + export + EXPORT_FILE_NAME + " successfully created");
+            } catch (final IOException ex) {
+                LOG.error("Error creating content.xml file in {} directory", export, ex);
+                System.out.println(" - Error creating " + export + EXPORT_FILE_NAME + " " + ex.getMessage());
+            } catch (final ParserConfigurationException ex) {
+                LOG.error("Error creating content.xml file in {} directory", export, ex);
+                System.out.println(" - Error creating " + export + EXPORT_FILE_NAME + " " + ex.getMessage());
+            } catch (final SAXException ex) {
+                LOG.error("Error creating content.xml file in {} directory", export, ex);
+                System.out.println(" - Error creating " + export + EXPORT_FILE_NAME + " " + ex.getMessage());
+            } catch (final TransformerConfigurationException ex) {
+                LOG.error("Error creating content.xml file in {} directory", export, ex);
+                System.out.println(" - Error creating " + export + EXPORT_FILE_NAME + " " + ex.getMessage());
+            } catch (final TransformerException ex) {
+                LOG.error("Error creating content.xml file in {} directory", export, ex);
+                System.out.println(" - Error creating " + export + EXPORT_FILE_NAME + " " + ex.getMessage());
+            } catch (final SyncopeClientException ex) {
+                LOG.error("Error calling configuration service", ex);
+                System.out.println(" - Error calling configuration service " + ex.getMessage());
+            }
+        } else {
+            System.out.println(helpMessage);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/c6006673/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
index 3c2a415..e4d3a1c 100644
--- a/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.cli.SyncopeServices;
 import org.apache.syncope.cli.validators.DebugLevelValidator;
+import org.apache.syncope.common.SyncopeClientException;
 import org.apache.syncope.common.services.LoggerService;
 import org.apache.syncope.common.to.LoggerTO;
 import org.apache.syncope.common.types.LoggerLevel;
@@ -38,43 +39,48 @@ import org.slf4j.LoggerFactory;
         optionPrefixes = "-",
         separators = "=",
         commandDescription = "Apache Syncope logger service")
-public class LoggerCommand {
+public class LoggerCommand extends AbstractCommand {
 
     private static final Logger LOG = LoggerFactory.getLogger(LoggerCommand.class);
 
-    private static final Class syncopeLoggerClass = LoggerService.class;
+    private static final Class SYNCOPE_LOGGER_CLASS = LoggerService.class;
 
     private final String helpMessage = "Usage: logger [options]\n"
             + "  Options:\n"
             + "    -h, --help \n"
             + "    -l, --list \n"
-            + "    -ua, --update-all \n"
-            + "       Syntax: -ua={LOGGER-LEVEL} \n"
+            + "    -r, --read \n"
+            + "       Syntax: -r={LOG-NAME} \n"
             + "    -u, --update \n"
             + "       Syntax: {LOG-NAME}={LOG-LEVEL} \n"
+            + "    -ua, --update-all \n"
+            + "       Syntax: -ua={LOG-LEVEL} \n"
+            + "    -c, --create \n"
+            + "       Syntax: {LOG-NAME}={LOG-LEVEL} \n"
             + "    -d, --delete \n"
-            + "       Syntax: -d={LOGGER-NAME}";
-
-    @Parameter(names = {"-h", "--help"})
-    public boolean help = false;
+            + "       Syntax: -d={LOG-NAME}";
 
     @Parameter(names = {"-l", "--list"})
     public boolean list = false;
 
+    @Parameter(names = {"-r", "--read"})
+    public String logNameToRead;
+
+    @DynamicParameter(names = {"-u", "--update"})
+    private final Map<String, String> updateLogs = new HashMap<String, String>();
+
     @Parameter(names = {"-ua", "--update-all"}, validateWith = DebugLevelValidator.class)
     public String logLevel;
 
-    @Parameter(names = {"-r", "--read"})
-    public String logNameToRead;
+    @DynamicParameter(names = {"-u", "--update"})
+    private final Map<String, String> createLogs = new HashMap<String, String>();
 
     @Parameter(names = {"-d", "--delete"})
     public String logNameToDelete;
 
-    @DynamicParameter(names = {"-u", "--update"})
-    private final Map<String, String> params = new HashMap<String, String>();
-
+    @Override
     public void execute() {
-        final LoggerService loggerService = ((LoggerService) SyncopeServices.get(syncopeLoggerClass));
+        final LoggerService loggerService = ((LoggerService) SyncopeServices.get(SYNCOPE_LOGGER_CLASS));
 
         LOG.debug("Logger service successfully created");
 
@@ -83,32 +89,66 @@ public class LoggerCommand {
             System.out.println(helpMessage);
         } else if (list) {
             LOG.debug("- logger list command");
-            for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
-                System.out.println(" - " + loggerTO.getName() + " -> " + loggerTO.getLevel());
+            try {
+                for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
+                    System.out.println(" - " + loggerTO.getName() + " -> " + loggerTO.getLevel());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (StringUtils.isNotBlank(logNameToRead)) {
+            LOG.debug("- logger read {} command", logNameToRead);
+            try {
+                final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, logNameToRead);
+                System.out.println(" - Logger " + loggerTO.getName() + " with level -> " + loggerTO.getLevel());
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (!updateLogs.isEmpty()) {
+            LOG.debug("- logger update command with params {}", updateLogs);
+            try {
+                for (final Map.Entry<String, String> entrySet : updateLogs.entrySet()) {
+                    final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, entrySet.getKey());
+                    loggerTO.setLevel(LoggerLevel.valueOf(entrySet.getValue()));
+                    loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
+                    System.out.println(" - Logger " + loggerTO.getName() + " new level -> " + loggerTO.getLevel());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
             }
         } else if (StringUtils.isNotBlank(logLevel)) {
             LOG.debug("- logger update all command with level {}", logLevel);
-            for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
-                loggerTO.setLevel(LoggerLevel.valueOf(logLevel));
-                loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
-                System.out.println(" - Logger " + loggerTO.getName() + " new value -> " + loggerTO.getLevel());
+            try {
+
+                for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
+                    loggerTO.setLevel(LoggerLevel.valueOf(logLevel));
+                    loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
+                    System.out.println(" - Logger " + loggerTO.getName() + " new level -> " + loggerTO.getLevel());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
             }
-        } else if (!params.isEmpty()) {
-            LOG.debug("- logger update command with params {}", params);
-            for (final Map.Entry<String, String> entrySet : params.entrySet()) {
-                final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, entrySet.getKey());
-                loggerTO.setLevel(LoggerLevel.valueOf(entrySet.getValue()));
-                loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
-                System.out.println(" - Logger " + loggerTO.getName() + " new value -> " + loggerTO.getLevel());
+        } else if (!createLogs.isEmpty()) {
+            LOG.debug("- logger create command with params {}", createLogs);
+            try {
+                for (final Map.Entry<String, String> entrySet : createLogs.entrySet()) {
+                    final LoggerTO loggerTO = new LoggerTO();
+                    loggerTO.setName(entrySet.getKey());
+                    loggerTO.setLevel(LoggerLevel.valueOf(entrySet.getValue()));
+                    loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
+                    System.out.println(" - Logger " + loggerTO.getName() + " created with level -> " + loggerTO.getLevel());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
             }
-        } else if (StringUtils.isNotBlank(logNameToRead)) {
-            LOG.debug("- logger read {} command", logNameToRead);
-            final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, logNameToRead);
-            System.out.println(" - Logger " + loggerTO.getName() + " with level -> " + loggerTO.getLevel());
         } else if (StringUtils.isNotBlank(logNameToDelete)) {
-            LOG.debug("- logger delete {} command", logNameToDelete);
-            loggerService.delete(LoggerType.LOG, logNameToDelete);
-            System.out.println(" - Logger " + logNameToDelete + " deleted!");
+            try {
+                LOG.debug("- logger delete {} command", logNameToDelete);
+                loggerService.delete(LoggerType.LOG, logNameToDelete);
+                System.out.println(" - Logger " + logNameToDelete + " deleted!");
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
         } else {
             System.out.println(helpMessage);
         }


[03/12] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/2_0_X
Commit: ed3993b6dfb7223c24e79e30898fe4bdd5654d2b
Parents: 172908d b2cac79
Author: massi <ma...@tirasa.net>
Authored: Fri Jan 23 16:39:20 2015 +0100
Committer: massi <ma...@tirasa.net>
Committed: Fri Jan 23 16:39:20 2015 +0100

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[05/12] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/2_0_X
Commit: 344a9400853a25fa324d0ca56c835b827952f99b
Parents: ed3993b 9df1e03
Author: massi <ma...@tirasa.net>
Authored: Mon Jan 26 10:08:00 2015 +0100
Committer: massi <ma...@tirasa.net>
Committed: Mon Jan 26 10:08:00 2015 +0100

----------------------------------------------------------------------
 .../core/rest/ConfigurationTestITCase.java      | 79 +++++++++++---------
 1 file changed, 42 insertions(+), 37 deletions(-)
----------------------------------------------------------------------



[06/12] syncope git commit: Fixed #SYNCOPE-587

Posted by il...@apache.org.
Fixed #SYNCOPE-587


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

Branch: refs/heads/2_0_X
Commit: f32528c1fb798ec51a6da7a43abaa1f52b1efe28
Parents: 344a940
Author: massi <ma...@tirasa.net>
Authored: Mon Jan 26 15:41:01 2015 +0100
Committer: massi <ma...@tirasa.net>
Committed: Mon Jan 26 15:41:01 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/syncope/cli/SyncopeAdm.java |  29 ++-
 .../syncope/cli/commands/AbstractCommand.java   |   7 +-
 .../cli/commands/ConfigurationCommand.java      |  27 +--
 .../syncope/cli/commands/LoggerCommand.java     |  59 +++---
 .../cli/commands/NotificationCommand.java       |  95 +++++++++
 .../syncope/cli/commands/PolicyCommand.java     | 107 ++++++++++
 .../syncope/cli/commands/ReportCommand.java     | 195 +++++++++++++++++++
 .../org/apache/syncope/cli/util/XmlUtils.java   |  28 +++
 cli/src/main/resources/syncope.properties       |   4 +-
 .../core/services/ReportServiceImpl.java        |   2 +-
 10 files changed, 504 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java b/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
index 296614f..da87d46 100644
--- a/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
+++ b/cli/src/main/java/org/apache/syncope/cli/SyncopeAdm.java
@@ -22,6 +22,9 @@ import com.beust.jcommander.JCommander;
 import com.beust.jcommander.ParameterException;
 import org.apache.syncope.cli.commands.ConfigurationCommand;
 import org.apache.syncope.cli.commands.LoggerCommand;
+import org.apache.syncope.cli.commands.NotificationCommand;
+import org.apache.syncope.cli.commands.PolicyCommand;
+import org.apache.syncope.cli.commands.ReportCommand;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,7 +35,10 @@ public class SyncopeAdm {
     private static final String helpMessage = "Usage: Main [options]\n"
             + "  Options:\n"
             + "    logger --help \n"
-            + "    config --help \n";
+            + "    config --help \n"
+            + "    notification --help \n"
+            + "    report --help \n"
+            + "    policy --help \n";
 
     private static final JCommander jcommander = new JCommander();
 
@@ -40,6 +46,12 @@ public class SyncopeAdm {
 
     private static ConfigurationCommand configurationCommand;
 
+    private static NotificationCommand notificationCommand;
+
+    private static ReportCommand reportCommand;
+
+    private static PolicyCommand policyCommand;
+
     public static void main(final String[] args) {
         LOG.debug("Starting with args \n");
 
@@ -71,6 +83,15 @@ public class SyncopeAdm {
         configurationCommand = new ConfigurationCommand();
         jcommander.addCommand(configurationCommand);
         LOG.debug("Added ConfigurationCommand");
+        notificationCommand = new NotificationCommand();
+        jcommander.addCommand(notificationCommand);
+        LOG.debug("Added NotificationCommand");
+        reportCommand = new ReportCommand();
+        jcommander.addCommand(reportCommand);
+        LOG.debug("Added ReportCommand");
+        policyCommand = new PolicyCommand();
+        jcommander.addCommand(policyCommand);
+        LOG.debug("Added PolicyCommand");
     }
 
     private static void executeCommand() {
@@ -82,6 +103,12 @@ public class SyncopeAdm {
             loggerCommand.execute();
         } else if ("config".equalsIgnoreCase(command)) {
             configurationCommand.execute();
+        } else if ("notification".equalsIgnoreCase(command)) {
+            notificationCommand.execute();
+        } else if ("report".equalsIgnoreCase(command)) {
+            reportCommand.execute();
+        } else if ("policy".equalsIgnoreCase(command)) {
+            policyCommand.execute();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
index 290f974..e7cddd4 100644
--- a/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
@@ -24,6 +24,9 @@ public abstract class AbstractCommand {
 
     @Parameter(names = {"-h", "--help"})
     protected boolean help = false;
-    
-    public abstract void execute();
+
+    @Parameter(names = {"-l", "--list"})
+    protected boolean list = false;
+
+    protected abstract void execute();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
index f0f54ee..5aea462 100644
--- a/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/ConfigurationCommand.java
@@ -21,22 +21,16 @@ package org.apache.syncope.cli.commands;
 import com.beust.jcommander.DynamicParameter;
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
-import java.io.File;
 import java.io.IOException;
 import java.io.SequenceInputStream;
-import java.io.StringReader;
 import java.util.HashMap;
 import java.util.Map;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.cxf.helpers.IOUtils;
 import org.apache.syncope.cli.SyncopeServices;
+import org.apache.syncope.cli.util.XmlUtils;
 import org.apache.syncope.common.SyncopeClientException;
 import org.apache.syncope.common.services.ConfigurationService;
 import org.apache.syncope.common.to.AttributeTO;
@@ -45,7 +39,6 @@ import org.apache.syncope.common.wrap.MailTemplate;
 import org.apache.syncope.common.wrap.Validator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 @Parameters(
@@ -78,9 +71,6 @@ public class ConfigurationCommand extends AbstractCommand {
             + "    -e, --export \n"
             + "       Syntax: -e={WHERE-DIR} \n";
 
-    @Parameter(names = {"-l", "--list"})
-    public boolean list = false;
-
     @Parameter(names = {"-r", "--read"})
     public String confNameToRead;
 
@@ -171,8 +161,9 @@ public class ConfigurationCommand extends AbstractCommand {
         } else if (validators) {
             LOG.debug("- configuration validators command");
             try {
+                System.out.println("Conf validator class: ");
                 for (final Validator validator : configurationService.getValidators()) {
-                    System.out.println(" - Conf validator class: " + validator.getElement());
+                    System.out.println("  *** " + validator.getElement());
                 }
             } catch (final SyncopeClientException ex) {
                 System.out.println(" - Error: " + ex.getMessage());
@@ -180,9 +171,9 @@ public class ConfigurationCommand extends AbstractCommand {
         } else if (mailTemplates) {
             LOG.debug("- configuration mailTemplates command");
             try {
-                System.out.println(" - Conf mail template for:");
+                System.out.println("Conf mail template for:");
                 for (final MailTemplate mailTemplate : configurationService.getMailTemplates()) {
-                    System.out.println("    *** " + mailTemplate.getElement());
+                    System.out.println("  *** " + mailTemplate.getElement());
                 }
             } catch (final SyncopeClientException ex) {
                 System.out.println(" - Error: " + ex.getMessage());
@@ -191,12 +182,8 @@ public class ConfigurationCommand extends AbstractCommand {
             LOG.debug("- configuration export command, directory where xml will be export: {}", export);
 
             try {
-                TransformerFactory.newInstance().newTransformer()
-                        .transform(new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
-                                                new InputSource(new StringReader(IOUtils.toString(
-                                                                        (SequenceInputStream) configurationService.
-                                                                        export().getEntity()))))),
-                                new StreamResult(new File(export + EXPORT_FILE_NAME)));
+                XmlUtils.createXMLFile((SequenceInputStream) configurationService.export().getEntity(), export
+                        + EXPORT_FILE_NAME);
                 System.out.println(" - " + export + EXPORT_FILE_NAME + " successfully created");
             } catch (final IOException ex) {
                 LOG.error("Error creating content.xml file in {} directory", export, ex);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
index e4d3a1c..f6007dd 100644
--- a/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/LoggerCommand.java
@@ -25,7 +25,6 @@ import java.util.HashMap;
 import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.cli.SyncopeServices;
-import org.apache.syncope.cli.validators.DebugLevelValidator;
 import org.apache.syncope.common.SyncopeClientException;
 import org.apache.syncope.common.services.LoggerService;
 import org.apache.syncope.common.to.LoggerTO;
@@ -60,19 +59,16 @@ public class LoggerCommand extends AbstractCommand {
             + "    -d, --delete \n"
             + "       Syntax: -d={LOG-NAME}";
 
-    @Parameter(names = {"-l", "--list"})
-    public boolean list = false;
-
     @Parameter(names = {"-r", "--read"})
     public String logNameToRead;
 
     @DynamicParameter(names = {"-u", "--update"})
     private final Map<String, String> updateLogs = new HashMap<String, String>();
 
-    @Parameter(names = {"-ua", "--update-all"}, validateWith = DebugLevelValidator.class)
+    @Parameter(names = {"-ua", "--update-all"})
     public String logLevel;
 
-    @DynamicParameter(names = {"-u", "--update"})
+    @DynamicParameter(names = {"-c", "--create"})
     private final Map<String, String> createLogs = new HashMap<String, String>();
 
     @Parameter(names = {"-d", "--delete"})
@@ -106,40 +102,57 @@ public class LoggerCommand extends AbstractCommand {
             }
         } else if (!updateLogs.isEmpty()) {
             LOG.debug("- logger update command with params {}", updateLogs);
-            try {
-                for (final Map.Entry<String, String> entrySet : updateLogs.entrySet()) {
-                    final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, entrySet.getKey());
-                    loggerTO.setLevel(LoggerLevel.valueOf(entrySet.getValue()));
+
+            for (final Map.Entry<String, String> log : updateLogs.entrySet()) {
+                final LoggerTO loggerTO = loggerService.read(LoggerType.LOG, log.getKey());
+                try {
+                    loggerTO.setLevel(LoggerLevel.valueOf(log.getValue()));
                     loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
                     System.out.println(" - Logger " + loggerTO.getName() + " new level -> " + loggerTO.getLevel());
+                } catch (final SyncopeClientException ex) {
+                    System.out.println(" - Error: " + ex.getMessage());
+                } catch (final IllegalArgumentException ex) {
+                    System.out.println(" - Error: " + log.getValue() + " isn't a valid logger level, try with:");
+                    for (final LoggerLevel level : LoggerLevel.values()) {
+                        System.out.println("  *** " + level.name());
+                    }
                 }
-            } catch (final SyncopeClientException ex) {
-                System.out.println(" - Error: " + ex.getMessage());
             }
         } else if (StringUtils.isNotBlank(logLevel)) {
             LOG.debug("- logger update all command with level {}", logLevel);
-            try {
-
-                for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
+            for (final LoggerTO loggerTO : loggerService.list(LoggerType.LOG)) {
+                try {
                     loggerTO.setLevel(LoggerLevel.valueOf(logLevel));
                     loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
                     System.out.println(" - Logger " + loggerTO.getName() + " new level -> " + loggerTO.getLevel());
+                } catch (final SyncopeClientException ex) {
+                    System.out.println(" - Error: " + ex.getMessage());
+                } catch (final IllegalArgumentException ex) {
+                    System.out.println(" - Error: " + loggerTO.getLevel() + " isn't a valid logger level, try with:");
+                    for (final LoggerLevel level : LoggerLevel.values()) {
+                        System.out.println("  *** " + level.name());
+                    }
                 }
-            } catch (final SyncopeClientException ex) {
-                System.out.println(" - Error: " + ex.getMessage());
             }
         } else if (!createLogs.isEmpty()) {
             LOG.debug("- logger create command with params {}", createLogs);
-            try {
-                for (final Map.Entry<String, String> entrySet : createLogs.entrySet()) {
-                    final LoggerTO loggerTO = new LoggerTO();
+
+            for (final Map.Entry<String, String> entrySet : createLogs.entrySet()) {
+                final LoggerTO loggerTO = new LoggerTO();
+                try {
                     loggerTO.setName(entrySet.getKey());
                     loggerTO.setLevel(LoggerLevel.valueOf(entrySet.getValue()));
                     loggerService.update(LoggerType.LOG, loggerTO.getName(), loggerTO);
-                    System.out.println(" - Logger " + loggerTO.getName() + " created with level -> " + loggerTO.getLevel());
+                    System.out.println(" - Logger " + loggerTO.getName() + " created with level -> " + loggerTO.
+                            getLevel());
+                } catch (final SyncopeClientException ex) {
+                    System.out.println(" - Error: " + ex.getMessage());
+                } catch (final IllegalArgumentException ex) {
+                    System.out.println(" - Error: " + loggerTO.getLevel() + " isn't a valid logger level, try with:");
+                    for (final LoggerLevel level : LoggerLevel.values()) {
+                        System.out.println("  *** " + level.name());
+                    }
                 }
-            } catch (final SyncopeClientException ex) {
-                System.out.println(" - Error: " + ex.getMessage());
             }
         } else if (StringUtils.isNotBlank(logNameToDelete)) {
             try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/commands/NotificationCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/NotificationCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/NotificationCommand.java
new file mode 100644
index 0000000..fdc0d37
--- /dev/null
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/NotificationCommand.java
@@ -0,0 +1,95 @@
+/*
+ * 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.cli.commands;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.syncope.cli.SyncopeServices;
+import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.services.NotificationService;
+import org.apache.syncope.common.to.NotificationTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Parameters(
+        commandNames = "notification",
+        optionPrefixes = "-",
+        separators = "=",
+        commandDescription = "Apache Syncope notification service")
+public class NotificationCommand extends AbstractCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationCommand.class);
+
+    private static final Class SYNCOPE_NOTIFICATION_CLASS = NotificationService.class;
+
+    private final String helpMessage = "Usage: notification [options]\n"
+            + "  Options:\n"
+            + "    -h, --help \n"
+            + "    -l, --list \n"
+            + "    -r, --read \n"
+            + "       Syntax: -r={NOTIFICATION-ID} \n"
+            + "    -d, --delete \n"
+            + "       Syntax: -d={NOTIFICATION-ID}";
+
+    @Parameter(names = {"-r", "--read"})
+    public Long notificationIdToRead = -1L;
+
+    @Parameter(names = {"-d", "--delete"})
+    public Long notificationIdToDelete = -1L;
+
+    @Override
+    public void execute() {
+        final NotificationService notificationService = ((NotificationService) SyncopeServices.get(
+                SYNCOPE_NOTIFICATION_CLASS));
+
+        LOG.debug("Notification service successfully created");
+
+        if (help) {
+            LOG.debug("- notification help command");
+            System.out.println(helpMessage);
+        } else if (list) {
+            LOG.debug("- notification list command");
+            try {
+                for (final NotificationTO notificationTO : notificationService.list()) {
+                    System.out.println(notificationTO);
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (notificationIdToRead > -1L) {
+            LOG.debug("- notification read {} command", notificationIdToRead);
+            try {
+                System.out.println(notificationService.read(notificationIdToRead));
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (notificationIdToDelete > -1L) {
+            try {
+                LOG.debug("- notification delete {} command", notificationIdToDelete);
+                notificationService.delete(notificationIdToDelete);
+                System.out.println(" - Notification " + notificationIdToDelete + " deleted!");
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else {
+            System.out.println(helpMessage);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/commands/PolicyCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/PolicyCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/PolicyCommand.java
new file mode 100644
index 0000000..d1574eb
--- /dev/null
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/PolicyCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.cli.commands;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.cli.SyncopeServices;
+import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.services.PolicyService;
+import org.apache.syncope.common.to.AbstractPolicyTO;
+import org.apache.syncope.common.types.PolicyType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Parameters(
+        commandNames = "policy",
+        optionPrefixes = "-",
+        separators = "=",
+        commandDescription = "Apache Syncope policy service")
+public class PolicyCommand extends AbstractCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PolicyCommand.class);
+
+    private static final Class SYNCOPE_POLICY_CLASS = PolicyService.class;
+
+    private final String helpMessage = "Usage: policy [options]\n"
+            + "  Options:\n"
+            + "    -h, --help \n"
+            + "    -l, --list \n"
+            + "    -ll, --list-policy \n"
+            + "       Syntax: -ll={POLICY-TYPE} \n"
+            + "    -r, --read \n"
+            + "       Syntax: -r={POLICY-ID} \n"
+            + "    -d, --delete \n"
+            + "       Syntax: -d={POLICY-ID}";
+
+    @Parameter(names = {"-ll", "--list-policy"})
+    public String policyType;
+
+    @Parameter(names = {"-r", "--read"})
+    public Long policyIdToRead = -1L;
+
+    @Parameter(names = {"-d", "--delete"})
+    public Long policyIdToDelete = -1L;
+
+    @Override
+    public void execute() {
+        final PolicyService policyService = (PolicyService) SyncopeServices.get(SYNCOPE_POLICY_CLASS);
+        LOG.debug("Policy service successfully created");
+
+        if (help) {
+            LOG.debug("- policy help command");
+            System.out.println(helpMessage);
+        } else if (list) {
+
+        } else if (StringUtils.isNotBlank(policyType)) {
+            LOG.debug("- policy list command for type {}", policyType);
+            try {
+                for (final AbstractPolicyTO policyTO : policyService.list(PolicyType.valueOf(policyType))) {
+                    System.out.println(policyTO);
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            } catch (final IllegalArgumentException ex) {
+                System.out.println(" - Error: " + policyType + " isn't a valid policy type, try with:");
+                for (final PolicyType type : PolicyType.values()) {
+                    System.out.println("  *** " + type.name() + ": " + type.getDescription());
+                }
+            }
+        } else if (policyIdToRead > -1L) {
+            LOG.debug("- policy read {} command", policyIdToRead);
+            try {
+                System.out.println(policyService.read(policyIdToRead));
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (policyIdToDelete > -1L) {
+            try {
+                LOG.debug("- policy delete {} command", policyIdToDelete);
+                policyService.delete(policyIdToDelete);
+                System.out.println(" - Report " + policyIdToDelete + " deleted!");
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else {
+            System.out.println(helpMessage);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/commands/ReportCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/ReportCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/ReportCommand.java
new file mode 100644
index 0000000..721503b
--- /dev/null
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/ReportCommand.java
@@ -0,0 +1,195 @@
+/*
+ * 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.cli.commands;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import java.io.IOException;
+import java.io.SequenceInputStream;
+import java.util.List;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import org.apache.syncope.cli.SyncopeServices;
+import org.apache.syncope.cli.util.XmlUtils;
+import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.services.ReportService;
+import org.apache.syncope.common.to.ReportExecTO;
+import org.apache.syncope.common.to.ReportTO;
+import org.apache.syncope.common.types.ReportExecExportFormat;
+import org.apache.syncope.common.wrap.ReportletConfClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+@Parameters(
+        commandNames = "report",
+        optionPrefixes = "-",
+        separators = "=",
+        commandDescription = "Apache Syncope report service")
+public class ReportCommand extends AbstractCommand {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ReportCommand.class);
+
+    private static final Class SYNCOPE_REPORT_CLASS = ReportService.class;
+
+    private final String helpMessage = "Usage: report [options]\n"
+            + "  Options:\n"
+            + "    -h, --help \n"
+            + "    -l, --list \n"
+            + "    -r, --read \n"
+            + "       Syntax: -r={POLICY-ID} \n"
+            + "    -d, --delete \n"
+            + "       Syntax: -d={POLICY-ID} \n"
+            + "    -e, --execute \n"
+            + "       Syntax: -e={POLICY-ID} \n"
+            + "    -re, --read-executecution \n"
+            + "       Syntax: -re={EXECUTION-ID} \n"
+            + "    -de, --delete-executecution \n"
+            + "       Syntax: -de={EXECUTION-ID} \n"
+            + "    -eer, --export-executecution-result \n"
+            + "       Syntax: -eer={EXECUTION-ID} \n"
+            + "    -rc, --reportlet-class";
+
+    @Parameter(names = {"-r", "--read"})
+    public Long reportIdToRead = -1L;
+
+    @Parameter(names = {"-d", "--delete"})
+    public Long reportIdToDelete = -1L;
+
+    @Parameter(names = {"-e", "--execute"})
+    public Long reportIdToExecute = -1L;
+
+    @Parameter(names = {"-re", "--read-execution"})
+    public Long executionIdToRead = -1L;
+
+    @Parameter(names = {"-de", "--delete-execution"})
+    public Long executionIdToDelete = -1L;
+
+    @Parameter(names = {"-eer", "--export-execution-result"})
+    public Long exportId = -1L;
+
+    @Parameter(names = {"-rc", "--reportlet-class"})
+    public boolean reportletClass = false;
+
+    @Override
+    public void execute() {
+        final ReportService reportService = (ReportService) SyncopeServices.get(SYNCOPE_REPORT_CLASS);
+        LOG.debug("Report service successfully created");
+
+        if (help) {
+            LOG.debug("- report help command");
+            System.out.println(helpMessage);
+        } else if (list) {
+            LOG.debug("- report list command");
+            try {
+                for (final ReportTO reportTO : reportService.list().getResult()) {
+                    System.out.println(reportTO);
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (reportIdToRead > -1L) {
+            LOG.debug("- report read {} command", reportIdToRead);
+            try {
+                System.out.println(reportService.read(reportIdToRead));
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (reportIdToDelete > -1L) {
+            try {
+                LOG.debug("- report delete {} command", reportIdToDelete);
+                reportService.delete(reportIdToDelete);
+                System.out.println(" - Report " + reportIdToDelete + " deleted!");
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (reportIdToExecute > -1L) {
+            try {
+                LOG.debug("- report execute {} command", reportIdToExecute);
+                reportService.execute(reportIdToExecute);
+                final List<ReportExecTO> executionList = reportService.read(reportIdToExecute).getExecutions();
+                final ReportExecTO lastExecution = executionList.get(executionList.size() - 1);
+                System.out.println(" - Report execution id: " + lastExecution.getId());
+                System.out.println(" - Report execution status: " + lastExecution.getStatus());
+                System.out.println(" - Report execution start date: " + lastExecution.getStartDate());
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (executionIdToRead > -1L) {
+            try {
+                LOG.debug("- report execution read {} command", executionIdToRead);
+                ReportExecTO reportExecTO = reportService.readExecution(executionIdToRead);
+                System.out.println(" - Report execution id: " + reportExecTO.getId());
+                System.out.println(" - Report execution status: " + reportExecTO.getStatus());
+                System.out.println(" - Report execution start date: " + reportExecTO.getStartDate());
+                System.out.println(" - Report execution end date: " + reportExecTO.getEndDate());
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (executionIdToDelete > -1L) {
+            try {
+                LOG.debug("- report execution delete {} command", executionIdToDelete);
+                reportService.deleteExecution(executionIdToDelete);
+                System.out.println(" - Report execution " + executionIdToDelete + "successfyllt deleted!");
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else if (exportId > -1L) {
+            LOG.debug("- report export command for report: {}", exportId);
+
+            try {
+                XmlUtils.createXMLFile((SequenceInputStream) reportService.exportExecutionResult(exportId,
+                        ReportExecExportFormat.XML).getEntity(), "export_" + exportId + ".xml");
+                System.out.println(" - " + "export_" + exportId + " successfully created");
+            } catch (final IOException ex) {
+                LOG.error("Error creating xml file", ex);
+                System.out.println(" - Error creating " + "export_" + exportId + " " + ex.getMessage());
+            } catch (final ParserConfigurationException ex) {
+                LOG.error("Error creating xml file", ex);
+                System.out.println(" - Error creating " + "export_" + exportId + " " + ex.getMessage());
+            } catch (final SAXException ex) {
+                LOG.error("Error creating xml file", ex);
+                System.out.println(" - Error creating " + "export_" + exportId + " " + ex.getMessage());
+            } catch (final TransformerConfigurationException ex) {
+                LOG.error("Error creating xml file", ex);
+                System.out.println(" - Error creating " + "export_" + exportId + " " + ex.getMessage());
+            } catch (final TransformerException ex) {
+                LOG.error("Error creating xml file", ex);
+                System.out.println(" - Error creating export_" + exportId + " " + ex.getMessage());
+            } catch (final SyncopeClientException ex) {
+                LOG.error("Error calling configuration service", ex);
+                System.out.println(" - Error calling configuration service " + ex.getMessage());
+            }
+        } else if (reportletClass) {
+            try {
+                LOG.debug("- reportlet configuration class list command");
+                System.out.println("Reportlet conf classes");
+                for (final ReportletConfClass reportletConfClass : reportService.getReportletConfClasses()) {
+                    System.out.println("  *** " + reportletConfClass.getElement());
+                }
+            } catch (final SyncopeClientException ex) {
+                System.out.println(" - Error: " + ex.getMessage());
+            }
+        } else {
+            System.out.println(helpMessage);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/java/org/apache/syncope/cli/util/XmlUtils.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/util/XmlUtils.java b/cli/src/main/java/org/apache/syncope/cli/util/XmlUtils.java
new file mode 100644
index 0000000..8da1fba
--- /dev/null
+++ b/cli/src/main/java/org/apache/syncope/cli/util/XmlUtils.java
@@ -0,0 +1,28 @@
+package org.apache.syncope.cli.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.SequenceInputStream;
+import java.io.StringReader;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.cxf.helpers.IOUtils;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class XmlUtils {
+
+    public static void createXMLFile(SequenceInputStream sis, String filePath)
+            throws TransformerConfigurationException, TransformerException, SAXException, IOException,
+            ParserConfigurationException {
+        TransformerFactory.newInstance().newTransformer()
+                .transform(new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+                                        new InputSource(new StringReader(IOUtils.toString(sis))))),
+                        new StreamResult(new File(filePath)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/cli/src/main/resources/syncope.properties
----------------------------------------------------------------------
diff --git a/cli/src/main/resources/syncope.properties b/cli/src/main/resources/syncope.properties
index e9fd513..9f84a72 100644
--- a/cli/src/main/resources/syncope.properties
+++ b/cli/src/main/resources/syncope.properties
@@ -14,6 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-syncope.rest.services=http://localhost:8080/syncope/rest/
+syncope.rest.services=http://localhost:9080/syncope/rest/
 syncope.user=admin
-syncope.password=password
\ No newline at end of file
+syncope.password=password

http://git-wip-us.apache.org/repos/asf/syncope/blob/f32528c1/core/src/main/java/org/apache/syncope/core/services/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/services/ReportServiceImpl.java b/core/src/main/java/org/apache/syncope/core/services/ReportServiceImpl.java
index 05ec25b..afe4d8d 100644
--- a/core/src/main/java/org/apache/syncope/core/services/ReportServiceImpl.java
+++ b/core/src/main/java/org/apache/syncope/core/services/ReportServiceImpl.java
@@ -50,7 +50,7 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
         ReportTO createdReportTO = controller.create(reportTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdReportTO.getId())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID.toString(), createdReportTO.getId()).
+                header(RESTHeaders.RESOURCE_ID, createdReportTO.getId()).
                 build();
     }
 


[04/12] syncope git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope

Posted by il...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/syncope


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

Branch: refs/heads/2_0_X
Commit: 9df1e03de222148e3e2bdc62d8e2870c555293fe
Parents: 336d8d6 b2cac79
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jan 23 17:43:00 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jan 23 17:43:00 2015 +0100

----------------------------------------------------------------------
 cli/pom.xml                                     | 186 +++++++++++++++++++
 .../java/org/apache/syncope/cli/SyncopeAdm.java |  78 ++++++++
 .../org/apache/syncope/cli/SyncopeServices.java |  41 ++++
 .../syncope/cli/commands/LoggerCommand.java     | 117 ++++++++++++
 .../cli/validators/DebugLevelValidator.java     |  61 ++++++
 cli/src/main/resources/log4j2.xml               |  58 ++++++
 cli/src/main/resources/syncope.properties       |  19 ++
 pom.xml                                         |   9 +-
 8 files changed, 568 insertions(+), 1 deletion(-)
----------------------------------------------------------------------



[02/12] syncope git commit: Fixed #SYNCOPE-581

Posted by il...@apache.org.
Fixed #SYNCOPE-581


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

Branch: refs/heads/2_0_X
Commit: 172908de1fcd055be242be2f932e080dc5b21b66
Parents: c600667
Author: massi <ma...@tirasa.net>
Authored: Fri Jan 23 16:38:48 2015 +0100
Committer: massi <ma...@tirasa.net>
Committed: Fri Jan 23 16:38:48 2015 +0100

----------------------------------------------------------------------
 .../syncope/cli/commands/AbstractCommand.java     | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/172908de/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java b/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
index 5dd3d38..290f974 100644
--- a/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
+++ b/cli/src/main/java/org/apache/syncope/cli/commands/AbstractCommand.java
@@ -1,3 +1,21 @@
+/*
+ * 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.cli.commands;
 
 import com.beust.jcommander.Parameter;


[10/12] syncope git commit: [SYNCOPE-620] IT with Activiti

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
index c144dbd..0c191f4 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
@@ -77,10 +77,7 @@ import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.common.lib.wrap.JobClass;
-import org.apache.syncope.common.lib.wrap.PushActionClass;
 import org.apache.syncope.common.lib.wrap.ResourceName;
-import org.apache.syncope.common.lib.wrap.SyncActionClass;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
@@ -151,21 +148,21 @@ public class TaskITCase extends AbstractITCase {
 
     @Test
     public void getJobClasses() {
-        List<JobClass> jobClasses = taskService.getJobClasses();
+        List<String> jobClasses = syncopeService.info().getTaskJobs();
         assertNotNull(jobClasses);
         assertFalse(jobClasses.isEmpty());
     }
 
     @Test
     public void getSyncActionsClasses() {
-        List<SyncActionClass> actions = taskService.getSyncActionsClasses();
+        List<String> actions = syncopeService.info().getSyncActions();
         assertNotNull(actions);
         assertFalse(actions.isEmpty());
     }
 
     @Test
     public void getPushActionsClasses() {
-        List<PushActionClass> actions = taskService.getPushActionsClasses();
+        List<String> actions = syncopeService.info().getPushActions();
         assertNotNull(actions);
     }
 
@@ -382,7 +379,8 @@ public class TaskITCase extends AbstractITCase {
             UserTO userTO = userService.read(inUserTO.getKey());
             assertNotNull(userTO);
             assertEquals(userName, userTO.getUsername());
-            assertEquals(ActivitiDetector.isActivitiEnabledForUsers() ? "active" : "created", userTO.getStatus());
+            assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                    ? "active" : "created", userTO.getStatus());
             assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
             assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
             assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
index 96ca3de..5df855a 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
@@ -806,7 +806,7 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void createActivate() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         UserTO userTO = getUniqueSampleTO("createActivate@syncope.apache.org");
 
@@ -844,7 +844,7 @@ public class UserITCase extends AbstractITCase {
         userTO = createUser(userTO);
 
         assertNotNull(userTO);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers()
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
                 ? "active"
                 : "created", userTO.getStatus());
 
@@ -877,7 +877,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getResources().add(RESOURCE_NAME_LDAP);
         userTO = createUser(userTO);
         assertNotNull(userTO);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers()
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
                 ? "active"
                 : "created", userTO.getStatus());
         long userId = userTO.getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
index 8795f06..1847422 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
@@ -63,7 +63,7 @@ public class UserSelfITCase extends AbstractITCase {
 
     @Test
     public void create() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         // 1. self-registration as admin: failure
         try {
@@ -84,7 +84,7 @@ public class UserSelfITCase extends AbstractITCase {
 
     @Test
     public void createAndApprove() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         // self-create user with membership: goes 'createApproval' with resources and membership but no propagation
         UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
@@ -153,13 +153,14 @@ public class UserSelfITCase extends AbstractITCase {
         UserTO updated = authClient.getService(UserSelfService.class).update(created.getKey(), userMod).
                 readEntity(UserTO.class);
         assertNotNull(updated);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers() ? "active" : "created", updated.getStatus());
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                ? "active" : "created", updated.getStatus());
         assertTrue(updated.getUsername().endsWith("XX"));
     }
 
     @Test
     public void updateWitApproval() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         // 1. create user as admin
         UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
@@ -227,7 +228,8 @@ public class UserSelfITCase extends AbstractITCase {
         SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
         UserTO deleted = authClient.getService(UserSelfService.class).delete().readEntity(UserTO.class);
         assertNotNull(deleted);
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers() ? "deleteApproval" : null, deleted.getStatus());
+        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                ? "deleteApproval" : null, deleted.getStatus());
     }
 
     @Test
@@ -238,7 +240,7 @@ public class UserSelfITCase extends AbstractITCase {
 
     @Test
     public void noContent() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         SyncopeClient anonClient = clientFactory.createAnonymous();
         UserSelfService noContentService = anonClient.prefer(UserSelfService.class, Preference.RETURN_NO_CONTENT);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
index 9c81d0f..c7354dd 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
@@ -49,7 +49,7 @@ public class UserWorkflowITCase extends AbstractITCase {
 
     @Test
     public void createWithReject() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
         userTO.getResources().add(RESOURCE_NAME_TESTDB);
@@ -118,7 +118,7 @@ public class UserWorkflowITCase extends AbstractITCase {
 
     @Test
     public void createWithApproval() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         // read forms *before* any operation
         List<WorkflowFormTO> forms = userWorkflowService.getForms();
@@ -201,7 +201,7 @@ public class UserWorkflowITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE15() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         // read forms *before* any operation
         List<WorkflowFormTO> forms = userWorkflowService.getForms();

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
index 161a23c..2f203e6 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.server.reference;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
@@ -33,14 +32,6 @@ import org.junit.Test;
 
 public class WorkflowITCase extends AbstractITCase {
 
-    @Test
-    public void isActivitiEnabled() {
-        assertEquals(ActivitiDetector.isActivitiEnabledForUsers(),
-                adminClient.isActivitiEnabledFor(SubjectType.USER));
-        assertEquals(ActivitiDetector.isActivitiEnabledForRoles(),
-                adminClient.isActivitiEnabledFor(SubjectType.ROLE));
-    }
-
     private void exportDefinition(final SubjectType type) throws IOException {
         Response response = workflowService.exportDefinition(type);
         assertTrue(response.getMediaType().toString().
@@ -53,13 +44,13 @@ public class WorkflowITCase extends AbstractITCase {
 
     @Test
     public void exportUserDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
         exportDefinition(SubjectType.USER);
     }
 
     @Test
     public void getRoleDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForRoles());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForRoles(syncopeService));
         exportDefinition(SubjectType.ROLE);
     }
 
@@ -72,14 +63,14 @@ public class WorkflowITCase extends AbstractITCase {
 
     @Test
     public void updateUserDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         importDefinition(SubjectType.USER);
     }
 
     @Test
     public void updateRoleDefinition() throws IOException {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForRoles());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForRoles(syncopeService));
 
         importDefinition(SubjectType.ROLE);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/resources/addActivitiToContent.xsl
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/resources/addActivitiToContent.xsl b/syncope620/fit/reference/src/test/resources/addActivitiToContent.xsl
new file mode 100644
index 0000000..44fd18e
--- /dev/null
+++ b/syncope620/fit/reference/src/test/resources/addActivitiToContent.xsl
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0">
+  
+  <xsl:template match="/dataset">
+    <dataset>
+      <xsl:apply-templates/>
+      
+      <ACT_RU_EXECUTION ID_="4" REV_="2" PROC_INST_ID_="4" PROC_DEF_ID_="userWorkflow:1:4" ACT_ID_="active" IS_ACTIVE_="1" IS_CONCURRENT_="0" IS_SCOPE_="1" IS_EVENT_SCOPE_="0" SUSPENSION_STATE_="1"/>
+      <ACT_RU_TASK ID_="5" REV_="2" EXECUTION_ID_="4" PROC_INST_ID_="4" PROC_DEF_ID_="userWorkflow:1:4" NAME_="Active" TASK_DEF_KEY_="active" PRIORITY_="50" CREATE_TIME_="2013-02-25T17:19:03+0100"/>
+
+      <ACT_RU_EXECUTION ID_="6" REV_="2" PROC_INST_ID_="6" PROC_DEF_ID_="userWorkflow:1:4" ACT_ID_="active" IS_ACTIVE_="1" IS_CONCURRENT_="0" IS_SCOPE_="1" IS_EVENT_SCOPE_="0" SUSPENSION_STATE_="1"/>
+      <ACT_RU_TASK ID_="7" REV_="2" EXECUTION_ID_="6" PROC_INST_ID_="6" PROC_DEF_ID_="userWorkflow:1:4" NAME_="Active" TASK_DEF_KEY_="active" PRIORITY_="50" CREATE_TIME_="2013-02-25T17:19:03+0100"/>
+
+      <ACT_RU_EXECUTION ID_="8" REV_="2" PROC_INST_ID_="8" PROC_DEF_ID_="userWorkflow:1:4" ACT_ID_="active" IS_ACTIVE_="1" IS_CONCURRENT_="0" IS_SCOPE_="1" IS_EVENT_SCOPE_="0" SUSPENSION_STATE_="1"/>
+      <ACT_RU_TASK ID_="9" REV_="2" EXECUTION_ID_="8" PROC_INST_ID_="8" PROC_DEF_ID_="userWorkflow:1:4" NAME_="Active" TASK_DEF_KEY_="active" PRIORITY_="50" CREATE_TIME_="2013-02-25T17:19:03+0100"/>
+
+      <ACT_RU_EXECUTION ID_="10" REV_="2" PROC_INST_ID_="10" PROC_DEF_ID_="userWorkflow:1:4" ACT_ID_="active" IS_ACTIVE_="1" IS_CONCURRENT_="0" IS_SCOPE_="1" IS_EVENT_SCOPE_="0" SUSPENSION_STATE_="1"/>
+      <ACT_RU_TASK ID_="11" REV_="2" EXECUTION_ID_="10" PROC_INST_ID_="10" PROC_DEF_ID_="userWorkflow:1:4" NAME_="Active" TASK_DEF_KEY_="active" PRIORITY_="50" CREATE_TIME_="2013-02-25T17:19:03+0100"/>
+
+      <ACT_RU_EXECUTION ID_="12" REV_="2" PROC_INST_ID_="12" PROC_DEF_ID_="userWorkflow:1:4" ACT_ID_="active" IS_ACTIVE_="1" IS_CONCURRENT_="0" IS_SCOPE_="1" IS_EVENT_SCOPE_="0" SUSPENSION_STATE_="1"/>
+      <ACT_RU_TASK ID_="13" REV_="2" EXECUTION_ID_="12" PROC_INST_ID_="12" PROC_DEF_ID_="userWorkflow:1:4" NAME_="Active" TASK_DEF_KEY_="active" PRIORITY_="50" CREATE_TIME_="2013-02-25T17:19:03+0100"/>
+    </dataset>
+  </xsl:template>
+  
+  <xsl:template match="node()|@*|comment()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/pom.xml b/syncope620/pom.xml
index e5f86d3..c7e6cf2 100644
--- a/syncope620/pom.xml
+++ b/syncope620/pom.xml
@@ -337,7 +337,7 @@ under the License.
 
     <cocoon.version>3.0.0-alpha-3</cocoon.version>
 
-    <groovy.version>2.3.9</groovy.version>
+    <groovy.version>2.4.0</groovy.version>
 
     <activiti.version>5.16.4</activiti.version>
 
@@ -986,6 +986,19 @@ under the License.
         </plugin>
         
         <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>xml-maven-plugin</artifactId>
+          <version>1.0</version>
+          <dependencies>
+            <dependency>
+              <groupId>xalan</groupId>
+              <artifactId>xalan</artifactId>
+              <version>2.7.1</version>
+            </dependency>
+          </dependencies>
+        </plugin>
+        
+        <plugin>
           <groupId>org.codehaus.cargo</groupId>
           <artifactId>cargo-maven2-plugin</artifactId>
           <version>1.4.12</version>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
index 7c6e43f..ac6b816 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ConfigurationLogic.java
@@ -18,14 +18,10 @@
  */
 package org.apache.syncope.server.logic;
 
-import java.io.IOException;
 import java.io.OutputStream;
 import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Set;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
-import org.apache.syncope.common.lib.wrap.Validator;
 import org.apache.syncope.server.persistence.api.content.ContentExporter;
 import org.apache.syncope.server.persistence.api.dao.ConfDAO;
 import org.apache.syncope.server.persistence.api.dao.NotFoundException;
@@ -33,12 +29,8 @@ import org.apache.syncope.server.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.server.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.server.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.server.provisioning.api.data.ConfigurationDataBinder;
-import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
 import org.apache.syncope.server.logic.init.WorkflowAdapterLoader;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManagerImpl;
-import org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.Resource;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -59,12 +51,6 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
     private ContentExporter exporter;
 
     @Autowired
-    private ImplementationClassNamesLoader classNamesLoader;
-
-    @javax.annotation.Resource(name = "velocityResourceLoader")
-    private ResourceWithFallbackLoader resourceLoader;
-
-    @Autowired
     private WorkflowAdapterLoader wfAdapterLoader;
 
     @PreAuthorize("hasRole('CONFIGURATION_DELETE')")
@@ -102,39 +88,6 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
         confDAO.save(binder.getAttribute(value));
     }
 
-    @PreAuthorize("hasRole('CONFIGURATION_LIST')")
-    public Set<String> getValidators() {
-        return classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.VALIDATOR);
-    }
-
-    @PreAuthorize("hasRole('CONFIGURATION_LIST')")
-    public Set<String> getMailTemplates() {
-        Set<String> htmlTemplates = new HashSet<>();
-        Set<String> textTemplates = new HashSet<>();
-
-        try {
-            for (Resource resource : resourceLoader.getResources(NotificationManagerImpl.MAIL_TEMPLATES + "*.vm")) {
-                String template = resource.getURL().toExternalForm();
-                if (template.endsWith(NotificationManagerImpl.MAIL_TEMPLATE_HTML_SUFFIX)) {
-                    htmlTemplates.add(template.substring(template.indexOf(NotificationManagerImpl.MAIL_TEMPLATES) + 14,
-                                    template.indexOf(NotificationManagerImpl.MAIL_TEMPLATE_HTML_SUFFIX)));
-                } else if (template.endsWith(NotificationManagerImpl.MAIL_TEMPLATE_TEXT_SUFFIX)) {
-                    textTemplates.add(template.substring(template.indexOf(NotificationManagerImpl.MAIL_TEMPLATES) + 14,
-                                    template.indexOf(NotificationManagerImpl.MAIL_TEMPLATE_TEXT_SUFFIX)));
-                } else {
-                    LOG.warn("Unexpected template found: {}, ignoring...", template);
-                }
-            }
-        } catch (IOException e) {
-            LOG.error("While searching for class implementing {}", Validator.class.getName(), e);
-        }
-
-        // Only templates available both as HTML and TEXT are considered
-        htmlTemplates.retainAll(textTemplates);
-
-        return htmlTemplates;
-    }
-
     @PreAuthorize("hasRole('CONFIGURATION_EXPORT')")
     @Transactional(readOnly = true)
     public void export(final OutputStream os) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/EntitlementLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/EntitlementLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/EntitlementLogic.java
index d0b051c..0a890ad 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/EntitlementLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/EntitlementLogic.java
@@ -37,7 +37,7 @@ public class EntitlementLogic extends AbstractTransactionalLogic<EntitlementTO>
 
     public List<String> getAll() {
         List<Entitlement> entitlements = entitlementDAO.findAll();
-        List<String> result = new ArrayList<String>(entitlements.size());
+        List<String> result = new ArrayList<>(entitlements.size());
         for (Entitlement entitlement : entitlements) {
             result.add(entitlement.getKey());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
index 3c9a614..49050fc 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
@@ -295,7 +295,7 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
             LOG.error("Failure retrieving audit/notification events", e);
         }
 
-        return new ArrayList<EventCategoryTO>(events);
+        return new ArrayList<>(events);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/NotificationLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/NotificationLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/NotificationLogic.java
index 3e4ce46..bfd0137 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/NotificationLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/NotificationLogic.java
@@ -101,21 +101,21 @@ public class NotificationLogic extends AbstractTransactionalLogic<NotificationTO
     protected NotificationTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
-        Long id = null;
+        Long key = null;
 
         if (ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; id == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof Long) {
-                    id = (Long) args[i];
+                    key = (Long) args[i];
                 } else if (args[i] instanceof NotificationTO) {
-                    id = ((NotificationTO) args[i]).getKey();
+                    key = ((NotificationTO) args[i]).getKey();
                 }
             }
         }
 
-        if ((id != null) && !id.equals(0l)) {
+        if ((key != null) && !key.equals(0l)) {
             try {
-                return binder.getNotificationTO(notificationDAO.find(id));
+                return binder.getNotificationTO(notificationDAO.find(key));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/PolicyLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/PolicyLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/PolicyLogic.java
index 1bc03de..062886e 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/PolicyLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/PolicyLogic.java
@@ -21,7 +21,6 @@ package org.apache.syncope.server.logic;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.to.AbstractPolicyTO;
 import org.apache.syncope.common.lib.to.AccountPolicyTO;
@@ -35,7 +34,6 @@ import org.apache.syncope.server.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.server.persistence.api.entity.Policy;
 import org.apache.syncope.server.persistence.api.entity.SyncPolicy;
 import org.apache.syncope.server.provisioning.api.data.PolicyDataBinder;
-import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -44,9 +42,6 @@ import org.springframework.stereotype.Component;
 public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> {
 
     @Autowired
-    private ImplementationClassNamesLoader classNamesLoader;
-
-    @Autowired
     private PolicyDAO policyDAO;
 
     @Autowired
@@ -160,11 +155,6 @@ public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> {
         return policyToDelete;
     }
 
-    @PreAuthorize("hasRole('POLICY_LIST')")
-    public Set<String> getSyncCorrelationRuleClasses() {
-        return classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_CORRELATION_RULES);
-    }
-
     /**
      * {@inheritDoc}
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
index e8502ec..22ebff9 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
@@ -161,18 +161,6 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
         return result;
     }
 
-    public Class<Reportlet> findReportletClassHavingConfClass(final Class<? extends ReportletConf> reportletConfClass) {
-        Class<Reportlet> result = null;
-        for (Class<Reportlet> reportletClass : getAllReportletClasses()) {
-            Class<? extends ReportletConf> found = getReportletConfClass(reportletClass);
-            if (found != null && found.equals(reportletConfClass)) {
-                result = reportletClass;
-            }
-        }
-
-        return result;
-    }
-
     @SuppressWarnings({ "unchecked", "rawtypes" })
     private Set<Class<Reportlet>> getAllReportletClasses() {
         Set<Class<Reportlet>> reportletClasses = new HashSet<>();
@@ -191,7 +179,6 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
     }
 
     @PreAuthorize("hasRole('REPORT_LIST')")
-    @SuppressWarnings("rawtypes")
     public Set<String> getReportletConfClasses() {
         Set<String> reportletConfClasses = new HashSet<>();
 
@@ -205,6 +192,18 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
         return reportletConfClasses;
     }
 
+    public Class<Reportlet> findReportletClassHavingConfClass(final Class<? extends ReportletConf> reportletConfClass) {
+        Class<Reportlet> result = null;
+        for (Class<Reportlet> reportletClass : getAllReportletClasses()) {
+            Class<? extends ReportletConf> found = getReportletConfClass(reportletClass);
+            if (found != null && found.equals(reportletConfClass)) {
+                result = reportletClass;
+            }
+        }
+
+        return result;
+    }
+
     @PreAuthorize("hasRole('REPORT_READ')")
     public ReportTO read(final Long reportKey) {
         Report report = reportDAO.find(reportKey);
@@ -360,30 +359,27 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
         return reportExecToDelete;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected ReportTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
-        Long id = null;
+        Long key = null;
 
         if (ArrayUtils.isNotEmpty(args) && ("create".equals(method.getName())
                 || "update".equals(method.getName())
                 || "delete".equals(method.getName()))) {
-            for (int i = 0; id == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof Long) {
-                    id = (Long) args[i];
+                    key = (Long) args[i];
                 } else if (args[i] instanceof ReportTO) {
-                    id = ((ReportTO) args[i]).getKey();
+                    key = ((ReportTO) args[i]).getKey();
                 }
             }
         }
 
-        if ((id != null) && !id.equals(0l)) {
+        if ((key != null) && !key.equals(0l)) {
             try {
-                return binder.getReportTO(reportDAO.find(id));
+                return binder.getReportTO(reportDAO.find(key));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java
index d18fc15..07d2795 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ResourceLogic.java
@@ -46,7 +46,6 @@ import org.apache.syncope.server.persistence.api.entity.Subject;
 import org.apache.syncope.server.provisioning.api.Connector;
 import org.apache.syncope.server.provisioning.api.ConnectorFactory;
 import org.apache.syncope.server.provisioning.api.data.ResourceDataBinder;
-import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
 import org.apache.syncope.server.misc.ConnObjectUtil;
 import org.apache.syncope.server.misc.MappingUtil;
 import org.identityconnectors.framework.common.objects.Attribute;
@@ -79,9 +78,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private ResourceDataBinder binder;
 
     @Autowired
-    private ImplementationClassNamesLoader classNamesLoader;
-
-    @Autowired
     private ConnObjectUtil connObjectUtil;
 
     @Autowired
@@ -162,14 +158,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         return binder.getResourceTO(resource);
     }
 
-    @PreAuthorize("hasRole('RESOURCE_READ')")
-    public Set<String> getPropagationActionsClasses() {
-        Set<String> actionsClasses = classNamesLoader.getClassNames(
-                ImplementationClassNamesLoader.Type.PROPAGATION_ACTIONS);
-
-        return actionsClasses;
-    }
-
     @PreAuthorize("isAuthenticated()")
     @Transactional(readOnly = true)
     public List<ResourceTO> list(final Long connInstanceId) {
@@ -268,28 +256,25 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         return res;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected ResourceTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
-        String name = null;
+        String key = null;
 
         if (ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; name == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof String) {
-                    name = (String) args[i];
+                    key = (String) args[i];
                 } else if (args[i] instanceof ResourceTO) {
-                    name = ((ResourceTO) args[i]).getKey();
+                    key = ((ResourceTO) args[i]).getKey();
                 }
             }
         }
 
-        if (name != null) {
+        if (key != null) {
             try {
-                return binder.getResourceTO(resourceDAO.find(name));
+                return binder.getResourceTO(resourceDAO.find(key));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/RoleLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/RoleLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/RoleLogic.java
index 838827c..f2175b9 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/RoleLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/RoleLogic.java
@@ -377,23 +377,23 @@ public class RoleLogic extends AbstractSubjectLogic<RoleTO, RoleMod> {
 
     @Override
     protected RoleTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException {
-        Long id = null;
+        Long key = null;
 
         if (ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; id == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof Long) {
-                    id = (Long) args[i];
+                    key = (Long) args[i];
                 } else if (args[i] instanceof RoleTO) {
-                    id = ((RoleTO) args[i]).getKey();
+                    key = ((RoleTO) args[i]).getKey();
                 } else if (args[i] instanceof RoleMod) {
-                    id = ((RoleMod) args[i]).getKey();
+                    key = ((RoleMod) args[i]).getKey();
                 }
             }
         }
 
-        if ((id != null) && !id.equals(0l)) {
+        if ((key != null) && !key.equals(0l)) {
             try {
-                return binder.getRoleTO(id);
+                return binder.getRoleTO(key);
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SchemaLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SchemaLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SchemaLogic.java
index ccf191f..7f70be0 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SchemaLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SchemaLogic.java
@@ -272,40 +272,37 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected AbstractSchemaTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
         String kind = null;
-        String name = null;
+        String key = null;
         if (ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; (name == null || kind == null) && i < args.length; i++) {
+            for (int i = 0; (key == null || kind == null) && i < args.length; i++) {
                 if (args[i] instanceof String) {
                     if (kind == null) {
                         kind = (String) args[i];
                     } else {
-                        name = (String) args[i];
+                        key = (String) args[i];
                     }
                 } else if (args[i] instanceof AbstractSchemaTO) {
-                    name = ((AbstractSchemaTO) args[i]).getKey();
+                    key = ((AbstractSchemaTO) args[i]).getKey();
                 }
             }
         }
 
-        if (name != null) {
+        if (key != null) {
             try {
                 final AttributableUtil attrUtil = attrUtilFactory.getInstance(kind);
 
                 AbstractSchemaTO result = null;
 
-                PlainSchema plainSchema = plainSchemaDAO.find(name, attrUtil.plainSchemaClass());
+                PlainSchema plainSchema = plainSchemaDAO.find(key, attrUtil.plainSchemaClass());
                 if (plainSchema == null) {
-                    DerSchema derSchema = derSchemaDAO.find(name, attrUtil.derSchemaClass());
+                    DerSchema derSchema = derSchemaDAO.find(key, attrUtil.derSchemaClass());
                     if (derSchema == null) {
-                        VirSchema virSchema = virSchemaDAO.find(name, attrUtil.virSchemaClass());
+                        VirSchema virSchema = virSchemaDAO.find(key, attrUtil.virSchemaClass());
                         if (virSchema != null) {
                             result = binder.getVirSchemaTO(virSchema);
                         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SecurityQuestionLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SecurityQuestionLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SecurityQuestionLogic.java
index 65f3ce2..749ee81 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SecurityQuestionLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SecurityQuestionLogic.java
@@ -124,21 +124,21 @@ public class SecurityQuestionLogic extends AbstractTransactionalLogic<SecurityQu
     protected SecurityQuestionTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
-        Long id = null;
+        Long key = null;
 
         if (ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; id == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof Long) {
-                    id = (Long) args[i];
+                    key = (Long) args[i];
                 } else if (args[i] instanceof SecurityQuestionTO) {
-                    id = ((SecurityQuestionTO) args[i]).getKey();
+                    key = ((SecurityQuestionTO) args[i]).getKey();
                 }
             }
         }
 
-        if ((id != null) && !id.equals(0l)) {
+        if ((key != null) && !key.equals(0l)) {
             try {
-                return binder.getSecurityQuestionTO(securityQuestionDAO.find(id));
+                return binder.getSecurityQuestionTO(securityQuestionDAO.find(key));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SyncopeLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SyncopeLogic.java
new file mode 100644
index 0000000..b706efd
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SyncopeLogic.java
@@ -0,0 +1,143 @@
+/*
+ * 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.server.logic;
+
+import static org.apache.syncope.server.logic.AbstractLogic.LOG;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+import javax.annotation.Resource;
+import org.apache.syncope.common.lib.to.SyncopeTO;
+import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
+import org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.server.provisioning.api.AttributableTransformer;
+import org.apache.syncope.server.provisioning.api.ConnIdBundleManager;
+import org.apache.syncope.server.provisioning.api.RoleProvisioningManager;
+import org.apache.syncope.server.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.server.provisioning.java.notification.NotificationManagerImpl;
+import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
+import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
+
+    @Resource(name = "version")
+    private String version;
+
+    @Autowired
+    private ConnIdBundleManager bundleManager;
+
+    @Autowired
+    private AttributableTransformer attrTransformer;
+
+    @Autowired
+    private UserWorkflowAdapter uwfAdapter;
+
+    @Autowired
+    private RoleWorkflowAdapter rwfAdapter;
+
+    @Autowired
+    private UserProvisioningManager uProvisioningManager;
+
+    @Autowired
+    private RoleProvisioningManager rProvisioningManager;
+
+    @Autowired
+    private ImplementationClassNamesLoader classNamesLoader;
+
+    @Resource(name = "velocityResourceLoader")
+    private ResourceWithFallbackLoader resourceLoader;
+
+    @PreAuthorize("isAuthenticated()")
+    public SyncopeTO info() {
+        SyncopeTO syncopeTO = new SyncopeTO();
+        syncopeTO.setVersion(version);
+
+        if (bundleManager.getLocations() != null) {
+            for (URI location : bundleManager.getLocations()) {
+                syncopeTO.getConnIdLocations().add(location.toASCIIString());
+            }
+        }
+
+        syncopeTO.setAttributableTransformer(attrTransformer.getClass().getName());
+
+        syncopeTO.setUserWorkflowAdapter(AopUtils.getTargetClass(uwfAdapter).getName());
+        syncopeTO.setRoleWorkflowAdapter(AopUtils.getTargetClass(rwfAdapter).getName());
+
+        syncopeTO.setUserProvisioningManager(uProvisioningManager.getClass().getName());
+        syncopeTO.setRoleProvisioningManager(rProvisioningManager.getClass().getName());
+
+        syncopeTO.getReportlets().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET));
+        syncopeTO.getTaskJobs().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOB));
+        syncopeTO.getPropagationActions().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PROPAGATION_ACTIONS));
+        syncopeTO.getSyncActions().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_ACTIONS));
+        syncopeTO.getPushActions().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_ACTIONS));
+        syncopeTO.getSyncCorrelationRules().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_CORRELATION_RULE));
+        syncopeTO.getPushCorrelationRules().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_CORRELATION_RULE));
+        syncopeTO.getValidators().addAll(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.VALIDATOR));
+
+        Set<String> htmlTemplates = new HashSet<>();
+        Set<String> textTemplates = new HashSet<>();
+        try {
+            for (org.springframework.core.io.Resource resource : resourceLoader.getResources(
+                    NotificationManagerImpl.MAIL_TEMPLATES + "*.vm")) {
+
+                String template = resource.getURL().toExternalForm();
+                if (template.endsWith(NotificationManagerImpl.MAIL_TEMPLATE_HTML_SUFFIX)) {
+                    htmlTemplates.add(template.substring(template.indexOf(NotificationManagerImpl.MAIL_TEMPLATES) + 14,
+                            template.indexOf(NotificationManagerImpl.MAIL_TEMPLATE_HTML_SUFFIX)));
+                } else if (template.endsWith(NotificationManagerImpl.MAIL_TEMPLATE_TEXT_SUFFIX)) {
+                    textTemplates.add(template.substring(template.indexOf(NotificationManagerImpl.MAIL_TEMPLATES) + 14,
+                            template.indexOf(NotificationManagerImpl.MAIL_TEMPLATE_TEXT_SUFFIX)));
+                } else {
+                    LOG.warn("Unexpected template found: {}, ignoring...", template);
+                }
+            }
+        } catch (IOException e) {
+            LOG.error("While searching for mail templates", e);
+        }
+        // Only templates available both as HTML and TEXT are considered
+        htmlTemplates.retainAll(textTemplates);
+        syncopeTO.getMailTemplates().addAll(htmlTemplates);
+
+        return syncopeTO;
+    }
+
+    @Override
+    protected SyncopeTO resolveReference(final Method method, final Object... args)
+            throws UnresolvedReferenceException {
+
+        throw new UnresolvedReferenceException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
index f97bc83..a7f9725 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
@@ -22,7 +22,6 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-import java.util.Set;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
@@ -50,7 +49,6 @@ import org.apache.syncope.server.provisioning.api.data.TaskDataBinder;
 import org.apache.syncope.server.provisioning.api.job.JobNamer;
 import org.apache.syncope.server.provisioning.api.job.TaskJob;
 import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
 import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.server.logic.notification.NotificationJob;
 import org.quartz.JobDataMap;
@@ -86,9 +84,6 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
     private SchedulerFactoryBean scheduler;
 
     @Autowired
-    private ImplementationClassNamesLoader classNamesLoader;
-
-    @Autowired
     private TaskUtilFactory taskUtilFactory;
 
     @PreAuthorize("hasRole('TASK_CREATE')")
@@ -162,21 +157,6 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         return taskTOs;
     }
 
-    @PreAuthorize("hasRole('TASK_LIST')")
-    public Set<String> getJobClasses() {
-        return classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOB);
-    }
-
-    @PreAuthorize("hasRole('TASK_LIST')")
-    public Set<String> getSyncActionsClasses() {
-        return classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_ACTIONS);
-    }
-
-    @PreAuthorize("hasRole('TASK_LIST')")
-    public Set<String> getPushActionsClasses() {
-        return classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_ACTIONS);
-    }
-
     @PreAuthorize("hasRole('TASK_READ')")
     public <T extends AbstractTaskTO> T read(final Long taskId) {
         Task task = taskDAO.find(taskId);
@@ -378,23 +358,23 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
     protected AbstractTaskTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
 
-        Long id = null;
+        Long key = null;
 
         if (ArrayUtils.isNotEmpty(args)
                 && !"deleteExecution".equals(method.getName()) && !"readExecution".equals(method.getName())) {
 
-            for (int i = 0; id == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof Long) {
-                    id = (Long) args[i];
+                    key = (Long) args[i];
                 } else if (args[i] instanceof AbstractTaskTO) {
-                    id = ((AbstractTaskTO) args[i]).getKey();
+                    key = ((AbstractTaskTO) args[i]).getKey();
                 }
             }
         }
 
-        if ((id != null) && !id.equals(0l)) {
+        if ((key != null) && !key.equals(0l)) {
             try {
-                final Task task = taskDAO.find(id);
+                final Task task = taskDAO.find(key);
                 return binder.getTaskTO(task, taskUtilFactory.getInstance(task));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
index 3e0de7e..c9b9249 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
@@ -508,25 +508,25 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
 
     @Override
     protected UserTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException {
-        Object id = null;
+        Object key = null;
 
         if (!"confirmPasswordReset".equals(method.getName()) && ArrayUtils.isNotEmpty(args)) {
-            for (int i = 0; id == null && i < args.length; i++) {
+            for (int i = 0; key == null && i < args.length; i++) {
                 if (args[i] instanceof Long) {
-                    id = (Long) args[i];
+                    key = (Long) args[i];
                 } else if (args[i] instanceof String) {
-                    id = (String) args[i];
+                    key = (String) args[i];
                 } else if (args[i] instanceof UserTO) {
-                    id = ((UserTO) args[i]).getKey();
+                    key = ((UserTO) args[i]).getKey();
                 } else if (args[i] instanceof UserMod) {
-                    id = ((UserMod) args[i]).getKey();
+                    key = ((UserMod) args[i]).getKey();
                 }
             }
         }
 
-        if ((id != null) && !id.equals(0l)) {
+        if ((key != null) && !key.equals(0l)) {
             try {
-                return id instanceof Long ? binder.getUserTO((Long) id) : binder.getUserTO((String) id);
+                return key instanceof Long ? binder.getUserTO((Long) key) : binder.getUserTO((String) key);
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/ImplementationClassNamesLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/ImplementationClassNamesLoader.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/ImplementationClassNamesLoader.java
index f7f608f..3546089 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/ImplementationClassNamesLoader.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/ImplementationClassNamesLoader.java
@@ -24,7 +24,6 @@ import java.util.EnumMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import org.apache.syncope.common.lib.wrap.Validator;
 import org.apache.syncope.server.provisioning.api.job.PushJob;
 import org.apache.syncope.server.provisioning.api.job.SyncJob;
 import org.apache.syncope.server.provisioning.api.job.TaskJob;
@@ -34,6 +33,7 @@ import org.apache.syncope.server.provisioning.api.sync.SyncActions;
 import org.apache.syncope.server.provisioning.api.sync.SyncCorrelationRule;
 import org.apache.syncope.server.logic.report.Reportlet;
 import org.apache.syncope.server.persistence.api.SyncopeLoader;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.Validator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,11 +54,11 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
 
         REPORTLET,
         TASKJOB,
+        PROPAGATION_ACTIONS,
         SYNC_ACTIONS,
         PUSH_ACTIONS,
-        SYNC_CORRELATION_RULES,
-        PUSH_CORRELATION_RULES,
-        PROPAGATION_ACTIONS,
+        SYNC_CORRELATION_RULE,
+        PUSH_CORRELATION_RULE,
         VALIDATOR
 
     }
@@ -116,10 +116,13 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
                     }
 
                     if (interfaces.contains(SyncCorrelationRule.class) && !metadata.isAbstract()) {
-                        classNames.get(Type.SYNC_CORRELATION_RULES).add(metadata.getClassName());
+                        classNames.get(Type.SYNC_CORRELATION_RULE).add(metadata.getClassName());
                     }
 
-                    // TODO: add push correlation rules management
+                    // TODO: SYNCOPE-631
+                    /* if (interfaces.contains(PushCorrelationRule.class) && !metadata.isAbstract()) {
+                     * classNames.get(Type.PUSH_CORRELATION_RULES).add(metadata.getClassName());
+                     * } */
                     if (interfaces.contains(PropagationActions.class) && !metadata.isAbstract()) {
                         classNames.get(Type.PROPAGATION_ACTIONS).add(metadata.getClassName());
                     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/logic/src/main/resources/logicContext.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/resources/logicContext.xml b/syncope620/server/logic/src/main/resources/logicContext.xml
index 273b8a2..6b9aa08 100644
--- a/syncope620/server/logic/src/main/resources/logicContext.xml
+++ b/syncope620/server/logic/src/main/resources/logicContext.xml
@@ -28,6 +28,10 @@ under the License.
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">
   
+  <bean id="version" class="java.lang.String">
+    <constructor-arg value="${syncope.version}"/>
+  </bean>
+
   <aop:aspectj-autoproxy/>
 
   <context:component-scan base-package="org.apache.syncope.server.logic"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/resources/content.xml b/syncope620/server/persistence-jpa/src/test/resources/content.xml
index ecbf06d..4d34efc 100644
--- a/syncope620/server/persistence-jpa/src/test/resources/content.xml
+++ b/syncope620/server/persistence-jpa/src/test/resources/content.xml
@@ -1014,7 +1014,7 @@ under the License.
                          serializedInstance='{"@class":"org.apache.syncope.common.lib.report.UserReportletConf","name":"testUserReportlet","matchingCond":null,"plainAttributes":["fullname","gender"],"derivedAttributes":["cn"],"virtualAttributes":["virtualdata"],"features":["key","username","workflowId","status","creationDate","lastLoginDate","changePwdDate","passwordHistorySize","failedLoginCount","memberships","resources"]}'/>
   <ReportExec Report_id="1" id="1" status="SUCCESS" startDate="2012-02-26 15:40:04" endDate="2012-02-26 15:41:04"/>
   
-  <SyncopeLogger logName="syncope.audit.[REST]:[EntitlementController]:[]:[getOwn]:[SUCCESS]" logLevel="DEBUG" logType="AUDIT"/>
+  <SyncopeLogger logName="syncope.audit.[REST]:[EntitlementLogic]:[]:[getOwn]:[SUCCESS]" logLevel="DEBUG" logType="AUDIT"/>
 
   <!-- Authentication and authorization -->
   <Entitlement name="base"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/ConnIdBundleManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/ConnIdBundleManager.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/ConnIdBundleManager.java
index 764f76e..68587af 100644
--- a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/ConnIdBundleManager.java
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/ConnIdBundleManager.java
@@ -41,6 +41,8 @@ public interface ConnIdBundleManager {
 
     void resetConnManagers();
 
+    List<URI> getLocations();
+
     void setStringLocations(final String stringLocations);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnIdBundleManagerImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnIdBundleManagerImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnIdBundleManagerImpl.java
index 78591e6..bf9dc02 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnIdBundleManagerImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnIdBundleManagerImpl.java
@@ -65,6 +65,13 @@ public class ConnIdBundleManagerImpl implements ConnIdBundleManager {
             Collections.synchronizedMap(new LinkedHashMap<URI, ConnectorInfoManager>());
 
     @Override
+    public List<URI> getLocations() {
+        init();
+
+        return locations;
+    }
+
+    @Override
     public void setStringLocations(final String stringLocations) {
         this.stringLocations = stringLocations;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
index 47a118f..94a6a4a 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
@@ -177,8 +177,8 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
                     throw new JobExecutionException("While updating SyncToken", e);
                 }
             }
-        } catch (Exception e) {
-            throw new JobExecutionException("While syncing on connector", e);
+        } catch (Throwable t) {
+            throw new JobExecutionException("While syncing on connector", t);
         }
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConfigurationServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConfigurationServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConfigurationServiceImpl.java
index 3a06c51..11c6bfd 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConfigurationServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConfigurationServiceImpl.java
@@ -20,16 +20,12 @@ package org.apache.syncope.server.rest.cxf.service;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.StreamingOutput;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
-import org.apache.syncope.common.lib.wrap.MailTemplate;
-import org.apache.syncope.common.lib.wrap.Validator;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.ConfigurationService;
 import org.apache.syncope.server.logic.ConfigurationLogic;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -64,16 +60,6 @@ public class ConfigurationServiceImpl extends AbstractServiceImpl implements Con
     }
 
     @Override
-    public List<MailTemplate> getMailTemplates() {
-        return CollectionWrapper.wrap(logic.getMailTemplates(), MailTemplate.class);
-    }
-
-    @Override
-    public List<Validator> getValidators() {
-        return CollectionWrapper.wrap(logic.getValidators(), Validator.class);
-    }
-
-    @Override
     public ConfTO list() {
         return logic.list();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
index da50761..976e9b6 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
@@ -27,8 +27,6 @@ import org.apache.syncope.common.lib.to.AccountPolicyTO;
 import org.apache.syncope.common.lib.to.PasswordPolicyTO;
 import org.apache.syncope.common.lib.to.SyncPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.wrap.CorrelationRuleClass;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.PolicyService;
 import org.apache.syncope.server.logic.PolicyLogic;
@@ -46,7 +44,7 @@ public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyServ
         AbstractPolicyTO policy = logic.create(policyTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(policy.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID.toString(), policy.getKey()).
+                header(RESTHeaders.RESOURCE_ID, policy.getKey()).
                 build();
     }
 
@@ -117,9 +115,4 @@ public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyServ
                 break;
         }
     }
-
-    @Override
-    public List<CorrelationRuleClass> getSyncCorrelationRuleClasses() {
-        return CollectionWrapper.wrap(logic.getSyncCorrelationRuleClasses(), CorrelationRuleClass.class);
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
index 82da1a9..cc28c50 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
@@ -30,9 +30,7 @@ import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.wrap.PropagationActionClass;
 import org.apache.syncope.common.lib.wrap.SubjectId;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.server.logic.AbstractResourceAssociator;
@@ -80,11 +78,6 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     }
 
     @Override
-    public List<PropagationActionClass> getPropagationActionsClasses() {
-        return CollectionWrapper.wrap(logic.getPropagationActionsClasses(), PropagationActionClass.class);
-    }
-
-    @Override
     public List<ResourceTO> list() {
         return logic.list(null);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SyncopeServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SyncopeServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SyncopeServiceImpl.java
new file mode 100644
index 0000000..d3e6334
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SyncopeServiceImpl.java
@@ -0,0 +1,38 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import org.apache.syncope.common.lib.to.SyncopeTO;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.syncope.server.logic.SyncopeLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SyncopeServiceImpl extends AbstractServiceImpl implements SyncopeService {
+
+    @Autowired
+    private SyncopeLogic logic;
+
+    @Override
+    public SyncopeTO info() {
+        return logic.info();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
index 717c15d..fc01f52 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
@@ -33,10 +33,6 @@ import org.apache.syncope.common.lib.to.SyncTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.lib.wrap.JobClass;
-import org.apache.syncope.common.lib.wrap.PushActionClass;
-import org.apache.syncope.common.lib.wrap.SyncActionClass;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.syncope.server.logic.TaskLogic;
@@ -81,21 +77,6 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     }
 
     @Override
-    public List<JobClass> getJobClasses() {
-        return CollectionWrapper.wrap(logic.getJobClasses(), JobClass.class);
-    }
-
-    @Override
-    public List<SyncActionClass> getSyncActionsClasses() {
-        return CollectionWrapper.wrap(logic.getSyncActionsClasses(), SyncActionClass.class);
-    }
-
-    @Override
-    public List<PushActionClass> getPushActionsClasses() {
-        return CollectionWrapper.wrap(logic.getPushActionsClasses(), PushActionClass.class);
-    }
-
-    @Override
     public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType) {
         return list(taskType, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/pom.xml b/syncope620/server/workflow-activiti/pom.xml
index 3d6db04..947ca5a 100644
--- a/syncope620/server/workflow-activiti/pom.xml
+++ b/syncope620/server/workflow-activiti/pom.xml
@@ -57,6 +57,11 @@ under the License.
     </dependency>
     
     <dependency>
+      <groupId>org.codehaus.groovy</groupId>
+      <artifactId>groovy-all</artifactId>
+    </dependency>
+      
+    <dependency>
       <groupId>org.apache.syncope.server</groupId>
       <artifactId>syncope-server-workflow-java</artifactId>
       <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
new file mode 100644
index 0000000..04ffdb6
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiDefinitionLoader.java
@@ -0,0 +1,104 @@
+/*
+ * 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.server.workflow.activiti;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import javax.annotation.Resource;
+import org.activiti.editor.constants.ModelDataJsonConstants;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class ActivitiDefinitionLoader implements WorkflowDefinitionLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ActivitiDefinitionLoader.class);
+
+    @Resource(name = "userWorkflowDef")
+    private ResourceWithFallbackLoader userWorkflowDef;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private SpringProcessEngineConfiguration conf;
+
+    @Autowired
+    private ActivitiImportUtils importUtils;
+
+    @Override
+    public String getPrefix() {
+        return "ACT_";
+    }
+
+    @Override
+    public void init() {
+        // jump to the next ID block
+        for (int i = 0; i < conf.getIdBlockSize(); i++) {
+            conf.getIdGenerator().getNextId();
+        }
+    }
+
+    @Override
+    public void load() {
+        List<ProcessDefinition> processes = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
+                ActivitiUserWorkflowAdapter.WF_PROCESS_ID).list();
+        LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes);
+
+        // Only loads process definition from file if not found in repository
+        if (processes.isEmpty()) {
+            InputStream wfIn = null;
+            try {
+                wfIn = userWorkflowDef.getResource().getInputStream();
+                repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
+                        new ByteArrayInputStream(IOUtils.toByteArray(wfIn))).deploy();
+
+                ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
+                        ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
+
+                Model model = repositoryService.newModel();
+                ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
+                modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, procDef.getName());
+                modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
+                modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, procDef.getDescription());
+                model.setMetaInfo(modelObjectNode.toString());
+                model.setName(procDef.getName());
+                model.setDeploymentId(procDef.getDeploymentId());
+                importUtils.fromJSON(procDef, model);
+
+                LOG.debug("Activiti Workflow definition loaded");
+            } catch (IOException e) {
+                LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+            } finally {
+                IOUtils.closeQuietly(wfIn);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiImportUtils.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiImportUtils.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiImportUtils.java
new file mode 100644
index 0000000..d09092e
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiImportUtils.java
@@ -0,0 +1,92 @@
+/*
+ * 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.server.workflow.activiti;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.activiti.bpmn.converter.BpmnXMLConverter;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.editor.language.json.converter.BpmnJsonConverter;
+import org.activiti.engine.ActivitiException;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.server.workflow.api.WorkflowException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ActivitiImportUtils {
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    public void fromXML(final byte[] definition) {
+        try {
+            repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
+                    new ByteArrayInputStream(definition)).deploy();
+        } catch (ActivitiException e) {
+            throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+        }
+    }
+
+    public void fromJSON(final byte[] definition, final ProcessDefinition procDef, final Model model) {
+        try {
+            model.setVersion(procDef.getVersion());
+            model.setDeploymentId(procDef.getDeploymentId());
+            repositoryService.saveModel(model);
+
+            repositoryService.addModelEditorSource(model.getId(), definition);
+        } catch (Exception e) {
+            throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+        }
+    }
+
+    public void fromJSON(final ProcessDefinition procDef, final Model model) {
+        InputStream bpmnStream = null;
+        InputStreamReader isr = null;
+        XMLStreamReader xtr = null;
+        try {
+            bpmnStream = repositoryService.getResourceAsStream(
+                    procDef.getDeploymentId(), procDef.getResourceName());
+            isr = new InputStreamReader(bpmnStream);
+            xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr);
+            BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
+
+            fromJSON(new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model);
+        } catch (Exception e) {
+            throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+        } finally {
+            if (xtr != null) {
+                try {
+                    xtr.close();
+                } catch (XMLStreamException e) {
+                    // ignore
+                }
+            }
+            IOUtils.closeQuietly(isr);
+            IOUtils.closeQuietly(bpmnStream);
+        }
+    }
+}


[08/12] syncope git commit: [SYNCOPE-620] IT with Activiti

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Update.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Update.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Update.java
new file mode 100644
index 0000000..731f7ac
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Update.java
@@ -0,0 +1,54 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Update extends AbstractActivitiServiceTask {
+
+    @Autowired
+    private UserDataBinder dataBinder;
+
+    @Override
+    protected void doExecute(final String executionId) {
+        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        UserMod userMod =
+                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class);
+
+        // update password internally only if required
+        UserMod actualMod = SerializationUtils.clone(userMod);
+        if (actualMod.getPwdPropRequest() != null && !actualMod.getPwdPropRequest().isOnSyncope()) {
+            actualMod.setPassword(null);
+        }
+        // update SyncopeUser
+        PropagationByResource propByRes = dataBinder.update(user, actualMod);
+
+        // report updated user and propagation by resource as result
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiDefinitionLoader.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiDefinitionLoader.java
deleted file mode 100644
index 05bcc94..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiDefinitionLoader.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.workflow.activiti;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import javax.annotation.Resource;
-import org.activiti.editor.constants.ModelDataJsonConstants;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.repository.Model;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.spring.SpringProcessEngineConfiguration;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class ActivitiDefinitionLoader implements WorkflowDefinitionLoader {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ActivitiDefinitionLoader.class);
-
-    @Resource(name = "userWorkflowDef")
-    private ResourceWithFallbackLoader userWorkflowDef;
-
-    @Autowired
-    private RepositoryService repositoryService;
-
-    @Autowired
-    private SpringProcessEngineConfiguration conf;
-
-    @Autowired
-    private ActivitiImportUtils importUtils;
-
-    @Override
-    public String getPrefix() {
-        return "ACT_";
-    }
-
-    @Override
-    public void init() {
-        // jump to the next ID block
-        for (int i = 0; i < conf.getIdBlockSize(); i++) {
-            conf.getIdGenerator().getNextId();
-        }
-    }
-
-    @Override
-    public void load() {
-        List<ProcessDefinition> processes = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                ActivitiUserWorkflowAdapter.WF_PROCESS_ID).list();
-        LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes);
-
-        // Only loads process definition from file if not found in repository
-        if (processes.isEmpty()) {
-            InputStream wfIn = null;
-            try {
-                wfIn = userWorkflowDef.getResource().getInputStream();
-                repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
-                        new ByteArrayInputStream(IOUtils.toByteArray(wfIn))).deploy();
-
-                ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                        ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
-
-                Model model = repositoryService.newModel();
-                ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
-                modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, procDef.getName());
-                modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
-                modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, procDef.getDescription());
-                model.setMetaInfo(modelObjectNode.toString());
-                model.setName(procDef.getName());
-                model.setDeploymentId(procDef.getDeploymentId());
-                importUtils.fromJSON(procDef, model);
-
-                LOG.debug("Activiti Workflow definition loaded");
-            } catch (IOException e) {
-                LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-            } finally {
-                IOUtils.closeQuietly(wfIn);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiImportUtils.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiImportUtils.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiImportUtils.java
deleted file mode 100644
index 388f7e9..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiImportUtils.java
+++ /dev/null
@@ -1,92 +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.workflow.activiti;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import org.activiti.bpmn.converter.BpmnXMLConverter;
-import org.activiti.bpmn.model.BpmnModel;
-import org.activiti.editor.language.json.converter.BpmnJsonConverter;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.repository.Model;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.server.workflow.api.WorkflowException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class ActivitiImportUtils {
-
-    @Autowired
-    private RepositoryService repositoryService;
-
-    public void fromXML(final byte[] definition) {
-        try {
-            repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
-                    new ByteArrayInputStream(definition)).deploy();
-        } catch (ActivitiException e) {
-            throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-        }
-    }
-
-    public void fromJSON(final byte[] definition, final ProcessDefinition procDef, final Model model) {
-        try {
-            model.setVersion(procDef.getVersion());
-            model.setDeploymentId(procDef.getDeploymentId());
-            repositoryService.saveModel(model);
-
-            repositoryService.addModelEditorSource(model.getId(), definition);
-        } catch (Exception e) {
-            throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-        }
-    }
-
-    public void fromJSON(final ProcessDefinition procDef, final Model model) {
-        InputStream bpmnStream = null;
-        InputStreamReader isr = null;
-        XMLStreamReader xtr = null;
-        try {
-            bpmnStream = repositoryService.getResourceAsStream(
-                    procDef.getDeploymentId(), procDef.getResourceName());
-            isr = new InputStreamReader(bpmnStream);
-            xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr);
-            BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
-
-            fromJSON(new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model);
-        } catch (Exception e) {
-            throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-        } finally {
-            if (xtr != null) {
-                try {
-                    xtr.close();
-                } catch (XMLStreamException e) {
-                    // ignore
-                }
-            }
-            IOUtils.closeQuietly(isr);
-            IOUtils.closeQuietly(bpmnStream);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiUserWorkflowAdapter.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiUserWorkflowAdapter.java
deleted file mode 100644
index 604848b..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ /dev/null
@@ -1,893 +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.workflow.activiti;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Resource;
-import javax.ws.rs.NotFoundException;
-import org.activiti.bpmn.converter.BpmnXMLConverter;
-import org.activiti.bpmn.model.BpmnModel;
-import org.activiti.editor.constants.ModelDataJsonConstants;
-import org.activiti.editor.language.json.converter.BpmnJsonConverter;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.FormService;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.TaskService;
-import org.activiti.engine.form.FormProperty;
-import org.activiti.engine.form.FormType;
-import org.activiti.engine.form.TaskFormData;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricDetail;
-import org.activiti.engine.history.HistoricTaskInstance;
-import org.activiti.engine.impl.persistence.entity.HistoricFormPropertyEntity;
-import org.activiti.engine.query.Query;
-import org.activiti.engine.repository.Model;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.task.Task;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.WorkflowFormPropertyType;
-import org.apache.syncope.server.misc.security.AuthContextUtil;
-import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
-import org.apache.syncope.server.misc.spring.BeanUtils;
-import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.server.persistence.api.attrvalue.validation.ParsingValidationException;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.WorkflowResult;
-import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionFormat;
-import org.apache.syncope.server.workflow.api.WorkflowException;
-import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
-import org.apache.syncope.server.workflow.java.AbstractUserWorkflowAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Activiti (http://www.activiti.org/) based implementation.
- */
-public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
-
-    /**
-     * Logger.
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(ActivitiUserWorkflowAdapter.class);
-
-    private static final String[] PROPERTY_IGNORE_PROPS = { "type" };
-
-    public static final String WF_PROCESS_ID = "userWorkflow";
-
-    public static final String WF_PROCESS_RESOURCE = "userWorkflow.bpmn20.xml";
-
-    public static final String WF_DGRM_RESOURCE = "userWorkflow.userWorkflow.png";
-
-    public static final String SYNCOPE_USER = "user";
-
-    public static final String WF_EXECUTOR = "wfExecutor";
-
-    public static final String FORM_SUBMITTER = "formSubmitter";
-
-    public static final String USER_TO = "userTO";
-
-    public static final String ENABLED = "enabled";
-
-    public static final String USER_MOD = "userMod";
-
-    public static final String EMAIL_KIND = "emailKind";
-
-    public static final String TASK = "task";
-
-    public static final String TOKEN = "token";
-
-    public static final String PASSWORD = "password";
-
-    public static final String PROP_BY_RESOURCE = "propByResource";
-
-    public static final String PROPAGATE_ENABLE = "propagateEnable";
-
-    public static final String ENCRYPTED_PWD = "encryptedPwd";
-
-    public static final String TASK_IS_FORM = "taskIsForm";
-
-    public static final String MODEL_DATA_JSON_MODEL = "model";
-
-    public static final String STORE_PASSWORD = "storePassword";
-
-    public static final String EVENT = "event";
-
-    @Resource(name = "adminUser")
-    private String adminUser;
-
-    @Autowired
-    private RuntimeService runtimeService;
-
-    @Autowired
-    private TaskService taskService;
-
-    @Autowired
-    private FormService formService;
-
-    @Autowired
-    private HistoryService historyService;
-
-    @Autowired
-    private RepositoryService repositoryService;
-
-    @Autowired
-    private ActivitiImportUtils importUtils;
-
-    @Autowired
-    private UserDataBinder userDataBinder;
-
-    @Override
-    public Class<? extends WorkflowDefinitionLoader> getDefinitionLoaderClass() {
-        return ActivitiDefinitionLoader.class;
-    }
-
-    private void throwException(final ActivitiException e, final String defaultMessage) {
-        if (e.getCause() != null) {
-            if (e.getCause().getCause() instanceof SyncopeClientException) {
-                throw (SyncopeClientException) e.getCause().getCause();
-            } else if (e.getCause().getCause() instanceof ParsingValidationException) {
-                throw (ParsingValidationException) e.getCause().getCause();
-            } else if (e.getCause().getCause() instanceof InvalidEntityException) {
-                throw (InvalidEntityException) e.getCause().getCause();
-            }
-        }
-
-        throw new WorkflowException(defaultMessage, e);
-    }
-
-    private void updateStatus(final User user) {
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
-        if (tasks.isEmpty() || tasks.size() > 1) {
-            LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
-        } else {
-            user.setStatus(tasks.get(0).getTaskDefinitionKey());
-        }
-    }
-
-    private String getFormTask(final User user) {
-        String result = null;
-
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
-        if (tasks.isEmpty() || tasks.size() > 1) {
-            LOG.warn("While checking if form task: unexpected task number ({})", tasks.size());
-        } else {
-            try {
-                TaskFormData formData = formService.getTaskFormData(tasks.get(0).getId());
-                if (formData != null && !formData.getFormProperties().isEmpty()) {
-                    result = tasks.get(0).getId();
-                }
-            } catch (ActivitiException e) {
-                LOG.warn("Could not get task form data", e);
-            }
-        }
-
-        return result;
-    }
-
-    private Set<String> getPerformedTasks(final User user) {
-        final Set<String> result = new HashSet<>();
-
-        for (HistoricActivityInstance task
-                : historyService.createHistoricActivityInstanceQuery().executionId(user.getWorkflowId()).list()) {
-
-            result.add(task.getActivityId());
-        }
-
-        return result;
-    }
-
-    /**
-     * Saves resources to be propagated and password for later - after form submission - propagation.
-     */
-    private void saveForFormSubmit(final User user, final String password,
-            final PropagationByResource propByRes) {
-
-        String formTaskId = getFormTask(user);
-        if (formTaskId != null) {
-            // SYNCOPE-238: This is needed to simplify the task query in this.getForms()
-            taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
-            runtimeService.setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
-            if (propByRes != null) {
-                propByRes.clear();
-            }
-
-            if (StringUtils.isNotBlank(password)) {
-                runtimeService.setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
-            }
-        }
-    }
-
-    @Override
-    public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
-            final boolean storePassword) throws WorkflowException {
-
-        return create(userTO, disablePwdPolicyCheck, null, storePassword);
-    }
-
-    @Override
-    public WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean storePassword) throws
-            UnauthorizedRoleException, WorkflowException {
-
-        return create(userTO, false, storePassword);
-    }
-
-    @Override
-    public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
-            final Boolean enabled, final boolean storePassword) throws WorkflowException {
-
-        final Map<String, Object> variables = new HashMap<>();
-        variables.put(WF_EXECUTOR, AuthContextUtil.getAuthenticatedUsername());
-        variables.put(USER_TO, userTO);
-        variables.put(ENABLED, enabled);
-        variables.put(STORE_PASSWORD, storePassword);
-
-        ProcessInstance processInstance = null;
-        try {
-            processInstance = runtimeService.startProcessInstanceByKey(WF_PROCESS_ID, variables);
-        } catch (ActivitiException e) {
-            throwException(e, "While starting " + WF_PROCESS_ID + " instance");
-        }
-
-        User user =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), SYNCOPE_USER, User.class);
-
-        Boolean updatedEnabled =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
-        if (updatedEnabled != null) {
-            user.setSuspended(!updatedEnabled);
-        }
-
-        // this will make UserValidator not to consider password policies at all
-        if (disablePwdPolicyCheck) {
-            user.removeClearPassword();
-        }
-
-        updateStatus(user);
-        user = userDAO.save(user);
-
-        Boolean propagateEnable =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
-        if (propagateEnable == null) {
-            propagateEnable = enabled;
-        }
-
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.set(ResourceOperation.CREATE, user.getResourceNames());
-
-        saveForFormSubmit(user, userTO.getPassword(), propByRes);
-
-        return new WorkflowResult<Map.Entry<Long, Boolean>>(
-                new SimpleEntry<>(user.getKey(), propagateEnable), propByRes, getPerformedTasks(user));
-    }
-
-    private Set<String> doExecuteTask(final User user, final String task,
-            final Map<String, Object> moreVariables) throws WorkflowException {
-
-        Set<String> preTasks = getPerformedTasks(user);
-
-        final Map<String, Object> variables = new HashMap<>();
-        variables.put(WF_EXECUTOR, AuthContextUtil.getAuthenticatedUsername());
-        variables.put(TASK, task);
-
-        // using BeanUtils to access all user's properties and trigger lazy loading - we are about to
-        // serialize a User instance for availability within workflow tasks, and this breaks transactions
-        BeanUtils.copyProperties(user, entityFactory.newEntity(User.class));
-        variables.put(SYNCOPE_USER, user);
-
-        if (moreVariables != null && !moreVariables.isEmpty()) {
-            variables.putAll(moreVariables);
-        }
-
-        if (StringUtils.isBlank(user.getWorkflowId())) {
-            throw new WorkflowException(new NotFoundException("Empty workflow id for " + user));
-        }
-
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
-        if (tasks.size() == 1) {
-            try {
-                taskService.complete(tasks.get(0).getId(), variables);
-            } catch (ActivitiException e) {
-                throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user);
-            }
-        } else {
-            LOG.warn("Expected a single task, found {}", tasks.size());
-        }
-
-        Set<String> postTasks = getPerformedTasks(user);
-        postTasks.removeAll(preTasks);
-        postTasks.add(task);
-        return postTasks;
-    }
-
-    @Override
-    protected WorkflowResult<Long> doActivate(final User user, final String token)
-            throws WorkflowException {
-
-        Set<String> tasks = doExecuteTask(user, "activate", Collections.singletonMap(TOKEN, (Object) token));
-
-        updateStatus(user);
-        User updated = userDAO.save(user);
-
-        return new WorkflowResult<>(updated.getKey(), null, tasks);
-    }
-
-    @Override
-    protected WorkflowResult<Map.Entry<UserMod, Boolean>> doUpdate(final User user, final UserMod userMod)
-            throws WorkflowException {
-
-        Set<String> tasks = doExecuteTask(user, "update", Collections.singletonMap(USER_MOD, (Object) userMod));
-
-        updateStatus(user);
-        User updated = userDAO.save(user);
-
-        PropagationByResource propByRes =
-                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
-
-        saveForFormSubmit(updated, userMod.getPassword(), propByRes);
-
-        Boolean propagateEnable = runtimeService.getVariable(user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
-
-        return new WorkflowResult<Map.Entry<UserMod, Boolean>>(
-                new SimpleEntry<>(userMod, propagateEnable), propByRes, tasks);
-    }
-
-    @Override
-    @Transactional(rollbackFor = { Throwable.class })
-    protected WorkflowResult<Long> doSuspend(final User user) throws WorkflowException {
-        Set<String> performedTasks = doExecuteTask(user, "suspend", null);
-        updateStatus(user);
-        User updated = userDAO.save(user);
-
-        return new WorkflowResult<>(updated.getKey(), null, performedTasks);
-    }
-
-    @Override
-    protected WorkflowResult<Long> doReactivate(final User user) throws WorkflowException {
-        Set<String> performedTasks = doExecuteTask(user, "reactivate", null);
-        updateStatus(user);
-
-        User updated = userDAO.save(user);
-
-        return new WorkflowResult<>(updated.getKey(), null, performedTasks);
-    }
-
-    @Override
-    protected void doRequestPasswordReset(final User user) throws WorkflowException {
-        Map<String, Object> variables = new HashMap<>(2);
-        variables.put(USER_TO, userDataBinder.getUserTO(user));
-        variables.put(EVENT, "requestPasswordReset");
-
-        doExecuteTask(user, "requestPasswordReset", variables);
-        userDAO.save(user);
-    }
-
-    @Override
-    protected void doConfirmPasswordReset(final User user, final String token, final String password)
-            throws WorkflowException {
-
-        Map<String, Object> variables = new HashMap<>(4);
-        variables.put(TOKEN, token);
-        variables.put(PASSWORD, password);
-        variables.put(USER_TO, userDataBinder.getUserTO(user));
-        variables.put(EVENT, "confirmPasswordReset");
-
-        doExecuteTask(user, "confirmPasswordReset", variables);
-        userDAO.save(user);
-    }
-
-    @Override
-    protected void doDelete(final User user) throws WorkflowException {
-        doExecuteTask(user, "delete", null);
-
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.set(ResourceOperation.DELETE, user.getResourceNames());
-
-        saveForFormSubmit(user, null, propByRes);
-
-        if (runtimeService.createProcessInstanceQuery().
-                processInstanceId(user.getWorkflowId()).active().list().isEmpty()) {
-
-            userDAO.delete(user.getKey());
-
-            if (!historyService.createHistoricProcessInstanceQuery().
-                    processInstanceId(user.getWorkflowId()).list().isEmpty()) {
-
-                historyService.deleteHistoricProcessInstance(user.getWorkflowId());
-            }
-        } else {
-            updateStatus(user);
-            userDAO.save(user);
-        }
-    }
-
-    @Override
-    public WorkflowResult<Long> execute(final UserTO userTO, final String taskId)
-            throws UnauthorizedRoleException, WorkflowException {
-
-        User user = userDAO.authFetch(userTO.getKey());
-
-        final Map<String, Object> variables = new HashMap<>();
-        variables.put(USER_TO, userTO);
-
-        Set<String> performedTasks = doExecuteTask(user, taskId, variables);
-        updateStatus(user);
-        User updated = userDAO.save(user);
-
-        return new WorkflowResult<>(updated.getKey(), null, performedTasks);
-    }
-
-    protected ProcessDefinition getProcessDefinition() {
-        try {
-            return repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                    ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
-        } catch (ActivitiException e) {
-            throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
-        }
-
-    }
-
-    protected Model getModel(final ProcessDefinition procDef) {
-        try {
-            Model model = repositoryService.createModelQuery().deploymentId(procDef.getDeploymentId()).singleResult();
-            if (model == null) {
-                throw new NotFoundException("Could not find Model for deployment " + procDef.getDeploymentId());
-            }
-            return model;
-        } catch (Exception e) {
-            throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
-        }
-    }
-
-    protected void exportProcessResource(final String resourceName, final OutputStream os) {
-        ProcessDefinition procDef = getProcessDefinition();
-
-        InputStream procDefIS = repositoryService.getResourceAsStream(procDef.getDeploymentId(), resourceName);
-        try {
-            IOUtils.copy(procDefIS, os);
-        } catch (IOException e) {
-            LOG.error("While exporting workflow definition {}", procDef.getKey(), e);
-        } finally {
-            IOUtils.closeQuietly(procDefIS);
-        }
-    }
-
-    protected void exportProcessModel(final OutputStream os) {
-        Model model = getModel(getProcessDefinition());
-
-        ObjectMapper objectMapper = new ObjectMapper();
-        try {
-            ObjectNode modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
-            modelNode.put(ModelDataJsonConstants.MODEL_ID, model.getKey());
-            modelNode.replace(MODEL_DATA_JSON_MODEL,
-                    objectMapper.readTree(repositoryService.getModelEditorSource(model.getKey())));
-
-            os.write(modelNode.toString().getBytes());
-        } catch (IOException e) {
-            LOG.error("While exporting workflow definition {}", model.getKey(), e);
-        }
-    }
-
-    @Override
-    public void exportDefinition(final WorkflowDefinitionFormat format, final OutputStream os)
-            throws WorkflowException {
-
-        switch (format) {
-            case JSON:
-                exportProcessModel(os);
-                break;
-
-            case XML:
-            default:
-                exportProcessResource(WF_PROCESS_RESOURCE, os);
-        }
-    }
-
-    @Override
-    public void exportDiagram(final OutputStream os) throws WorkflowException {
-        exportProcessResource(WF_DGRM_RESOURCE, os);
-    }
-
-    @Override
-    public void importDefinition(final WorkflowDefinitionFormat format, final String definition)
-            throws WorkflowException {
-
-        Model model = getModel(getProcessDefinition());
-        switch (format) {
-            case JSON:
-                JsonNode definitionNode;
-                try {
-                    definitionNode = new ObjectMapper().readTree(definition);
-                    if (definitionNode.has(MODEL_DATA_JSON_MODEL)) {
-                        definitionNode = definitionNode.get(MODEL_DATA_JSON_MODEL);
-                    }
-                    if (!definitionNode.has(BpmnJsonConverter.EDITOR_CHILD_SHAPES)) {
-                        throw new IllegalArgumentException(
-                                "Could not find JSON node " + BpmnJsonConverter.EDITOR_CHILD_SHAPES);
-                    }
-
-                    BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
-                    importUtils.fromXML(new BpmnXMLConverter().convertToXML(bpmnModel));
-                } catch (Exception e) {
-                    throw new WorkflowException("While updating process "
-                            + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-                }
-
-                importUtils.fromJSON(definitionNode.toString().getBytes(), getProcessDefinition(), model);
-                break;
-
-            case XML:
-            default:
-                importUtils.fromXML(definition.getBytes());
-
-                importUtils.fromJSON(getProcessDefinition(), model);
-        }
-    }
-
-    private WorkflowFormPropertyType fromActivitiFormType(final FormType activitiFormType) {
-        WorkflowFormPropertyType result = WorkflowFormPropertyType.String;
-
-        if ("string".equals(activitiFormType.getName())) {
-            result = WorkflowFormPropertyType.String;
-        }
-        if ("long".equals(activitiFormType.getName())) {
-            result = WorkflowFormPropertyType.Long;
-        }
-        if ("enum".equals(activitiFormType.getName())) {
-            result = WorkflowFormPropertyType.Enum;
-        }
-        if ("date".equals(activitiFormType.getName())) {
-            result = WorkflowFormPropertyType.Date;
-        }
-        if ("boolean".equals(activitiFormType.getName())) {
-            result = WorkflowFormPropertyType.Boolean;
-        }
-
-        return result;
-    }
-
-    private WorkflowFormTO getFormTO(final Task task) {
-        return getFormTO(task, formService.getTaskFormData(task.getId()));
-    }
-
-    private WorkflowFormTO getFormTO(final Task task, final TaskFormData fd) {
-        final WorkflowFormTO formTO =
-                getFormTO(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
-
-        BeanUtils.copyProperties(task, formTO);
-        return formTO;
-    }
-
-    private WorkflowFormTO getFormTO(final HistoricTaskInstance task) {
-        final List<HistoricFormPropertyEntity> props = new ArrayList<>();
-
-        for (HistoricDetail historicDetail : historyService.createHistoricDetailQuery().taskId(task.getId()).list()) {
-
-            if (historicDetail instanceof HistoricFormPropertyEntity) {
-                props.add((HistoricFormPropertyEntity) historicDetail);
-            }
-        }
-
-        final WorkflowFormTO formTO = getHistoricFormTO(
-                task.getProcessInstanceId(), task.getId(), task.getFormKey(), props);
-        BeanUtils.copyProperties(task, formTO);
-
-        final HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().
-                executionId(task.getExecutionId()).activityType("userTask").activityName(task.getName()).singleResult();
-
-        if (historicActivityInstance != null) {
-            formTO.setCreateTime(historicActivityInstance.getStartTime());
-            formTO.setDueDate(historicActivityInstance.getEndTime());
-        }
-
-        return formTO;
-    }
-
-    private WorkflowFormTO getHistoricFormTO(
-            final String processInstanceId,
-            final String taskId,
-            final String formKey,
-            final List<HistoricFormPropertyEntity> props) {
-
-        WorkflowFormTO formTO = new WorkflowFormTO();
-
-        User user = userDAO.findByWorkflowId(processInstanceId);
-        if (user == null) {
-            throw new NotFoundException("User with workflow id " + processInstanceId);
-        }
-        formTO.setUserKey(user.getKey());
-
-        formTO.setTaskId(taskId);
-        formTO.setKey(formKey);
-
-        for (HistoricFormPropertyEntity prop : props) {
-            WorkflowFormPropertyTO propertyTO = new WorkflowFormPropertyTO();
-            propertyTO.setKey(prop.getPropertyId());
-            propertyTO.setName(prop.getPropertyId());
-            propertyTO.setValue(prop.getPropertyValue());
-            formTO.addProperty(propertyTO);
-        }
-
-        return formTO;
-    }
-
-    @SuppressWarnings("unchecked")
-    private WorkflowFormTO getFormTO(
-            final String processInstanceId,
-            final String taskId,
-            final String formKey,
-            final List<FormProperty> properties) {
-
-        WorkflowFormTO formTO = new WorkflowFormTO();
-
-        User user = userDAO.findByWorkflowId(processInstanceId);
-        if (user == null) {
-            throw new NotFoundException("User with workflow id " + processInstanceId);
-        }
-        formTO.setUserKey(user.getKey());
-
-        formTO.setTaskId(taskId);
-        formTO.setKey(formKey);
-
-        for (FormProperty fProp : properties) {
-            WorkflowFormPropertyTO propertyTO = new WorkflowFormPropertyTO();
-            BeanUtils.copyProperties(fProp, propertyTO, PROPERTY_IGNORE_PROPS);
-            propertyTO.setType(fromActivitiFormType(fProp.getType()));
-
-            if (propertyTO.getType() == WorkflowFormPropertyType.Date) {
-                propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
-            }
-            if (propertyTO.getType() == WorkflowFormPropertyType.Enum) {
-                propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
-            }
-
-            formTO.addProperty(propertyTO);
-        }
-
-        return formTO;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<WorkflowFormTO> getForms() {
-        List<WorkflowFormTO> forms = new ArrayList<>();
-
-        final String authUser = AuthContextUtil.getAuthenticatedUsername();
-        if (adminUser.equals(authUser)) {
-            forms.addAll(getForms(taskService.createTaskQuery().
-                    taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
-        } else {
-            User user = userDAO.find(authUser);
-            if (user == null) {
-                throw new NotFoundException("Syncope User " + authUser);
-            }
-
-            forms.addAll(getForms(taskService.createTaskQuery().
-                    taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
-                    taskCandidateOrAssigned(user.getKey().toString())));
-
-            List<String> candidateGroups = new ArrayList<>();
-            for (Long roleId : user.getRoleKeys()) {
-                candidateGroups.add(roleId.toString());
-            }
-            if (!candidateGroups.isEmpty()) {
-                forms.addAll(getForms(taskService.createTaskQuery().
-                        taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
-                        taskCandidateGroupIn(candidateGroups)));
-            }
-        }
-
-        return forms;
-    }
-
-    @Override
-    public List<WorkflowFormTO> getForms(final String workflowId, final String name) {
-        List<WorkflowFormTO> forms = getForms(
-                taskService.createTaskQuery().processInstanceId(workflowId).taskName(name).
-                taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE));
-
-        forms.addAll(getForms(historyService.createHistoricTaskInstanceQuery().taskName(name).
-                taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
-
-        return forms;
-    }
-
-    private <T extends Query<?, ?>, U extends Object> List<WorkflowFormTO> getForms(final Query<T, U> query) {
-        List<WorkflowFormTO> forms = new ArrayList<>();
-
-        for (U obj : query.list()) {
-            try {
-                if (obj instanceof HistoricTaskInstance) {
-                    forms.add(getFormTO((HistoricTaskInstance) obj));
-                } else if (obj instanceof Task) {
-                    forms.add(getFormTO((Task) obj));
-                } else {
-                    throw new ActivitiException(
-                            "Failure retrieving form", new IllegalArgumentException("Invalid task type"));
-                }
-            } catch (ActivitiException e) {
-                LOG.debug("No form found for task {}", obj, e);
-            }
-        }
-
-        return forms;
-    }
-
-    @Override
-    public WorkflowFormTO getForm(final String workflowId)
-            throws NotFoundException, WorkflowException {
-
-        Task task;
-        try {
-            task = taskService.createTaskQuery().processInstanceId(workflowId).singleResult();
-        } catch (ActivitiException e) {
-            throw new WorkflowException("While reading form for workflow instance " + workflowId, e);
-        }
-
-        TaskFormData formData;
-        try {
-            formData = formService.getTaskFormData(task.getId());
-        } catch (ActivitiException e) {
-            LOG.debug("No form found for task {}", task.getId(), e);
-            formData = null;
-        }
-
-        WorkflowFormTO result = null;
-        if (formData != null && !formData.getFormProperties().isEmpty()) {
-            result = getFormTO(task);
-        }
-
-        return result;
-    }
-
-    private Map.Entry<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
-        Task task;
-        try {
-            task = taskService.createTaskQuery().taskId(taskId).singleResult();
-        } catch (ActivitiException e) {
-            throw new NotFoundException("Activiti Task " + taskId, e);
-        }
-
-        TaskFormData formData;
-        try {
-            formData = formService.getTaskFormData(task.getId());
-        } catch (ActivitiException e) {
-            throw new NotFoundException("Form for Activiti Task " + taskId, e);
-        }
-
-        if (!adminUser.equals(authUser)) {
-            User user = userDAO.find(authUser);
-            if (user == null) {
-                throw new NotFoundException("Syncope User " + authUser);
-            }
-        }
-
-        return new SimpleEntry<>(task, formData);
-    }
-
-    @Transactional
-    @Override
-    public WorkflowFormTO claimForm(final String taskId)
-            throws WorkflowException {
-
-        final String authUser = AuthContextUtil.getAuthenticatedUsername();
-        Map.Entry<Task, TaskFormData> checked = checkTask(taskId, authUser);
-
-        if (!adminUser.equals(authUser)) {
-            List<Task> tasksForUser = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(authUser).list();
-            if (tasksForUser.isEmpty()) {
-                throw new WorkflowException(
-                        new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
-            }
-        }
-
-        Task task;
-        try {
-            taskService.setOwner(taskId, authUser);
-            task = taskService.createTaskQuery().taskId(taskId).singleResult();
-        } catch (ActivitiException e) {
-            throw new WorkflowException("While reading task " + taskId, e);
-        }
-
-        return getFormTO(task, checked.getValue());
-    }
-
-    @Transactional
-    @Override
-    public WorkflowResult<UserMod> submitForm(final WorkflowFormTO form)
-            throws WorkflowException {
-
-        final String authUser = AuthContextUtil.getAuthenticatedUsername();
-        Map.Entry<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
-
-        if (!checked.getKey().getOwner().equals(authUser)) {
-            throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId() + " assigned to "
-                    + checked.getKey().getOwner() + " but submitted by " + authUser));
-        }
-
-        User user = userDAO.findByWorkflowId(checked.getKey().getProcessInstanceId());
-        if (user == null) {
-            throw new NotFoundException("User with workflow id " + checked.getKey().getProcessInstanceId());
-        }
-
-        Set<String> preTasks = getPerformedTasks(user);
-        try {
-            formService.submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
-            runtimeService.setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
-        } catch (ActivitiException e) {
-            throwException(e, "While submitting form for task " + form.getTaskId());
-        }
-
-        Set<String> postTasks = getPerformedTasks(user);
-        postTasks.removeAll(preTasks);
-        postTasks.add(form.getTaskId());
-
-        updateStatus(user);
-        User updated = userDAO.save(user);
-
-        // see if there is any propagation to be done
-        PropagationByResource propByRes =
-                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
-
-        // fetch - if available - the encrypted password
-        String clearPassword = null;
-        String encryptedPwd = runtimeService.getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
-        if (StringUtils.isNotBlank(encryptedPwd)) {
-            clearPassword = decrypt(encryptedPwd);
-        }
-
-        // supports approval chains
-        saveForFormSubmit(user, clearPassword, propByRes);
-
-        UserMod userMod = runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
-        if (userMod == null) {
-            userMod = new UserMod();
-            userMod.setKey(updated.getKey());
-            userMod.setPassword(clearPassword);
-        }
-
-        return new WorkflowResult<>(userMod, propByRes, postTasks);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeEntitiesVariableType.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeEntitiesVariableType.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeEntitiesVariableType.java
deleted file mode 100644
index f2be8e3..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeEntitiesVariableType.java
+++ /dev/null
@@ -1,35 +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.workflow.activiti;
-
-import org.activiti.engine.impl.variable.SerializableType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-/**
- * Activiti variable type for handling Syncope entities as Activiti variables.
- * Main purpose: avoid Activiti to handle Syncope entities as JPA entities,
- * since this can cause troubles with transactions.
- */
-public class SyncopeEntitiesVariableType extends SerializableType {
-
-    @Override
-    public boolean isAbleToStore(final Object value) {
-        return value instanceof AbstractBaseBean;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupManager.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupManager.java
deleted file mode 100644
index 8c9427a..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupManager.java
+++ /dev/null
@@ -1,122 +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.workflow.activiti;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.activiti.engine.identity.Group;
-import org.activiti.engine.identity.GroupQuery;
-import org.activiti.engine.impl.GroupQueryImpl;
-import org.activiti.engine.impl.Page;
-import org.activiti.engine.impl.persistence.entity.GroupEntity;
-import org.activiti.engine.impl.persistence.entity.GroupIdentityManager;
-import org.apache.syncope.server.persistence.api.dao.RoleDAO;
-import org.apache.syncope.server.persistence.api.dao.UserDAO;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class SyncopeGroupManager implements GroupIdentityManager, SyncopeSession {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private RoleDAO roleDAO;
-
-    @Override
-    public Class<?> getType() {
-        return GroupIdentityManager.class;
-    }
-
-    @Override
-    public Group createNewGroup(final String groupId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public GroupQuery createNewGroupQuery() {
-        return new SyncopeGroupQueryImpl(roleDAO);
-    }
-
-    @Override
-    public void deleteGroup(final String groupId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<Group> findGroupsByUser(final String userId) {
-        List<Group> result = Collections.emptyList();
-        User user = userDAO.find(userId);
-        if (user != null) {
-            result = new ArrayList<>();
-            for (Long roleId : user.getRoleKeys()) {
-                result.add(new GroupEntity(roleId.toString()));
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Group> findGroupByQueryCriteria(final GroupQueryImpl query, final Page page) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findGroupCountByQueryCriteria(final GroupQueryImpl query) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<Group> findGroupsByNativeQuery(final Map<String, Object> parameterMap, final int firstResult,
-            final int maxResults) {
-
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findGroupCountByNativeQuery(final Map<String, Object> parameterMap) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void insertGroup(final Group group) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void updateGroup(final Group updatedGroup) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isNewGroup(final Group group) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void flush() {
-    }
-
-    @Override
-    public void close() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupQueryImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupQueryImpl.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupQueryImpl.java
deleted file mode 100644
index 0f28a15..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeGroupQueryImpl.java
+++ /dev/null
@@ -1,157 +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.workflow.activiti;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.identity.Group;
-import org.activiti.engine.identity.GroupQuery;
-import org.activiti.engine.impl.persistence.entity.GroupEntity;
-import org.apache.syncope.server.persistence.api.dao.RoleDAO;
-import org.apache.syncope.server.persistence.api.entity.role.Role;
-
-public class SyncopeGroupQueryImpl implements GroupQuery {
-
-    private RoleDAO roleDAO;
-
-    private Long roleId;
-
-    private List<Group> result;
-
-    public SyncopeGroupQueryImpl(final RoleDAO roleDAO) {
-        this.roleDAO = roleDAO;
-    }
-
-    @Override
-    public GroupQuery groupId(final String groupId) {
-        try {
-            roleId = Long.valueOf(groupId);
-        } catch (NumberFormatException e) {
-        }
-
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupName(final String groupName) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupNameLike(final String groupNameLike) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupType(final String groupType) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupMember(final String groupMemberUserId) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery orderByGroupId() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery orderByGroupName() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery orderByGroupType() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery asc() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery desc() {
-        return this;
-    }
-
-    private Group fromSyncopeRole(Role role) {
-        return new GroupEntity(role.getKey().toString());
-    }
-
-    private void execute() {
-        if (roleId != null) {
-            Role role = roleDAO.find(roleId);
-            if (role == null) {
-                result = Collections.emptyList();
-            } else {
-                result = Collections.singletonList(fromSyncopeRole(role));
-            }
-        }
-        if (result == null) {
-            result = new ArrayList<Group>();
-            for (Role role : roleDAO.findAll()) {
-                result.add(fromSyncopeRole(role));
-            }
-        }
-    }
-
-    @Override
-    public long count() {
-        if (result == null) {
-            execute();
-        }
-        return result.size();
-    }
-
-    @Override
-    public Group singleResult() {
-        if (result == null) {
-            execute();
-        }
-        if (result.isEmpty()) {
-            throw new ActivitiException("Empty result");
-        }
-
-        return result.get(0);
-    }
-
-    @Override
-    public List<Group> list() {
-        if (result == null) {
-            execute();
-        }
-        return result;
-    }
-
-    @Override
-    public List<Group> listPage(final int firstResult, final int maxResults) {
-        return list();
-    }
-
-    @Override
-    public GroupQuery potentialStarter(final String procDefId) {
-        throw new UnsupportedOperationException();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSession.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSession.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSession.java
deleted file mode 100644
index 723b7e3..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSession.java
+++ /dev/null
@@ -1,26 +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.workflow.activiti;
-
-import org.activiti.engine.impl.interceptor.Session;
-
-public interface SyncopeSession extends Session {
-
-    Class<?> getType();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSessionFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSessionFactory.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSessionFactory.java
deleted file mode 100644
index 7a9bd6b..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeSessionFactory.java
+++ /dev/null
@@ -1,45 +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.workflow.activiti;
-
-import org.activiti.engine.impl.interceptor.Session;
-import org.activiti.engine.impl.interceptor.SessionFactory;
-
-public class SyncopeSessionFactory implements SessionFactory {
-
-    private SyncopeSession syncopeSession;
-
-    @Override
-    public Class<?> getSessionType() {
-        return syncopeSession.getType();
-    }
-
-    @Override
-    public Session openSession() {
-        return syncopeSession;
-    }
-
-    public SyncopeSession getSyncopeSession() {
-        return syncopeSession;
-    }
-
-    public void setSyncopeSession(final SyncopeSession syncopeSession) {
-        this.syncopeSession = syncopeSession;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserManager.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserManager.java
deleted file mode 100644
index f36c250..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserManager.java
+++ /dev/null
@@ -1,170 +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.workflow.activiti;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.activiti.engine.identity.Group;
-import org.activiti.engine.identity.Picture;
-import org.activiti.engine.identity.User;
-import org.activiti.engine.identity.UserQuery;
-import org.activiti.engine.impl.Page;
-import org.activiti.engine.impl.UserQueryImpl;
-import org.activiti.engine.impl.persistence.entity.GroupEntity;
-import org.activiti.engine.impl.persistence.entity.IdentityInfoEntity;
-import org.activiti.engine.impl.persistence.entity.UserEntity;
-import org.activiti.engine.impl.persistence.entity.UserIdentityManager;
-import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.server.persistence.api.dao.RoleDAO;
-import org.apache.syncope.server.persistence.api.dao.UserDAO;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class SyncopeUserManager implements UserIdentityManager, SyncopeSession {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private RoleDAO roleDAO;
-
-    @Autowired
-    private EntitlementDAO entitlementDAO;
-
-    @Override
-    public Class<?> getType() {
-        return UserIdentityManager.class;
-    }
-
-    @Override
-    public Boolean checkPassword(final String userKey, final String password) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public User createNewUser(final String userKey) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public UserQuery createNewUserQuery() {
-        return new SyncopeUserQueryImpl(userDAO, roleDAO, entitlementDAO);
-    }
-
-    @Override
-    public void deleteUser(final String userKey) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<Group> findGroupsByUser(final String userKey) {
-        List<Group> result = Collections.emptyList();
-        org.apache.syncope.server.persistence.api.entity.user.User user = userDAO.find(userKey);
-        if (user != null) {
-            result = new ArrayList<>();
-            for (Long roleId : user.getRoleKeys()) {
-                result.add(new GroupEntity(roleId.toString()));
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public UserEntity findUserById(final String userKey) {
-        UserEntity result = null;
-        org.apache.syncope.server.persistence.api.entity.user.User user = userDAO.find(userKey);
-        if (user != null) {
-            result = new UserEntity(userKey);
-        }
-
-        return result;
-    }
-
-    @Override
-    public void flush() {
-    }
-
-    @Override
-    public void close() {
-    }
-
-    @Override
-    public void insertUser(final User user) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isNewUser(final User user) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void updateUser(final User updatedUser) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Picture getUserPicture(final String string) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setUserPicture(final String string, final Picture pctr) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<User> findUserByQueryCriteria(final UserQueryImpl query, final Page page) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findUserCountByQueryCriteria(final UserQueryImpl query) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public IdentityInfoEntity findUserInfoByUserIdAndKey(final String userKey, final String key) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<String> findUserInfoKeysByUserIdAndType(final String userKey, final String type) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<User> findPotentialStarterUsers(final String proceDefId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<User> findUsersByNativeQuery(final Map<String, Object> parameterMap,
-            final int firstResult, final int maxResults) {
-
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findUserCountByNativeQuery(final Map<String, Object> parameterMap) {
-        throw new UnsupportedOperationException();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserQueryImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserQueryImpl.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserQueryImpl.java
deleted file mode 100644
index d2c4e31..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/SyncopeUserQueryImpl.java
+++ /dev/null
@@ -1,218 +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.workflow.activiti;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.identity.User;
-import org.activiti.engine.identity.UserQuery;
-import org.activiti.engine.impl.persistence.entity.UserEntity;
-import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
-import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.server.persistence.api.dao.RoleDAO;
-import org.apache.syncope.server.persistence.api.dao.UserDAO;
-import org.apache.syncope.server.persistence.api.entity.membership.Membership;
-import org.apache.syncope.server.persistence.api.entity.role.Role;
-
-public class SyncopeUserQueryImpl implements UserQuery {
-
-    private UserDAO userDAO;
-
-    private RoleDAO roleDAO;
-
-    private EntitlementDAO entitlementDAO;
-
-    private String username;
-
-    private Long memberOf;
-
-    private List<User> result;
-
-    public SyncopeUserQueryImpl(final UserDAO userDAO, final RoleDAO roleDAO, final EntitlementDAO entitlementDAO) {
-        this.userDAO = userDAO;
-        this.roleDAO = roleDAO;
-        this.entitlementDAO = entitlementDAO;
-    }
-
-    @Override
-    public UserQuery userId(final String id) {
-        this.username = id;
-        return this;
-    }
-
-    @Override
-    public UserQuery userFirstName(final String firstName) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userFirstNameLike(final String firstNameLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userLastName(final String lastName) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userLastNameLike(final String lastNameLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userFullNameLike(final String fullNameLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userEmail(final String email) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userEmailLike(final String emailLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery memberOfGroup(final String groupId) {
-        try {
-            memberOf = Long.valueOf(groupId);
-        } catch (NumberFormatException e) {
-        }
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserId() {
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserFirstName() {
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserLastName() {
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserEmail() {
-        return this;
-    }
-
-    @Override
-    public UserQuery asc() {
-        return this;
-    }
-
-    @Override
-    public UserQuery desc() {
-        return this;
-    }
-
-    private User fromSyncopeUser(final org.apache.syncope.server.persistence.api.entity.user.User user) {
-        return new UserEntity(user.getUsername());
-    }
-
-    private void execute(final int page, final int itemsPerPage) {
-        if (username != null) {
-            org.apache.syncope.server.persistence.api.entity.user.User user = userDAO.find(username);
-            if (user == null) {
-                result = Collections.<User>emptyList();
-            } else {
-                if (memberOf == null || user.getRoleKeys().contains(memberOf)) {
-                    result = Collections.singletonList(fromSyncopeUser(user));
-                }
-            }
-        }
-        if (memberOf != null) {
-            Role role = roleDAO.find(memberOf);
-            if (role == null) {
-                result = Collections.<User>emptyList();
-            } else {
-                result = new ArrayList<>();
-                List<Membership> memberships = roleDAO.findMemberships(role);
-                User user;
-                for (Membership membership : memberships) {
-                    user = fromSyncopeUser(membership.getUser());
-                    if (!result.contains(user)) {
-                        result.add(user);
-                    }
-                }
-            }
-        }
-        // THIS CAN BE *VERY* DANGEROUS
-        if (result == null) {
-            result = new ArrayList<>();
-
-            List<org.apache.syncope.server.persistence.api.entity.user.User> users =
-                    userDAO.findAll(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()), page, itemsPerPage);
-            for (org.apache.syncope.server.persistence.api.entity.user.User user : users) {
-                result.add(fromSyncopeUser(user));
-            }
-        }
-    }
-
-    @Override
-    public long count() {
-        if (result == null) {
-            execute(-1, -1);
-        }
-        return result.size();
-    }
-
-    @Override
-    public User singleResult() {
-        if (result == null) {
-            execute(-1, -1);
-        }
-        if (result.isEmpty()) {
-            throw new ActivitiException("Empty result");
-        }
-
-        return result.get(0);
-    }
-
-    @Override
-    public List<User> list() {
-        if (result == null) {
-            execute(-1, -1);
-        }
-        return result;
-    }
-
-    @Override
-    public List<User> listPage(final int firstResult, final int maxResults) {
-        if (result == null) {
-            execute((firstResult / maxResults) + 1, maxResults);
-        }
-        return result;
-    }
-
-    @Override
-    public UserQuery potentialStarter(final String string) {
-        throw new UnsupportedOperationException();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AbstractActivitiServiceTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AbstractActivitiServiceTask.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AbstractActivitiServiceTask.java
deleted file mode 100644
index 04962bf..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AbstractActivitiServiceTask.java
+++ /dev/null
@@ -1,48 +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.workflow.activiti.task;
-
-import org.activiti.engine.RuntimeService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Abstract base class for Activiti's service tasks in Syncope, with Spring support.
- */
-@Component
-public abstract class AbstractActivitiServiceTask {
-
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractActivitiServiceTask.class);
-
-    @Autowired
-    protected RuntimeService runtimeService;
-
-    @Transactional(rollbackFor = { Throwable.class })
-    public void execute(final String executionId) {
-        doExecute(executionId);
-    }
-
-    protected abstract void doExecute(final String executionId);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AutoActivate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AutoActivate.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AutoActivate.java
deleted file mode 100644
index 3a95089..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/AutoActivate.java
+++ /dev/null
@@ -1,31 +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.workflow.activiti.task;
-
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.stereotype.Component;
-
-@Component
-public class AutoActivate extends AbstractActivitiServiceTask {
-
-    @Override
-    protected void doExecute(final String executionId) {
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Create.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Create.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Create.java
deleted file mode 100644
index cc4e1be..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Create.java
+++ /dev/null
@@ -1,51 +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.workflow.activiti.task;
-
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.server.persistence.api.entity.EntityFactory;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class Create extends AbstractActivitiServiceTask {
-
-    @Autowired
-    private UserDataBinder dataBinder;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    @Override
-    protected void doExecute(final String executionId) {
-        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
-        Boolean storePassword =
-                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.STORE_PASSWORD, Boolean.class);
-        // create and set workflow id
-        User user = entityFactory.newEntity(User.class);
-        dataBinder.create(user, userTO, storePassword == null ? true : storePassword);
-        user.setWorkflowId(executionId);
-
-        // report SyncopeUser as result
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Delete.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Delete.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Delete.java
deleted file mode 100644
index 5e9109d..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Delete.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.workflow.activiti.task;
-
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.stereotype.Component;
-
-@Component
-public class Delete extends AbstractActivitiServiceTask {
-
-    @Override
-    protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, User.class);
-
-        // Do something with SyncopeUser...
-        if (user != null) {
-            user.checkToken("");
-        }
-
-        // remove SyncopeUser variable
-        runtimeService.removeVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/GenerateToken.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/GenerateToken.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/GenerateToken.java
deleted file mode 100644
index 48750b2..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/GenerateToken.java
+++ /dev/null
@@ -1,43 +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.workflow.activiti.task;
-
-import org.apache.syncope.server.persistence.api.dao.ConfDAO;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class GenerateToken extends AbstractActivitiServiceTask {
-
-    @Autowired
-    private ConfDAO confDAO;
-
-    @Override
-    protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, User.class);
-
-        user.generateToken(
-                confDAO.find("token.length", "256").getValues().get(0).getLongValue().intValue(),
-                confDAO.find("token.expireTime", "60").getValues().get(0).getLongValue().intValue());
-
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user);
-    }
-}


[11/12] syncope git commit: [SYNCOPE-620] IT with Activiti

Posted by il...@apache.org.
[SYNCOPE-620] IT with Activiti


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

Branch: refs/heads/2_0_X
Commit: 1327b2a44abe1cc1cea08540af17749bdbd88d4e
Parents: 702810d
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jan 26 15:47:02 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jan 26 15:47:02 2015 +0100

----------------------------------------------------------------------
 .../syncope/common/to/WorkflowFormTO.java       |   1 -
 .../syncope/client/lib/SyncopeClient.java       |  28 -
 .../apache/syncope/common/lib/to/SyncopeTO.java | 186 ++++
 .../common/lib/to/WorkflowFormPropertyTO.java   |  12 +-
 .../syncope/common/lib/to/WorkflowFormTO.java   |  24 +-
 .../common/lib/wrap/CorrelationRuleClass.java   |  30 -
 .../syncope/common/lib/wrap/JobClass.java       |  30 -
 .../syncope/common/lib/wrap/MailTemplate.java   |  30 -
 .../common/lib/wrap/PropagationActionClass.java |  30 -
 .../common/lib/wrap/PushActionClass.java        |  30 -
 .../common/lib/wrap/SyncActionClass.java        |  30 -
 .../syncope/common/lib/wrap/Validator.java      |  30 -
 .../rest/api/service/ConfigurationService.java  |  23 -
 .../common/rest/api/service/PolicyService.java  |  11 -
 .../rest/api/service/ResourceService.java       |  11 -
 .../common/rest/api/service/SyncopeService.java |  33 +
 .../common/rest/api/service/TaskService.java    |  36 +-
 syncope620/fit/reference/pom.xml                |  56 +-
 .../src/main/resources/userWorkflow.bpmn20.xml  | 577 ++++++++++++
 .../src/main/resources/workflow.properties      |  20 +
 .../fit/server/reference/AbstractITCase.java    |   4 +
 .../fit/server/reference/ActivitiDetector.java  |  10 +-
 .../server/reference/AuthenticationITCase.java  |   2 +-
 .../fit/server/reference/PolicyITCase.java      |   2 +-
 .../fit/server/reference/ResourceITCase.java    |   3 +-
 .../fit/server/reference/TaskITCase.java        |  12 +-
 .../fit/server/reference/UserITCase.java        |   6 +-
 .../fit/server/reference/UserSelfITCase.java    |  14 +-
 .../server/reference/UserWorkflowITCase.java    |   6 +-
 .../fit/server/reference/WorkflowITCase.java    |  17 +-
 .../src/test/resources/addActivitiToContent.xsl |  50 ++
 syncope620/pom.xml                              |  15 +-
 .../server/logic/ConfigurationLogic.java        |  47 -
 .../syncope/server/logic/EntitlementLogic.java  |   2 +-
 .../syncope/server/logic/LoggerLogic.java       |   2 +-
 .../syncope/server/logic/NotificationLogic.java |  12 +-
 .../syncope/server/logic/PolicyLogic.java       |  10 -
 .../syncope/server/logic/ReportLogic.java       |  40 +-
 .../syncope/server/logic/ResourceLogic.java     |  27 +-
 .../apache/syncope/server/logic/RoleLogic.java  |  14 +-
 .../syncope/server/logic/SchemaLogic.java       |  19 +-
 .../server/logic/SecurityQuestionLogic.java     |  12 +-
 .../syncope/server/logic/SyncopeLogic.java      | 143 +++
 .../apache/syncope/server/logic/TaskLogic.java  |  32 +-
 .../apache/syncope/server/logic/UserLogic.java  |  16 +-
 .../init/ImplementationClassNamesLoader.java    |  15 +-
 .../logic/src/main/resources/logicContext.xml   |   4 +
 .../src/test/resources/content.xml              |   2 +-
 .../provisioning/api/ConnIdBundleManager.java   |   2 +
 .../java/ConnIdBundleManagerImpl.java           |   7 +
 .../provisioning/java/sync/SyncJobImpl.java     |   4 +-
 .../cxf/service/ConfigurationServiceImpl.java   |  14 -
 .../rest/cxf/service/PolicyServiceImpl.java     |   9 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |   7 -
 .../rest/cxf/service/SyncopeServiceImpl.java    |  38 +
 .../rest/cxf/service/TaskServiceImpl.java       |  19 -
 syncope620/server/workflow-activiti/pom.xml     |   5 +
 .../activiti/ActivitiDefinitionLoader.java      | 104 +++
 .../workflow/activiti/ActivitiImportUtils.java  |  92 ++
 .../activiti/ActivitiUserWorkflowAdapter.java   | 893 +++++++++++++++++++
 .../activiti/SyncopeEntitiesVariableType.java   |  35 +
 .../workflow/activiti/SyncopeGroupManager.java  | 122 +++
 .../activiti/SyncopeGroupQueryImpl.java         | 157 ++++
 .../workflow/activiti/SyncopeSession.java       |  26 +
 .../activiti/SyncopeSessionFactory.java         |  45 +
 .../workflow/activiti/SyncopeUserManager.java   | 170 ++++
 .../workflow/activiti/SyncopeUserQueryImpl.java | 218 +++++
 .../task/AbstractActivitiServiceTask.java       |  48 +
 .../workflow/activiti/task/AutoActivate.java    |  31 +
 .../server/workflow/activiti/task/Create.java   |  51 ++
 .../server/workflow/activiti/task/Delete.java   |  40 +
 .../workflow/activiti/task/GenerateToken.java   |  43 +
 .../server/workflow/activiti/task/Notify.java   |  62 ++
 .../workflow/activiti/task/PasswordReset.java   |  44 +
 .../workflow/activiti/task/Reactivate.java      |  29 +
 .../server/workflow/activiti/task/Suspend.java  |  29 +
 .../server/workflow/activiti/task/Update.java   |  54 ++
 .../activiti/ActivitiDefinitionLoader.java      | 104 ---
 .../workflow/activiti/ActivitiImportUtils.java  |  92 --
 .../activiti/ActivitiUserWorkflowAdapter.java   | 893 -------------------
 .../activiti/SyncopeEntitiesVariableType.java   |  35 -
 .../workflow/activiti/SyncopeGroupManager.java  | 122 ---
 .../activiti/SyncopeGroupQueryImpl.java         | 157 ----
 .../workflow/activiti/SyncopeSession.java       |  26 -
 .../activiti/SyncopeSessionFactory.java         |  45 -
 .../workflow/activiti/SyncopeUserManager.java   | 170 ----
 .../workflow/activiti/SyncopeUserQueryImpl.java | 218 -----
 .../task/AbstractActivitiServiceTask.java       |  48 -
 .../workflow/activiti/task/AutoActivate.java    |  31 -
 .../syncope/workflow/activiti/task/Create.java  |  51 --
 .../syncope/workflow/activiti/task/Delete.java  |  40 -
 .../workflow/activiti/task/GenerateToken.java   |  43 -
 .../syncope/workflow/activiti/task/Notify.java  |  62 --
 .../workflow/activiti/task/PasswordReset.java   |  44 -
 .../workflow/activiti/task/Reactivate.java      |  29 -
 .../syncope/workflow/activiti/task/Suspend.java |  29 -
 .../syncope/workflow/activiti/task/Update.java  |  54 --
 .../src/main/resources/workflow.properties      |  20 +
 .../main/resources/workflowActivitiContext.xml  |  14 +-
 .../src/main/resources/workflow.properties      |   2 +
 100 files changed, 3584 insertions(+), 2909 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/common/src/main/java/org/apache/syncope/common/to/WorkflowFormTO.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/syncope/common/to/WorkflowFormTO.java b/common/src/main/java/org/apache/syncope/common/to/WorkflowFormTO.java
index 0269e92..26d023b 100644
--- a/common/src/main/java/org/apache/syncope/common/to/WorkflowFormTO.java
+++ b/common/src/main/java/org/apache/syncope/common/to/WorkflowFormTO.java
@@ -32,7 +32,6 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.AbstractBaseBean;
-import org.apache.syncope.common.to.WorkflowFormPropertyTO;
 
 @XmlRootElement(name = "workflowForm")
 @XmlType

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --git a/syncope620/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java b/syncope620/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
index 8407662..11bfa51 100644
--- a/syncope620/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
+++ b/syncope620/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
@@ -20,16 +20,13 @@ package org.apache.syncope.client.lib;
 
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.common.lib.search.OrderByClauseBuilder;
 import org.apache.syncope.common.lib.search.RoleFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.common.rest.api.service.WorkflowService;
 
 /**
  * Entry point for client access to all REST services exposed by Syncope core; obtain instances via
@@ -239,31 +236,6 @@ public class SyncopeClient {
     }
 
     /**
-     * Checks whether Activiti workflow is enabled for users / roles, by calling <tt>WorkflowService</tt>'s options.
-     *
-     * @param subjectType user / role
-     * @return whether Activiti workflow is enabled for given attributable type
-     * @see WorkflowService#getOptions(org.apache.syncope.common.types.SubjectType)
-     */
-    public boolean isActivitiEnabledFor(final SubjectType subjectType) {
-        Response options = getService(WorkflowService.class).getOptions(subjectType);
-
-        boolean result;
-        switch (subjectType) {
-            case ROLE:
-                result = Boolean.valueOf(options.getHeaderString(RESTHeaders.ACTIVITI_ROLE_ENABLED));
-                break;
-
-            case USER:
-            default:
-                result = Boolean.valueOf(options.getHeaderString(RESTHeaders.ACTIVITI_USER_ENABLED));
-                break;
-        }
-
-        return result;
-    }
-
-    /**
      * Fetches <tt>ETag</tt> header value from latest service run (if available).
      *
      * @param <T> any service class

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
new file mode 100644
index 0000000..d21e03f
--- /dev/null
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
@@ -0,0 +1,186 @@
+/*
+ * 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.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "syncope")
+@XmlType
+public class SyncopeTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -7941853999417673827L;
+
+    private String version;
+
+    private final List<String> connIdLocations = new ArrayList<>();
+
+    private String attributableTransformer;
+
+    private String userWorkflowAdapter;
+
+    private String roleWorkflowAdapter;
+
+    private String userProvisioningManager;
+
+    private String roleProvisioningManager;
+
+    private final List<String> reportlets = new ArrayList<>();
+
+    private final List<String> taskJobs = new ArrayList<>();
+
+    private final List<String> propagationActions = new ArrayList<>();
+
+    private final List<String> syncActions = new ArrayList<>();
+
+    private final List<String> pushActions = new ArrayList<>();
+
+    private final List<String> syncCorrelationRules = new ArrayList<>();
+
+    private final List<String> pushCorrelationRules = new ArrayList<>();
+
+    private final List<String> validators = new ArrayList<>();
+
+    private final List<String> mailTemplates = new ArrayList<>();
+
+    public String getVersion() {
+        return version;
+    }
+
+    @XmlElementWrapper(name = "connIdLocations")
+    @XmlElement(name = "connIdLocation")
+    @JsonProperty("connIdLocations")
+    public List<String> getConnIdLocations() {
+        return connIdLocations;
+    }
+
+    public String getAttributableTransformer() {
+        return attributableTransformer;
+    }
+
+    public String getUserWorkflowAdapter() {
+        return userWorkflowAdapter;
+    }
+
+    public String getRoleWorkflowAdapter() {
+        return roleWorkflowAdapter;
+    }
+
+    public String getUserProvisioningManager() {
+        return userProvisioningManager;
+    }
+
+    public String getRoleProvisioningManager() {
+        return roleProvisioningManager;
+    }
+
+    @XmlElementWrapper(name = "reportlets")
+    @XmlElement(name = "reportlet")
+    @JsonProperty("reportlets")
+    public List<String> getReportlets() {
+        return reportlets;
+    }
+
+    @XmlElementWrapper(name = "taskJobs")
+    @XmlElement(name = "taskJob")
+    @JsonProperty("taskJobs")
+    public List<String> getTaskJobs() {
+        return taskJobs;
+    }
+
+    @XmlElementWrapper(name = "propagationActions")
+    @XmlElement(name = "propagationAction")
+    @JsonProperty("propagationActions")
+    public List<String> getPropagationActions() {
+        return propagationActions;
+    }
+
+    @XmlElementWrapper(name = "syncActions")
+    @XmlElement(name = "syncAction")
+    @JsonProperty("syncActions")
+    public List<String> getSyncActions() {
+        return syncActions;
+    }
+
+    @XmlElementWrapper(name = "pushActions")
+    @XmlElement(name = "pushAction")
+    @JsonProperty("pushActions")
+    public List<String> getPushActions() {
+        return pushActions;
+    }
+
+    @XmlElementWrapper(name = "syncCorrelationRules")
+    @XmlElement(name = "syncCorrelationRule")
+    @JsonProperty("syncCorrelationRules")
+    public List<String> getSyncCorrelationRules() {
+        return syncCorrelationRules;
+    }
+
+    @XmlElementWrapper(name = "pushCorrelationRules")
+    @XmlElement(name = "pushCorrelationRule")
+    @JsonProperty("pushCorrelationRules")
+    public List<String> getPushCorrelationRules() {
+        return pushCorrelationRules;
+    }
+
+    @XmlElementWrapper(name = "validators")
+    @XmlElement(name = "validator")
+    @JsonProperty("validators")
+    public List<String> getValidators() {
+        return validators;
+    }
+
+    @XmlElementWrapper(name = "mailTemplates")
+    @XmlElement(name = "mailTemplate")
+    @JsonProperty("mailTemplates")
+    public List<String> getMailTemplates() {
+        return mailTemplates;
+    }
+
+    public void setVersion(final String version) {
+        this.version = version;
+    }
+
+    public void setAttributableTransformer(final String attributableTransformer) {
+        this.attributableTransformer = attributableTransformer;
+    }
+
+    public void setUserWorkflowAdapter(final String userWorkflowAdapter) {
+        this.userWorkflowAdapter = userWorkflowAdapter;
+    }
+
+    public void setRoleWorkflowAdapter(final String roleWorkflowAdapter) {
+        this.roleWorkflowAdapter = roleWorkflowAdapter;
+    }
+
+    public void setUserProvisioningManager(final String userProvisioningManager) {
+        this.userProvisioningManager = userProvisioningManager;
+    }
+
+    public void setRoleProvisioningManager(final String roleProvisioningManager) {
+        this.roleProvisioningManager = roleProvisioningManager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
index c89bfcd..5b67c92 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
@@ -31,7 +31,7 @@ public class WorkflowFormPropertyTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = 9139969592634304261L;
 
-    private String key;
+    private String id;
 
     private String name;
 
@@ -47,14 +47,14 @@ public class WorkflowFormPropertyTO extends AbstractBaseBean {
 
     private String datePattern;
 
-    private Map<String, String> enumValues = new HashMap<>();
+    private final Map<String, String> enumValues = new HashMap<>();
 
-    public String getKey() {
-        return key;
+    public String getId() {
+        return id;
     }
 
-    public void setKey(final String key) {
-        this.key = key;
+    public void setId(final String id) {
+        this.id = id;
     }
 
     public String getName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
index f63d9fe..90dc7c2 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
@@ -52,11 +52,7 @@ public class WorkflowFormTO extends AbstractBaseBean {
 
     private String owner;
 
-    private final List<WorkflowFormPropertyTO> properties;
-
-    public WorkflowFormTO() {
-        properties = new ArrayList<>();
-    }
+    private final List<WorkflowFormPropertyTO> properties = new ArrayList<>();
 
     public long getUserKey() {
         return userKey;
@@ -133,27 +129,21 @@ public class WorkflowFormTO extends AbstractBaseBean {
 
     @JsonIgnore
     public Map<String, WorkflowFormPropertyTO> getPropertyMap() {
-        Map<String, WorkflowFormPropertyTO> result;
-
-        if (getProperties() == null) {
-            result = Collections.emptyMap();
-        } else {
-            result = new HashMap<>();
-            for (WorkflowFormPropertyTO prop : getProperties()) {
-                result.put(prop.getKey(), prop);
-            }
-            result = Collections.unmodifiableMap(result);
+        Map<String, WorkflowFormPropertyTO> result = new HashMap<>();
+        for (WorkflowFormPropertyTO prop : getProperties()) {
+            result.put(prop.getId(), prop);
         }
+        result = Collections.unmodifiableMap(result);
 
         return result;
     }
 
     @JsonIgnore
     public Map<String, String> getPropertiesForSubmit() {
-        Map<String, String> props = new HashMap<String, String>();
+        Map<String, String> props = new HashMap<>();
         for (WorkflowFormPropertyTO prop : getProperties()) {
             if (prop.isWritable()) {
-                props.put(prop.getKey(), prop.getValue());
+                props.put(prop.getId(), prop.getValue());
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/CorrelationRuleClass.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/CorrelationRuleClass.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/CorrelationRuleClass.java
deleted file mode 100644
index 6a8997c..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/CorrelationRuleClass.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "correlationRuleClass")
-@XmlType
-public class CorrelationRuleClass extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = -6715106427060816725L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/JobClass.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/JobClass.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/JobClass.java
deleted file mode 100644
index b85a6f5..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/JobClass.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "jobClass")
-@XmlType
-public class JobClass extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = -1953799905627918822L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/MailTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/MailTemplate.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/MailTemplate.java
deleted file mode 100644
index 11e254d..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/MailTemplate.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "mailTemplate")
-@XmlType
-public class MailTemplate extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = 7232619557172031478L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PropagationActionClass.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PropagationActionClass.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PropagationActionClass.java
deleted file mode 100644
index f8e54b6..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PropagationActionClass.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "propagationActionClass")
-@XmlType
-public class PropagationActionClass extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = 2187654394121198308L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PushActionClass.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PushActionClass.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PushActionClass.java
deleted file mode 100644
index e12fd8e..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/PushActionClass.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "pushActionClass")
-@XmlType
-public class PushActionClass extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = 1669581609310071906L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SyncActionClass.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SyncActionClass.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SyncActionClass.java
deleted file mode 100644
index d6c7a77..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SyncActionClass.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "syncActionClass")
-@XmlType
-public class SyncActionClass extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = 1669581609310071905L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/Validator.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/Validator.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/Validator.java
deleted file mode 100644
index 71cad00..0000000
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/Validator.java
+++ /dev/null
@@ -1,30 +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.common.lib.wrap;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "validator")
-@XmlType
-public class Validator extends AbstractWrappable<String> {
-
-    private static final long serialVersionUID = 7233619557177034453L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
index d886b91..3fa5f8a 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConfigurationService.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.common.rest.api.service;
 
-import java.util.List;
 import javax.validation.constraints.NotNull;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -31,8 +30,6 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
-import org.apache.syncope.common.lib.wrap.MailTemplate;
-import org.apache.syncope.common.lib.wrap.Validator;
 
 /**
  * REST operations for configuration.
@@ -50,26 +47,6 @@ public interface ConfigurationService extends JAXRSService {
     Response export();
 
     /**
-     * Returns a list of known mail-template names.
-     *
-     * @return a list of known mail-template names
-     */
-    @GET
-    @Path("mailTemplates")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<MailTemplate> getMailTemplates();
-
-    /**
-     * Returns a list of known validator names.
-     *
-     * @return a list of known validator names
-     */
-    @GET
-    @Path("validators")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<Validator> getValidators();
-
-    /**
      * Returns all configuration parameters.
      *
      * @return all configuration parameters

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
index 6050d9c..c2a4e6a 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
@@ -36,7 +36,6 @@ import org.apache.cxf.jaxrs.model.wadl.Descriptions;
 import org.apache.cxf.jaxrs.model.wadl.DocTarget;
 import org.apache.syncope.common.lib.to.AbstractPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.wrap.CorrelationRuleClass;
 
 /**
  * REST operations for policies.
@@ -45,16 +44,6 @@ import org.apache.syncope.common.lib.wrap.CorrelationRuleClass;
 public interface PolicyService extends JAXRSService {
 
     /**
-     * Returns a list of classes to be used as correlation rules.
-     *
-     * @return list of classes to be used as correlation rules
-     */
-    @GET
-    @Path("syncCorrelationRuleClasses")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<CorrelationRuleClass> getSyncCorrelationRuleClasses();
-
-    /**
      * Returns the policy matching the given key.
      *
      * @param policyKey key of requested policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
index 044025b..313b0e9 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
@@ -40,7 +40,6 @@ import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.wrap.PropagationActionClass;
 import org.apache.syncope.common.lib.wrap.SubjectId;
 
 /**
@@ -64,16 +63,6 @@ public interface ResourceService extends JAXRSService {
             @NotNull @PathParam("type") SubjectType type, @NotNull @PathParam("key") Long key);
 
     /**
-     * Returns a list of classes that can be used to customize the propagation process.
-     *
-     * @return list of classes that can be used to customize the propagation process
-     */
-    @GET
-    @Path("propagationActionsClasses")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<PropagationActionClass> getPropagationActionsClasses();
-
-    /**
      * Returns the resource with matching name.
      *
      * @param resourceKey Name of resource to be read

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
new file mode 100644
index 0000000..55cc092
--- /dev/null
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.common.rest.api.service;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.syncope.common.lib.to.SyncopeTO;
+
+@Path("")
+public interface SyncopeService extends JAXRSService {
+
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XHTML_XML })
+    SyncopeTO info();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
index c3296dd..24c9b0e 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.common.rest.api.service;
 
-import java.util.List;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
 import javax.ws.rs.Consumes;
@@ -45,9 +44,6 @@ import org.apache.syncope.common.lib.to.ReportExecTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.lib.wrap.JobClass;
-import org.apache.syncope.common.lib.wrap.PushActionClass;
-import org.apache.syncope.common.lib.wrap.SyncActionClass;
 
 /**
  * REST operations for tasks.
@@ -56,37 +52,7 @@ import org.apache.syncope.common.lib.wrap.SyncActionClass;
 public interface TaskService extends JAXRSService {
 
     /**
-     * Returns a list of classes to be used for jobs.
-     *
-     * @return list of classes to be used for jobs
-     */
-    @GET
-    @Path("jobClasses")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<JobClass> getJobClasses();
-
-    /**
-     * Returns a list of classes to be used as synchronization actions.
-     *
-     * @return list of classes to be used as synchronization actions
-     */
-    @GET
-    @Path("syncActionsClasses")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<SyncActionClass> getSyncActionsClasses();
-
-    /**
-     * Returns a list of classes to be used as push actions.
-     *
-     * @return list of classes to be used as push actions
-     */
-    @GET
-    @Path("pushActionsClasses")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<PushActionClass> getPushActionsClasses();
-
-    /**
-     * Returns the task matching the given id.
+     * Returns the task matching the given key.
      *
      * @param taskKey key of task to be read
      * @param <T> type of taskTO

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/pom.xml b/syncope620/fit/reference/pom.xml
index 564d8f0..ec094cb 100644
--- a/syncope620/fit/reference/pom.xml
+++ b/syncope620/fit/reference/pom.xml
@@ -241,7 +241,7 @@ under the License.
               <cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port>
               <cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port>
 
-              <cargo.jvmargs>-noverify -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m</cargo.jvmargs>
+              <cargo.jvmargs>-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m</cargo.jvmargs>
             </properties>
             <configfiles>
               <configfile>
@@ -355,7 +355,7 @@ under the License.
               <configuration>
                 <properties>
                   <cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
-                    -noverify -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m</cargo.jvmargs>
+                    -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m</cargo.jvmargs>
                 </properties>
               </configuration>
             </configuration>
@@ -427,5 +427,57 @@ under the License.
         </plugins>
       </build>
     </profile>
+    
+    <profile>
+      <id>all</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      
+      <dependencies>
+        <dependency>
+          <groupId>org.apache.syncope.server</groupId>
+          <artifactId>syncope-server-workflow-activiti</artifactId>
+          <version>${project.version}</version>
+        </dependency>
+      </dependencies>
+      
+      <build>
+        <plugins>
+          <!-- Adds Activiti test content -->
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>xml-maven-plugin</artifactId>
+            <inherited>true</inherited>
+            <executions>
+              <execution>
+                <phase>prepare-package</phase>
+                <goals>
+                  <goal>transform</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <transformationSets>
+                <transformationSet>
+                  <dir>${project.build.directory}/classes</dir>
+                  <includes>
+                    <include>content.xml</include>
+                  </includes>
+                  <outputDir>${project.build.directory}/classes</outputDir>
+                  <stylesheet>${basedir}/src/test/resources/addActivitiToContent.xsl</stylesheet>
+                  <outputProperties>
+                    <outputProperty>
+                      <name>indent</name>
+                      <value>yes</value>
+                    </outputProperty>
+                  </outputProperties>
+                </transformationSet>
+              </transformationSets>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/main/resources/userWorkflow.bpmn20.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/resources/userWorkflow.bpmn20.xml b/syncope620/fit/reference/src/main/resources/userWorkflow.bpmn20.xml
new file mode 100644
index 0000000..d26dbe3
--- /dev/null
+++ b/syncope620/fit/reference/src/main/resources/userWorkflow.bpmn20.xml
@@ -0,0 +1,577 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+             xmlns:activiti="http://activiti.org/bpmn" 
+             xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" 
+             xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" 
+             xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" 
+             typeLanguage="http://www.w3.org/2001/XMLSchema" 
+             expressionLanguage="http://www.w3.org/1999/XPath" 
+             targetNamespace="http://activiti.org/bpmn20">
+  
+  <process id="userWorkflow" name="User Workflow" isExecutable="true">
+    <startEvent id="theStart"/>
+    <sequenceFlow id="flow1" sourceRef="theStart" targetRef="create"/>
+    <serviceTask id="create" name="Create" activiti:expression="#{create.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow2" sourceRef="create" targetRef="createGW"/>
+    <exclusiveGateway id="createGW"/>
+    <sequenceFlow id="createAsAnonymous2Approval" sourceRef="createGW" targetRef="createApproval">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == 'anonymous' || user.getRoleKeys().contains(9)}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="create2Activate" sourceRef="createGW" targetRef="enableGW">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!user.getRoleKeys().contains(9)}]]></conditionExpression>
+    </sequenceFlow>
+    <userTask id="createApproval" name="Create approval" activiti:candidateGroups="7" activiti:formKey="createApproval">
+      <extensionElements>
+        <activiti:formProperty id="username" name="Username" type="string" expression="${user.username}" writable="false"/>
+        <activiti:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+        <activiti:formProperty id="rejectReason" name="Reason for rejecting" type="string" variable="rejectReason"/>
+      </extensionElements>
+    </userTask>
+    <sequenceFlow id="flow3" sourceRef="createApproval" targetRef="createApprovalGW"/>
+    <exclusiveGateway id="createApprovalGW"/>
+    <sequenceFlow id="createApprovalGW2EnableGW" sourceRef="createApprovalGW" targetRef="enableGW">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="createApproval2Reject" sourceRef="createApprovalGW" targetRef="reject">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+    </sequenceFlow>
+    <exclusiveGateway id="enableGW"/>
+    <sequenceFlow id="createApprovalGW2OptIn" sourceRef="enableGW" targetRef="generateToken">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${user.getRoleKeys().contains(11)}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="createApprovalGW2Activate" sourceRef="enableGW" targetRef="activate">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled == null}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="createApprovalGW2Active" sourceRef="enableGW" targetRef="active">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled}]]></conditionExpression>
+    </sequenceFlow>    
+    <sequenceFlow id="createApprovalGW2Suspended" sourceRef="enableGW" targetRef="suspend">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!enabled}]]></conditionExpression>
+    </sequenceFlow>
+    <serviceTask id="activate" name="Activate" activiti:expression="#{autoActivate.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow4" sourceRef="activate" targetRef="active"/>
+    <serviceTask id="generateToken" name="Generate token" activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow5" sourceRef="generateToken" targetRef="created"/>
+    <userTask id="created" name="Created"/>
+    <sequenceFlow id="flow6" sourceRef="created" targetRef="optinGW"/>
+    <exclusiveGateway id="optinGW"/>
+    <sequenceFlow id="created2Activate" sourceRef="optinGW" targetRef="removeToken">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${user.checkToken(token)}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="created2Created" sourceRef="optinGW" targetRef="created">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!user.checkToken(token)}]]></conditionExpression>
+    </sequenceFlow>
+    <scriptTask id="removeToken" name="Remove Token and Activate" scriptFormat="groovy" activiti:autoStoreVariables="false">
+      <script>
+        user.removeToken()    
+      </script>
+    </scriptTask>
+    <sequenceFlow id="flow7" sourceRef="removeToken" targetRef="active"/>
+    <userTask id="active" name="Active"/>
+    <sequenceFlow id="flow8" sourceRef="active" targetRef="activeGw"/>
+    <exclusiveGateway id="activeGw"/>
+    <sequenceFlow id="active2UpdateApproval" sourceRef="activeGw" targetRef="updateApproval">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == user.getUsername() and task == 'update' 
+        and (!userMod.getMembershipsToAdd().isEmpty() or !userMod.getMembershipsToRemove().isEmpty())}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="active2DeleteApproval" sourceRef="activeGw" targetRef="deleteApproval">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == user.getUsername() and task == 'delete'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="active2Update" sourceRef="activeGw" targetRef="update">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'update'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="active2Suspend" sourceRef="activeGw" targetRef="suspend">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'suspend'}]]></conditionExpression>
+    </sequenceFlow>    
+    <sequenceFlow id="active2Delete" sourceRef="activeGw" targetRef="delete">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+    </sequenceFlow>    
+    <sequenceFlow id="active2RequestPasswordReset" sourceRef="activeGw" targetRef="generateToken4PasswordReset">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'requestPasswordReset'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="active2ConfirmPasswordReset" sourceRef="activeGw" targetRef="checkToken4ConfirmPasswordReset">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'confirmPasswordReset'}]]></conditionExpression>
+    </sequenceFlow>    
+    <userTask id="updateApproval" name="Update approval" activiti:candidateGroups="7" activiti:formKey="updateApproval">
+      <extensionElements>
+        <activiti:formProperty id="username" name="Username" type="string" expression="${user.username}" writable="false"/>
+        <activiti:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+        <activiti:formProperty id="rejectReason" name="Reason for rejecting" type="string" variable="rejectReason"/>
+      </extensionElements>
+    </userTask>
+    <sequenceFlow id="flow8bis" sourceRef="updateApproval" targetRef="updateApprovalGW"/>
+    <exclusiveGateway id="updateApprovalGW"/>
+    <sequenceFlow id="updateApprovalGW2Update" sourceRef="updateApprovalGW" targetRef="update">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="updateApprovalGW2Reject" sourceRef="updateApprovalGW" targetRef="rejectUpdate">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+    </sequenceFlow>
+    <scriptTask id="rejectUpdate" name="Reject update" scriptFormat="groovy" activiti:autoStoreVariables="false">
+      <script>
+        execution.setVariable("propByResource", null);
+      </script>
+    </scriptTask>
+    <sequenceFlow id="flow8ter" sourceRef="rejectUpdate" targetRef="active"/>
+    <serviceTask id="update" name="Update" activiti:expression="#{update.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow9" sourceRef="update" targetRef="active"/>    
+    <serviceTask id="suspend" name="Suspend" activiti:expression="#{suspend.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow10" sourceRef="suspend" targetRef="suspended"/>
+    <userTask id="suspended" name="Suspended"/>
+    <sequenceFlow id="flow11" sourceRef="suspended" targetRef="suspendedGw"/>
+    <exclusiveGateway id="suspendedGw"/>
+    <sequenceFlow id="suspended2Reactivate" sourceRef="suspendedGw" targetRef="reactivate">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'reactivate'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="suspended2Delete" sourceRef="suspendedGw" targetRef="delete">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+    </sequenceFlow>
+    <serviceTask id="reactivate" name="Reactivate" activiti:expression="#{reactivate.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow12" sourceRef="reactivate" targetRef="active"/>
+    <scriptTask id="reject" name="Reject" scriptFormat="groovy" activiti:autoStoreVariables="false">
+      <script>
+        def scriptVar = rejectReason
+        execution.setVariable("propByResource", null);
+      </script>
+    </scriptTask>
+    <sequenceFlow id="flow13" sourceRef="reject" targetRef="rejected"/>
+    <userTask id="rejected" name="Rejected"/>
+    <sequenceFlow id="flow14" sourceRef="rejected" targetRef="rejectedGw"/>
+    <exclusiveGateway id="rejectedGw"/>
+    <sequenceFlow id="rejected2Delete" sourceRef="rejectedGw" targetRef="delete">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="rejected2Rejected" sourceRef="rejectedGw" targetRef="rejected">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${empty task}]]></conditionExpression>
+    </sequenceFlow>    
+    <userTask id="deleteApproval" name="Delete approval" activiti:candidateGroups="7" activiti:formKey="deleteApproval">
+      <extensionElements>
+        <activiti:formProperty id="username" name="Username" type="string" expression="${user.username}" writable="false"/>
+        <activiti:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+        <activiti:formProperty id="rejectReason" name="Reason for rejecting" type="string" variable="rejectReason"/>
+      </extensionElements>
+    </userTask>
+    <sequenceFlow id="flow14bis" sourceRef="deleteApproval" targetRef="deleteApprovalGW"/>
+    <exclusiveGateway id="deleteApprovalGW"/>
+    <sequenceFlow id="deleteApprovalGW2Delete" sourceRef="deleteApprovalGW" targetRef="delete">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="deleteApprovalGW2Reject" sourceRef="deleteApprovalGW" targetRef="rejectDelete">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+    </sequenceFlow>
+    <scriptTask id="rejectDelete" name="Reject delete" scriptFormat="groovy" activiti:autoStoreVariables="false">
+      <script>
+        execution.setVariable("propByResource", null);
+      </script>
+    </scriptTask>
+    <sequenceFlow id="flow14ter" sourceRef="rejectDelete" targetRef="active"/>            
+
+    <serviceTask id="generateToken4PasswordReset" name="Generate token" activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow15" sourceRef="generateToken4PasswordReset" targetRef="notify4RequestPasswordReset"/>
+    <serviceTask id="notify4RequestPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow16" sourceRef="notify4RequestPasswordReset" targetRef="active"/>
+    
+    <serviceTask id="checkToken4ConfirmPasswordReset" name="Check token, remove and update password" activiti:expression="#{passwordReset.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow17" sourceRef="checkToken4ConfirmPasswordReset" targetRef="notify4ConfirmPasswordReset"/>
+    <serviceTask id="notify4ConfirmPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow18" sourceRef="notify4ConfirmPasswordReset" targetRef="active"/>    
+    
+    <serviceTask id="delete" name="Delete" activiti:expression="#{delete.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="flow99" sourceRef="delete" targetRef="theEnd"/>
+    <endEvent id="theEnd"/>
+  </process>
+  
+  <bpmndi:BPMNDiagram id="BPMNDiagram_userWorkflow">
+    <bpmndi:BPMNPlane bpmnElement="userWorkflow" id="BPMNPlane_userWorkflow">
+      <bpmndi:BPMNShape bpmnElement="theStart" id="BPMNShape_theStart">
+        <omgdc:Bounds height="30.0" width="30.0" x="0.0" y="512.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="create" id="BPMNShape_create">
+        <omgdc:Bounds height="60.0" width="100.0" x="80.0" y="497.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="createGW" id="BPMNShape_createGW">
+        <omgdc:Bounds height="40.0" width="40.0" x="230.0" y="506.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="createApproval" id="BPMNShape_createApproval">
+        <omgdc:Bounds height="60.0" width="100.0" x="320.0" y="560.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="createApprovalGW" id="BPMNShape_createApprovalGW">
+        <omgdc:Bounds height="40.0" width="40.0" x="470.0" y="556.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="enableGW" id="BPMNShape_enableGW">
+        <omgdc:Bounds height="40.0" width="40.0" x="590.0" y="429.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="activate" id="BPMNShape_activate">
+        <omgdc:Bounds height="60.0" width="100.0" x="710.0" y="610.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="generateToken" id="BPMNShape_generateToken">
+        <omgdc:Bounds height="60.0" width="100.0" x="702.0" y="188.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="created" id="BPMNShape_created">
+        <omgdc:Bounds height="60.0" width="100.0" x="852.0" y="213.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="optinGW" id="BPMNShape_optinGW">
+        <omgdc:Bounds height="40.0" width="40.0" x="1002.0" y="240.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="removeToken" id="BPMNShape_removeToken">
+        <omgdc:Bounds height="60.0" width="100.0" x="1092.0" y="248.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="active" id="BPMNShape_active">
+        <omgdc:Bounds height="60.0" width="100.0" x="1030.0" y="511.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="activeGw" id="BPMNShape_activeGw">
+        <omgdc:Bounds height="40.0" width="40.0" x="1400.0" y="520.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="updateApproval" id="BPMNShape_updateApproval">
+        <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="740.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="updateApprovalGW" id="BPMNShape_updateApprovalGW">
+        <omgdc:Bounds height="40.0" width="40.0" x="1670.0" y="740.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="rejectUpdate" id="BPMNShape_rejectUpdate">
+        <omgdc:Bounds height="60.0" width="100.0" x="1790.0" y="840.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="update" id="BPMNShape_update">
+        <omgdc:Bounds height="60.0" width="100.0" x="1790.0" y="700.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="suspend" id="BPMNShape_suspend">
+        <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="100.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="suspended" id="BPMNShape_suspended">
+        <omgdc:Bounds height="60.0" width="100.0" x="1640.0" y="120.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="suspendedGw" id="BPMNShape_suspendedGw">
+        <omgdc:Bounds height="40.0" width="40.0" x="1820.0" y="180.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="reactivate" id="BPMNShape_reactivate">
+        <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="110.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="reject" id="BPMNShape_reject">
+        <omgdc:Bounds height="60.0" width="100.0" x="560.0" y="659.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="rejected" id="BPMNShape_rejected">
+        <omgdc:Bounds height="60.0" width="100.0" x="710.0" y="770.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="rejectedGw" id="BPMNShape_rejectedGw">
+        <omgdc:Bounds height="40.0" width="40.0" x="890.0" y="775.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="deleteApproval" id="BPMNShape_deleteApproval">
+        <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="280.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="deleteApprovalGW" id="BPMNShape_deleteApprovalGW">
+        <omgdc:Bounds height="40.0" width="40.0" x="1670.0" y="300.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="rejectDelete" id="BPMNShape_rejectDelete">
+        <omgdc:Bounds height="60.0" width="100.0" x="1790.0" y="240.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="delete" id="BPMNShape_delete">
+        <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="358.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="theEnd" id="BPMNShape_theEnd">
+        <omgdc:Bounds height="28.0" width="28.0" x="2078.1893792531678" y="374.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="generateToken4PasswordReset" id="BPMNShape_generateToken4PasswordReset">
+        <omgdc:Bounds height="59.99999999999994" width="100.0" x="1543.209935088986" y="452.6749142927693"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="notify4RequestPasswordReset" id="BPMNShape_notify4RequestPasswordReset">
+        <omgdc:Bounds height="60.00000000000006" width="100.0" x="1748.9712597675173" y="452.6749142927692"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="checkToken4ConfirmPasswordReset" id="BPMNShape_checkToken4ConfirmPasswordReset">
+        <omgdc:Bounds height="60.0" width="100.0" x="1558.797798366986" y="561.167207412115"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="notify4ConfirmPasswordReset" id="BPMNShape_notify4ConfirmPasswordReset">
+        <omgdc:Bounds height="60.0" width="100.0" x="1748.971259767517" y="561.167207412115"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">
+        <omgdi:waypoint x="1658.797798366986" y="591.167207412115"/>
+        <omgdi:waypoint x="1748.971259767517" y="591.167207412115"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
+        <omgdi:waypoint x="1940.0" y="129.51612903225805"/>
+        <omgdi:waypoint x="1928.0" y="127.0"/>
+        <omgdi:waypoint x="1378.0" y="40.0"/>
+        <omgdi:waypoint x="1097.8443113772455" y="511.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
+        <omgdi:waypoint x="1740.0" y="150.0"/>
+        <omgdi:waypoint x="1752.0" y="150.0"/>
+        <omgdi:waypoint x="1752.0" y="200.0"/>
+        <omgdi:waypoint x="1820.0" y="200.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2DeleteApproval" id="BPMNEdge_active2DeleteApproval">
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1454.0" y="540.0"/>
+        <omgdi:waypoint x="1454.0" y="310.0"/>
+        <omgdi:waypoint x="1490.0" y="310.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow14bis" id="BPMNEdge_flow14bis">
+        <omgdi:waypoint x="1590.0" y="310.0"/>
+        <omgdi:waypoint x="1602.0" y="310.0"/>
+        <omgdi:waypoint x="1602.0" y="320.0"/>
+        <omgdi:waypoint x="1670.0" y="320.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
+        <omgdi:waypoint x="1590.0" y="130.0"/>
+        <omgdi:waypoint x="1602.0" y="130.0"/>
+        <omgdi:waypoint x="1602.0" y="150.0"/>
+        <omgdi:waypoint x="1640.0" y="150.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2RequestPasswordReset" id="BPMNEdge_active2RequestPasswordReset">
+        <omgdi:waypoint x="1439.5" y="540.5"/>
+        <omgdi:waypoint x="1593.209935088986" y="540.5"/>
+        <omgdi:waypoint x="1593.209935088986" y="512.6749142927692"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2ConfirmPasswordReset" id="BPMNEdge_active2ConfirmPasswordReset">
+        <omgdi:waypoint x="1439.5" y="540.5"/>
+        <omgdi:waypoint x="1608.797798366986" y="540.5"/>
+        <omgdi:waypoint x="1608.797798366986" y="561.167207412115"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="deleteApprovalGW2Delete" id="BPMNEdge_deleteApprovalGW2Delete">
+        <omgdi:waypoint x="1710.0" y="320.0"/>
+        <omgdi:waypoint x="1752.0" y="320.0"/>
+        <omgdi:waypoint x="1752.0" y="388.0"/>
+        <omgdi:waypoint x="1940.0" y="388.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createApproval2Reject" id="BPMNEdge_createApproval2Reject">
+        <omgdi:waypoint x="510.0" y="576.0"/>
+        <omgdi:waypoint x="522.0" y="576.0"/>
+        <omgdi:waypoint x="522.0" y="689.0"/>
+        <omgdi:waypoint x="560.0" y="689.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2Delete" id="BPMNEdge_active2Delete">
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1452.0" y="540.0"/>
+        <omgdi:waypoint x="1452.0" y="680.6812757582483"/>
+        <omgdi:waypoint x="1955.9214707261015" y="680.6812757582483"/>
+        <omgdi:waypoint x="1986.506931044467" y="418.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="updateApprovalGW2Update" id="BPMNEdge_updateApprovalGW2Update">
+        <omgdi:waypoint x="1710.0" y="760.0"/>
+        <omgdi:waypoint x="1752.0" y="760.0"/>
+        <omgdi:waypoint x="1752.0" y="730.0"/>
+        <omgdi:waypoint x="1790.0" y="730.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2UpdateApproval" id="BPMNEdge_active2UpdateApproval">
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1454.0" y="540.0"/>
+        <omgdi:waypoint x="1454.0" y="770.0"/>
+        <omgdi:waypoint x="1490.0" y="770.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="rejected2Delete" id="BPMNEdge_rejected2Delete">
+        <omgdi:waypoint x="930.0" y="795.0"/>
+        <omgdi:waypoint x="972.0" y="795.0"/>
+        <omgdi:waypoint x="1470.0" y="911.0"/>
+        <omgdi:waypoint x="1990.0" y="911.0"/>
+        <omgdi:waypoint x="1990.0" y="418.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createApprovalGW2Active" id="BPMNEdge_createApprovalGW2Active">
+        <omgdi:waypoint x="630.0" y="449.0"/>
+        <omgdi:waypoint x="674.0" y="449.0"/>
+        <omgdi:waypoint x="674.0" y="540.0"/>
+        <omgdi:waypoint x="1030.0" y="540.8768472906404"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="updateApprovalGW2Reject" id="BPMNEdge_updateApprovalGW2Reject">
+        <omgdi:waypoint x="1710.0" y="760.0"/>
+        <omgdi:waypoint x="1752.0" y="760.0"/>
+        <omgdi:waypoint x="1752.0" y="870.0"/>
+        <omgdi:waypoint x="1790.0" y="870.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow8ter" id="BPMNEdge_flow8ter">
+        <omgdi:waypoint x="1790.0" y="879.6774193548387"/>
+        <omgdi:waypoint x="1778.0" y="882.0"/>
+        <omgdi:waypoint x="1225.0" y="787.0"/>
+        <omgdi:waypoint x="1080.0" y="726.0"/>
+        <omgdi:waypoint x="1080.0" y="571.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
+        <omgdi:waypoint x="1643.209935088986" y="482.6749142927693"/>
+        <omgdi:waypoint x="1748.9712597675173" y="482.67491429276924"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="suspended2Reactivate" id="BPMNEdge_suspended2Reactivate">
+        <omgdi:waypoint x="1860.0" y="200.0"/>
+        <omgdi:waypoint x="1902.0" y="200.0"/>
+        <omgdi:waypoint x="1902.0" y="140.0"/>
+        <omgdi:waypoint x="1940.0" y="140.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
+        <omgdi:waypoint x="660.0" y="689.0"/>
+        <omgdi:waypoint x="672.0" y="689.0"/>
+        <omgdi:waypoint x="672.0" y="800.0"/>
+        <omgdi:waypoint x="710.0" y="800.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
+        <omgdi:waypoint x="760.0" y="770.0"/>
+        <omgdi:waypoint x="760.0" y="732.8074937730017"/>
+        <omgdi:waypoint x="910.0" y="732.8074937730017"/>
+        <omgdi:waypoint x="910.0" y="775.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createApprovalGW2EnableGW" id="BPMNEdge_createApprovalGW2EnableGW">
+        <omgdi:waypoint x="510.0" y="576.0"/>
+        <omgdi:waypoint x="522.0" y="576.0"/>
+        <omgdi:waypoint x="522.0" y="449.0"/>
+        <omgdi:waypoint x="590.0" y="449.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2Update" id="BPMNEdge_active2Update">
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1456.0" y="540.0"/>
+        <omgdi:waypoint x="1456.0" y="730.0"/>
+        <omgdi:waypoint x="1790.0" y="730.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="create2Activate" id="BPMNEdge_create2Activate">
+        <omgdi:waypoint x="270.0" y="526.0"/>
+        <omgdi:waypoint x="282.0" y="526.0"/>
+        <omgdi:waypoint x="282.0" y="449.0"/>
+        <omgdi:waypoint x="590.0" y="449.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2Suspend" id="BPMNEdge_active2Suspend">
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1452.0" y="540.0"/>
+        <omgdi:waypoint x="1452.0" y="130.0"/>
+        <omgdi:waypoint x="1490.0" y="130.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="suspended2Delete" id="BPMNEdge_suspended2Delete">
+        <omgdi:waypoint x="1860.0" y="200.0"/>
+        <omgdi:waypoint x="1990.0" y="200.0"/>
+        <omgdi:waypoint x="1990.0" y="358.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="created2Activate" id="BPMNEdge_created2Activate">
+        <omgdi:waypoint x="1042.0" y="260.0"/>
+        <omgdi:waypoint x="1054.0" y="260.0"/>
+        <omgdi:waypoint x="1054.0" y="278.0"/>
+        <omgdi:waypoint x="1092.0" y="278.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createAsAnonymous2Approval" id="BPMNEdge_createAsAnonymous2Approval">
+        <omgdi:waypoint x="270.0" y="526.0"/>
+        <omgdi:waypoint x="282.0" y="526.0"/>
+        <omgdi:waypoint x="282.0" y="590.0"/>
+        <omgdi:waypoint x="320.0" y="590.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
+        <omgdi:waypoint x="420.0" y="590.0"/>
+        <omgdi:waypoint x="432.0" y="590.0"/>
+        <omgdi:waypoint x="432.0" y="576.0"/>
+        <omgdi:waypoint x="470.0" y="576.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
+        <omgdi:waypoint x="180.0" y="527.0"/>
+        <omgdi:waypoint x="192.0" y="527.0"/>
+        <omgdi:waypoint x="192.0" y="526.0"/>
+        <omgdi:waypoint x="230.0" y="526.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="rejected2Rejected" id="BPMNEdge_rejected2Rejected">
+        <omgdi:waypoint x="890.6451612903226" y="795.6451612903226"/>
+        <omgdi:waypoint x="810.0" y="798.3333333333334"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
+        <omgdi:waypoint x="802.0" y="218.0"/>
+        <omgdi:waypoint x="814.0" y="218.0"/>
+        <omgdi:waypoint x="814.0" y="243.0"/>
+        <omgdi:waypoint x="852.0" y="243.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
+        <omgdi:waypoint x="810.0" y="640.0"/>
+        <omgdi:waypoint x="822.0" y="640.0"/>
+        <omgdi:waypoint x="959.0" y="640.0"/>
+        <omgdi:waypoint x="1043.3333333333333" y="571.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createApprovalGW2Suspended" id="BPMNEdge_createApprovalGW2Suspended">
+        <omgdi:waypoint x="630.0" y="449.0"/>
+        <omgdi:waypoint x="672.0" y="449.0"/>
+        <omgdi:waypoint x="672.0" y="130.0"/>
+        <omgdi:waypoint x="1490.0" y="130.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow14ter" id="BPMNEdge_flow14ter">
+        <omgdi:waypoint x="1790.0" y="260.7608891486752"/>
+        <omgdi:waypoint x="1424.117736926915" y="193.1523534073587"/>
+        <omgdi:waypoint x="1109.678315230625" y="511.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createApprovalGW2OptIn" id="BPMNEdge_createApprovalGW2OptIn">
+        <omgdi:waypoint x="630.0" y="449.0"/>
+        <omgdi:waypoint x="674.0" y="449.0"/>
+        <omgdi:waypoint x="700.0" y="449.0"/>
+        <omgdi:waypoint x="745.2467532467532" y="248.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+        <omgdi:waypoint x="30.0" y="527.0"/>
+        <omgdi:waypoint x="80.0" y="527.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
+        <omgdi:waypoint x="1748.9712597675173" y="459.5470829510475"/>
+        <omgdi:waypoint x="1592.4096593525787" y="387.128477171313"/>
+        <omgdi:waypoint x="1130.0" y="525.9854974413342"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="created2Created" id="BPMNEdge_created2Created">
+        <omgdi:waypoint x="1002.0" y="260.0"/>
+        <omgdi:waypoint x="990.0" y="260.0"/>
+        <omgdi:waypoint x="990.0" y="243.0"/>
+        <omgdi:waypoint x="952.0" y="243.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18">
+        <omgdi:waypoint x="1748.971259767517" y="619.7464352880323"/>
+        <omgdi:waypoint x="1673.525420205687" y="662.8701121105813"/>
+        <omgdi:waypoint x="1130.0" y="551.266629529393"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="createApprovalGW2Activate" id="BPMNEdge_createApprovalGW2Activate">
+        <omgdi:waypoint x="630.0" y="449.0"/>
+        <omgdi:waypoint x="672.0" y="449.0"/>
+        <omgdi:waypoint x="672.0" y="640.0"/>
+        <omgdi:waypoint x="710.0" y="640.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
+        <omgdi:waypoint x="1134.9277566539924" y="308.0"/>
+        <omgdi:waypoint x="1087.0722433460076" y="511.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
+        <omgdi:waypoint x="952.0" y="252.67741935483872"/>
+        <omgdi:waypoint x="964.0" y="255.0"/>
+        <omgdi:waypoint x="964.0" y="260.0"/>
+        <omgdi:waypoint x="1002.0" y="260.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
+        <omgdi:waypoint x="1828.6246202240113" y="760.0"/>
+        <omgdi:waypoint x="1811.88836468294" y="804.1381014189917"/>
+        <omgdi:waypoint x="1474.4398193359375" y="804.1381014189917"/>
+        <omgdi:waypoint x="1124.969521769241" y="571.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="deleteApprovalGW2Reject" id="BPMNEdge_deleteApprovalGW2Reject">
+        <omgdi:waypoint x="1710.0" y="320.0"/>
+        <omgdi:waypoint x="1752.0" y="320.0"/>
+        <omgdi:waypoint x="1752.0" y="270.0"/>
+        <omgdi:waypoint x="1790.0" y="270.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow8bis" id="BPMNEdge_flow8bis">
+        <omgdi:waypoint x="1590.0" y="770.0"/>
+        <omgdi:waypoint x="1602.0" y="770.0"/>
+        <omgdi:waypoint x="1602.0" y="760.0"/>
+        <omgdi:waypoint x="1670.0" y="760.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow99" id="BPMNEdge_flow99">
+        <omgdi:waypoint x="2040.0" y="388.0"/>
+        <omgdi:waypoint x="2078.1893792531678" y="388.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
+        <omgdi:waypoint x="1130.0" y="540.8529411764706"/>
+        <omgdi:waypoint x="1400.058651026393" y="540.0586510263929"/>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</definitions>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/resources/workflow.properties b/syncope620/fit/reference/src/main/resources/workflow.properties
new file mode 100644
index 0000000..0cad37e
--- /dev/null
+++ b/syncope620/fit/reference/src/main/resources/workflow.properties
@@ -0,0 +1,20 @@
+# 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.
+wf.directory=${conf.directory}
+jobExecutorActivate=true
+uwfAdapter=org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter
+rwfAdapter=org.apache.syncope.server.workflow.java.DefaultRoleWorkflowAdapter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
index fc81657..255666c 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
@@ -59,6 +59,7 @@ import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.RoleService;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
 import org.apache.syncope.common.rest.api.service.UserService;
@@ -142,6 +143,8 @@ public abstract class AbstractITCase {
 
     protected static SyncopeClient adminClient;
 
+    protected static SyncopeService syncopeService;
+
     protected static UserService userService;
 
     protected static UserSelfService userSelfService;
@@ -207,6 +210,7 @@ public abstract class AbstractITCase {
 
         adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
 
+        syncopeService = adminClient.getService(SyncopeService.class);
         userService = adminClient.getService(UserService.class);
         userSelfService = adminClient.getService(UserSelfService.class);
         userWorkflowService = adminClient.getService(UserWorkflowService.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
index ae35a23..03b686b 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
@@ -18,19 +18,19 @@
  */
 package org.apache.syncope.fit.server.reference;
 
+import org.apache.syncope.common.rest.api.service.SyncopeService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-// TODO: REMOVE!!!
 public class ActivitiDetector {
 
     private static final Logger LOG = LoggerFactory.getLogger(ActivitiDetector.class);
 
-    public static boolean isActivitiEnabledForUsers() {
-        return false;
+    public static boolean isActivitiEnabledForUsers(final SyncopeService syncopeService) {
+        return syncopeService.info().getUserWorkflowAdapter().indexOf("Activiti") != -1;
     }
 
-    public static boolean isActivitiEnabledForRoles() {
-        return false;
+    public static boolean isActivitiEnabledForRoles(final SyncopeService syncopeService) {
+        return syncopeService.info().getRoleWorkflowAdapter().indexOf("Activiti") != -1;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
index 9c18a4d..5b3b4b0 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
@@ -366,7 +366,7 @@ public class AuthenticationITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE434() {
-        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
         // 1. create user with role 9 (users with role 9 are defined in workflow as subject to approval)
         UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
index 075cdd9..c25dc7f 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
@@ -205,7 +205,7 @@ public class PolicyITCase extends AbstractITCase {
 
     @Test
     public void getCorrelationRules() {
-        assertEquals(1, policyService.getSyncCorrelationRuleClasses().size());
+        assertEquals(1, syncopeService.info().getSyncCorrelationRules().size());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
index 6cb624a..69f26e3 100644
--- a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
@@ -43,7 +43,6 @@ import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.wrap.PropagationActionClass;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -88,7 +87,7 @@ public class ResourceITCase extends AbstractITCase {
 
     @Test
     public void getPropagationActionsClasses() {
-        List<PropagationActionClass> actions = resourceService.getPropagationActionsClasses();
+        List<String> actions = syncopeService.info().getPropagationActions();
         assertNotNull(actions);
         assertFalse(actions.isEmpty());
     }


[07/12] syncope git commit: [SYNCOPE-620] IT with Activiti

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Notify.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Notify.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Notify.java
deleted file mode 100644
index 3c2bd86..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Notify.java
+++ /dev/null
@@ -1,62 +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.workflow.activiti.task;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-/**
- * General-purpose notification task for usage within workflow.
- * It requires a pre-existing <tt>Notification</tt> with category <tt>CUSTOM</tt> and result <tt>SUCCESS</tt>.
- * An <tt>event</tt> workflow variable needs to be provided as well.
- */
-@Component
-public class Notify extends AbstractActivitiServiceTask {
-
-    @Autowired
-    private NotificationManager notificationManager;
-
-    @Override
-    protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, User.class);
-        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
-        String event = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT, String.class);
-
-        if (StringUtils.isNotBlank(event)) {
-            notificationManager.createTasks(
-                    AuditElements.EventCategoryType.CUSTOM,
-                    null,
-                    null,
-                    event,
-                    AuditElements.Result.SUCCESS,
-                    userTO,
-                    null,
-                    user.getToken());
-        } else {
-            LOG.debug("Not sending any notification since no event was found");
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/PasswordReset.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/PasswordReset.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/PasswordReset.java
deleted file mode 100644
index 7b9e4be..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/PasswordReset.java
+++ /dev/null
@@ -1,44 +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.workflow.activiti.task;
-
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.workflow.api.WorkflowException;
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.stereotype.Component;
-
-@Component
-public class PasswordReset extends AbstractActivitiServiceTask {
-
-    @Override
-    protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, User.class);
-        String token = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN, String.class);
-        String password = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD, String.class);
-
-        if (!user.checkToken(token)) {
-            throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user));
-        }
-
-        user.removeToken();
-        user.setPassword(password, user.getCipherAlgorithm());
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Reactivate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Reactivate.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Reactivate.java
deleted file mode 100644
index 6d105ba..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Reactivate.java
+++ /dev/null
@@ -1,29 +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.workflow.activiti.task;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class Reactivate extends AbstractActivitiServiceTask {
-
-    @Override
-    protected void doExecute(final String executionId) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Suspend.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Suspend.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Suspend.java
deleted file mode 100644
index 24a7bdd..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Suspend.java
+++ /dev/null
@@ -1,29 +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.workflow.activiti.task;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class Suspend extends AbstractActivitiServiceTask {
-
-    @Override
-    protected void doExecute(final String executionId) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Update.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Update.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Update.java
deleted file mode 100644
index 15d1b3f..0000000
--- a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/workflow/activiti/task/Update.java
+++ /dev/null
@@ -1,54 +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.workflow.activiti.task;
-
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.workflow.activiti.ActivitiUserWorkflowAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class Update extends AbstractActivitiServiceTask {
-
-    @Autowired
-    private UserDataBinder dataBinder;
-
-    @Override
-    protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, User.class);
-        UserMod userMod =
-                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class);
-
-        // update password internally only if required
-        UserMod actualMod = SerializationUtils.clone(userMod);
-        if (actualMod.getPwdPropRequest() != null && !actualMod.getPwdPropRequest().isOnSyncope()) {
-            actualMod.setPassword(null);
-        }
-        // update SyncopeUser
-        PropagationByResource propByRes = dataBinder.update(user, actualMod);
-
-        // report updated user and propagation by resource as result
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user);
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/resources/workflow.properties b/syncope620/server/workflow-activiti/src/main/resources/workflow.properties
new file mode 100644
index 0000000..0cad37e
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/resources/workflow.properties
@@ -0,0 +1,20 @@
+# 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.
+wf.directory=${conf.directory}
+jobExecutorActivate=true
+uwfAdapter=org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter
+rwfAdapter=org.apache.syncope.server.workflow.java.DefaultRoleWorkflowAdapter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/resources/workflowActivitiContext.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/syncope620/server/workflow-activiti/src/main/resources/workflowActivitiContext.xml
index 463c2c7..41670fb 100644
--- a/syncope620/server/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/syncope620/server/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -26,12 +26,12 @@ under the License.
                            http://www.springframework.org/schema/context/spring-context.xsd">
 
   <bean id="userWorkflowDef" class="org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${conf.directory}/userWorkflow.bpmn20.xml"/>
+    <property name="primary" value="file:${wf.directory}/userWorkflow.bpmn20.xml"/>
     <property name="fallback" value="classpath:userWorkflow.bpmn20.xml"/>
   </bean>
 
-  <bean id="syncopeActivitiUserManager" class="org.apache.syncope.workflow.activiti.SyncopeUserManager"/>
-  <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.workflow.activiti.SyncopeGroupManager"/>
+  <bean id="syncopeActivitiUserManager" class="org.apache.syncope.server.workflow.activiti.SyncopeUserManager"/>
+  <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.server.workflow.activiti.SyncopeGroupManager"/>
 
   <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
     <property name="dataSource" ref="dataSource"/>
@@ -47,17 +47,17 @@ under the License.
 
     <property name="customSessionFactories">
       <list>
-        <bean class="org.apache.syncope.workflow.activiti.SyncopeSessionFactory">
+        <bean class="org.apache.syncope.server.workflow.activiti.SyncopeSessionFactory">
           <property name="syncopeSession" ref="syncopeActivitiUserManager"/>
         </bean>
-        <bean class="org.apache.syncope.workflow.activiti.SyncopeSessionFactory">
+        <bean class="org.apache.syncope.server.workflow.activiti.SyncopeSessionFactory">
           <property name="syncopeSession" ref="syncopeActivitiGroupManager"/>
         </bean>
       </list>
     </property>
     <property name="customPreVariableTypes">
       <list>
-        <bean class="org.apache.syncope.workflow.activiti.SyncopeEntitiesVariableType"/>
+        <bean class="org.apache.syncope.server.workflow.activiti.SyncopeEntitiesVariableType"/>
       </list>
     </property>
   </bean>
@@ -74,6 +74,6 @@ under the License.
   <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
   <bean id="formService" factory-bean="processEngine" factory-method="getFormService"/>
 
-  <context:component-scan base-package="org.apache.syncope.workflow.activiti"/>
+  <context:component-scan base-package="org.apache.syncope.server.workflow.activiti"/>
     
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-java/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-java/src/main/resources/workflow.properties b/syncope620/server/workflow-java/src/main/resources/workflow.properties
index a72e766..2c08d50 100644
--- a/syncope620/server/workflow-java/src/main/resources/workflow.properties
+++ b/syncope620/server/workflow-java/src/main/resources/workflow.properties
@@ -14,5 +14,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+wf.directory=${conf.directory}
+jobExecutorActivate=false
 uwfAdapter=org.apache.syncope.server.workflow.java.DefaultUserWorkflowAdapter
 rwfAdapter=org.apache.syncope.server.workflow.java.DefaultRoleWorkflowAdapter
\ No newline at end of file


[09/12] syncope git commit: [SYNCOPE-620] IT with Activiti

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
new file mode 100644
index 0000000..845362c
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -0,0 +1,893 @@
+/*
+ * 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.server.workflow.activiti;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Resource;
+import javax.ws.rs.NotFoundException;
+import org.activiti.bpmn.converter.BpmnXMLConverter;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.editor.constants.ModelDataJsonConstants;
+import org.activiti.editor.language.json.converter.BpmnJsonConverter;
+import org.activiti.engine.ActivitiException;
+import org.activiti.engine.FormService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.activiti.engine.form.FormProperty;
+import org.activiti.engine.form.FormType;
+import org.activiti.engine.form.TaskFormData;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricDetail;
+import org.activiti.engine.history.HistoricTaskInstance;
+import org.activiti.engine.impl.persistence.entity.HistoricFormPropertyEntity;
+import org.activiti.engine.query.Query;
+import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.WorkflowFormPropertyType;
+import org.apache.syncope.server.misc.security.AuthContextUtil;
+import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
+import org.apache.syncope.server.misc.spring.BeanUtils;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.WorkflowResult;
+import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.server.workflow.api.WorkflowDefinitionFormat;
+import org.apache.syncope.server.workflow.api.WorkflowException;
+import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
+import org.apache.syncope.server.workflow.java.AbstractUserWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Activiti (http://www.activiti.org/) based implementation.
+ */
+public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(ActivitiUserWorkflowAdapter.class);
+
+    private static final String[] PROPERTY_IGNORE_PROPS = { "type" };
+
+    public static final String WF_PROCESS_ID = "userWorkflow";
+
+    public static final String WF_PROCESS_RESOURCE = "userWorkflow.bpmn20.xml";
+
+    public static final String WF_DGRM_RESOURCE = "userWorkflow.userWorkflow.png";
+
+    public static final String USER = "user";
+
+    public static final String WF_EXECUTOR = "wfExecutor";
+
+    public static final String FORM_SUBMITTER = "formSubmitter";
+
+    public static final String USER_TO = "userTO";
+
+    public static final String ENABLED = "enabled";
+
+    public static final String USER_MOD = "userMod";
+
+    public static final String EMAIL_KIND = "emailKind";
+
+    public static final String TASK = "task";
+
+    public static final String TOKEN = "token";
+
+    public static final String PASSWORD = "password";
+
+    public static final String PROP_BY_RESOURCE = "propByResource";
+
+    public static final String PROPAGATE_ENABLE = "propagateEnable";
+
+    public static final String ENCRYPTED_PWD = "encryptedPwd";
+
+    public static final String TASK_IS_FORM = "taskIsForm";
+
+    public static final String MODEL_DATA_JSON_MODEL = "model";
+
+    public static final String STORE_PASSWORD = "storePassword";
+
+    public static final String EVENT = "event";
+
+    @Resource(name = "adminUser")
+    private String adminUser;
+
+    @Autowired
+    private RuntimeService runtimeService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Autowired
+    private FormService formService;
+
+    @Autowired
+    private HistoryService historyService;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private ActivitiImportUtils importUtils;
+
+    @Autowired
+    private UserDataBinder userDataBinder;
+
+    @Override
+    public Class<? extends WorkflowDefinitionLoader> getDefinitionLoaderClass() {
+        return ActivitiDefinitionLoader.class;
+    }
+
+    private void throwException(final ActivitiException e, final String defaultMessage) {
+        if (e.getCause() != null) {
+            if (e.getCause().getCause() instanceof SyncopeClientException) {
+                throw (SyncopeClientException) e.getCause().getCause();
+            } else if (e.getCause().getCause() instanceof ParsingValidationException) {
+                throw (ParsingValidationException) e.getCause().getCause();
+            } else if (e.getCause().getCause() instanceof InvalidEntityException) {
+                throw (InvalidEntityException) e.getCause().getCause();
+            }
+        }
+
+        throw new WorkflowException(defaultMessage, e);
+    }
+
+    private void updateStatus(final User user) {
+        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        if (tasks.isEmpty() || tasks.size() > 1) {
+            LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
+        } else {
+            user.setStatus(tasks.get(0).getTaskDefinitionKey());
+        }
+    }
+
+    private String getFormTask(final User user) {
+        String result = null;
+
+        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        if (tasks.isEmpty() || tasks.size() > 1) {
+            LOG.warn("While checking if form task: unexpected task number ({})", tasks.size());
+        } else {
+            try {
+                TaskFormData formData = formService.getTaskFormData(tasks.get(0).getId());
+                if (formData != null && !formData.getFormProperties().isEmpty()) {
+                    result = tasks.get(0).getId();
+                }
+            } catch (ActivitiException e) {
+                LOG.warn("Could not get task form data", e);
+            }
+        }
+
+        return result;
+    }
+
+    private Set<String> getPerformedTasks(final User user) {
+        final Set<String> result = new HashSet<>();
+
+        for (HistoricActivityInstance task
+                : historyService.createHistoricActivityInstanceQuery().executionId(user.getWorkflowId()).list()) {
+
+            result.add(task.getActivityId());
+        }
+
+        return result;
+    }
+
+    /**
+     * Saves resources to be propagated and password for later - after form submission - propagation.
+     */
+    private void saveForFormSubmit(final User user, final String password,
+            final PropagationByResource propByRes) {
+
+        String formTaskId = getFormTask(user);
+        if (formTaskId != null) {
+            // SYNCOPE-238: This is needed to simplify the task query in this.getForms()
+            taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
+            runtimeService.setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
+            if (propByRes != null) {
+                propByRes.clear();
+            }
+
+            if (StringUtils.isNotBlank(password)) {
+                runtimeService.setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
+            }
+        }
+    }
+
+    @Override
+    public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
+            final boolean storePassword) throws WorkflowException {
+
+        return create(userTO, disablePwdPolicyCheck, null, storePassword);
+    }
+
+    @Override
+    public WorkflowResult<Map.Entry<Long, Boolean>> create(UserTO userTO, boolean storePassword) throws
+            UnauthorizedRoleException, WorkflowException {
+
+        return create(userTO, false, storePassword);
+    }
+
+    @Override
+    public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
+            final Boolean enabled, final boolean storePassword) throws WorkflowException {
+
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(WF_EXECUTOR, AuthContextUtil.getAuthenticatedUsername());
+        variables.put(USER_TO, userTO);
+        variables.put(ENABLED, enabled);
+        variables.put(STORE_PASSWORD, storePassword);
+
+        ProcessInstance processInstance = null;
+        try {
+            processInstance = runtimeService.startProcessInstanceByKey(WF_PROCESS_ID, variables);
+        } catch (ActivitiException e) {
+            throwException(e, "While starting " + WF_PROCESS_ID + " instance");
+        }
+
+        User user =
+                runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
+
+        Boolean updatedEnabled =
+                runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
+        if (updatedEnabled != null) {
+            user.setSuspended(!updatedEnabled);
+        }
+
+        // this will make UserValidator not to consider password policies at all
+        if (disablePwdPolicyCheck) {
+            user.removeClearPassword();
+        }
+
+        updateStatus(user);
+        user = userDAO.save(user);
+
+        Boolean propagateEnable =
+                runtimeService.getVariable(processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
+        if (propagateEnable == null) {
+            propagateEnable = enabled;
+        }
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.set(ResourceOperation.CREATE, user.getResourceNames());
+
+        saveForFormSubmit(user, userTO.getPassword(), propByRes);
+
+        return new WorkflowResult<Map.Entry<Long, Boolean>>(
+                new SimpleEntry<>(user.getKey(), propagateEnable), propByRes, getPerformedTasks(user));
+    }
+
+    private Set<String> doExecuteTask(final User user, final String task,
+            final Map<String, Object> moreVariables) throws WorkflowException {
+
+        Set<String> preTasks = getPerformedTasks(user);
+
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(WF_EXECUTOR, AuthContextUtil.getAuthenticatedUsername());
+        variables.put(TASK, task);
+
+        // using BeanUtils to access all user's properties and trigger lazy loading - we are about to
+        // serialize a User instance for availability within workflow tasks, and this breaks transactions
+        BeanUtils.copyProperties(user, entityFactory.newEntity(User.class));
+        variables.put(USER, user);
+
+        if (moreVariables != null && !moreVariables.isEmpty()) {
+            variables.putAll(moreVariables);
+        }
+
+        if (StringUtils.isBlank(user.getWorkflowId())) {
+            throw new WorkflowException(new NotFoundException("Empty workflow id for " + user));
+        }
+
+        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        if (tasks.size() == 1) {
+            try {
+                taskService.complete(tasks.get(0).getId(), variables);
+            } catch (ActivitiException e) {
+                throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user);
+            }
+        } else {
+            LOG.warn("Expected a single task, found {}", tasks.size());
+        }
+
+        Set<String> postTasks = getPerformedTasks(user);
+        postTasks.removeAll(preTasks);
+        postTasks.add(task);
+        return postTasks;
+    }
+
+    @Override
+    protected WorkflowResult<Long> doActivate(final User user, final String token)
+            throws WorkflowException {
+
+        Set<String> tasks = doExecuteTask(user, "activate", Collections.singletonMap(TOKEN, (Object) token));
+
+        updateStatus(user);
+        User updated = userDAO.save(user);
+
+        return new WorkflowResult<>(updated.getKey(), null, tasks);
+    }
+
+    @Override
+    protected WorkflowResult<Map.Entry<UserMod, Boolean>> doUpdate(final User user, final UserMod userMod)
+            throws WorkflowException {
+
+        Set<String> tasks = doExecuteTask(user, "update", Collections.singletonMap(USER_MOD, (Object) userMod));
+
+        updateStatus(user);
+        User updated = userDAO.save(user);
+
+        PropagationByResource propByRes =
+                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+
+        saveForFormSubmit(updated, userMod.getPassword(), propByRes);
+
+        Boolean propagateEnable = runtimeService.getVariable(user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
+
+        return new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+                new SimpleEntry<>(userMod, propagateEnable), propByRes, tasks);
+    }
+
+    @Override
+    @Transactional(rollbackFor = { Throwable.class })
+    protected WorkflowResult<Long> doSuspend(final User user) throws WorkflowException {
+        Set<String> performedTasks = doExecuteTask(user, "suspend", null);
+        updateStatus(user);
+        User updated = userDAO.save(user);
+
+        return new WorkflowResult<>(updated.getKey(), null, performedTasks);
+    }
+
+    @Override
+    protected WorkflowResult<Long> doReactivate(final User user) throws WorkflowException {
+        Set<String> performedTasks = doExecuteTask(user, "reactivate", null);
+        updateStatus(user);
+
+        User updated = userDAO.save(user);
+
+        return new WorkflowResult<>(updated.getKey(), null, performedTasks);
+    }
+
+    @Override
+    protected void doRequestPasswordReset(final User user) throws WorkflowException {
+        Map<String, Object> variables = new HashMap<>(2);
+        variables.put(USER_TO, userDataBinder.getUserTO(user));
+        variables.put(EVENT, "requestPasswordReset");
+
+        doExecuteTask(user, "requestPasswordReset", variables);
+        userDAO.save(user);
+    }
+
+    @Override
+    protected void doConfirmPasswordReset(final User user, final String token, final String password)
+            throws WorkflowException {
+
+        Map<String, Object> variables = new HashMap<>(4);
+        variables.put(TOKEN, token);
+        variables.put(PASSWORD, password);
+        variables.put(USER_TO, userDataBinder.getUserTO(user));
+        variables.put(EVENT, "confirmPasswordReset");
+
+        doExecuteTask(user, "confirmPasswordReset", variables);
+        userDAO.save(user);
+    }
+
+    @Override
+    protected void doDelete(final User user) throws WorkflowException {
+        doExecuteTask(user, "delete", null);
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.set(ResourceOperation.DELETE, user.getResourceNames());
+
+        saveForFormSubmit(user, null, propByRes);
+
+        if (runtimeService.createProcessInstanceQuery().
+                processInstanceId(user.getWorkflowId()).active().list().isEmpty()) {
+
+            userDAO.delete(user.getKey());
+
+            if (!historyService.createHistoricProcessInstanceQuery().
+                    processInstanceId(user.getWorkflowId()).list().isEmpty()) {
+
+                historyService.deleteHistoricProcessInstance(user.getWorkflowId());
+            }
+        } else {
+            updateStatus(user);
+            userDAO.save(user);
+        }
+    }
+
+    @Override
+    public WorkflowResult<Long> execute(final UserTO userTO, final String taskId)
+            throws UnauthorizedRoleException, WorkflowException {
+
+        User user = userDAO.authFetch(userTO.getKey());
+
+        final Map<String, Object> variables = new HashMap<>();
+        variables.put(USER_TO, userTO);
+
+        Set<String> performedTasks = doExecuteTask(user, taskId, variables);
+        updateStatus(user);
+        User updated = userDAO.save(user);
+
+        return new WorkflowResult<>(updated.getKey(), null, performedTasks);
+    }
+
+    protected ProcessDefinition getProcessDefinition() {
+        try {
+            return repositoryService.createProcessDefinitionQuery().processDefinitionKey(
+                    ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
+        } catch (ActivitiException e) {
+            throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
+        }
+
+    }
+
+    protected Model getModel(final ProcessDefinition procDef) {
+        try {
+            Model model = repositoryService.createModelQuery().deploymentId(procDef.getDeploymentId()).singleResult();
+            if (model == null) {
+                throw new NotFoundException("Could not find Model for deployment " + procDef.getDeploymentId());
+            }
+            return model;
+        } catch (Exception e) {
+            throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
+        }
+    }
+
+    protected void exportProcessResource(final String resourceName, final OutputStream os) {
+        ProcessDefinition procDef = getProcessDefinition();
+
+        InputStream procDefIS = repositoryService.getResourceAsStream(procDef.getDeploymentId(), resourceName);
+        try {
+            IOUtils.copy(procDefIS, os);
+        } catch (IOException e) {
+            LOG.error("While exporting workflow definition {}", procDef.getKey(), e);
+        } finally {
+            IOUtils.closeQuietly(procDefIS);
+        }
+    }
+
+    protected void exportProcessModel(final OutputStream os) {
+        Model model = getModel(getProcessDefinition());
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            ObjectNode modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
+            modelNode.put(ModelDataJsonConstants.MODEL_ID, model.getId());
+            modelNode.replace(MODEL_DATA_JSON_MODEL,
+                    objectMapper.readTree(repositoryService.getModelEditorSource(model.getId())));
+
+            os.write(modelNode.toString().getBytes());
+        } catch (IOException e) {
+            LOG.error("While exporting workflow definition {}", model.getId(), e);
+        }
+    }
+
+    @Override
+    public void exportDefinition(final WorkflowDefinitionFormat format, final OutputStream os)
+            throws WorkflowException {
+
+        switch (format) {
+            case JSON:
+                exportProcessModel(os);
+                break;
+
+            case XML:
+            default:
+                exportProcessResource(WF_PROCESS_RESOURCE, os);
+        }
+    }
+
+    @Override
+    public void exportDiagram(final OutputStream os) throws WorkflowException {
+        exportProcessResource(WF_DGRM_RESOURCE, os);
+    }
+
+    @Override
+    public void importDefinition(final WorkflowDefinitionFormat format, final String definition)
+            throws WorkflowException {
+
+        Model model = getModel(getProcessDefinition());
+        switch (format) {
+            case JSON:
+                JsonNode definitionNode;
+                try {
+                    definitionNode = new ObjectMapper().readTree(definition);
+                    if (definitionNode.has(MODEL_DATA_JSON_MODEL)) {
+                        definitionNode = definitionNode.get(MODEL_DATA_JSON_MODEL);
+                    }
+                    if (!definitionNode.has(BpmnJsonConverter.EDITOR_CHILD_SHAPES)) {
+                        throw new IllegalArgumentException(
+                                "Could not find JSON node " + BpmnJsonConverter.EDITOR_CHILD_SHAPES);
+                    }
+
+                    BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
+                    importUtils.fromXML(new BpmnXMLConverter().convertToXML(bpmnModel));
+                } catch (Exception e) {
+                    throw new WorkflowException("While updating process "
+                            + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+                }
+
+                importUtils.fromJSON(definitionNode.toString().getBytes(), getProcessDefinition(), model);
+                break;
+
+            case XML:
+            default:
+                importUtils.fromXML(definition.getBytes());
+
+                importUtils.fromJSON(getProcessDefinition(), model);
+        }
+    }
+
+    private WorkflowFormPropertyType fromActivitiFormType(final FormType activitiFormType) {
+        WorkflowFormPropertyType result = WorkflowFormPropertyType.String;
+
+        if ("string".equals(activitiFormType.getName())) {
+            result = WorkflowFormPropertyType.String;
+        }
+        if ("long".equals(activitiFormType.getName())) {
+            result = WorkflowFormPropertyType.Long;
+        }
+        if ("enum".equals(activitiFormType.getName())) {
+            result = WorkflowFormPropertyType.Enum;
+        }
+        if ("date".equals(activitiFormType.getName())) {
+            result = WorkflowFormPropertyType.Date;
+        }
+        if ("boolean".equals(activitiFormType.getName())) {
+            result = WorkflowFormPropertyType.Boolean;
+        }
+
+        return result;
+    }
+
+    private WorkflowFormTO getFormTO(final Task task) {
+        return getFormTO(task, formService.getTaskFormData(task.getId()));
+    }
+
+    private WorkflowFormTO getFormTO(final Task task, final TaskFormData fd) {
+        final WorkflowFormTO formTO =
+                getFormTO(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
+
+        BeanUtils.copyProperties(task, formTO);
+        return formTO;
+    }
+
+    private WorkflowFormTO getFormTO(final HistoricTaskInstance task) {
+        final List<HistoricFormPropertyEntity> props = new ArrayList<>();
+
+        for (HistoricDetail historicDetail : historyService.createHistoricDetailQuery().taskId(task.getId()).list()) {
+
+            if (historicDetail instanceof HistoricFormPropertyEntity) {
+                props.add((HistoricFormPropertyEntity) historicDetail);
+            }
+        }
+
+        final WorkflowFormTO formTO = getHistoricFormTO(
+                task.getProcessInstanceId(), task.getId(), task.getFormKey(), props);
+        BeanUtils.copyProperties(task, formTO);
+
+        final HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().
+                executionId(task.getExecutionId()).activityType("userTask").activityName(task.getName()).singleResult();
+
+        if (historicActivityInstance != null) {
+            formTO.setCreateTime(historicActivityInstance.getStartTime());
+            formTO.setDueDate(historicActivityInstance.getEndTime());
+        }
+
+        return formTO;
+    }
+
+    private WorkflowFormTO getHistoricFormTO(
+            final String processInstanceId,
+            final String taskId,
+            final String formKey,
+            final List<HistoricFormPropertyEntity> props) {
+
+        WorkflowFormTO formTO = new WorkflowFormTO();
+
+        User user = userDAO.findByWorkflowId(processInstanceId);
+        if (user == null) {
+            throw new NotFoundException("User with workflow id " + processInstanceId);
+        }
+        formTO.setUserKey(user.getKey());
+
+        formTO.setTaskId(taskId);
+        formTO.setKey(formKey);
+
+        for (HistoricFormPropertyEntity prop : props) {
+            WorkflowFormPropertyTO propertyTO = new WorkflowFormPropertyTO();
+            propertyTO.setId(prop.getPropertyId());
+            propertyTO.setName(prop.getPropertyId());
+            propertyTO.setValue(prop.getPropertyValue());
+            formTO.addProperty(propertyTO);
+        }
+
+        return formTO;
+    }
+
+    @SuppressWarnings("unchecked")
+    private WorkflowFormTO getFormTO(
+            final String processInstanceId,
+            final String taskId,
+            final String formKey,
+            final List<FormProperty> properties) {
+
+        WorkflowFormTO formTO = new WorkflowFormTO();
+
+        User user = userDAO.findByWorkflowId(processInstanceId);
+        if (user == null) {
+            throw new NotFoundException("User with workflow id " + processInstanceId);
+        }
+        formTO.setUserKey(user.getKey());
+
+        formTO.setTaskId(taskId);
+        formTO.setKey(formKey);
+
+        for (FormProperty fProp : properties) {
+            WorkflowFormPropertyTO propertyTO = new WorkflowFormPropertyTO();
+            BeanUtils.copyProperties(fProp, propertyTO, PROPERTY_IGNORE_PROPS);
+            propertyTO.setType(fromActivitiFormType(fProp.getType()));
+
+            if (propertyTO.getType() == WorkflowFormPropertyType.Date) {
+                propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
+            }
+            if (propertyTO.getType() == WorkflowFormPropertyType.Enum) {
+                propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
+            }
+
+            formTO.addProperty(propertyTO);
+        }
+
+        return formTO;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public List<WorkflowFormTO> getForms() {
+        List<WorkflowFormTO> forms = new ArrayList<>();
+
+        final String authUser = AuthContextUtil.getAuthenticatedUsername();
+        if (adminUser.equals(authUser)) {
+            forms.addAll(getForms(taskService.createTaskQuery().
+                    taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
+        } else {
+            User user = userDAO.find(authUser);
+            if (user == null) {
+                throw new NotFoundException("Syncope User " + authUser);
+            }
+
+            forms.addAll(getForms(taskService.createTaskQuery().
+                    taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
+                    taskCandidateOrAssigned(user.getKey().toString())));
+
+            List<String> candidateGroups = new ArrayList<>();
+            for (Long roleId : user.getRoleKeys()) {
+                candidateGroups.add(roleId.toString());
+            }
+            if (!candidateGroups.isEmpty()) {
+                forms.addAll(getForms(taskService.createTaskQuery().
+                        taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
+                        taskCandidateGroupIn(candidateGroups)));
+            }
+        }
+
+        return forms;
+    }
+
+    @Override
+    public List<WorkflowFormTO> getForms(final String workflowId, final String name) {
+        List<WorkflowFormTO> forms = getForms(
+                taskService.createTaskQuery().processInstanceId(workflowId).taskName(name).
+                taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE));
+
+        forms.addAll(getForms(historyService.createHistoricTaskInstanceQuery().taskName(name).
+                taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
+
+        return forms;
+    }
+
+    private <T extends Query<?, ?>, U extends Object> List<WorkflowFormTO> getForms(final Query<T, U> query) {
+        List<WorkflowFormTO> forms = new ArrayList<>();
+
+        for (U obj : query.list()) {
+            try {
+                if (obj instanceof HistoricTaskInstance) {
+                    forms.add(getFormTO((HistoricTaskInstance) obj));
+                } else if (obj instanceof Task) {
+                    forms.add(getFormTO((Task) obj));
+                } else {
+                    throw new ActivitiException(
+                            "Failure retrieving form", new IllegalArgumentException("Invalid task type"));
+                }
+            } catch (ActivitiException e) {
+                LOG.debug("No form found for task {}", obj, e);
+            }
+        }
+
+        return forms;
+    }
+
+    @Override
+    public WorkflowFormTO getForm(final String workflowId)
+            throws NotFoundException, WorkflowException {
+
+        Task task;
+        try {
+            task = taskService.createTaskQuery().processInstanceId(workflowId).singleResult();
+        } catch (ActivitiException e) {
+            throw new WorkflowException("While reading form for workflow instance " + workflowId, e);
+        }
+
+        TaskFormData formData;
+        try {
+            formData = formService.getTaskFormData(task.getId());
+        } catch (ActivitiException e) {
+            LOG.debug("No form found for task {}", task.getId(), e);
+            formData = null;
+        }
+
+        WorkflowFormTO result = null;
+        if (formData != null && !formData.getFormProperties().isEmpty()) {
+            result = getFormTO(task);
+        }
+
+        return result;
+    }
+
+    private Map.Entry<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
+        Task task;
+        try {
+            task = taskService.createTaskQuery().taskId(taskId).singleResult();
+        } catch (ActivitiException e) {
+            throw new NotFoundException("Activiti Task " + taskId, e);
+        }
+
+        TaskFormData formData;
+        try {
+            formData = formService.getTaskFormData(task.getId());
+        } catch (ActivitiException e) {
+            throw new NotFoundException("Form for Activiti Task " + taskId, e);
+        }
+
+        if (!adminUser.equals(authUser)) {
+            User user = userDAO.find(authUser);
+            if (user == null) {
+                throw new NotFoundException("Syncope User " + authUser);
+            }
+        }
+
+        return new SimpleEntry<>(task, formData);
+    }
+
+    @Transactional
+    @Override
+    public WorkflowFormTO claimForm(final String taskId)
+            throws WorkflowException {
+
+        final String authUser = AuthContextUtil.getAuthenticatedUsername();
+        Map.Entry<Task, TaskFormData> checked = checkTask(taskId, authUser);
+
+        if (!adminUser.equals(authUser)) {
+            List<Task> tasksForUser = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(authUser).list();
+            if (tasksForUser.isEmpty()) {
+                throw new WorkflowException(
+                        new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
+            }
+        }
+
+        Task task;
+        try {
+            taskService.setOwner(taskId, authUser);
+            task = taskService.createTaskQuery().taskId(taskId).singleResult();
+        } catch (ActivitiException e) {
+            throw new WorkflowException("While reading task " + taskId, e);
+        }
+
+        return getFormTO(task, checked.getValue());
+    }
+
+    @Transactional
+    @Override
+    public WorkflowResult<UserMod> submitForm(final WorkflowFormTO form)
+            throws WorkflowException {
+
+        final String authUser = AuthContextUtil.getAuthenticatedUsername();
+        Map.Entry<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
+
+        if (!checked.getKey().getOwner().equals(authUser)) {
+            throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId() + " assigned to "
+                    + checked.getKey().getOwner() + " but submitted by " + authUser));
+        }
+
+        User user = userDAO.findByWorkflowId(checked.getKey().getProcessInstanceId());
+        if (user == null) {
+            throw new NotFoundException("User with workflow id " + checked.getKey().getProcessInstanceId());
+        }
+
+        Set<String> preTasks = getPerformedTasks(user);
+        try {
+            formService.submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
+            runtimeService.setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
+        } catch (ActivitiException e) {
+            throwException(e, "While submitting form for task " + form.getTaskId());
+        }
+
+        Set<String> postTasks = getPerformedTasks(user);
+        postTasks.removeAll(preTasks);
+        postTasks.add(form.getTaskId());
+
+        updateStatus(user);
+        User updated = userDAO.save(user);
+
+        // see if there is any propagation to be done
+        PropagationByResource propByRes =
+                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+
+        // fetch - if available - the encrypted password
+        String clearPassword = null;
+        String encryptedPwd = runtimeService.getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
+        if (StringUtils.isNotBlank(encryptedPwd)) {
+            clearPassword = decrypt(encryptedPwd);
+        }
+
+        // supports approval chains
+        saveForFormSubmit(user, clearPassword, propByRes);
+
+        UserMod userMod = runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
+        if (userMod == null) {
+            userMod = new UserMod();
+            userMod.setKey(updated.getKey());
+            userMod.setPassword(clearPassword);
+        }
+
+        return new WorkflowResult<>(userMod, propByRes, postTasks);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeEntitiesVariableType.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeEntitiesVariableType.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeEntitiesVariableType.java
new file mode 100644
index 0000000..850a375
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeEntitiesVariableType.java
@@ -0,0 +1,35 @@
+/*
+ * 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.server.workflow.activiti;
+
+import org.activiti.engine.impl.variable.SerializableType;
+import org.apache.syncope.server.persistence.api.entity.Entity;
+
+/**
+ * Activiti variable type for handling Syncope entities as Activiti variables.
+ * Main purpose: avoid Activiti to handle Syncope entities as JPA entities,
+ * since this can cause troubles with transactions.
+ */
+public class SyncopeEntitiesVariableType extends SerializableType {
+
+    @Override
+    public boolean isAbleToStore(final Object value) {
+        return value instanceof Entity;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupManager.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupManager.java
new file mode 100644
index 0000000..e01f240
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupManager.java
@@ -0,0 +1,122 @@
+/*
+ * 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.server.workflow.activiti;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.activiti.engine.identity.Group;
+import org.activiti.engine.identity.GroupQuery;
+import org.activiti.engine.impl.GroupQueryImpl;
+import org.activiti.engine.impl.Page;
+import org.activiti.engine.impl.persistence.entity.GroupEntity;
+import org.activiti.engine.impl.persistence.entity.GroupIdentityManager;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class SyncopeGroupManager implements GroupIdentityManager, SyncopeSession {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Override
+    public Class<?> getType() {
+        return GroupIdentityManager.class;
+    }
+
+    @Override
+    public Group createNewGroup(final String groupId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public GroupQuery createNewGroupQuery() {
+        return new SyncopeGroupQueryImpl(roleDAO);
+    }
+
+    @Override
+    public void deleteGroup(final String groupId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<Group> findGroupsByUser(final String userId) {
+        List<Group> result = Collections.emptyList();
+        User user = userDAO.find(userId);
+        if (user != null) {
+            result = new ArrayList<>();
+            for (Long roleId : user.getRoleKeys()) {
+                result.add(new GroupEntity(roleId.toString()));
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<Group> findGroupByQueryCriteria(final GroupQueryImpl query, final Page page) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long findGroupCountByQueryCriteria(final GroupQueryImpl query) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<Group> findGroupsByNativeQuery(final Map<String, Object> parameterMap, final int firstResult,
+            final int maxResults) {
+
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long findGroupCountByNativeQuery(final Map<String, Object> parameterMap) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void insertGroup(final Group group) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void updateGroup(final Group updatedGroup) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isNewGroup(final Group group) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public void close() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupQueryImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupQueryImpl.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupQueryImpl.java
new file mode 100644
index 0000000..c5d3570
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeGroupQueryImpl.java
@@ -0,0 +1,157 @@
+/*
+ * 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.server.workflow.activiti;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.activiti.engine.ActivitiException;
+import org.activiti.engine.identity.Group;
+import org.activiti.engine.identity.GroupQuery;
+import org.activiti.engine.impl.persistence.entity.GroupEntity;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+
+public class SyncopeGroupQueryImpl implements GroupQuery {
+
+    private RoleDAO roleDAO;
+
+    private Long roleId;
+
+    private List<Group> result;
+
+    public SyncopeGroupQueryImpl(final RoleDAO roleDAO) {
+        this.roleDAO = roleDAO;
+    }
+
+    @Override
+    public GroupQuery groupId(final String groupId) {
+        try {
+            roleId = Long.valueOf(groupId);
+        } catch (NumberFormatException e) {
+        }
+
+        return this;
+    }
+
+    @Override
+    public GroupQuery groupName(final String groupName) {
+        return this;
+    }
+
+    @Override
+    public GroupQuery groupNameLike(final String groupNameLike) {
+        return this;
+    }
+
+    @Override
+    public GroupQuery groupType(final String groupType) {
+        return this;
+    }
+
+    @Override
+    public GroupQuery groupMember(final String groupMemberUserId) {
+        return this;
+    }
+
+    @Override
+    public GroupQuery orderByGroupId() {
+        return this;
+    }
+
+    @Override
+    public GroupQuery orderByGroupName() {
+        return this;
+    }
+
+    @Override
+    public GroupQuery orderByGroupType() {
+        return this;
+    }
+
+    @Override
+    public GroupQuery asc() {
+        return this;
+    }
+
+    @Override
+    public GroupQuery desc() {
+        return this;
+    }
+
+    private Group fromSyncopeRole(Role role) {
+        return new GroupEntity(role.getKey().toString());
+    }
+
+    private void execute() {
+        if (roleId != null) {
+            Role role = roleDAO.find(roleId);
+            if (role == null) {
+                result = Collections.emptyList();
+            } else {
+                result = Collections.singletonList(fromSyncopeRole(role));
+            }
+        }
+        if (result == null) {
+            result = new ArrayList<Group>();
+            for (Role role : roleDAO.findAll()) {
+                result.add(fromSyncopeRole(role));
+            }
+        }
+    }
+
+    @Override
+    public long count() {
+        if (result == null) {
+            execute();
+        }
+        return result.size();
+    }
+
+    @Override
+    public Group singleResult() {
+        if (result == null) {
+            execute();
+        }
+        if (result.isEmpty()) {
+            throw new ActivitiException("Empty result");
+        }
+
+        return result.get(0);
+    }
+
+    @Override
+    public List<Group> list() {
+        if (result == null) {
+            execute();
+        }
+        return result;
+    }
+
+    @Override
+    public List<Group> listPage(final int firstResult, final int maxResults) {
+        return list();
+    }
+
+    @Override
+    public GroupQuery potentialStarter(final String procDefId) {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSession.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSession.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSession.java
new file mode 100644
index 0000000..dee3125
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSession.java
@@ -0,0 +1,26 @@
+/*
+ * 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.server.workflow.activiti;
+
+import org.activiti.engine.impl.interceptor.Session;
+
+public interface SyncopeSession extends Session {
+
+    Class<?> getType();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSessionFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSessionFactory.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSessionFactory.java
new file mode 100644
index 0000000..ef1d0d1
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeSessionFactory.java
@@ -0,0 +1,45 @@
+/*
+ * 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.server.workflow.activiti;
+
+import org.activiti.engine.impl.interceptor.Session;
+import org.activiti.engine.impl.interceptor.SessionFactory;
+
+public class SyncopeSessionFactory implements SessionFactory {
+
+    private SyncopeSession syncopeSession;
+
+    @Override
+    public Class<?> getSessionType() {
+        return syncopeSession.getType();
+    }
+
+    @Override
+    public Session openSession() {
+        return syncopeSession;
+    }
+
+    public SyncopeSession getSyncopeSession() {
+        return syncopeSession;
+    }
+
+    public void setSyncopeSession(final SyncopeSession syncopeSession) {
+        this.syncopeSession = syncopeSession;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserManager.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserManager.java
new file mode 100644
index 0000000..d604d98
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserManager.java
@@ -0,0 +1,170 @@
+/*
+ * 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.server.workflow.activiti;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.activiti.engine.identity.Group;
+import org.activiti.engine.identity.Picture;
+import org.activiti.engine.identity.User;
+import org.activiti.engine.identity.UserQuery;
+import org.activiti.engine.impl.Page;
+import org.activiti.engine.impl.UserQueryImpl;
+import org.activiti.engine.impl.persistence.entity.GroupEntity;
+import org.activiti.engine.impl.persistence.entity.IdentityInfoEntity;
+import org.activiti.engine.impl.persistence.entity.UserEntity;
+import org.activiti.engine.impl.persistence.entity.UserIdentityManager;
+import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class SyncopeUserManager implements UserIdentityManager, SyncopeSession {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private EntitlementDAO entitlementDAO;
+
+    @Override
+    public Class<?> getType() {
+        return UserIdentityManager.class;
+    }
+
+    @Override
+    public Boolean checkPassword(final String userKey, final String password) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public User createNewUser(final String userKey) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public UserQuery createNewUserQuery() {
+        return new SyncopeUserQueryImpl(userDAO, roleDAO, entitlementDAO);
+    }
+
+    @Override
+    public void deleteUser(final String userKey) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<Group> findGroupsByUser(final String userKey) {
+        List<Group> result = Collections.emptyList();
+        org.apache.syncope.server.persistence.api.entity.user.User user = userDAO.find(userKey);
+        if (user != null) {
+            result = new ArrayList<>();
+            for (Long roleId : user.getRoleKeys()) {
+                result.add(new GroupEntity(roleId.toString()));
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public UserEntity findUserById(final String userKey) {
+        UserEntity result = null;
+        org.apache.syncope.server.persistence.api.entity.user.User user = userDAO.find(userKey);
+        if (user != null) {
+            result = new UserEntity(userKey);
+        }
+
+        return result;
+    }
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public void insertUser(final User user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isNewUser(final User user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void updateUser(final User updatedUser) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Picture getUserPicture(final String string) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setUserPicture(final String string, final Picture pctr) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<User> findUserByQueryCriteria(final UserQueryImpl query, final Page page) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long findUserCountByQueryCriteria(final UserQueryImpl query) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public IdentityInfoEntity findUserInfoByUserIdAndKey(final String userKey, final String key) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<String> findUserInfoKeysByUserIdAndType(final String userKey, final String type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<User> findPotentialStarterUsers(final String proceDefId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<User> findUsersByNativeQuery(final Map<String, Object> parameterMap,
+            final int firstResult, final int maxResults) {
+
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long findUserCountByNativeQuery(final Map<String, Object> parameterMap) {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserQueryImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserQueryImpl.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserQueryImpl.java
new file mode 100644
index 0000000..097a1ea
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/SyncopeUserQueryImpl.java
@@ -0,0 +1,218 @@
+/*
+ * 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.server.workflow.activiti;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.activiti.engine.ActivitiException;
+import org.activiti.engine.identity.User;
+import org.activiti.engine.identity.UserQuery;
+import org.activiti.engine.impl.persistence.entity.UserEntity;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+
+public class SyncopeUserQueryImpl implements UserQuery {
+
+    private UserDAO userDAO;
+
+    private RoleDAO roleDAO;
+
+    private EntitlementDAO entitlementDAO;
+
+    private String username;
+
+    private Long memberOf;
+
+    private List<User> result;
+
+    public SyncopeUserQueryImpl(final UserDAO userDAO, final RoleDAO roleDAO, final EntitlementDAO entitlementDAO) {
+        this.userDAO = userDAO;
+        this.roleDAO = roleDAO;
+        this.entitlementDAO = entitlementDAO;
+    }
+
+    @Override
+    public UserQuery userId(final String id) {
+        this.username = id;
+        return this;
+    }
+
+    @Override
+    public UserQuery userFirstName(final String firstName) {
+        return this;
+    }
+
+    @Override
+    public UserQuery userFirstNameLike(final String firstNameLike) {
+        return this;
+    }
+
+    @Override
+    public UserQuery userLastName(final String lastName) {
+        return this;
+    }
+
+    @Override
+    public UserQuery userLastNameLike(final String lastNameLike) {
+        return this;
+    }
+
+    @Override
+    public UserQuery userFullNameLike(final String fullNameLike) {
+        return this;
+    }
+
+    @Override
+    public UserQuery userEmail(final String email) {
+        return this;
+    }
+
+    @Override
+    public UserQuery userEmailLike(final String emailLike) {
+        return this;
+    }
+
+    @Override
+    public UserQuery memberOfGroup(final String groupId) {
+        try {
+            memberOf = Long.valueOf(groupId);
+        } catch (NumberFormatException e) {
+        }
+        return this;
+    }
+
+    @Override
+    public UserQuery orderByUserId() {
+        return this;
+    }
+
+    @Override
+    public UserQuery orderByUserFirstName() {
+        return this;
+    }
+
+    @Override
+    public UserQuery orderByUserLastName() {
+        return this;
+    }
+
+    @Override
+    public UserQuery orderByUserEmail() {
+        return this;
+    }
+
+    @Override
+    public UserQuery asc() {
+        return this;
+    }
+
+    @Override
+    public UserQuery desc() {
+        return this;
+    }
+
+    private User fromSyncopeUser(final org.apache.syncope.server.persistence.api.entity.user.User user) {
+        return new UserEntity(user.getUsername());
+    }
+
+    private void execute(final int page, final int itemsPerPage) {
+        if (username != null) {
+            org.apache.syncope.server.persistence.api.entity.user.User user = userDAO.find(username);
+            if (user == null) {
+                result = Collections.<User>emptyList();
+            } else {
+                if (memberOf == null || user.getRoleKeys().contains(memberOf)) {
+                    result = Collections.singletonList(fromSyncopeUser(user));
+                }
+            }
+        }
+        if (memberOf != null) {
+            Role role = roleDAO.find(memberOf);
+            if (role == null) {
+                result = Collections.<User>emptyList();
+            } else {
+                result = new ArrayList<>();
+                List<Membership> memberships = roleDAO.findMemberships(role);
+                User user;
+                for (Membership membership : memberships) {
+                    user = fromSyncopeUser(membership.getUser());
+                    if (!result.contains(user)) {
+                        result.add(user);
+                    }
+                }
+            }
+        }
+        // THIS CAN BE *VERY* DANGEROUS
+        if (result == null) {
+            result = new ArrayList<>();
+
+            List<org.apache.syncope.server.persistence.api.entity.user.User> users =
+                    userDAO.findAll(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()), page, itemsPerPage);
+            for (org.apache.syncope.server.persistence.api.entity.user.User user : users) {
+                result.add(fromSyncopeUser(user));
+            }
+        }
+    }
+
+    @Override
+    public long count() {
+        if (result == null) {
+            execute(-1, -1);
+        }
+        return result.size();
+    }
+
+    @Override
+    public User singleResult() {
+        if (result == null) {
+            execute(-1, -1);
+        }
+        if (result.isEmpty()) {
+            throw new ActivitiException("Empty result");
+        }
+
+        return result.get(0);
+    }
+
+    @Override
+    public List<User> list() {
+        if (result == null) {
+            execute(-1, -1);
+        }
+        return result;
+    }
+
+    @Override
+    public List<User> listPage(final int firstResult, final int maxResults) {
+        if (result == null) {
+            execute((firstResult / maxResults) + 1, maxResults);
+        }
+        return result;
+    }
+
+    @Override
+    public UserQuery potentialStarter(final String string) {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AbstractActivitiServiceTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AbstractActivitiServiceTask.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AbstractActivitiServiceTask.java
new file mode 100644
index 0000000..a401cad
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AbstractActivitiServiceTask.java
@@ -0,0 +1,48 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.activiti.engine.RuntimeService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Abstract base class for Activiti's service tasks in Syncope, with Spring support.
+ */
+@Component
+public abstract class AbstractActivitiServiceTask {
+
+    /**
+     * Logger.
+     */
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractActivitiServiceTask.class);
+
+    @Autowired
+    protected RuntimeService runtimeService;
+
+    @Transactional(rollbackFor = { Throwable.class })
+    public void execute(final String executionId) {
+        doExecute(executionId);
+    }
+
+    protected abstract void doExecute(final String executionId);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AutoActivate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AutoActivate.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AutoActivate.java
new file mode 100644
index 0000000..4f70d91
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/AutoActivate.java
@@ -0,0 +1,31 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AutoActivate extends AbstractActivitiServiceTask {
+
+    @Override
+    protected void doExecute(final String executionId) {
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Create.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Create.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Create.java
new file mode 100644
index 0000000..3a6238d
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Create.java
@@ -0,0 +1,51 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.server.persistence.api.entity.EntityFactory;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Create extends AbstractActivitiServiceTask {
+
+    @Autowired
+    private UserDataBinder dataBinder;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Override
+    protected void doExecute(final String executionId) {
+        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
+        Boolean storePassword =
+                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.STORE_PASSWORD, Boolean.class);
+        // create and set workflow id
+        User user = entityFactory.newEntity(User.class);
+        dataBinder.create(user, userTO, storePassword == null ? true : storePassword);
+        user.setWorkflowId(executionId);
+
+        // report SyncopeUser as result
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Delete.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Delete.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Delete.java
new file mode 100644
index 0000000..b8b3f94
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Delete.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.workflow.activiti.task;
+
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Delete extends AbstractActivitiServiceTask {
+
+    @Override
+    protected void doExecute(final String executionId) {
+        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+
+        // Do something with SyncopeUser...
+        if (user != null) {
+            user.checkToken("");
+        }
+
+        // remove SyncopeUser variable
+        runtimeService.removeVariable(executionId, ActivitiUserWorkflowAdapter.USER);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/GenerateToken.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/GenerateToken.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/GenerateToken.java
new file mode 100644
index 0000000..23508ef
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/GenerateToken.java
@@ -0,0 +1,43 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.apache.syncope.server.persistence.api.dao.ConfDAO;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GenerateToken extends AbstractActivitiServiceTask {
+
+    @Autowired
+    private ConfDAO confDAO;
+
+    @Override
+    protected void doExecute(final String executionId) {
+        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+
+        user.generateToken(
+                confDAO.find("token.length", "256").getValues().get(0).getLongValue().intValue(),
+                confDAO.find("token.expireTime", "60").getValues().get(0).getLongValue().intValue());
+
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Notify.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Notify.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Notify.java
new file mode 100644
index 0000000..c6152d8
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Notify.java
@@ -0,0 +1,62 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * General-purpose notification task for usage within workflow.
+ * It requires a pre-existing <tt>Notification</tt> with category <tt>CUSTOM</tt> and result <tt>SUCCESS</tt>.
+ * An <tt>event</tt> workflow variable needs to be provided as well.
+ */
+@Component
+public class Notify extends AbstractActivitiServiceTask {
+
+    @Autowired
+    private NotificationManager notificationManager;
+
+    @Override
+    protected void doExecute(final String executionId) {
+        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
+        String event = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT, String.class);
+
+        if (StringUtils.isNotBlank(event)) {
+            notificationManager.createTasks(
+                    AuditElements.EventCategoryType.CUSTOM,
+                    null,
+                    null,
+                    event,
+                    AuditElements.Result.SUCCESS,
+                    userTO,
+                    null,
+                    user.getToken());
+        } else {
+            LOG.debug("Not sending any notification since no event was found");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/PasswordReset.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/PasswordReset.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/PasswordReset.java
new file mode 100644
index 0000000..56be394
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/PasswordReset.java
@@ -0,0 +1,44 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.workflow.api.WorkflowException;
+import org.apache.syncope.server.workflow.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PasswordReset extends AbstractActivitiServiceTask {
+
+    @Override
+    protected void doExecute(final String executionId) {
+        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        String token = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN, String.class);
+        String password = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD, String.class);
+
+        if (!user.checkToken(token)) {
+            throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user));
+        }
+
+        user.removeToken();
+        user.setPassword(password, user.getCipherAlgorithm());
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Reactivate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Reactivate.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Reactivate.java
new file mode 100644
index 0000000..d4c011b
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Reactivate.java
@@ -0,0 +1,29 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class Reactivate extends AbstractActivitiServiceTask {
+
+    @Override
+    protected void doExecute(final String executionId) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/1327b2a4/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Suspend.java
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Suspend.java b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Suspend.java
new file mode 100644
index 0000000..197d737
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/server/workflow/activiti/task/Suspend.java
@@ -0,0 +1,29 @@
+/*
+ * 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.server.workflow.activiti.task;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class Suspend extends AbstractActivitiServiceTask {
+
+    @Override
+    protected void doExecute(final String executionId) {
+    }
+}


[12/12] syncope git commit: Merge branch 'master' into 2_0_X

Posted by il...@apache.org.
Merge branch 'master' into 2_0_X


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

Branch: refs/heads/2_0_X
Commit: 59bd58ce662c4550c9723264f1460e90b6b51756
Parents: 1327b2a f32528c
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jan 26 15:47:55 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jan 26 15:47:55 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/syncope/cli/SyncopeAdm.java |  46 +++-
 .../syncope/cli/commands/AbstractCommand.java   |  32 +++
 .../cli/commands/ConfigurationCommand.java      | 212 +++++++++++++++++++
 .../syncope/cli/commands/LoggerCommand.java     | 125 +++++++----
 .../cli/commands/NotificationCommand.java       |  95 +++++++++
 .../syncope/cli/commands/PolicyCommand.java     | 107 ++++++++++
 .../syncope/cli/commands/ReportCommand.java     | 195 +++++++++++++++++
 .../org/apache/syncope/cli/util/XmlUtils.java   |  28 +++
 cli/src/main/resources/syncope.properties       |   4 +-
 .../core/services/ReportServiceImpl.java        |   2 +-
 10 files changed, 802 insertions(+), 44 deletions(-)
----------------------------------------------------------------------