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/24 15:16:20 UTC
[3/3] syncope git commit: [SYNCOPE-620] workflow-activiti in,
IT needs to be adapted
[SYNCOPE-620] workflow-activiti in, IT needs to be adapted
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/702810d8
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/702810d8
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/702810d8
Branch: refs/heads/2_0_X
Commit: 702810d8b0f28e57896686670096cb1977106537
Parents: 0f9194e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Sat Jan 24 15:15:58 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Sat Jan 24 15:15:58 2015 +0100
----------------------------------------------------------------------
syncope620/pom.xml | 45 +
.../server/logic/ConfigurationLogic.java | 24 +-
.../server/logic/LogicInvocationHandler.java | 2 +-
.../apache/syncope/server/logic/RoleLogic.java | 2 +-
.../logic/init/WorkflowAdapterLoader.java | 22 +-
.../logic/notification/NotificationJob.java | 2 +-
.../syncope/server/logic/NotificationTest.java | 2 +-
.../persistence/api/entity/user/User.java | 2 +-
.../jpa/content/XMLContentExporter.java | 3 +-
.../server/persistence/jpa/dao/JPARoleDAO.java | 8 +-
.../server/persistence/jpa/dao/JPAUserDAO.java | 10 +-
.../persistence/jpa/entity/user/JPAUser.java | 2 +-
syncope620/server/pom.xml | 1 +
.../api/notification/NotificationManager.java | 65 ++
.../provisioning/java/job/AbstractTaskJob.java | 2 +-
.../java/notification/NotificationManager.java | 437 ---------
.../notification/NotificationManagerImpl.java | 416 +++++++++
.../AbstractPropagationTaskExecutor.java | 2 +-
.../java/sync/AbstractSyncopeResultHandler.java | 2 +-
.../java/sync/LDAPMembershipSyncActions.java | 2 +-
syncope620/server/workflow-activiti/pom.xml | 83 ++
.../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/userWorkflow.bpmn20.xml | 232 +++++
.../main/resources/workflowActivitiContext.xml | 79 ++
.../workflow/api/UserWorkflowAdapter.java | 4 +-
.../server/workflow/api/WorkflowAdapter.java | 2 +-
.../workflow/api/WorkflowDefinitionLoader.java | 29 +
.../workflow/api/WorkflowInstanceLoader.java | 28 -
.../java/AbstractRoleWorkflowAdapter.java | 4 +-
.../java/AbstractUserWorkflowAdapter.java | 4 +-
49 files changed, 3293 insertions(+), 516 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/pom.xml b/syncope620/pom.xml
index b784741..e5f86d3 100644
--- a/syncope620/pom.xml
+++ b/syncope620/pom.xml
@@ -339,6 +339,8 @@ under the License.
<groovy.version>2.3.9</groovy.version>
+ <activiti.version>5.16.4</activiti.version>
+
<slf4j.version>1.7.10</slf4j.version>
<log4j.version>2.1</log4j.version>
<disruptor.version>3.3.0</disruptor.version>
@@ -750,6 +752,49 @@ under the License.
</dependency>
<dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-engine</artifactId>
+ <version>${activiti.version}</version>
+ <!-- Using geronimo-* for this -->
+ <exclusions>
+ <exclusion>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-spring</artifactId>
+ <version>${activiti.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-json-converter</artifactId>
+ <version>${activiti.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-webapp-explorer2</artifactId>
+ <version>${activiti.version}</version>
+ <type>war</type>
+ </dependency>
+
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/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 06bb568..7c6e43f 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
@@ -35,7 +35,7 @@ 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.NotificationManager;
+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;
@@ -109,20 +109,18 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
@PreAuthorize("hasRole('CONFIGURATION_LIST')")
public Set<String> getMailTemplates() {
- Set<String> htmlTemplates = new HashSet<String>();
- Set<String> textTemplates = new HashSet<String>();
+ Set<String> htmlTemplates = new HashSet<>();
+ Set<String> textTemplates = new HashSet<>();
try {
- for (Resource resource : resourceLoader.getResources(NotificationManager.MAIL_TEMPLATES + "*.vm")) {
+ for (Resource resource : resourceLoader.getResources(NotificationManagerImpl.MAIL_TEMPLATES + "*.vm")) {
String template = resource.getURL().toExternalForm();
- if (template.endsWith(NotificationManager.MAIL_TEMPLATE_HTML_SUFFIX)) {
- htmlTemplates.add(
- template.substring(template.indexOf(NotificationManager.MAIL_TEMPLATES) + 14,
- template.indexOf(NotificationManager.MAIL_TEMPLATE_HTML_SUFFIX)));
- } else if (template.endsWith(NotificationManager.MAIL_TEMPLATE_TEXT_SUFFIX)) {
- textTemplates.add(
- template.substring(template.indexOf(NotificationManager.MAIL_TEMPLATES) + 14,
- template.indexOf(NotificationManager.MAIL_TEMPLATE_TEXT_SUFFIX)));
+ 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);
}
@@ -141,7 +139,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
@Transactional(readOnly = true)
public void export(final OutputStream os) {
try {
- exporter.export(os, wfAdapterLoader.getTablePrefix());
+ exporter.export(os, wfAdapterLoader.getPrefix());
LOG.debug("Database content successfully exported");
} catch (Exception e) {
LOG.error("While exporting database content", e);
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LogicInvocationHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LogicInvocationHandler.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LogicInvocationHandler.java
index 0baad34..0e5ca8e 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LogicInvocationHandler.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LogicInvocationHandler.java
@@ -22,7 +22,7 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.server.misc.AuditManager;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/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 c1a5582..838827c 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
@@ -125,7 +125,7 @@ public class RoleLogic extends AbstractSubjectLogic<RoleTO, RoleMod> {
if (authUser == null) {
ownedRoleIds = Collections.<Long>emptySet();
} else {
- ownedRoleIds = authUser.getRoleIds();
+ ownedRoleIds = authUser.getRoleKeys();
}
Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
index b89e165..fb9cbe7 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/WorkflowAdapterLoader.java
@@ -21,7 +21,7 @@ package org.apache.syncope.server.logic.init;
import org.apache.syncope.server.persistence.api.SyncopeLoader;
import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
-import org.apache.syncope.server.workflow.api.WorkflowInstanceLoader;
+import org.apache.syncope.server.workflow.api.WorkflowDefinitionLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
@@ -45,7 +45,7 @@ public class WorkflowAdapterLoader implements BeanFactoryAware, SyncopeLoader {
private DefaultListableBeanFactory beanFactory;
- private WorkflowInstanceLoader wfLoader;
+ private WorkflowDefinitionLoader wfLoader;
@Override
public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
@@ -54,20 +54,20 @@ public class WorkflowAdapterLoader implements BeanFactoryAware, SyncopeLoader {
private void lazyInit() {
if (wfLoader == null) {
- if (uwfAdapter.getLoaderClass() != null) {
- wfLoader = (WorkflowInstanceLoader) beanFactory.createBean(
- uwfAdapter.getLoaderClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+ if (uwfAdapter.getDefinitionLoaderClass() != null) {
+ wfLoader = (WorkflowDefinitionLoader) beanFactory.createBean(
+ uwfAdapter.getDefinitionLoaderClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
}
- if (rwfAdapter.getLoaderClass() != null) {
- wfLoader = (WorkflowInstanceLoader) beanFactory.createBean(
- rwfAdapter.getLoaderClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+ if (rwfAdapter.getDefinitionLoaderClass() != null) {
+ wfLoader = (WorkflowDefinitionLoader) beanFactory.createBean(
+ rwfAdapter.getDefinitionLoaderClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
}
}
}
- public String getTablePrefix() {
+ public String getPrefix() {
lazyInit();
- return wfLoader == null ? null : wfLoader.getTablePrefix();
+ return wfLoader == null ? null : wfLoader.getPrefix();
}
public void init() {
@@ -86,7 +86,7 @@ public class WorkflowAdapterLoader implements BeanFactoryAware, SyncopeLoader {
public void load() {
lazyInit();
if (wfLoader == null) {
- LOG.debug("Configured workflow adapter does not need loading");
+ LOG.debug("The configured workflow adapter does not need loading");
} else {
LOG.debug("Loading workflow adapter by {}", wfLoader.getClass().getName());
wfLoader.load();
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/notification/NotificationJob.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/notification/NotificationJob.java
index c91b827..de1c7d7 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/notification/NotificationJob.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/notification/NotificationJob.java
@@ -31,8 +31,8 @@ import org.apache.syncope.server.persistence.api.entity.EntityFactory;
import org.apache.syncope.server.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
import org.apache.syncope.server.misc.AuditManager;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
import org.apache.syncope.server.misc.ExceptionUtil;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
index 83a238f..3d25bc1 100644
--- a/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
+++ b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
@@ -62,8 +62,8 @@ import org.apache.syncope.server.persistence.api.entity.Notification;
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.persistence.api.entity.task.NotificationTask;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
import org.apache.syncope.server.logic.notification.NotificationJob;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/entity/user/User.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/entity/user/User.java b/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/entity/user/User.java
index 918937c..d6b30d0 100644
--- a/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/entity/user/User.java
+++ b/syncope620/server/persistence-api/src/main/java/org/apache/syncope/server/persistence/api/entity/user/User.java
@@ -57,7 +57,7 @@ public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> {
List<String> getPasswordHistory();
- Set<Long> getRoleIds();
+ Set<Long> getRoleKeys();
List<Role> getRoles();
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
index 3456431..8a60151 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
@@ -319,6 +319,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
}
}
+ @Override
public void export(final OutputStream os, final String wfTablePrefix)
throws SAXException, TransformerConfigurationException {
@@ -345,7 +346,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
rs = meta.getTables(null, StringUtils.isBlank(dbSchema) ? null : dbSchema, null, new String[] { "TABLE" });
- final Set<String> tableNames = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+ final Set<String> tableNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
while (rs.next()) {
String tableName = rs.getString("TABLE_NAME");
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
index 1bb81b4..b7877d5 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
@@ -169,8 +169,8 @@ public class JPARoleDAO extends AbstractSubjectDAO<RPlainAttr, RDerAttr, RVirAtt
StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPARole.class.getSimpleName()).
append(" e WHERE e.userOwner=:owner ");
- for (Long roleId : owner.getRoleIds()) {
- queryString.append("OR e.roleOwner.id=").append(roleId).append(' ');
+ for (Long roleKey : owner.getRoleKeys()) {
+ queryString.append("OR e.roleOwner.id=").append(roleKey).append(' ');
}
TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
@@ -550,8 +550,8 @@ public class JPARoleDAO extends AbstractSubjectDAO<RPlainAttr, RDerAttr, RVirAtt
throw new NotFoundException("Role " + key);
}
- Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
- if (!allowedRoleIds.contains(role.getKey())) {
+ Set<Long> allowedRoleKeys = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
+ if (!allowedRoleKeys.contains(role.getKey())) {
throw new UnauthorizedRoleException(role.getKey());
}
return role;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
index 2a45ad3..b4a6171 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
@@ -241,11 +241,11 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
if (!AuthContextUtil.getAuthenticatedUsername().equals(anonymousUser)
&& !AuthContextUtil.getAuthenticatedUsername().equals(user.getUsername())) {
- Set<Long> roleIds = user.getRoleIds();
- Set<Long> adminRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
- roleIds.removeAll(adminRoleIds);
- if (!roleIds.isEmpty()) {
- throw new UnauthorizedRoleException(roleIds);
+ Set<Long> roleKeys = user.getRoleKeys();
+ Set<Long> adminRoleKeys = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
+ roleKeys.removeAll(adminRoleKeys);
+ if (!roleKeys.isEmpty()) {
+ throw new UnauthorizedRoleException(roleKeys);
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUser.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUser.java
index f7b3372..276cf63 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUser.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUser.java
@@ -242,7 +242,7 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
}
@Override
- public Set<Long> getRoleIds() {
+ public Set<Long> getRoleKeys() {
List<Role> roles = getRoles();
Set<Long> result = new HashSet<>(roles.size());
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/pom.xml b/syncope620/server/pom.xml
index 240c8c3..112fabc 100644
--- a/syncope620/server/pom.xml
+++ b/syncope620/server/pom.xml
@@ -41,6 +41,7 @@ under the License.
<module>provisioning-java</module>
<module>workflow-api</module>
<module>workflow-java</module>
+ <module>workflow-activiti</module>
<module>logic</module>
<module>rest-cxf</module>
</modules>
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/notification/NotificationManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/notification/NotificationManager.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/notification/NotificationManager.java
new file mode 100644
index 0000000..f0ef4c8
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/notification/NotificationManager.java
@@ -0,0 +1,65 @@
+/*
+ * 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.provisioning.api.notification;
+
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
+
+/**
+ * Create notification tasks that will be executed by NotificationJob.
+ *
+ * @see org.apache.syncope.server.persistence.api.entity.task.NotificationTask
+ */
+public interface NotificationManager {
+
+ /**
+ * Count the number of task executions of a given task with a given status.
+ *
+ * @param taskId task id
+ * @param status status
+ * @return number of task executions
+ */
+ long countExecutionsWithStatus(final Long taskId, final String status);
+
+ /**
+ * Create notification tasks for each notification matching the given user id and (some of) tasks performed.
+ */
+ void createTasks(final AuditElements.EventCategoryType type, final String category, final String subcategory,
+ final String event, final AuditElements.Result condition, final Object before, final Object output,
+ final Object... input);
+
+ long getMaxRetries();
+
+ /**
+ * Set execution state of NotificationTask with provided id.
+ *
+ * @param taskId task to be updated
+ * @param executed execution state
+ */
+ void setTaskExecuted(final Long taskId, final boolean executed);
+
+ /**
+ * Store execution of a NotificationTask.
+ *
+ * @param execution task execution.
+ * @return merged task execution.
+ */
+ TaskExec storeExec(final TaskExec execution);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/AbstractTaskJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/AbstractTaskJob.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/AbstractTaskJob.java
index 22ce042..cf328cc 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/AbstractTaskJob.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/AbstractTaskJob.java
@@ -28,8 +28,8 @@ import org.apache.syncope.server.persistence.api.entity.task.Task;
import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
import org.apache.syncope.server.provisioning.api.job.TaskJob;
import org.apache.syncope.server.misc.AuditManager;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
import org.apache.syncope.server.misc.ExceptionUtil;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
deleted file mode 100644
index 436f32c..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
+++ /dev/null
@@ -1,437 +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.server.provisioning.java.notification;
-
-import java.io.StringWriter;
-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 org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
-import org.apache.syncope.server.persistence.api.dao.ConfDAO;
-import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.server.persistence.api.dao.NotificationDAO;
-import org.apache.syncope.server.persistence.api.dao.RoleDAO;
-import org.apache.syncope.server.persistence.api.dao.SubjectSearchDAO;
-import org.apache.syncope.server.persistence.api.dao.TaskDAO;
-import org.apache.syncope.server.persistence.api.dao.UserDAO;
-import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.server.persistence.api.entity.Attributable;
-import org.apache.syncope.server.persistence.api.entity.AttributableUtilFactory;
-import org.apache.syncope.server.persistence.api.entity.EntityFactory;
-import org.apache.syncope.server.persistence.api.entity.Notification;
-import org.apache.syncope.server.persistence.api.entity.PlainAttr;
-import org.apache.syncope.server.persistence.api.entity.Subject;
-import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.api.entity.task.NotificationTask;
-import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.server.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.server.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.server.persistence.api.entity.user.UVirAttr;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.data.RoleDataBinder;
-import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.server.misc.ConnObjectUtil;
-import org.apache.syncope.server.misc.search.SearchCondConverter;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.VelocityEngine;
-import org.apache.velocity.context.Context;
-import org.apache.velocity.exception.VelocityException;
-import org.apache.velocity.tools.ToolManager;
-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;
-
-/**
- * Create notification tasks that will be executed by NotificationJob.
- *
- * @see NotificationTask
- */
-@Component
-@Transactional(rollbackFor = { Throwable.class })
-public class NotificationManager {
-
- /**
- * Logger.
- */
- private static final Logger LOG = LoggerFactory.getLogger(NotificationManager.class);
-
- public static final String MAIL_TEMPLATES = "mailTemplates/";
-
- public static final String MAIL_TEMPLATE_HTML_SUFFIX = ".html.vm";
-
- public static final String MAIL_TEMPLATE_TEXT_SUFFIX = ".txt.vm";
-
- /**
- * Notification DAO.
- */
- @Autowired
- private NotificationDAO notificationDAO;
-
- /**
- * Configuration DAO.
- */
- @Autowired
- private ConfDAO confDAO;
-
- /**
- * User DAO.
- */
- @Autowired
- private UserDAO userDAO;
-
- /**
- * Role DAO.
- */
- @Autowired
- private RoleDAO roleDAO;
-
- /**
- * User Search DAO.
- */
- @Autowired
- private SubjectSearchDAO searchDAO;
-
- /**
- * Task DAO.
- */
- @Autowired
- private TaskDAO taskDAO;
-
- /**
- * Velocity template engine.
- */
- @Autowired
- private VelocityEngine velocityEngine;
-
- /**
- * Velocity tool manager.
- */
- @Autowired
- private ToolManager velocityToolManager;
-
- @Autowired
- private EntitlementDAO entitlementDAO;
-
- @Autowired
- private ConnObjectUtil connObjectUtil;
-
- @Autowired
- private UserDataBinder userDataBinder;
-
- @Autowired
- private RoleDataBinder roleDataBinder;
-
- @Autowired
- private EntityFactory entityFactory;
-
- @Autowired
- private AttributableUtilFactory attrUtilFactory;
-
- @Transactional(readOnly = true)
- public long getMaxRetries() {
- return confDAO.find("notification.maxRetries", "0").getValues().get(0).getLongValue();
- }
-
- /**
- * Create a notification task.
- *
- * @param notification notification to take as model
- * @param attributable the user this task is about
- * @param model Velocity model
- * @return notification task, fully populated
- */
- private NotificationTask getNotificationTask(
- final Notification notification,
- final Attributable<?, ?, ?> attributable,
- final Map<String, Object> model) {
-
- if (attributable != null) {
- connObjectUtil.retrieveVirAttrValues(attributable,
- attrUtilFactory.getInstance(
- attributable instanceof User ? AttributableType.USER : AttributableType.ROLE));
- }
-
- final List<User> recipients = new ArrayList<>();
-
- if (notification.getRecipients() != null) {
- recipients.addAll(searchDAO.<User>search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()),
- SearchCondConverter.convert(notification.getRecipients()),
- Collections.<OrderByClause>emptyList(), SubjectType.USER));
- }
-
- if (notification.isSelfAsRecipient() && attributable instanceof User) {
- recipients.add((User) attributable);
- }
-
- final Set<String> recipientEmails = new HashSet<>();
- final List<UserTO> recipientTOs = new ArrayList<>(recipients.size());
- for (User recipient : recipients) {
- connObjectUtil.retrieveVirAttrValues(recipient, attrUtilFactory.getInstance(AttributableType.USER));
-
- String email = getRecipientEmail(notification.getRecipientAttrType(),
- notification.getRecipientAttrName(), recipient);
- if (email == null) {
- LOG.warn("{} cannot be notified: {} not found", recipient, notification.getRecipientAttrName());
- } else {
- recipientEmails.add(email);
- recipientTOs.add(userDataBinder.getUserTO(recipient));
- }
- }
-
- if (notification.getStaticRecipients() != null) {
- recipientEmails.addAll(notification.getStaticRecipients());
- }
-
- model.put("recipients", recipientTOs);
- model.put("syncopeConf", this.findAllSyncopeConfs());
- model.put("events", notification.getEvents());
-
- NotificationTask task = entityFactory.newEntity(NotificationTask.class);
- task.setTraceLevel(notification.getTraceLevel());
- task.getRecipients().addAll(recipientEmails);
- task.setSender(notification.getSender());
- task.setSubject(notification.getSubject());
-
- String htmlBody = mergeTemplateIntoString(
- MAIL_TEMPLATES + notification.getTemplate() + MAIL_TEMPLATE_HTML_SUFFIX, model);
- String textBody = mergeTemplateIntoString(
- MAIL_TEMPLATES + notification.getTemplate() + MAIL_TEMPLATE_TEXT_SUFFIX, model);
-
- task.setHtmlBody(htmlBody);
- task.setTextBody(textBody);
-
- return task;
- }
-
- private String mergeTemplateIntoString(final String templateLocation, final Map<String, Object> model) {
- StringWriter result = new StringWriter();
- try {
- Context velocityContext = createVelocityContext(model);
- velocityEngine.mergeTemplate(templateLocation, SyncopeConstants.DEFAULT_ENCODING, velocityContext, result);
- } catch (VelocityException e) {
- LOG.error("Could not get mail body", e);
- } catch (RuntimeException e) {
- // ensure same behaviour as by using Spring VelocityEngineUtils.mergeTemplateIntoString()
- throw e;
- } catch (Exception e) {
- LOG.error("Could not get mail body", e);
- }
-
- return result.toString();
- }
-
- /**
- * Create a Velocity Context for the given model, to be passed to the template for merging.
- *
- * @param model Velocity model
- * @return Velocity context
- */
- protected Context createVelocityContext(Map<String, Object> model) {
- Context toolContext = velocityToolManager.createContext();
- return new VelocityContext(model, toolContext);
- }
-
- /**
- * Create notification tasks for each notification matching the given user id and (some of) tasks performed.
- */
- public void createTasks(
- final AuditElements.EventCategoryType type,
- final String category,
- final String subcategory,
- final String event,
- final Result condition,
- final Object before,
- final Object output,
- final Object... input) {
-
- SubjectType subjectType = null;
- Subject<?, ?, ?> subject = null;
-
- if (before instanceof UserTO) {
- subjectType = SubjectType.USER;
- subject = userDAO.find(((UserTO) before).getKey());
- } else if (output instanceof UserTO) {
- subjectType = SubjectType.USER;
- subject = userDAO.find(((UserTO) output).getKey());
- } else if (before instanceof RoleTO) {
- subjectType = SubjectType.ROLE;
- subject = roleDAO.find(((RoleTO) before).getKey());
- } else if (output instanceof RoleTO) {
- subjectType = SubjectType.ROLE;
- subject = roleDAO.find(((RoleTO) output).getKey());
- }
-
- LOG.debug("Search notification for [{}]{}", subjectType, subject);
-
- for (Notification notification : notificationDAO.findAll()) {
- LOG.debug("Notification available user about {}", notification.getUserAbout());
- LOG.debug("Notification available role about {}", notification.getRoleAbout());
- if (notification.isActive()) {
-
- final Set<String> events = new HashSet<>(notification.getEvents());
- events.retainAll(Collections.<String>singleton(AuditLoggerName.buildEvent(
- type, category, subcategory, event, condition)));
-
- if (events.isEmpty()) {
- LOG.debug("No events found about {}", subject);
- } else if (subjectType == null || subject == null
- || notification.getUserAbout() == null || notification.getRoleAbout() == null
- || searchDAO.matches(subject,
- SearchCondConverter.convert(notification.getUserAbout()), subjectType)
- || searchDAO.matches(subject,
- SearchCondConverter.convert(notification.getRoleAbout()), subjectType)) {
-
- LOG.debug("Creating notification task for events {} about {}", events, subject);
-
- final Map<String, Object> model = new HashMap<>();
- model.put("type", type);
- model.put("category", category);
- model.put("subcategory", subcategory);
- model.put("event", event);
- model.put("condition", condition);
- model.put("before", before);
- model.put("output", output);
- model.put("input", input);
-
- if (subject instanceof User) {
- model.put("user", userDataBinder.getUserTO((User) subject));
- } else if (subject instanceof Role) {
- model.put("role", roleDataBinder.getRoleTO((Role) subject));
- }
-
- taskDAO.save(getNotificationTask(notification, subject, model));
- }
- } else {
- LOG.debug("Notification {}, userAbout {}, roleAbout {} is deactivated, "
- + "notification task will not be created", notification.getKey(),
- notification.getUserAbout(), notification.getRoleAbout());
- }
- }
- }
-
- private String getRecipientEmail(
- final IntMappingType recipientAttrType, final String recipientAttrName, final User user) {
-
- String email = null;
-
- switch (recipientAttrType) {
- case Username:
- email = user.getUsername();
- break;
-
- case UserPlainSchema:
- UPlainAttr attr = user.getPlainAttr(recipientAttrName);
- if (attr != null && !attr.getValuesAsStrings().isEmpty()) {
- email = attr.getValuesAsStrings().get(0);
- }
- break;
-
- case UserVirtualSchema:
- UVirAttr virAttr = user.getVirAttr(recipientAttrName);
- if (virAttr != null && !virAttr.getValues().isEmpty()) {
- email = virAttr.getValues().get(0);
- }
- break;
-
- case UserDerivedSchema:
- UDerAttr derAttr = user.getDerAttr(recipientAttrName);
- if (derAttr != null) {
- email = derAttr.getValue(user.getPlainAttrs());
- }
- break;
-
- default:
- }
-
- return email;
- }
-
- /**
- * Store execution of a NotificationTask.
- *
- * @param execution task execution.
- * @return merged task execution.
- */
- public TaskExec storeExec(final TaskExec execution) {
- NotificationTask task = taskDAO.find(execution.getTask().getKey());
- task.addExec(execution);
- task.setExecuted(true);
- taskDAO.save(task);
- // this flush call is needed to generate a value for the execution id
- taskDAO.flush();
- return execution;
- }
-
- /**
- * Set execution state of NotificationTask with provided id.
- *
- * @param taskId task to be updated
- * @param executed execution state
- */
- public void setTaskExecuted(final Long taskId, final boolean executed) {
- NotificationTask task = taskDAO.find(taskId);
- task.setExecuted(executed);
- taskDAO.save(task);
- }
-
- /**
- * Count the number of task executions of a given task with a given status.
- *
- * @param taskId task id
- * @param status status
- * @return number of task executions
- */
- public long countExecutionsWithStatus(final Long taskId, final String status) {
- NotificationTask task = taskDAO.find(taskId);
- long count = 0;
- for (TaskExec taskExec : task.getExecs()) {
- if (status == null) {
- if (taskExec.getStatus() == null) {
- count++;
- }
- } else if (status.equals(taskExec.getStatus())) {
- count++;
- }
- }
- return count;
- }
-
- protected Map<String, String> findAllSyncopeConfs() {
- Map<String, String> syncopeConfMap = new HashMap<>();
- for (PlainAttr attr : confDAO.get().getPlainAttrs()) {
- syncopeConfMap.put(attr.getSchema().getKey(), attr.getValuesAsStrings().get(0));
- }
- return syncopeConfMap;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManagerImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManagerImpl.java
new file mode 100644
index 0000000..dd323bc
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManagerImpl.java
@@ -0,0 +1,416 @@
+/*
+ * 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.provisioning.java.notification;
+
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
+import java.io.StringWriter;
+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 org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.dao.ConfDAO;
+import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.server.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.server.persistence.api.dao.TaskDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.server.persistence.api.entity.Attributable;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtilFactory;
+import org.apache.syncope.server.persistence.api.entity.EntityFactory;
+import org.apache.syncope.server.persistence.api.entity.Notification;
+import org.apache.syncope.server.persistence.api.entity.PlainAttr;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.server.persistence.api.entity.user.UDerAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UVirAttr;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.data.RoleDataBinder;
+import org.apache.syncope.server.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.server.misc.ConnObjectUtil;
+import org.apache.syncope.server.misc.search.SearchCondConverter;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.exception.VelocityException;
+import org.apache.velocity.tools.ToolManager;
+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;
+
+@Component
+@Transactional(rollbackFor = { Throwable.class })
+public class NotificationManagerImpl implements NotificationManager {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(NotificationManager.class);
+
+ public static final String MAIL_TEMPLATES = "mailTemplates/";
+
+ public static final String MAIL_TEMPLATE_HTML_SUFFIX = ".html.vm";
+
+ public static final String MAIL_TEMPLATE_TEXT_SUFFIX = ".txt.vm";
+
+ /**
+ * Notification DAO.
+ */
+ @Autowired
+ private NotificationDAO notificationDAO;
+
+ /**
+ * Configuration DAO.
+ */
+ @Autowired
+ private ConfDAO confDAO;
+
+ /**
+ * User DAO.
+ */
+ @Autowired
+ private UserDAO userDAO;
+
+ /**
+ * Role DAO.
+ */
+ @Autowired
+ private RoleDAO roleDAO;
+
+ /**
+ * User Search DAO.
+ */
+ @Autowired
+ private SubjectSearchDAO searchDAO;
+
+ /**
+ * Task DAO.
+ */
+ @Autowired
+ private TaskDAO taskDAO;
+
+ /**
+ * Velocity template engine.
+ */
+ @Autowired
+ private VelocityEngine velocityEngine;
+
+ /**
+ * Velocity tool manager.
+ */
+ @Autowired
+ private ToolManager velocityToolManager;
+
+ @Autowired
+ private EntitlementDAO entitlementDAO;
+
+ @Autowired
+ private ConnObjectUtil connObjectUtil;
+
+ @Autowired
+ private UserDataBinder userDataBinder;
+
+ @Autowired
+ private RoleDataBinder roleDataBinder;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private AttributableUtilFactory attrUtilFactory;
+
+ @Transactional(readOnly = true)
+ @Override
+ public long getMaxRetries() {
+ return confDAO.find("notification.maxRetries", "0").getValues().get(0).getLongValue();
+ }
+
+ /**
+ * Create a notification task.
+ *
+ * @param notification notification to take as model
+ * @param attributable the user this task is about
+ * @param model Velocity model
+ * @return notification task, fully populated
+ */
+ private NotificationTask getNotificationTask(
+ final Notification notification,
+ final Attributable<?, ?, ?> attributable,
+ final Map<String, Object> model) {
+
+ if (attributable != null) {
+ connObjectUtil.retrieveVirAttrValues(attributable,
+ attrUtilFactory.getInstance(
+ attributable instanceof User ? AttributableType.USER : AttributableType.ROLE));
+ }
+
+ final List<User> recipients = new ArrayList<>();
+
+ if (notification.getRecipients() != null) {
+ recipients.addAll(searchDAO.<User>search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()),
+ SearchCondConverter.convert(notification.getRecipients()),
+ Collections.<OrderByClause>emptyList(), SubjectType.USER));
+ }
+
+ if (notification.isSelfAsRecipient() && attributable instanceof User) {
+ recipients.add((User) attributable);
+ }
+
+ final Set<String> recipientEmails = new HashSet<>();
+ final List<UserTO> recipientTOs = new ArrayList<>(recipients.size());
+ for (User recipient : recipients) {
+ connObjectUtil.retrieveVirAttrValues(recipient, attrUtilFactory.getInstance(AttributableType.USER));
+
+ String email = getRecipientEmail(notification.getRecipientAttrType(),
+ notification.getRecipientAttrName(), recipient);
+ if (email == null) {
+ LOG.warn("{} cannot be notified: {} not found", recipient, notification.getRecipientAttrName());
+ } else {
+ recipientEmails.add(email);
+ recipientTOs.add(userDataBinder.getUserTO(recipient));
+ }
+ }
+
+ if (notification.getStaticRecipients() != null) {
+ recipientEmails.addAll(notification.getStaticRecipients());
+ }
+
+ model.put("recipients", recipientTOs);
+ model.put("syncopeConf", this.findAllSyncopeConfs());
+ model.put("events", notification.getEvents());
+
+ NotificationTask task = entityFactory.newEntity(NotificationTask.class);
+ task.setTraceLevel(notification.getTraceLevel());
+ task.getRecipients().addAll(recipientEmails);
+ task.setSender(notification.getSender());
+ task.setSubject(notification.getSubject());
+
+ String htmlBody = mergeTemplateIntoString(
+ MAIL_TEMPLATES + notification.getTemplate() + MAIL_TEMPLATE_HTML_SUFFIX, model);
+ String textBody = mergeTemplateIntoString(
+ MAIL_TEMPLATES + notification.getTemplate() + MAIL_TEMPLATE_TEXT_SUFFIX, model);
+
+ task.setHtmlBody(htmlBody);
+ task.setTextBody(textBody);
+
+ return task;
+ }
+
+ private String mergeTemplateIntoString(final String templateLocation, final Map<String, Object> model) {
+ StringWriter result = new StringWriter();
+ try {
+ Context velocityContext = createVelocityContext(model);
+ velocityEngine.mergeTemplate(templateLocation, SyncopeConstants.DEFAULT_ENCODING, velocityContext, result);
+ } catch (VelocityException e) {
+ LOG.error("Could not get mail body", e);
+ } catch (RuntimeException e) {
+ // ensure same behaviour as by using Spring VelocityEngineUtils.mergeTemplateIntoString()
+ throw e;
+ } catch (Exception e) {
+ LOG.error("Could not get mail body", e);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Create a Velocity Context for the given model, to be passed to the template for merging.
+ *
+ * @param model Velocity model
+ * @return Velocity context
+ */
+ protected Context createVelocityContext(Map<String, Object> model) {
+ Context toolContext = velocityToolManager.createContext();
+ return new VelocityContext(model, toolContext);
+ }
+
+ @Override
+ public void createTasks(
+ final AuditElements.EventCategoryType type,
+ final String category,
+ final String subcategory,
+ final String event,
+ final Result condition,
+ final Object before,
+ final Object output,
+ final Object... input) {
+
+ SubjectType subjectType = null;
+ Subject<?, ?, ?> subject = null;
+
+ if (before instanceof UserTO) {
+ subjectType = SubjectType.USER;
+ subject = userDAO.find(((UserTO) before).getKey());
+ } else if (output instanceof UserTO) {
+ subjectType = SubjectType.USER;
+ subject = userDAO.find(((UserTO) output).getKey());
+ } else if (before instanceof RoleTO) {
+ subjectType = SubjectType.ROLE;
+ subject = roleDAO.find(((RoleTO) before).getKey());
+ } else if (output instanceof RoleTO) {
+ subjectType = SubjectType.ROLE;
+ subject = roleDAO.find(((RoleTO) output).getKey());
+ }
+
+ LOG.debug("Search notification for [{}]{}", subjectType, subject);
+
+ for (Notification notification : notificationDAO.findAll()) {
+ LOG.debug("Notification available user about {}", notification.getUserAbout());
+ LOG.debug("Notification available role about {}", notification.getRoleAbout());
+ if (notification.isActive()) {
+
+ final Set<String> events = new HashSet<>(notification.getEvents());
+ events.retainAll(Collections.<String>singleton(AuditLoggerName.buildEvent(
+ type, category, subcategory, event, condition)));
+
+ if (events.isEmpty()) {
+ LOG.debug("No events found about {}", subject);
+ } else if (subjectType == null || subject == null
+ || notification.getUserAbout() == null || notification.getRoleAbout() == null
+ || searchDAO.matches(subject,
+ SearchCondConverter.convert(notification.getUserAbout()), subjectType)
+ || searchDAO.matches(subject,
+ SearchCondConverter.convert(notification.getRoleAbout()), subjectType)) {
+
+ LOG.debug("Creating notification task for events {} about {}", events, subject);
+
+ final Map<String, Object> model = new HashMap<>();
+ model.put("type", type);
+ model.put("category", category);
+ model.put("subcategory", subcategory);
+ model.put("event", event);
+ model.put("condition", condition);
+ model.put("before", before);
+ model.put("output", output);
+ model.put("input", input);
+
+ if (subject instanceof User) {
+ model.put("user", userDataBinder.getUserTO((User) subject));
+ } else if (subject instanceof Role) {
+ model.put("role", roleDataBinder.getRoleTO((Role) subject));
+ }
+
+ taskDAO.save(getNotificationTask(notification, subject, model));
+ }
+ } else {
+ LOG.debug("Notification {}, userAbout {}, roleAbout {} is deactivated, "
+ + "notification task will not be created", notification.getKey(),
+ notification.getUserAbout(), notification.getRoleAbout());
+ }
+ }
+ }
+
+ private String getRecipientEmail(
+ final IntMappingType recipientAttrType, final String recipientAttrName, final User user) {
+
+ String email = null;
+
+ switch (recipientAttrType) {
+ case Username:
+ email = user.getUsername();
+ break;
+
+ case UserPlainSchema:
+ UPlainAttr attr = user.getPlainAttr(recipientAttrName);
+ if (attr != null && !attr.getValuesAsStrings().isEmpty()) {
+ email = attr.getValuesAsStrings().get(0);
+ }
+ break;
+
+ case UserVirtualSchema:
+ UVirAttr virAttr = user.getVirAttr(recipientAttrName);
+ if (virAttr != null && !virAttr.getValues().isEmpty()) {
+ email = virAttr.getValues().get(0);
+ }
+ break;
+
+ case UserDerivedSchema:
+ UDerAttr derAttr = user.getDerAttr(recipientAttrName);
+ if (derAttr != null) {
+ email = derAttr.getValue(user.getPlainAttrs());
+ }
+ break;
+
+ default:
+ }
+
+ return email;
+ }
+
+ @Override
+ public TaskExec storeExec(final TaskExec execution) {
+ NotificationTask task = taskDAO.find(execution.getTask().getKey());
+ task.addExec(execution);
+ task.setExecuted(true);
+ taskDAO.save(task);
+ // this flush call is needed to generate a value for the execution id
+ taskDAO.flush();
+ return execution;
+ }
+
+ @Override
+ public void setTaskExecuted(final Long taskId, final boolean executed) {
+ NotificationTask task = taskDAO.find(taskId);
+ task.setExecuted(executed);
+ taskDAO.save(task);
+ }
+
+ @Override
+ public long countExecutionsWithStatus(final Long taskId, final String status) {
+ NotificationTask task = taskDAO.find(taskId);
+ long count = 0;
+ for (TaskExec taskExec : task.getExecs()) {
+ if (status == null) {
+ if (taskExec.getStatus() == null) {
+ count++;
+ }
+ } else if (status.equals(taskExec.getStatus())) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ protected Map<String, String> findAllSyncopeConfs() {
+ Map<String, String> syncopeConfMap = new HashMap<>();
+ for (PlainAttr attr : confDAO.get().getPlainAttrs()) {
+ syncopeConfMap.put(attr.getSchema().getKey(), attr.getValuesAsStrings().get(0));
+ }
+ return syncopeConfMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 86df210..725a561 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -47,10 +47,10 @@ import org.apache.syncope.server.provisioning.api.propagation.PropagationActions
import org.apache.syncope.server.provisioning.api.propagation.PropagationReporter;
import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
import org.apache.syncope.server.misc.AuditManager;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
import org.apache.syncope.server.misc.ConnObjectUtil;
import org.apache.syncope.server.misc.ExceptionUtil;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncopeResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncopeResultHandler.java
index fbd5b7e..c991685 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncopeResultHandler.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncopeResultHandler.java
@@ -32,8 +32,8 @@ import org.apache.syncope.server.provisioning.api.sync.ProvisioningActions;
import org.apache.syncope.server.provisioning.api.sync.ProvisioningProfile;
import org.apache.syncope.server.provisioning.api.sync.SyncopeResultHandler;
import org.apache.syncope.server.misc.AuditManager;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
import org.apache.syncope.server.misc.ConnObjectUtil;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
index 145cd4d..5d2d6ad 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
@@ -47,7 +47,7 @@ import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExe
import org.apache.syncope.server.provisioning.api.sync.ProvisioningProfile;
import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
import org.apache.syncope.server.misc.AuditManager;
-import org.apache.syncope.server.provisioning.java.notification.NotificationManager;
+import org.apache.syncope.server.provisioning.api.notification.NotificationManager;
import org.apache.syncope.server.workflow.api.UserWorkflowAdapter;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.ObjectClass;
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/syncope620/server/workflow-activiti/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/workflow-activiti/pom.xml b/syncope620/server/workflow-activiti/pom.xml
new file mode 100644
index 0000000..3d6db04
--- /dev/null
+++ b/syncope620/server/workflow-activiti/pom.xml
@@ -0,0 +1,83 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-server</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Server Workflow Activiti</name>
+ <description>Apache Syncope Server Workflow Activiti</description>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-server-workflow-activiti</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-engine</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.activiti</groupId>
+ <artifactId>activiti-json-converter</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-server-workflow-java</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-server-misc</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/702810d8/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
new file mode 100644
index 0000000..05bcc94
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/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.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/702810d8/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
new file mode 100644
index 0000000..388f7e9
--- /dev/null
+++ b/syncope620/server/workflow-activiti/src/main/java/org/apache/syncope/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.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);
+ }
+ }
+}